mirror of
https://github.com/Relintai/godot-lportal.git
synced 2024-11-11 10:52:09 +01:00
Culling via layers
Changed culling to via the Godot layers mechanism, as a hack to allow shadows.
This commit is contained in:
parent
6795a2e05d
commit
9e7b392651
17
ldob.cpp
17
ldob.cpp
@ -34,11 +34,26 @@ Spatial * LSob::GetSpatial() const
|
||||
}
|
||||
|
||||
|
||||
VisualInstance * LSob::GetVI() const
|
||||
{
|
||||
Object * pObj = ObjectDB::get_instance(m_ID);
|
||||
VisualInstance * pVI = Object::cast_to<VisualInstance>(pObj);
|
||||
return pVI;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Spatial * LDob::GetSpatial() const
|
||||
{
|
||||
Object * pObj = ObjectDB::get_instance(m_ID);
|
||||
Object * pObj = ObjectDB::get_instance(m_ID_Spatial);
|
||||
Spatial * pSpat = Object::cast_to<Spatial>(pObj);
|
||||
return pSpat;
|
||||
}
|
||||
|
||||
VisualInstance * LDob::GetVI() const
|
||||
{
|
||||
Object * pObj = ObjectDB::get_instance(m_ID_VI);
|
||||
VisualInstance * pVI = Object::cast_to<VisualInstance>(pObj);
|
||||
return pVI;
|
||||
}
|
||||
|
||||
|
5
ldob.h
5
ldob.h
@ -34,6 +34,7 @@ class LSob
|
||||
{
|
||||
public:
|
||||
Spatial * GetSpatial() const;
|
||||
VisualInstance * GetVI() const;
|
||||
|
||||
ObjectID m_ID; // godot object
|
||||
AABB m_aabb; // world space
|
||||
@ -45,8 +46,10 @@ class LDob
|
||||
{
|
||||
public:
|
||||
Spatial * GetSpatial() const;
|
||||
VisualInstance * GetVI() const;
|
||||
|
||||
ObjectID m_ID;
|
||||
ObjectID m_ID_Spatial;
|
||||
ObjectID m_ID_VI;
|
||||
bool m_bVisible;
|
||||
float m_fRadius;
|
||||
};
|
||||
|
177
lroom.cpp
177
lroom.cpp
@ -32,6 +32,7 @@ LRoom::LRoom() {
|
||||
m_uiFrameTouched = 0;
|
||||
m_iFirstPortal = 0;
|
||||
m_iNumPortals = 0;
|
||||
m_bVisible = true;
|
||||
}
|
||||
|
||||
|
||||
@ -63,7 +64,7 @@ unsigned int LRoom::DOB_Find(Node * pDOB) const
|
||||
|
||||
for (int n=0; n<m_DOBs.size(); n++)
|
||||
{
|
||||
if (m_DOBs[n].m_ID == id)
|
||||
if (m_DOBs[n].m_ID_Spatial == id)
|
||||
{
|
||||
return n;
|
||||
}
|
||||
@ -119,6 +120,49 @@ LRoom * LRoom::DOB_Update(LRoomManager &manager, Spatial * pDOB)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// instead of directly showing and hiding objects we now set their layer,
|
||||
// and the camera will hide them with a cull mask. This is so that
|
||||
// objects can still be rendered outside immediate view for casting shadows.
|
||||
// All objects in view (that are set to cast shadows) should cast shadows, so the actual
|
||||
// shown objects are a superset of the softshown.
|
||||
void LRoom::SoftShow(VisualInstance * pVI, bool bShow) const
|
||||
{
|
||||
// hijack this layer number
|
||||
uint32_t mask = pVI->get_layer_mask();
|
||||
uint32_t orig_mask = mask;
|
||||
|
||||
const int SOFT_SHOW_MASK = 1 << SOFT_SHOW_BIT;
|
||||
const int SOFT_HIDE_MASK = 1 << SOFT_HIDE_BIT;
|
||||
|
||||
if (bShow)
|
||||
{
|
||||
// set
|
||||
mask |= SOFT_SHOW_MASK;
|
||||
// clear
|
||||
mask &= ~(1 | SOFT_HIDE_MASK);
|
||||
}
|
||||
else
|
||||
{
|
||||
// set
|
||||
mask |= SOFT_HIDE_MASK;
|
||||
// clear
|
||||
mask &= ~(1 | SOFT_SHOW_MASK);
|
||||
}
|
||||
|
||||
|
||||
// noop? don't touch the visual server if no change to mask
|
||||
if (mask == orig_mask)
|
||||
return;
|
||||
|
||||
pVI->set_layer_mask(mask);
|
||||
|
||||
// pVI->set_layer_mask_bit(0, false);
|
||||
// pVI->set_layer_mask_bit(SOFT_HIDE_BIT, bShow == false);
|
||||
// pVI->set_layer_mask_bit(SOFT_SHOW_BIT, bShow);
|
||||
}
|
||||
|
||||
|
||||
// hide all the objects not hit on this frame .. instead of calling godot hide without need
|
||||
// (it might be expensive)
|
||||
void LRoom::FinalizeVisibility(LRoomManager &manager)
|
||||
@ -128,14 +172,15 @@ void LRoom::FinalizeVisibility(LRoomManager &manager)
|
||||
for (int n=0; n<m_SOBs.size(); n++)
|
||||
{
|
||||
const LSob &sob = m_SOBs[n];
|
||||
Spatial * pS = sob.GetSpatial();
|
||||
VisualInstance * pVI = sob.GetVI();
|
||||
|
||||
if (pS)
|
||||
if (pVI)
|
||||
{
|
||||
if (sob.m_bVisible)
|
||||
pS->show();
|
||||
else
|
||||
pS->hide();
|
||||
SoftShow(pVI, sob.m_bVisible);
|
||||
// if (sob.m_bVisible)
|
||||
// pVI->show();
|
||||
// else
|
||||
// pVI->hide();
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,57 +189,99 @@ void LRoom::FinalizeVisibility(LRoomManager &manager)
|
||||
const LDob &dob = m_DOBs[n];
|
||||
|
||||
// don't cull the main camera
|
||||
if (dob.m_ID == manager.m_ID_camera)
|
||||
if (dob.m_ID_Spatial == manager.m_ID_camera)
|
||||
continue;
|
||||
|
||||
Spatial * pS = dob.GetSpatial();
|
||||
if (pS)
|
||||
// Spatial * pSpat = dob.GetSpatial();
|
||||
// if (pSpat)
|
||||
// {
|
||||
// // all should be showing .. this is mostly a no op
|
||||
// pSpat->show();
|
||||
// }
|
||||
|
||||
VisualInstance * pVI = dob.GetVI();
|
||||
if (pVI)
|
||||
{
|
||||
if (dob.m_bVisible)
|
||||
{
|
||||
//print("LRoom::FinalizeVisibility making visible dob " + pS->get_name());
|
||||
pS->show();
|
||||
}
|
||||
else
|
||||
pS->hide();
|
||||
SoftShow(pVI, dob.m_bVisible);
|
||||
// if (dob.m_bVisible)
|
||||
// {
|
||||
// //print("LRoom::FinalizeVisibility making visible dob " + pS->get_name());
|
||||
// pS->show();
|
||||
// }
|
||||
// else
|
||||
// pS->hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// hide godot room and all linked dobs
|
||||
void LRoom::Hide_All()
|
||||
// allows us to show / hide all dobs as the room visibility changes
|
||||
void LRoom::Room_MakeVisible(bool bVisible)
|
||||
{
|
||||
GetGodotRoom()->hide();
|
||||
// noop
|
||||
if (bVisible == m_bVisible)
|
||||
return;
|
||||
|
||||
for (int n=0; n<m_DOBs.size(); n++)
|
||||
m_bVisible = bVisible;
|
||||
|
||||
if (m_bVisible)
|
||||
{
|
||||
LDob &dob = m_DOBs[n];
|
||||
Spatial * pS = dob.GetSpatial();
|
||||
if (pS)
|
||||
pS->hide();
|
||||
// show room
|
||||
GetGodotRoom()->show();
|
||||
|
||||
// show all dobs
|
||||
for (int n=0; n<m_DOBs.size(); n++)
|
||||
{
|
||||
LDob &dob = m_DOBs[n];
|
||||
Spatial * pS = dob.GetSpatial();
|
||||
if (pS)
|
||||
pS->show();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// hide room
|
||||
GetGodotRoom()->hide();
|
||||
|
||||
// hide all dobs
|
||||
for (int n=0; n<m_DOBs.size(); n++)
|
||||
{
|
||||
LDob &dob = m_DOBs[n];
|
||||
Spatial * p = dob.GetSpatial();
|
||||
if (p)
|
||||
p->hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// hide godot room and all linked dobs
|
||||
//void LRoom::Hide_All()
|
||||
//{
|
||||
// GetGodotRoom()->hide();
|
||||
|
||||
// for (int n=0; n<m_DOBs.size(); n++)
|
||||
// {
|
||||
// LDob &dob = m_DOBs[n];
|
||||
// Spatial * p = dob.GetSpatial();
|
||||
// if (p)
|
||||
// p->hide();
|
||||
// }
|
||||
//}
|
||||
|
||||
// show godot room and all linked dobs and all sobs
|
||||
void LRoom::Show_All()
|
||||
void LRoom::Debug_ShowAll()
|
||||
{
|
||||
GetGodotRoom()->show();
|
||||
Room_MakeVisible(true);
|
||||
|
||||
for (int n=0; n<m_SOBs.size(); n++)
|
||||
{
|
||||
LSob &sob = m_SOBs[n];
|
||||
Spatial * pS = sob.GetSpatial();
|
||||
if (pS)
|
||||
pS->show();
|
||||
}
|
||||
// NYI .. change layers to all be visible
|
||||
// for (int n=0; n<m_SOBs.size(); n++)
|
||||
// {
|
||||
// LSob &sob = m_SOBs[n];
|
||||
// Spatial * pS = sob.GetSpatial();
|
||||
// if (pS)
|
||||
// pS->show();
|
||||
// }
|
||||
|
||||
for (int n=0; n<m_DOBs.size(); n++)
|
||||
{
|
||||
LDob &dob = m_DOBs[n];
|
||||
Spatial * pS = dob.GetSpatial();
|
||||
if (pS)
|
||||
pS->show();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -203,6 +290,11 @@ void LRoom::FirstTouch(LRoomManager &manager)
|
||||
// set the frame counter
|
||||
m_uiFrameTouched = manager.m_uiFrameCounter;
|
||||
|
||||
// show this room and add to visible list of rooms
|
||||
Room_MakeVisible(true);
|
||||
|
||||
manager.m_BF_visible_rooms.SetBit(m_RoomID, true);
|
||||
|
||||
// keep track of which rooms are shown this frame
|
||||
manager.m_pCurr_VisibleRoomList->push_back(m_RoomID);
|
||||
|
||||
@ -238,9 +330,6 @@ void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, cons
|
||||
if (m_uiFrameTouched < manager.m_uiFrameCounter)
|
||||
FirstTouch(manager);
|
||||
|
||||
// show this room and add to visible list of rooms
|
||||
GetGodotRoom()->show();
|
||||
manager.m_BF_visible_rooms.SetBit(m_RoomID, true);
|
||||
|
||||
#define LPORTAL_CULL_STATIC
|
||||
#ifdef LPORTAL_CULL_STATIC
|
||||
|
24
lroom.h
24
lroom.h
@ -54,6 +54,8 @@ class LRoom
|
||||
private:
|
||||
|
||||
public:
|
||||
static const int SOFT_SHOW_BIT = 18;
|
||||
static const int SOFT_HIDE_BIT = 19;
|
||||
|
||||
// static objects
|
||||
LVector<LSob> m_SOBs;
|
||||
@ -81,7 +83,6 @@ public:
|
||||
// when registering DOBs and teleporting them
|
||||
LBound m_Bound;
|
||||
|
||||
|
||||
String m_szName;
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
@ -91,13 +92,16 @@ public:
|
||||
void DetermineVisibility_Recursive(LRoomManager &manager, int depth, const LCamera &cam, const LVector<Plane> &planes, int portalID_from = -1);
|
||||
void FirstTouch(LRoomManager &manager);
|
||||
|
||||
|
||||
// allows us to show / hide all dobs as the room visibility changes
|
||||
void Room_MakeVisible(bool bVisible);
|
||||
|
||||
// hide godot room and all linked dobs
|
||||
// USED AT RUNTIME
|
||||
void Hide_All();
|
||||
// void Hide_All();
|
||||
|
||||
// show godot room and all linked dobs and all sobs
|
||||
// ONLY USED IN DEBUGGING to turn LPortal on and off
|
||||
void Show_All();
|
||||
void Debug_ShowAll();
|
||||
|
||||
// hide all the objects not hit on this frame .. instead of calling godot hide without need
|
||||
// (it might be expensive)
|
||||
@ -115,6 +119,18 @@ public:
|
||||
|
||||
// retained purely for debugging visualization
|
||||
Geometry::MeshData m_Bound_MeshData;
|
||||
|
||||
bool IsVisible() const {return m_bVisible;}
|
||||
private:
|
||||
// instead of directly showing and hiding objects we now set their layer,
|
||||
// and the camera will hide them with a cull mask. This is so that
|
||||
// objects can still be rendered outside immediate view for casting shadows.
|
||||
void SoftShow(VisualInstance * pVI, bool bShow) const;
|
||||
|
||||
// whether lportal thinks this room is currently visible
|
||||
// this allows us to show / hide dobs as they cross room boundaries
|
||||
bool m_bVisible;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "lroom_converter.h"
|
||||
#include "ldebug.h"
|
||||
#include "scene/3d/immediate_geometry.h"
|
||||
#include "lroom.h"
|
||||
|
||||
LRoomManager::LRoomManager()
|
||||
{
|
||||
@ -224,6 +225,24 @@ void LRoomManager::CreateDebug()
|
||||
}
|
||||
|
||||
|
||||
ObjectID LRoomManager::DobRegister_FindVIRecursive(Node * pNode) const
|
||||
{
|
||||
// is the node a VI?
|
||||
VisualInstance * pVI = Object::cast_to<VisualInstance>(pNode);
|
||||
if (pVI)
|
||||
return pVI->get_instance_id();
|
||||
|
||||
// try the children
|
||||
for (int n=0; n<pNode->get_child_count(); n++)
|
||||
{
|
||||
ObjectID res = DobRegister_FindVIRecursive(pNode->get_child(n));
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool LRoomManager::DobRegister(Spatial * pDOB, float radius, int iRoom)
|
||||
{
|
||||
//LPRINT(3, "register_dob " + pDOB->get_name());
|
||||
@ -238,14 +257,22 @@ bool LRoomManager::DobRegister(Spatial * pDOB, float radius, int iRoom)
|
||||
if (!pRoom)
|
||||
return false;
|
||||
|
||||
// The dob is derived from spatial, but the visual instances may be children of the dob
|
||||
// rather than the node itself .. we need visual instances for layer culling for shadows
|
||||
LDob dob;
|
||||
dob.m_ID = pDOB->get_instance_id();
|
||||
dob.m_ID_Spatial = pDOB->get_instance_id();
|
||||
dob.m_fRadius = radius;
|
||||
|
||||
dob.m_ID_VI = DobRegister_FindVIRecursive(pDOB);
|
||||
|
||||
pRoom->DOB_Add(dob);
|
||||
|
||||
// save the room ID on the dob metadata
|
||||
Obj_SetRoomNum(pDOB, iRoom);
|
||||
|
||||
// change visibility
|
||||
DobChangeVisibility(pDOB, 0, pRoom);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -305,7 +332,8 @@ int LRoomManager::dob_update(Node * pDOB)
|
||||
// remove from old room
|
||||
pRoom->DOB_Remove(dob_id);
|
||||
|
||||
|
||||
// change visibility
|
||||
DobChangeVisibility(pSpat, pRoom, pNewRoom);
|
||||
|
||||
// save the room ID on the dob metadata
|
||||
Obj_SetRoomNum(pSpat, iRoomNum);
|
||||
@ -383,6 +411,9 @@ bool LRoomManager::DobTeleport(Spatial * pDOB, int iNewRoomID)
|
||||
// save the room ID on the dob metadata
|
||||
Obj_SetRoomNum(pDOB, iNewRoomID);
|
||||
|
||||
// change visibility
|
||||
DobChangeVisibility(pDOB, pOldRoom, pNewRoom);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -420,6 +451,29 @@ bool LRoomManager::dob_unregister(Node * pDOB)
|
||||
return false;
|
||||
}
|
||||
|
||||
void LRoomManager::DobChangeVisibility(Spatial * pDOB, const LRoom * pOld, const LRoom * pNew)
|
||||
{
|
||||
bool bVisOld = false;
|
||||
bool bVisNew = false;
|
||||
|
||||
if (pOld)
|
||||
bVisOld = pOld->IsVisible();
|
||||
|
||||
if (pNew)
|
||||
bVisNew = pNew->IsVisible();
|
||||
|
||||
|
||||
if (bVisOld != bVisNew)
|
||||
{
|
||||
if (!bVisOld)
|
||||
pDOB->show();
|
||||
else
|
||||
pDOB->hide();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int LRoomManager::dob_get_room_id(Node * pDOB)
|
||||
{
|
||||
return Obj_GetRoomNum(pDOB);
|
||||
@ -486,7 +540,7 @@ void LRoomManager::rooms_set_active(bool bActive)
|
||||
for (int n=0; n<m_Rooms.size(); n++)
|
||||
{
|
||||
LRoom &lroom = m_Rooms[n];
|
||||
lroom.Show_All();
|
||||
lroom.Debug_ShowAll();
|
||||
}
|
||||
|
||||
|
||||
@ -521,6 +575,9 @@ void LRoomManager::rooms_set_camera(Node * pCam)
|
||||
|
||||
m_ID_camera = pCam->get_instance_id();
|
||||
|
||||
// new .. select the cull layer
|
||||
pCamera->set_cull_mask_bit(LRoom::SOFT_HIDE_BIT, false);
|
||||
|
||||
// use this temporarily to force debug
|
||||
// rooms_log_frame();
|
||||
}
|
||||
@ -637,7 +694,7 @@ void LRoomManager::FrameUpdate()
|
||||
{
|
||||
if (!m_BF_visible_rooms.GetBit(n))
|
||||
{
|
||||
m_Rooms[n].Hide_All();
|
||||
m_Rooms[n].Room_MakeVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -649,7 +706,7 @@ void LRoomManager::FrameUpdate()
|
||||
int r = (*m_pPrev_VisibleRoomList)[n];
|
||||
|
||||
if (!m_BF_visible_rooms.GetBit(r))
|
||||
m_Rooms[r].Hide_All();
|
||||
m_Rooms[r].Room_MakeVisible(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -125,8 +125,10 @@ protected:
|
||||
private:
|
||||
// internal
|
||||
bool DobRegister(Spatial * pDOB, float radius, int iRoom);
|
||||
ObjectID DobRegister_FindVIRecursive(Node * pNode) const;
|
||||
bool DobTeleport(Spatial * pDOB, int iNewRoomID);
|
||||
void CreateDebug();
|
||||
void DobChangeVisibility(Spatial * pDOB, const LRoom * pOld, const LRoom * pNew);
|
||||
|
||||
|
||||
// helper funcs
|
||||
|
Loading…
Reference in New Issue
Block a user