mirror of
https://github.com/Relintai/godot-lportal.git
synced 2024-11-11 10:52:09 +01:00
Starting to optimize shadow caster list
This commit is contained in:
parent
7dd45301fa
commit
47fc1fa319
10
ldebug.h
10
ldebug.h
@ -1,9 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#define LPRINT_RUN(a, b) {String sz;\
|
||||
for (int n=0; n<Lawn::LDebug::m_iTabDepth; n++)\
|
||||
sz += "\t";\
|
||||
LPRINT(a, sz + b);}
|
||||
#define LPRINT_RUN(a, b) ;
|
||||
|
||||
//#define LPRINT_RUN(a, b) {String sz;\
|
||||
//for (int n=0; n<Lawn::LDebug::m_iTabDepth; n++)\
|
||||
//sz += "\t";\
|
||||
//LPRINT(a, sz + b);}
|
||||
|
||||
#define LPRINT(a, b) if (!Lawn::LDebug::m_bRunning) {\
|
||||
if (a >= Lawn::LDebug::m_iLoggingLevel)\
|
||||
|
@ -33,6 +33,14 @@
|
||||
class LRoom;
|
||||
class LRoomManager;
|
||||
|
||||
|
||||
class LLight
|
||||
{
|
||||
public:
|
||||
Vector3 m_ptDir;
|
||||
};
|
||||
|
||||
|
||||
class LPortal {
|
||||
public:
|
||||
|
||||
|
50
lroom.cpp
50
lroom.cpp
@ -36,6 +36,9 @@ LRoom::LRoom() {
|
||||
|
||||
m_iFirstSOB = 0;
|
||||
m_iNumSOBs = 0;
|
||||
|
||||
m_iFirstShadowCaster_SOB = 0;
|
||||
m_iNumShadowCasters_SOB = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -169,17 +172,19 @@ void LRoom::SoftShow(VisualInstance * pVI, bool bShow)
|
||||
// naive version, adds all the non visible objects in visible rooms as shadow casters
|
||||
void LRoom::AddShadowCasters(LRoomManager &manager)
|
||||
{
|
||||
// return;
|
||||
|
||||
int last_sob = m_iFirstSOB + m_iNumSOBs;
|
||||
for (int n=m_iFirstSOB; n<last_sob; n++)
|
||||
{
|
||||
bool bVisible = manager.m_BF_visible_SOBs.GetBit(n) != 0;
|
||||
// bool bVisible = manager.m_BF_visible_SOBs.GetBit(n) != 0;
|
||||
|
||||
// already in list
|
||||
if (bVisible)
|
||||
continue;
|
||||
// // already in list
|
||||
// if (bVisible)
|
||||
// continue;
|
||||
|
||||
manager.m_BF_render_SOBs.SetBit(n, true);
|
||||
manager.m_RenderList_SOBs.push_back(n);
|
||||
manager.m_BF_caster_SOBs.SetBit(n, true);
|
||||
manager.m_CasterList_SOBs.push_back(n);
|
||||
}
|
||||
|
||||
}
|
||||
@ -189,22 +194,23 @@ void LRoom::AddShadowCasters(LRoomManager &manager)
|
||||
// (it might be expensive)
|
||||
void LRoom::FinalizeVisibility(LRoomManager &manager)
|
||||
{
|
||||
int last_sob = m_iFirstSOB + m_iNumSOBs;
|
||||
for (int n=m_iFirstSOB; n<last_sob; n++)
|
||||
{
|
||||
LSob &sob = manager.m_SOBs[n];
|
||||
Spatial * pS = sob.GetSpatial();
|
||||
if (!pS)
|
||||
continue;
|
||||
|
||||
if (manager.m_BF_master_SOBs.GetBit(n))
|
||||
pS->show();
|
||||
else
|
||||
pS->hide();
|
||||
}
|
||||
|
||||
|
||||
//print_line("FinalizeVisibility room " + get_name() + " NumSOBs " + itos(m_SOBs.size()) + ", NumDOBs " + itos(m_DOBs.size()));
|
||||
|
||||
// int last_sob = m_iFirstSOB + m_iNumSOBs;
|
||||
// for (int n=m_iFirstSOB; n<last_sob; n++)
|
||||
// {
|
||||
// const LSob &sob = manager.m_SOBs[n];
|
||||
// VisualInstance * pVI = sob.GetVI();
|
||||
|
||||
// if (pVI)
|
||||
// {
|
||||
// //SoftShow(pVI, sob.m_bSOBVisible);
|
||||
// bool bVisible = manager.m_BF_visible_SOBs.GetBit(n) != 0;
|
||||
// SoftShow(pVI, bVisible);
|
||||
// }
|
||||
// }
|
||||
|
||||
for (int n=0; n<m_DOBs.size(); n++)
|
||||
{
|
||||
const LDob &dob = m_DOBs[n];
|
||||
@ -402,8 +408,8 @@ void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, cons
|
||||
//sob.m_bSOBVisible = true;
|
||||
// sob is renderable and visible (not shadow only)
|
||||
manager.m_BF_visible_SOBs.SetBit(n, true);
|
||||
manager.m_BF_render_SOBs.SetBit(n, true);
|
||||
manager.m_RenderList_SOBs.push_back(n);
|
||||
//manager.m_BF_render_SOBs.SetBit(n, true);
|
||||
manager.m_VisibleList_SOBs.push_back(n);
|
||||
}
|
||||
|
||||
} // for through sobs
|
||||
|
3
lroom.h
3
lroom.h
@ -68,6 +68,9 @@ public:
|
||||
int m_iFirstPortal;
|
||||
int m_iNumPortals;
|
||||
|
||||
int m_iFirstShadowCaster_SOB;
|
||||
int m_iNumShadowCasters_SOB;
|
||||
|
||||
// Just very rough, room centre for determining start rooms of dobs
|
||||
Vector3 m_ptCentre;
|
||||
AABB m_AABB; // world bound
|
||||
|
@ -42,6 +42,8 @@ void LRoomConverter::Convert(LRoomManager &manager)
|
||||
int count = CountRooms();
|
||||
|
||||
LMAN->m_SOBs.clear();
|
||||
LMAN->m_ShadowCasters_SOB.clear();
|
||||
LMAN->m_Lights.clear();
|
||||
|
||||
// make sure bitfield is right size for number of rooms
|
||||
LMAN->m_BF_visible_rooms.Create(count);
|
||||
@ -57,21 +59,26 @@ void LRoomConverter::Convert(LRoomManager &manager)
|
||||
Convert_Rooms();
|
||||
Convert_Portals();
|
||||
Convert_Bounds();
|
||||
Convert_ShadowCasters();
|
||||
|
||||
// make sure manager bitfields are the correct size for number of objects
|
||||
int num_sobs = LMAN->m_SOBs.size();
|
||||
LPRINT(5,"Total SOBs " + itos(num_sobs));
|
||||
LMAN->m_BF_render_SOBs.Create(num_sobs);
|
||||
LMAN->m_BF_caster_SOBs.Create(num_sobs);
|
||||
LMAN->m_BF_visible_SOBs.Create(num_sobs);
|
||||
LMAN->m_BF_master_SOBs.Create(num_sobs);
|
||||
|
||||
|
||||
// temp rooms no longer needed
|
||||
m_TempRooms.clear(true);
|
||||
|
||||
|
||||
Lawn::LDebug::m_bRunning = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void LRoomConverter::Convert_Rooms()
|
||||
{
|
||||
LPRINT(5,"Convert_Rooms");
|
||||
@ -286,6 +293,18 @@ bool LRoomConverter::Convert_Bound(LRoom &lroom, MeshInstance * pMI)
|
||||
return false;
|
||||
}
|
||||
|
||||
void LRoomConverter::Convert_ShadowCasters()
|
||||
{
|
||||
LPRINT(5,"Convert_ShadowCasters");
|
||||
|
||||
for (int n=0; n<LMAN->m_Rooms.size(); n++)
|
||||
{
|
||||
LRoom &lroom = LMAN->m_Rooms[n];
|
||||
LRoom_FindShadowCasters(lroom);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LRoomConverter::Convert_Bounds()
|
||||
{
|
||||
for (int n=0; n<LMAN->m_Rooms.size(); n++)
|
||||
@ -364,6 +383,94 @@ int LRoomConverter::CountRooms()
|
||||
}
|
||||
|
||||
|
||||
// find all objects that cast shadows onto the objects in this room
|
||||
void LRoomConverter::LRoom_FindShadowCasters(LRoom &lroom)
|
||||
{
|
||||
return;
|
||||
|
||||
// first add all objects in this room as casters
|
||||
for (int n=0; n<lroom.m_iNumSOBs; n++)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
// just a constant light direction for now
|
||||
LLight light;
|
||||
light.m_ptDir = Vector3(1.0f, -1.0f, 0.0f);
|
||||
light.m_ptDir.normalize();
|
||||
|
||||
// reset the planes pool for each render out from the source room
|
||||
LMAN->m_Pool.Reset();
|
||||
|
||||
|
||||
// the first set of planes are blank
|
||||
unsigned int pool_member = LMAN->m_Pool.Request();
|
||||
assert (pool_member != -1);
|
||||
|
||||
LVector<Plane> &planes = LMAN->m_Pool.Get(pool_member);
|
||||
planes.clear();
|
||||
|
||||
LRoom_FindShadowCasters_Recursive(lroom, light, planes);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void LRoomConverter::LRoom_FindShadowCasters_Recursive(LRoom &lroom, const LLight &light, const LVector<Plane> &planes)
|
||||
{
|
||||
// look through every portal out
|
||||
for (int n=0; n<lroom.m_iNumPortals; n++)
|
||||
{
|
||||
int portalID = lroom.m_iFirstPortal + n;
|
||||
|
||||
const LPortal &port = LMAN->m_Portals[portalID];
|
||||
|
||||
|
||||
// cull with light direction
|
||||
float dot = port.m_Plane.normal.dot(light.m_ptDir);
|
||||
if (dot <= 0.0f)
|
||||
continue;
|
||||
|
||||
LRoom &linked_room = LMAN->Portal_GetLinkedRoom(port);
|
||||
|
||||
|
||||
// recurse into that portal
|
||||
unsigned int uiPoolMem = LMAN->m_Pool.Request();
|
||||
if (uiPoolMem != -1)
|
||||
{
|
||||
// get a vector of planes from the pool
|
||||
LVector<Plane> &new_planes = LMAN->m_Pool.Get(uiPoolMem);
|
||||
|
||||
// copy the existing planes
|
||||
new_planes.copy_from(planes);
|
||||
|
||||
// add the planes for the portal
|
||||
// port.AddPlanes(manager, cam.m_ptPos, new_planes);
|
||||
|
||||
|
||||
LRoom_FindShadowCasters_Recursive(linked_room, light, new_planes);
|
||||
// for debugging need to reset tab depth
|
||||
//Lawn::LDebug::m_iTabDepth = depth;
|
||||
|
||||
// we no longer need these planes
|
||||
LMAN->m_Pool.Free(uiPoolMem);
|
||||
}
|
||||
else
|
||||
{
|
||||
// planes pool is empty!
|
||||
// This will happen if the view goes through shedloads of portals
|
||||
// The solution is either to increase the plane pool size, or build levels
|
||||
// with views through multiple portals. Looking through multiple portals is likely to be
|
||||
// slow anyway because of the number of planes to test.
|
||||
WARN_PRINT_ONCE("LRoom_FindShadowCasters_Recursive : Planes pool is empty");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// go through the nodes hanging off the room looking for those that are meshes to mark portal locations
|
||||
void LRoomConverter::LRoom_DetectPortalMeshes(LRoom &lroom, LTempRoom &troom)
|
||||
{
|
||||
|
@ -93,6 +93,7 @@ private:
|
||||
void Convert_Portals();
|
||||
void Convert_Bounds();
|
||||
bool Convert_Bound(LRoom &lroom, MeshInstance * pMI);
|
||||
void Convert_ShadowCasters();
|
||||
|
||||
|
||||
void LRoom_DetectPortalMeshes(LRoom &lroom, LTempRoom &troom);
|
||||
@ -101,6 +102,8 @@ private:
|
||||
void LRoom_DetectedPortalMesh(LRoom &lroom, LTempRoom &troom, MeshInstance * pMeshInstance, String szLinkRoom);
|
||||
LPortal * LRoom_RequestNewPortal(LRoom &lroom);
|
||||
void LRoom_PushBackSOB(LRoom &lroom, const LSob &sob);
|
||||
void LRoom_FindShadowCasters(LRoom &lroom);
|
||||
void LRoom_FindShadowCasters_Recursive(LRoom &lroom, const LLight &light, const LVector<Plane> &planes);
|
||||
|
||||
void TRoom_MakeOppositePortal(const LPortal &port, int iRoomOrig);
|
||||
|
||||
|
@ -602,9 +602,13 @@ void LRoomManager::FrameUpdate_Prepare()
|
||||
m_DebugPlanes.clear();
|
||||
// clear the visible room list to write to each frame
|
||||
m_pCurr_VisibleRoomList->clear();
|
||||
m_RenderList_SOBs.clear();
|
||||
m_BF_render_SOBs.Blank();
|
||||
|
||||
m_VisibleList_SOBs.clear();
|
||||
m_CasterList_SOBs.clear();
|
||||
|
||||
m_BF_caster_SOBs.Blank();
|
||||
m_BF_visible_SOBs.Blank();
|
||||
m_BF_master_SOBs.Blank();
|
||||
|
||||
// as we hit visible rooms we will mark them in a bitset, so we can hide any rooms
|
||||
// that are showing that haven't been hit this frame
|
||||
@ -695,11 +699,13 @@ void LRoomManager::FrameUpdate()
|
||||
// finally hide all the rooms that are currently visible but not in the visible bitfield as having been hit
|
||||
FrameUpdate_FinalizeRooms();
|
||||
|
||||
FrameUpdate_AddShadowCasters();
|
||||
|
||||
FrameUpdate_CreateMasterList();
|
||||
|
||||
// set soft visibility of objects within visible rooms
|
||||
FrameUpdate_FinalizeVisibility_WithinRooms();
|
||||
|
||||
FrameUpdate_AddShadowCasters();
|
||||
|
||||
FrameUpdate_FinalizeVisibility_SoftShow();
|
||||
|
||||
// swap the current and previous visible room list
|
||||
@ -745,6 +751,32 @@ void LRoomManager::FrameUpdate_FinalizeRooms()
|
||||
}
|
||||
}
|
||||
|
||||
// to optimize just 1 call to the visual server, we want a list of all sobs that are either visible or casters
|
||||
// this allows 1 call to show / hide, and 1 call to layer flags
|
||||
void LRoomManager::FrameUpdate_CreateMasterList()
|
||||
{
|
||||
for (int n=0; n<m_VisibleList_SOBs.size(); n++)
|
||||
{
|
||||
int sob_id = m_VisibleList_SOBs[n];
|
||||
m_MasterList_SOBs.push_back(sob_id);
|
||||
m_BF_master_SOBs.SetBit(sob_id, true);
|
||||
}
|
||||
|
||||
for (int n=0; n<m_CasterList_SOBs.size(); n++)
|
||||
{
|
||||
int sob_id = m_CasterList_SOBs[n];
|
||||
|
||||
// if not already on master list
|
||||
if (m_BF_master_SOBs.GetBit(sob_id) == 0)
|
||||
{
|
||||
m_MasterList_SOBs.push_back(sob_id);
|
||||
m_BF_master_SOBs.SetBit(sob_id, true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void LRoomManager::FrameUpdate_AddShadowCasters()
|
||||
{
|
||||
// simple for the moment, add all objects in visible rooms as casters if they are not already visible
|
||||
@ -759,11 +791,11 @@ void LRoomManager::FrameUpdate_AddShadowCasters()
|
||||
void LRoomManager::FrameUpdate_FinalizeVisibility_SoftShow()
|
||||
{
|
||||
// apply the appropriate soft show for each sob in the render list
|
||||
int nSOBs = m_RenderList_SOBs.size();
|
||||
int nSOBs = m_MasterList_SOBs.size();
|
||||
|
||||
for (int n=0; n<nSOBs; n++)
|
||||
{
|
||||
int ID = m_RenderList_SOBs[n];
|
||||
int ID = m_MasterList_SOBs[n];
|
||||
const LSob &sob = m_SOBs[ID];
|
||||
|
||||
VisualInstance * pVI = sob.GetVI();
|
||||
|
@ -52,11 +52,15 @@ class LRoomManager : public Spatial {
|
||||
|
||||
// the render list is all objects that are in view,
|
||||
// and also objects out of view but casting shadows INTO the view
|
||||
LVector<int> m_RenderList_SOBs;
|
||||
Lawn::LBitField_Dynamic m_BF_render_SOBs;
|
||||
LVector<int> m_VisibleList_SOBs;
|
||||
LVector<int> m_CasterList_SOBs;
|
||||
LVector<int> m_MasterList_SOBs;
|
||||
|
||||
|
||||
// visible bit marks in view, if not set, it is a shadow caster only
|
||||
Lawn::LBitField_Dynamic m_BF_visible_SOBs;
|
||||
Lawn::LBitField_Dynamic m_BF_caster_SOBs;
|
||||
Lawn::LBitField_Dynamic m_BF_master_SOBs;
|
||||
|
||||
|
||||
LVector<int> m_VisibleRoomList_A;
|
||||
LVector<int> m_VisibleRoomList_B;
|
||||
@ -81,6 +85,10 @@ private:
|
||||
|
||||
// static objects
|
||||
LVector<LSob> m_SOBs;
|
||||
LVector<LLight> m_Lights;
|
||||
|
||||
// master list of shadow casters for each room
|
||||
LVector<uint32_t> m_ShadowCasters_SOB;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
@ -98,6 +106,7 @@ private:
|
||||
void FrameUpdate_Prepare();
|
||||
void FrameUpdate_FinalizeRooms();
|
||||
void FrameUpdate_AddShadowCasters();
|
||||
void FrameUpdate_CreateMasterList();
|
||||
void FrameUpdate_FinalizeVisibility_WithinRooms();
|
||||
void FrameUpdate_FinalizeVisibility_SoftShow();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user