mirror of
https://github.com/Relintai/godot-lportal.git
synced 2024-11-11 10:52:09 +01:00
Hiding of unvisited rooms more efficient
This commit is contained in:
parent
56e785ab4b
commit
092579db66
@ -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)
|
||||
|
@ -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:
|
||||
|
13
lroom.cpp
13
lroom.cpp
@ -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();
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user