mirror of
https://github.com/Relintai/godot-lportal.git
synced 2025-02-20 01:04:19 +01:00
Precalced shadow casters working
This commit is contained in:
parent
47fc1fa319
commit
ef9723744b
10
ldebug.h
10
ldebug.h
@ -1,11 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define LPRINT_RUN(a, b) ;
|
//#define LPRINT_RUN(a, b) ;
|
||||||
|
|
||||||
//#define LPRINT_RUN(a, b) {String sz;\
|
#define LPRINT_RUN(a, b) {String sz;\
|
||||||
//for (int n=0; n<Lawn::LDebug::m_iTabDepth; n++)\
|
for (int n=0; n<Lawn::LDebug::m_iTabDepth; n++)\
|
||||||
//sz += "\t";\
|
sz += "\t";\
|
||||||
//LPRINT(a, sz + b);}
|
LPRINT(a, sz + b);}
|
||||||
|
|
||||||
#define LPRINT(a, b) if (!Lawn::LDebug::m_bRunning) {\
|
#define LPRINT(a, b) if (!Lawn::LDebug::m_bRunning) {\
|
||||||
if (a >= Lawn::LDebug::m_iLoggingLevel)\
|
if (a >= Lawn::LDebug::m_iLoggingLevel)\
|
||||||
|
30
ldob.cpp
30
ldob.cpp
@ -34,6 +34,24 @@ Spatial * LSob::GetSpatial() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LSob::IsShadowCaster() const
|
||||||
|
{
|
||||||
|
Object * pObj = ObjectDB::get_instance(m_ID);
|
||||||
|
GeometryInstance * pGI = Object::cast_to<GeometryInstance>(pObj);
|
||||||
|
|
||||||
|
if (pGI)
|
||||||
|
{
|
||||||
|
if (pGI->get_cast_shadows_setting() == GeometryInstance::SHADOW_CASTING_SETTING_OFF)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not sure yet, maybe this should be true, depends what the non geometry objects are
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
VisualInstance * LSob::GetVI() const
|
VisualInstance * LSob::GetVI() const
|
||||||
{
|
{
|
||||||
Object * pObj = ObjectDB::get_instance(m_ID);
|
Object * pObj = ObjectDB::get_instance(m_ID);
|
||||||
@ -41,6 +59,18 @@ VisualInstance * LSob::GetVI() const
|
|||||||
return pVI;
|
return pVI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LSob::Show(bool bShow)
|
||||||
|
{
|
||||||
|
Spatial * pS = GetSpatial();
|
||||||
|
if (!pS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (bShow)
|
||||||
|
pS->show();
|
||||||
|
else
|
||||||
|
pS->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Spatial * LDob::GetSpatial() const
|
Spatial * LDob::GetSpatial() const
|
||||||
|
2
ldob.h
2
ldob.h
@ -35,6 +35,8 @@ class LSob
|
|||||||
public:
|
public:
|
||||||
Spatial * GetSpatial() const;
|
Spatial * GetSpatial() const;
|
||||||
VisualInstance * GetVI() const;
|
VisualInstance * GetVI() const;
|
||||||
|
void Show(bool bShow);
|
||||||
|
bool IsShadowCaster() const;
|
||||||
|
|
||||||
ObjectID m_ID; // godot object
|
ObjectID m_ID; // godot object
|
||||||
AABB m_aabb; // world space
|
AABB m_aabb; // world space
|
||||||
|
36
lportal.cpp
36
lportal.cpp
@ -71,6 +71,42 @@ String LPortal::FindNameAfter(Node * pNode, String szStart)
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// preprocess
|
||||||
|
void LPortal::AddLightPlanes(const LLight &light, LVector<Plane> &planes) const
|
||||||
|
{
|
||||||
|
const Vector<Vector3> &pts = m_ptsWorld;
|
||||||
|
|
||||||
|
// assuming ortho light
|
||||||
|
int nPoints = pts.size();
|
||||||
|
ERR_FAIL_COND(nPoints < 3);
|
||||||
|
|
||||||
|
const int max_points = 32;
|
||||||
|
Vector3 pushed_pts[max_points];
|
||||||
|
|
||||||
|
if (nPoints > max_points)
|
||||||
|
nPoints = max_points;
|
||||||
|
|
||||||
|
// transform pushed points
|
||||||
|
for (int n=0; n<nPoints; n++)
|
||||||
|
{
|
||||||
|
pushed_pts[n] = pts[n] + light.m_ptDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
Plane p;
|
||||||
|
|
||||||
|
for (int n=1; n<nPoints; n++)
|
||||||
|
{
|
||||||
|
p = Plane(pts[n-1], pts[n], pushed_pts[n]);
|
||||||
|
planes.push_back(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// first and last
|
||||||
|
p = Plane(pts[nPoints-1], pts[0], pushed_pts[0]);
|
||||||
|
planes.push_back(p);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// add clipping planes to the vector formed by each portal edge and the camera
|
// add clipping planes to the vector formed by each portal edge and the camera
|
||||||
void LPortal::AddPlanes(LRoomManager &manager, const Vector3 &ptCam, LVector<Plane> &planes) const
|
void LPortal::AddPlanes(LRoomManager &manager, const Vector3 &ptCam, LVector<Plane> &planes) const
|
||||||
{
|
{
|
||||||
|
@ -38,6 +38,8 @@ class LLight
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Vector3 m_ptDir;
|
Vector3 m_ptDir;
|
||||||
|
Vector3 m_ptPos;
|
||||||
|
ObjectID m_GodotID;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -60,6 +62,7 @@ public:
|
|||||||
|
|
||||||
LPortal::eClipResult ClipWithPlane(const Plane &p) const;
|
LPortal::eClipResult ClipWithPlane(const Plane &p) const;
|
||||||
void AddPlanes(LRoomManager &manager, const Vector3 &ptCam, LVector<Plane> &planes) const;
|
void AddPlanes(LRoomManager &manager, const Vector3 &ptCam, LVector<Plane> &planes) const;
|
||||||
|
void AddLightPlanes(const LLight &light, LVector<Plane> &planes) const;
|
||||||
|
|
||||||
// normal determined by winding order
|
// normal determined by winding order
|
||||||
Vector<Vector3> m_ptsWorld;
|
Vector<Vector3> m_ptsWorld;
|
||||||
|
54
lroom.cpp
54
lroom.cpp
@ -172,8 +172,29 @@ void LRoom::SoftShow(VisualInstance * pVI, bool bShow)
|
|||||||
// naive version, adds all the non visible objects in visible rooms as shadow casters
|
// naive version, adds all the non visible objects in visible rooms as shadow casters
|
||||||
void LRoom::AddShadowCasters(LRoomManager &manager)
|
void LRoom::AddShadowCasters(LRoomManager &manager)
|
||||||
{
|
{
|
||||||
// return;
|
LPRINT(2, "ADDSHADOWCASTERS room " + get_name() + ", " + itos(m_iNumShadowCasters_SOB) + " shadow casters");
|
||||||
|
|
||||||
|
// new!! use precalced list of shadow casters
|
||||||
|
int last = m_iFirstShadowCaster_SOB + m_iNumShadowCasters_SOB;
|
||||||
|
for (int n=m_iFirstShadowCaster_SOB; n<last; n++)
|
||||||
|
{
|
||||||
|
int sobID = manager.m_ShadowCasters_SOB[n];
|
||||||
|
|
||||||
|
// only add to the caster list if not in it already
|
||||||
|
if (!manager.m_BF_caster_SOBs.GetBit(sobID))
|
||||||
|
{
|
||||||
|
LPRINT(2, "\t" + itos(sobID) + ", " + manager.m_SOBs[sobID].GetSpatial()->get_name());
|
||||||
|
manager.m_BF_caster_SOBs.SetBit(sobID, true);
|
||||||
|
manager.m_CasterList_SOBs.push_back(sobID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LPRINT(2, "\t" + itos(sobID) + ", ALREADY CASTER " + manager.m_SOBs[sobID].GetSpatial()->get_name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
int last_sob = m_iFirstSOB + m_iNumSOBs;
|
int last_sob = m_iFirstSOB + m_iNumSOBs;
|
||||||
for (int n=m_iFirstSOB; n<last_sob; n++)
|
for (int n=m_iFirstSOB; n<last_sob; n++)
|
||||||
{
|
{
|
||||||
@ -186,7 +207,7 @@ void LRoom::AddShadowCasters(LRoomManager &manager)
|
|||||||
manager.m_BF_caster_SOBs.SetBit(n, true);
|
manager.m_BF_caster_SOBs.SetBit(n, true);
|
||||||
manager.m_CasterList_SOBs.push_back(n);
|
manager.m_CasterList_SOBs.push_back(n);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -194,19 +215,19 @@ void LRoom::AddShadowCasters(LRoomManager &manager)
|
|||||||
// (it might be expensive)
|
// (it might be expensive)
|
||||||
void LRoom::FinalizeVisibility(LRoomManager &manager)
|
void LRoom::FinalizeVisibility(LRoomManager &manager)
|
||||||
{
|
{
|
||||||
int last_sob = m_iFirstSOB + m_iNumSOBs;
|
// int last_sob = m_iFirstSOB + m_iNumSOBs;
|
||||||
for (int n=m_iFirstSOB; n<last_sob; n++)
|
// for (int n=m_iFirstSOB; n<last_sob; n++)
|
||||||
{
|
// {
|
||||||
LSob &sob = manager.m_SOBs[n];
|
// LSob &sob = manager.m_SOBs[n];
|
||||||
Spatial * pS = sob.GetSpatial();
|
// Spatial * pS = sob.GetSpatial();
|
||||||
if (!pS)
|
// if (!pS)
|
||||||
continue;
|
// continue;
|
||||||
|
|
||||||
if (manager.m_BF_master_SOBs.GetBit(n))
|
// if (manager.m_BF_master_SOBs.GetBit(n))
|
||||||
pS->show();
|
// pS->show();
|
||||||
else
|
// else
|
||||||
pS->hide();
|
// pS->hide();
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
//print_line("FinalizeVisibility room " + get_name() + " NumSOBs " + itos(m_SOBs.size()) + ", NumDOBs " + itos(m_DOBs.size()));
|
//print_line("FinalizeVisibility room " + get_name() + " NumSOBs " + itos(m_SOBs.size()) + ", NumDOBs " + itos(m_DOBs.size()));
|
||||||
@ -253,7 +274,7 @@ void LRoom::Room_MakeVisible(bool bVisible)
|
|||||||
if (m_bVisible)
|
if (m_bVisible)
|
||||||
{
|
{
|
||||||
// show room
|
// show room
|
||||||
GetGodotRoom()->show();
|
// GetGodotRoom()->show();
|
||||||
|
|
||||||
// show all dobs
|
// show all dobs
|
||||||
for (int n=0; n<m_DOBs.size(); n++)
|
for (int n=0; n<m_DOBs.size(); n++)
|
||||||
@ -267,7 +288,7 @@ void LRoom::Room_MakeVisible(bool bVisible)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// hide room
|
// hide room
|
||||||
GetGodotRoom()->hide();
|
// GetGodotRoom()->hide();
|
||||||
|
|
||||||
// hide all dobs
|
// hide all dobs
|
||||||
for (int n=0; n<m_DOBs.size(); n++)
|
for (int n=0; n<m_DOBs.size(); n++)
|
||||||
@ -405,7 +426,6 @@ void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, cons
|
|||||||
|
|
||||||
if (bShow)
|
if (bShow)
|
||||||
{
|
{
|
||||||
//sob.m_bSOBVisible = true;
|
|
||||||
// sob is renderable and visible (not shadow only)
|
// sob is renderable and visible (not shadow only)
|
||||||
manager.m_BF_visible_SOBs.SetBit(n, true);
|
manager.m_BF_visible_SOBs.SetBit(n, true);
|
||||||
//manager.m_BF_render_SOBs.SetBit(n, true);
|
//manager.m_BF_render_SOBs.SetBit(n, true);
|
||||||
|
@ -43,7 +43,7 @@ void LRoomConverter::Convert(LRoomManager &manager)
|
|||||||
|
|
||||||
LMAN->m_SOBs.clear();
|
LMAN->m_SOBs.clear();
|
||||||
LMAN->m_ShadowCasters_SOB.clear();
|
LMAN->m_ShadowCasters_SOB.clear();
|
||||||
LMAN->m_Lights.clear();
|
int num_global_lights = LMAN->m_Lights.size();
|
||||||
|
|
||||||
// make sure bitfield is right size for number of rooms
|
// make sure bitfield is right size for number of rooms
|
||||||
LMAN->m_BF_visible_rooms.Create(count);
|
LMAN->m_BF_visible_rooms.Create(count);
|
||||||
@ -59,7 +59,6 @@ void LRoomConverter::Convert(LRoomManager &manager)
|
|||||||
Convert_Rooms();
|
Convert_Rooms();
|
||||||
Convert_Portals();
|
Convert_Portals();
|
||||||
Convert_Bounds();
|
Convert_Bounds();
|
||||||
Convert_ShadowCasters();
|
|
||||||
|
|
||||||
// make sure manager bitfields are the correct size for number of objects
|
// make sure manager bitfields are the correct size for number of objects
|
||||||
int num_sobs = LMAN->m_SOBs.size();
|
int num_sobs = LMAN->m_SOBs.size();
|
||||||
@ -67,12 +66,19 @@ void LRoomConverter::Convert(LRoomManager &manager)
|
|||||||
LMAN->m_BF_caster_SOBs.Create(num_sobs);
|
LMAN->m_BF_caster_SOBs.Create(num_sobs);
|
||||||
LMAN->m_BF_visible_SOBs.Create(num_sobs);
|
LMAN->m_BF_visible_SOBs.Create(num_sobs);
|
||||||
LMAN->m_BF_master_SOBs.Create(num_sobs);
|
LMAN->m_BF_master_SOBs.Create(num_sobs);
|
||||||
|
LMAN->m_BF_master_SOBs_prev.Create(num_sobs);
|
||||||
|
|
||||||
|
// must be done after the bitfields
|
||||||
|
Convert_ShadowCasters();
|
||||||
|
|
||||||
|
// hide all in preparation for first frame
|
||||||
|
Convert_HideAll();
|
||||||
|
|
||||||
// temp rooms no longer needed
|
// temp rooms no longer needed
|
||||||
m_TempRooms.clear(true);
|
m_TempRooms.clear(true);
|
||||||
|
|
||||||
|
// clear out the local room lights, leave only global lights
|
||||||
|
LMAN->m_Lights.resize(num_global_lights);
|
||||||
Lawn::LDebug::m_bRunning = true;
|
Lawn::LDebug::m_bRunning = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,12 +299,23 @@ bool LRoomConverter::Convert_Bound(LRoom &lroom, MeshInstance * pMI)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hide all in preparation for first frame
|
||||||
|
void LRoomConverter::Convert_HideAll()
|
||||||
|
{
|
||||||
|
for (int n=0; n<LMAN->m_SOBs.size(); n++)
|
||||||
|
{
|
||||||
|
LSob &sob = LMAN->m_SOBs[n];
|
||||||
|
sob.Show(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LRoomConverter::Convert_ShadowCasters()
|
void LRoomConverter::Convert_ShadowCasters()
|
||||||
{
|
{
|
||||||
LPRINT(5,"Convert_ShadowCasters");
|
LPRINT(5,"Convert_ShadowCasters ... numlights " + itos (LMAN->m_Lights.size()));
|
||||||
|
|
||||||
for (int n=0; n<LMAN->m_Rooms.size(); n++)
|
for (int n=0; n<LMAN->m_Rooms.size(); n++)
|
||||||
{
|
{
|
||||||
|
LPRINT(2,"\tRoom " + itos(n));
|
||||||
LRoom &lroom = LMAN->m_Rooms[n];
|
LRoom &lroom = LMAN->m_Rooms[n];
|
||||||
LRoom_FindShadowCasters(lroom);
|
LRoom_FindShadowCasters(lroom);
|
||||||
}
|
}
|
||||||
@ -386,19 +403,51 @@ int LRoomConverter::CountRooms()
|
|||||||
// find all objects that cast shadows onto the objects in this room
|
// find all objects that cast shadows onto the objects in this room
|
||||||
void LRoomConverter::LRoom_FindShadowCasters(LRoom &lroom)
|
void LRoomConverter::LRoom_FindShadowCasters(LRoom &lroom)
|
||||||
{
|
{
|
||||||
return;
|
// each global light, and each light affecting this room
|
||||||
|
for (int n=0; n<LMAN->m_Lights.size(); n++)
|
||||||
// first add all objects in this room as casters
|
|
||||||
for (int n=0; n<lroom.m_iNumSOBs; n++)
|
|
||||||
{
|
{
|
||||||
|
LRoom_FindShadowCasters_FromLight(lroom, LMAN->m_Lights[n]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LRoomConverter::LRoom_AddShadowCaster_SOB(LRoom &lroom, int sobID)
|
||||||
|
{
|
||||||
|
// we will reuse the rendering bitflags for shadow casters for this ... to check for double entries (fnaa fnaa)
|
||||||
|
if (LMAN->m_BF_caster_SOBs.GetBit(sobID))
|
||||||
|
return;
|
||||||
|
|
||||||
|
LMAN->m_BF_caster_SOBs.SetBit(sobID, true);
|
||||||
|
|
||||||
|
// first?
|
||||||
|
if (!lroom.m_iNumShadowCasters_SOB)
|
||||||
|
lroom.m_iFirstShadowCaster_SOB = LMAN->m_ShadowCasters_SOB.size();
|
||||||
|
|
||||||
|
LMAN->m_ShadowCasters_SOB.push_back(sobID);
|
||||||
|
lroom.m_iNumShadowCasters_SOB++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LRoomConverter::LRoom_FindShadowCasters_FromLight(LRoom &lroom, const LLight &light)
|
||||||
|
{
|
||||||
|
// blank this each time as it is used to create the list of casters
|
||||||
|
LMAN->m_BF_caster_SOBs.Blank();
|
||||||
|
|
||||||
|
// first add all objects in this room as casters
|
||||||
|
// int last_sob = lroom.m_iFirstSOB + lroom.m_iNumSOBs;
|
||||||
|
// for (int n=lroom.m_iFirstSOB; n<last_sob; n++)
|
||||||
|
// {
|
||||||
|
// //LSob &sob = manager.m_SOBs[n];
|
||||||
|
// LRoom_AddShadowCaster_SOB(lroom, n);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
// just a constant light direction for now
|
// just a constant light direction for now
|
||||||
LLight light;
|
// LLight light;
|
||||||
light.m_ptDir = Vector3(1.0f, -1.0f, 0.0f);
|
// light.m_ptDir = Vector3(1.0f, -1.0f, 0.0f);
|
||||||
light.m_ptDir.normalize();
|
// light.m_ptDir.normalize();
|
||||||
|
|
||||||
// reset the planes pool for each render out from the source room
|
// reset the planes pool for each render out from the source room
|
||||||
LMAN->m_Pool.Reset();
|
LMAN->m_Pool.Reset();
|
||||||
@ -411,13 +460,66 @@ void LRoomConverter::LRoom_FindShadowCasters(LRoom &lroom)
|
|||||||
LVector<Plane> &planes = LMAN->m_Pool.Get(pool_member);
|
LVector<Plane> &planes = LMAN->m_Pool.Get(pool_member);
|
||||||
planes.clear();
|
planes.clear();
|
||||||
|
|
||||||
LRoom_FindShadowCasters_Recursive(lroom, light, planes);
|
Lawn::LDebug::m_iTabDepth = 0;
|
||||||
|
LRoom_FindShadowCasters_Recursive(lroom, 0, lroom, light, planes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LRoomConverter::LRoom_FindShadowCasters_Recursive(LRoom &lroom, const LLight &light, const LVector<Plane> &planes)
|
|
||||||
|
void LRoomConverter::LRoom_FindShadowCasters_Recursive(LRoom &source_lroom, int depth, LRoom &lroom, const LLight &light, const LVector<Plane> &planes)
|
||||||
{
|
{
|
||||||
|
// prevent too much depth
|
||||||
|
if (depth > 8)
|
||||||
|
{
|
||||||
|
LPRINT_RUN(2, "\t\t\tLRoom_FindShadowCasters_Recursive DEPTH LIMIT REACHED");
|
||||||
|
// WARN_PRINT_ONCE("LPortal Depth Limit reached (seeing through > 8 portals)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Lawn::LDebug::m_iTabDepth = depth;
|
||||||
|
LPRINT_RUN(2, "ROOM " + lroom.get_name());
|
||||||
|
|
||||||
|
|
||||||
|
// every object in this room is added that is within the planes
|
||||||
|
int last_sob = lroom.m_iFirstSOB + lroom.m_iNumSOBs;
|
||||||
|
for (int n=lroom.m_iFirstSOB; n<last_sob; n++)
|
||||||
|
{
|
||||||
|
LSob &sob = LMAN->m_SOBs[n];
|
||||||
|
|
||||||
|
// not a shadow caster? don't add to the list
|
||||||
|
if (!sob.IsShadowCaster())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool bShow = true;
|
||||||
|
const AABB &bb = sob.m_aabb;
|
||||||
|
|
||||||
|
// print("\t\t\tculling object " + pObj->get_name());
|
||||||
|
|
||||||
|
for (int p=0; p<planes.size(); p++)
|
||||||
|
{
|
||||||
|
// float dist = planes[p].distance_to(pt);
|
||||||
|
// print("\t\t\t\t" + itos(p) + " : dist " + String(Variant(dist)));
|
||||||
|
|
||||||
|
float r_min, r_max;
|
||||||
|
bb.project_range_in_plane(planes[p], r_min, r_max);
|
||||||
|
|
||||||
|
// print("\t\t\t\t" + itos(p) + " : r_min " + String(Variant(r_min)) + ", r_max " + String(Variant(r_max)));
|
||||||
|
|
||||||
|
|
||||||
|
if (r_min > 0.0f)
|
||||||
|
{
|
||||||
|
bShow = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bShow)
|
||||||
|
{
|
||||||
|
LPRINT_RUN(2, "\tcaster " + itos(n) + ", " + sob.GetSpatial()->get_name());
|
||||||
|
LRoom_AddShadowCaster_SOB(source_lroom, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// look through every portal out
|
// look through every portal out
|
||||||
for (int n=0; n<lroom.m_iNumPortals; n++)
|
for (int n=0; n<lroom.m_iNumPortals; n++)
|
||||||
{
|
{
|
||||||
@ -425,11 +527,47 @@ void LRoomConverter::LRoom_FindShadowCasters_Recursive(LRoom &lroom, const LLigh
|
|||||||
|
|
||||||
const LPortal &port = LMAN->m_Portals[portalID];
|
const LPortal &port = LMAN->m_Portals[portalID];
|
||||||
|
|
||||||
|
LPRINT_RUN(2, "\tPORTAL " + itos (n) + " (" + itos(portalID) + ") " + port.get_name() + " normal " + port.m_Plane.normal);
|
||||||
|
|
||||||
// cull with light direction
|
// cull with light direction
|
||||||
float dot = port.m_Plane.normal.dot(light.m_ptDir);
|
float dot = port.m_Plane.normal.dot(light.m_ptDir);
|
||||||
if (dot <= 0.0f)
|
if (dot <= 0.0f)
|
||||||
|
{
|
||||||
|
LPRINT_RUN(2, "\t\tCULLED (wrong direction)");
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// is it culled by the planes?
|
||||||
|
LPortal::eClipResult overall_res = LPortal::eClipResult::CLIP_INSIDE;
|
||||||
|
|
||||||
|
// cull portal with planes
|
||||||
|
for (int l=0; l<planes.size(); l++)
|
||||||
|
{
|
||||||
|
LPortal::eClipResult res = port.ClipWithPlane(planes[l]);
|
||||||
|
|
||||||
|
switch (res)
|
||||||
|
{
|
||||||
|
case LPortal::eClipResult::CLIP_OUTSIDE:
|
||||||
|
overall_res = res;
|
||||||
|
break;
|
||||||
|
case LPortal::eClipResult::CLIP_PARTIAL:
|
||||||
|
overall_res = res;
|
||||||
|
break;
|
||||||
|
default: // suppress warning
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overall_res == LPortal::eClipResult::CLIP_OUTSIDE)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this portal is culled
|
||||||
|
if (overall_res == LPortal::eClipResult::CLIP_OUTSIDE)
|
||||||
|
{
|
||||||
|
LPRINT_RUN(2, "\t\tCULLED (outside planes)");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
LRoom &linked_room = LMAN->Portal_GetLinkedRoom(port);
|
LRoom &linked_room = LMAN->Portal_GetLinkedRoom(port);
|
||||||
|
|
||||||
@ -445,12 +583,11 @@ void LRoomConverter::LRoom_FindShadowCasters_Recursive(LRoom &lroom, const LLigh
|
|||||||
new_planes.copy_from(planes);
|
new_planes.copy_from(planes);
|
||||||
|
|
||||||
// add the planes for the portal
|
// add the planes for the portal
|
||||||
// port.AddPlanes(manager, cam.m_ptPos, new_planes);
|
port.AddLightPlanes(light, new_planes);
|
||||||
|
|
||||||
|
LRoom_FindShadowCasters_Recursive(source_lroom, depth + 1, linked_room, light, new_planes);
|
||||||
LRoom_FindShadowCasters_Recursive(linked_room, light, new_planes);
|
|
||||||
// for debugging need to reset tab depth
|
// for debugging need to reset tab depth
|
||||||
//Lawn::LDebug::m_iTabDepth = depth;
|
Lawn::LDebug::m_iTabDepth = depth;
|
||||||
|
|
||||||
// we no longer need these planes
|
// we no longer need these planes
|
||||||
LMAN->m_Pool.Free(uiPoolMem);
|
LMAN->m_Pool.Free(uiPoolMem);
|
||||||
|
@ -94,6 +94,7 @@ private:
|
|||||||
void Convert_Bounds();
|
void Convert_Bounds();
|
||||||
bool Convert_Bound(LRoom &lroom, MeshInstance * pMI);
|
bool Convert_Bound(LRoom &lroom, MeshInstance * pMI);
|
||||||
void Convert_ShadowCasters();
|
void Convert_ShadowCasters();
|
||||||
|
void Convert_HideAll();
|
||||||
|
|
||||||
|
|
||||||
void LRoom_DetectPortalMeshes(LRoom &lroom, LTempRoom &troom);
|
void LRoom_DetectPortalMeshes(LRoom &lroom, LTempRoom &troom);
|
||||||
@ -102,8 +103,12 @@ private:
|
|||||||
void LRoom_DetectedPortalMesh(LRoom &lroom, LTempRoom &troom, MeshInstance * pMeshInstance, String szLinkRoom);
|
void LRoom_DetectedPortalMesh(LRoom &lroom, LTempRoom &troom, MeshInstance * pMeshInstance, String szLinkRoom);
|
||||||
LPortal * LRoom_RequestNewPortal(LRoom &lroom);
|
LPortal * LRoom_RequestNewPortal(LRoom &lroom);
|
||||||
void LRoom_PushBackSOB(LRoom &lroom, const LSob &sob);
|
void LRoom_PushBackSOB(LRoom &lroom, const LSob &sob);
|
||||||
|
|
||||||
|
// shadows
|
||||||
void LRoom_FindShadowCasters(LRoom &lroom);
|
void LRoom_FindShadowCasters(LRoom &lroom);
|
||||||
void LRoom_FindShadowCasters_Recursive(LRoom &lroom, const LLight &light, const LVector<Plane> &planes);
|
void LRoom_FindShadowCasters_FromLight(LRoom &lroom, const LLight &light);
|
||||||
|
void LRoom_FindShadowCasters_Recursive(LRoom &source_lroom, int depth, LRoom &lroom, const LLight &light, const LVector<Plane> &planes);
|
||||||
|
void LRoom_AddShadowCaster_SOB(LRoom &lroom, int sobID);
|
||||||
|
|
||||||
void TRoom_MakeOppositePortal(const LPortal &port, int iRoomOrig);
|
void TRoom_MakeOppositePortal(const LPortal &port, int iRoomOrig);
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "lroom_converter.h"
|
#include "lroom_converter.h"
|
||||||
#include "ldebug.h"
|
#include "ldebug.h"
|
||||||
#include "scene/3d/immediate_geometry.h"
|
#include "scene/3d/immediate_geometry.h"
|
||||||
|
#include "scene/3d/light.h"
|
||||||
#include "lroom.h"
|
#include "lroom.h"
|
||||||
|
|
||||||
LRoomManager::LRoomManager()
|
LRoomManager::LRoomManager()
|
||||||
@ -451,6 +452,39 @@ bool LRoomManager::dob_unregister(Node * pDOB)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LRoomManager::light_register(Node * pLightNode)
|
||||||
|
{
|
||||||
|
if (!pLightNode)
|
||||||
|
{
|
||||||
|
WARN_PRINT_ONCE("light_register : pLightNode is NULL");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPRINT(3, "light_register " + pLightNode->get_name());
|
||||||
|
|
||||||
|
Light * pLight = Object::cast_to<Light>(pLightNode);
|
||||||
|
if (!pLight)
|
||||||
|
{
|
||||||
|
WARN_PRINT_ONCE("light_register : Node is not a light");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create new light
|
||||||
|
LLight l;
|
||||||
|
l.m_GodotID = pLight->get_instance_id();
|
||||||
|
|
||||||
|
// direction
|
||||||
|
Transform tr = pLight->get_global_transform();
|
||||||
|
l.m_ptPos = tr.origin;
|
||||||
|
l.m_ptDir = tr.basis.get_axis(2); // or possibly get_axis .. z is what we want
|
||||||
|
|
||||||
|
m_Lights.push_back(l);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void LRoomManager::DobChangeVisibility(Spatial * pDOB, const LRoom * pOld, const LRoom * pNew)
|
void LRoomManager::DobChangeVisibility(Spatial * pDOB, const LRoom * pOld, const LRoom * pNew)
|
||||||
{
|
{
|
||||||
bool bVisOld = false;
|
bool bVisOld = false;
|
||||||
@ -589,6 +623,12 @@ void LRoomManager::rooms_convert()
|
|||||||
conv.Convert(*this);
|
conv.Convert(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// free memory for current set of rooms, prepare for converting a new game level
|
||||||
|
void LRoomManager::rooms_release()
|
||||||
|
{
|
||||||
|
m_Lights.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// debugging emulate view frustum
|
// debugging emulate view frustum
|
||||||
void LRoomManager::FrameUpdate_FrustumOnly()
|
void LRoomManager::FrameUpdate_FrustumOnly()
|
||||||
@ -603,8 +643,15 @@ void LRoomManager::FrameUpdate_Prepare()
|
|||||||
// clear the visible room list to write to each frame
|
// clear the visible room list to write to each frame
|
||||||
m_pCurr_VisibleRoomList->clear();
|
m_pCurr_VisibleRoomList->clear();
|
||||||
|
|
||||||
|
// keep previous
|
||||||
|
m_BF_master_SOBs_prev.CopyFrom(m_BF_master_SOBs);
|
||||||
|
|
||||||
|
// note this can be done more efficiently with swapping pointer
|
||||||
|
m_MasterList_SOBs_prev.copy_from(m_MasterList_SOBs);
|
||||||
|
|
||||||
m_VisibleList_SOBs.clear();
|
m_VisibleList_SOBs.clear();
|
||||||
m_CasterList_SOBs.clear();
|
m_CasterList_SOBs.clear();
|
||||||
|
m_MasterList_SOBs.clear();
|
||||||
|
|
||||||
m_BF_caster_SOBs.Blank();
|
m_BF_caster_SOBs.Blank();
|
||||||
m_BF_visible_SOBs.Blank();
|
m_BF_visible_SOBs.Blank();
|
||||||
@ -807,6 +854,7 @@ void LRoomManager::FrameUpdate_FinalizeVisibility_SoftShow()
|
|||||||
LRoom::SoftShow(pVI, bVisible);
|
LRoom::SoftShow(pVI, bVisible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -822,6 +870,24 @@ void LRoomManager::FrameUpdate_FinalizeVisibility_WithinRooms()
|
|||||||
m_Rooms[r].FinalizeVisibility(*this);
|
m_Rooms[r].FinalizeVisibility(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NEW shows and hides dobs according to the difference between the current and previous master list
|
||||||
|
for (int n=0; n<m_MasterList_SOBs_prev.size(); n++)
|
||||||
|
{
|
||||||
|
int ID = m_MasterList_SOBs_prev[n];
|
||||||
|
if (m_BF_master_SOBs.GetBit(ID) == 0)
|
||||||
|
{
|
||||||
|
LSob &sob = m_SOBs[ID];
|
||||||
|
sob.Show(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// show all in current master list
|
||||||
|
for (int n=0; n<m_MasterList_SOBs.size(); n++)
|
||||||
|
{
|
||||||
|
int ID = m_MasterList_SOBs[n];
|
||||||
|
LSob &sob = m_SOBs[ID];
|
||||||
|
sob.Show(true);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -912,6 +978,8 @@ void LRoomManager::_bind_methods()
|
|||||||
{
|
{
|
||||||
// main functions
|
// main functions
|
||||||
ClassDB::bind_method(D_METHOD("rooms_convert"), &LRoomManager::rooms_convert);
|
ClassDB::bind_method(D_METHOD("rooms_convert"), &LRoomManager::rooms_convert);
|
||||||
|
ClassDB::bind_method(D_METHOD("rooms_release"), &LRoomManager::rooms_release);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("rooms_set_camera"), &LRoomManager::rooms_set_camera);
|
ClassDB::bind_method(D_METHOD("rooms_set_camera"), &LRoomManager::rooms_set_camera);
|
||||||
ClassDB::bind_method(D_METHOD("rooms_get_room"), &LRoomManager::rooms_get_room);
|
ClassDB::bind_method(D_METHOD("rooms_get_room"), &LRoomManager::rooms_get_room);
|
||||||
|
|
||||||
@ -934,6 +1002,8 @@ void LRoomManager::_bind_methods()
|
|||||||
ClassDB::bind_method(D_METHOD("dob_register_hint"), &LRoomManager::dob_register_hint);
|
ClassDB::bind_method(D_METHOD("dob_register_hint"), &LRoomManager::dob_register_hint);
|
||||||
ClassDB::bind_method(D_METHOD("dob_teleport_hint"), &LRoomManager::dob_teleport_hint);
|
ClassDB::bind_method(D_METHOD("dob_teleport_hint"), &LRoomManager::dob_teleport_hint);
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("dob_get_room_id"), &LRoomManager::dob_get_room_id);
|
ClassDB::bind_method(D_METHOD("dob_get_room_id"), &LRoomManager::dob_get_room_id);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("light_register"), &LRoomManager::light_register);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@ class LRoomManager : public Spatial {
|
|||||||
// and also objects out of view but casting shadows INTO the view
|
// and also objects out of view but casting shadows INTO the view
|
||||||
LVector<int> m_VisibleList_SOBs;
|
LVector<int> m_VisibleList_SOBs;
|
||||||
LVector<int> m_CasterList_SOBs;
|
LVector<int> m_CasterList_SOBs;
|
||||||
|
|
||||||
LVector<int> m_MasterList_SOBs;
|
LVector<int> m_MasterList_SOBs;
|
||||||
|
|
||||||
|
|
||||||
@ -61,6 +62,10 @@ class LRoomManager : public Spatial {
|
|||||||
Lawn::LBitField_Dynamic m_BF_caster_SOBs;
|
Lawn::LBitField_Dynamic m_BF_caster_SOBs;
|
||||||
Lawn::LBitField_Dynamic m_BF_master_SOBs;
|
Lawn::LBitField_Dynamic m_BF_master_SOBs;
|
||||||
|
|
||||||
|
// previous frame
|
||||||
|
LVector<int> m_MasterList_SOBs_prev;
|
||||||
|
Lawn::LBitField_Dynamic m_BF_master_SOBs_prev;
|
||||||
|
|
||||||
|
|
||||||
LVector<int> m_VisibleRoomList_A;
|
LVector<int> m_VisibleRoomList_A;
|
||||||
LVector<int> m_VisibleRoomList_B;
|
LVector<int> m_VisibleRoomList_B;
|
||||||
@ -159,6 +164,9 @@ public:
|
|||||||
// convert empties and meshes to rooms and portals
|
// convert empties and meshes to rooms and portals
|
||||||
void rooms_convert();
|
void rooms_convert();
|
||||||
|
|
||||||
|
// free memory for current set of rooms, prepare for converting a new game level
|
||||||
|
void rooms_release();
|
||||||
|
|
||||||
// choose which camera you want to use to determine visibility.
|
// choose which camera you want to use to determine visibility.
|
||||||
// normally this will be your main camera, but you can choose another for debugging
|
// normally this will be your main camera, but you can choose another for debugging
|
||||||
void rooms_set_camera(Node * pCam);
|
void rooms_set_camera(Node * pCam);
|
||||||
@ -200,7 +208,9 @@ public:
|
|||||||
// helper func, not needed usually as dob_update returns the room
|
// helper func, not needed usually as dob_update returns the room
|
||||||
int dob_get_room_id(Node * pDOB);
|
int dob_get_room_id(Node * pDOB);
|
||||||
|
|
||||||
|
// LIGHTS
|
||||||
|
// global lights that will apply to all rooms
|
||||||
|
bool light_register(Node * pLightNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user