Hiding of unvisited rooms more efficient

This commit is contained in:
lawnjelly 2019-09-15 16:16:09 +01:00 committed by GitHub
parent 56e785ab4b
commit 092579db66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 59 additions and 14 deletions

View File

@ -23,6 +23,7 @@ unsigned int LPlanesPool::Request()
if (m_uiCount >= POOL_MAX)
return -1;
// could be done more efficiently .. NYI
for (unsigned int n=0; n<POOL_MAX; n++)
{
if (m_ucTaken[n] == 0)

View File

@ -3,6 +3,11 @@
#include "lvector.h"
#include "core/math/plane.h"
// The recursive visibility function needs to allocate lists of planes each time a room is traversed.
// Instead of doing this allocation on the fly we will use a pool which should be much faster and nearer
// constant time.
// Note this simple pool isn't super optimal but should be fine for now.
class LPlanesPool
{
public:

View File

@ -120,9 +120,18 @@ void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, cons
print("DetermineVisibility_Recursive from " + get_name());
// set the frame counter
// only handle one touch per frame so far (one portal into room)
assert (manager.m_uiFrameCounter > m_uiFrameTouched);
m_uiFrameTouched = manager.m_uiFrameCounter;
// first touch
if (m_uiFrameTouched < manager.m_uiFrameCounter)
{
// set the frame counter
m_uiFrameTouched = manager.m_uiFrameCounter;
// keep track of which rooms are shown this frame
manager.m_pCurr_VisibleRoomList->push_back(m_RoomID);
}
// show this room and add to visible list of rooms
GetGodotRoom()->show();

View File

@ -23,12 +23,12 @@ public:
}
void ExpandToEnclose(const AABB &bb)
{
if (bb.position.x < m_ptMins.x) m_ptMins.x = bb.position.x;
if (bb.position.y < m_ptMins.y) m_ptMins.y = bb.position.y;
if (bb.position.z < m_ptMins.z) m_ptMins.z = bb.position.z;
if (bb.position.x + bb.size.x > m_ptMaxs.x) m_ptMaxs.x = bb.position.x + bb.size.x;
if (bb.position.y + bb.size.y > m_ptMaxs.y) m_ptMaxs.y = bb.position.y + bb.size.y;
if (bb.position.z + bb.size.z > m_ptMaxs.z) m_ptMaxs.z = bb.position.z + bb.size.z;
if (bb.position.x < m_ptMins.x) m_ptMins.x = bb.position.x;
if (bb.position.y < m_ptMins.y) m_ptMins.y = bb.position.y;
if (bb.position.z < m_ptMins.z) m_ptMins.z = bb.position.z;
if (bb.position.x + bb.size.x > m_ptMaxs.x) m_ptMaxs.x = bb.position.x + bb.size.x;
if (bb.position.y + bb.size.y > m_ptMaxs.y) m_ptMaxs.y = bb.position.y + bb.size.y;
if (bb.position.z + bb.size.z > m_ptMaxs.z) m_ptMaxs.z = bb.position.z + bb.size.z;
}
Vector3 FindCentre() const
{

View File

@ -28,6 +28,10 @@ LRoomManager::LRoomManager()
{
m_cameraID = 0;
m_uiFrameCounter = 0;
// to know which rooms to hide we keep track of which were shown this, and the previous frame
m_pCurr_VisibleRoomList = &m_VisibleRoomList[0];
m_pPrev_VisibleRoomList = &m_VisibleRoomList[1];
}
int LRoomManager::FindClosestRoom(const Vector3 &pt) const
@ -226,6 +230,9 @@ void LRoomManager::FrameUpdate()
// we keep a frame counter to prevent visiting things multiple times on the same frame in recursive functions
m_uiFrameCounter++;
// clear the visible room list to write to each frame
m_pCurr_VisibleRoomList->clear();
// get the camera desired and make into lcamera
Camera * pCamera = 0;
if (m_cameraID)
@ -285,14 +292,35 @@ void LRoomManager::FrameUpdate()
pRoom->DetermineVisibility_Recursive(*this, 0, cam, planes);
// finally hide all the rooms that are currently visible but not in the visible bitfield as having been hit
// NOTE this will be done more efficiently, but is okay to start with
for (int n=0; n<m_Rooms.size(); n++)
// to get started
if (!m_pPrev_VisibleRoomList->size())
{
if (!m_BF_visible_rooms.GetBit(n))
// NOTE this will be done more efficiently, but is okay to start with
for (int n=0; n<m_Rooms.size(); n++)
{
m_Rooms[n].GetGodotRoom()->hide();
if (!m_BF_visible_rooms.GetBit(n))
{
m_Rooms[n].GetGodotRoom()->hide();
}
}
}
else
{
// hide all rooms that were visible last frame but aren't visible this frame
for (int n=0; n<m_pPrev_VisibleRoomList->size(); n++)
{
int r = (*m_pPrev_VisibleRoomList)[n];
if (!m_BF_visible_rooms.GetBit(r))
m_Rooms[r].GetGodotRoom()->hide();
}
// swap the current and previous visible room list
LVector<int> * pTemp = m_pCurr_VisibleRoomList;
m_pCurr_VisibleRoomList = m_pPrev_VisibleRoomList;
m_pPrev_VisibleRoomList = pTemp;
}
// when running, emit less debugging output so as not to choke the IDE
LPortal::m_bRunning = true;

View File

@ -48,8 +48,10 @@ class LRoomManager : public Spatial {
// keep track of which rooms are visible, so we can hide ones that aren't hit that were previously on
Lawn::LBitField_Dynamic m_BF_visible_rooms;
// Vector<int> m_VisibleRoomList[2];
// int m_CurrentVisibleRoomList;
LVector<int> m_VisibleRoomList[2];
LVector<int> * m_pCurr_VisibleRoomList;
LVector<int> * m_pPrev_VisibleRoomList;
// keep a frame counter, to mark when objects have been hit by the visiblity algorithm
// already to prevent multiple hits on rooms and objects