mirror of
https://github.com/Relintai/godot-lportal.git
synced 2024-11-11 10:52:09 +01:00
Dynamic objects now working
Code needs cleaning up though, and replacing Vector with LVector, and adding culling for dynamics.
This commit is contained in:
parent
811e6d984f
commit
664e8175bf
3
SCsub
3
SCsub
@ -7,7 +7,8 @@ sources = [
|
|||||||
"lroom_manager.cpp",
|
"lroom_manager.cpp",
|
||||||
"lportal.cpp",
|
"lportal.cpp",
|
||||||
"lplanes_pool.cpp",
|
"lplanes_pool.cpp",
|
||||||
"CoBitField_Dynamic.cpp",
|
"ldob.cpp",
|
||||||
|
"lbitfield_dynamic.cpp",
|
||||||
]
|
]
|
||||||
|
|
||||||
module_env = env.Clone()
|
module_env = env.Clone()
|
||||||
|
93
lbitfield_dynamic.cpp
Normal file
93
lbitfield_dynamic.cpp
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include "lbitfield_dynamic.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Lawn { // namespace start
|
||||||
|
|
||||||
|
void LBitField_Dynamic::Initialize() {assert (0 && "LBitField_Dynamic : Does not support Initialize, use IT version");}
|
||||||
|
void LBitField_Dynamic::Terminate() {assert (0 && "LBitField_Dynamic : Does not support Terminate, use IT version");}
|
||||||
|
|
||||||
|
|
||||||
|
void LBitField_Dynamic_IT::Initialize()
|
||||||
|
{
|
||||||
|
Initialize_Do();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LBitField_Dynamic_IT::Terminate()
|
||||||
|
{
|
||||||
|
Terminate_Do();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LBitField_Dynamic_IT::Initialize_Do()
|
||||||
|
{
|
||||||
|
memset (this, 0, sizeof (LBitField_Dynamic));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LBitField_Dynamic_IT::Terminate_Do()
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LBitField_Dynamic_IT::CopyFrom(const LBitField_Dynamic_IT &source)
|
||||||
|
{
|
||||||
|
Create(source.GetNumBits(), false);
|
||||||
|
memcpy(m_pucData, source.GetData(), source.GetNumBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LBitField_Dynamic_IT::Create(unsigned int uiNumBits, bool bBlank)
|
||||||
|
{
|
||||||
|
// first delete any initial
|
||||||
|
Destroy();
|
||||||
|
|
||||||
|
m_uiNumBits = uiNumBits;
|
||||||
|
if (uiNumBits)
|
||||||
|
{
|
||||||
|
m_uiNumBytes = (uiNumBits / 8) + 1;
|
||||||
|
|
||||||
|
m_pucData = new unsigned char[m_uiNumBytes];
|
||||||
|
|
||||||
|
if (bBlank)
|
||||||
|
Blank(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LBitField_Dynamic_IT::Destroy()
|
||||||
|
{
|
||||||
|
if (m_pucData)
|
||||||
|
{
|
||||||
|
delete[] m_pucData;
|
||||||
|
m_pucData = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (this, 0, sizeof (LBitField_Dynamic));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LBitField_Dynamic_IT::Blank(bool bSetOrZero)
|
||||||
|
{
|
||||||
|
if (bSetOrZero)
|
||||||
|
{
|
||||||
|
memset(m_pucData, 255, m_uiNumBytes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset(m_pucData, 0, m_uiNumBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LBitField_Dynamic_IT::Invert()
|
||||||
|
{
|
||||||
|
for (unsigned int n=0; n<m_uiNumBytes; n++)
|
||||||
|
{
|
||||||
|
m_pucData[n] = ~m_pucData[n];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace end
|
91
lbitfield_dynamic.h
Normal file
91
lbitfield_dynamic.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
namespace Lawn { // namespace start
|
||||||
|
|
||||||
|
class LBitField_Dynamic_IT
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction
|
||||||
|
void Initialize();
|
||||||
|
void Terminate();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// prevent copying (see effective C++ scott meyers)
|
||||||
|
// there is no implementation for copy constructor, hence compiler will complain if you try to copy.
|
||||||
|
LBitField_Dynamic_IT& operator=(const LBitField_Dynamic_IT&);
|
||||||
|
public:
|
||||||
|
|
||||||
|
// create automatically blanks
|
||||||
|
void Create(unsigned int uiNumBits, bool bBlank = true);
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
|
// public funcs
|
||||||
|
inline unsigned int GetNumBits() const {return m_uiNumBits;}
|
||||||
|
inline unsigned int GetBit(unsigned int uiBit) const;
|
||||||
|
inline void SetBit(unsigned int uiBit, unsigned int bSet);
|
||||||
|
void Blank(bool bSetOrZero = false);
|
||||||
|
void Invert();
|
||||||
|
void CopyFrom(const LBitField_Dynamic_IT &source);
|
||||||
|
|
||||||
|
// loading / saving
|
||||||
|
unsigned char * GetData() {return m_pucData;}
|
||||||
|
const unsigned char * GetData() const {return m_pucData;}
|
||||||
|
unsigned int GetNumBytes() const {return m_uiNumBytes;}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// member funcs
|
||||||
|
void Initialize_Do();
|
||||||
|
void Terminate_Do();
|
||||||
|
|
||||||
|
// member vars
|
||||||
|
unsigned char * m_pucData;
|
||||||
|
unsigned int m_uiNumBytes;
|
||||||
|
unsigned int m_uiNumBits;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LBitField_Dynamic : public LBitField_Dynamic_IT
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// call initialize and terminate automatically
|
||||||
|
LBitField_Dynamic(unsigned int uiNumBits) {Initialize_Do(); Create(uiNumBits);}
|
||||||
|
LBitField_Dynamic() {Initialize_Do();}
|
||||||
|
~LBitField_Dynamic() {Terminate_Do();}
|
||||||
|
|
||||||
|
// disallow explicit calls
|
||||||
|
void Initialize();
|
||||||
|
void Terminate();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
inline unsigned int LBitField_Dynamic_IT::GetBit(unsigned int uiBit) const
|
||||||
|
{
|
||||||
|
assert (m_pucData);
|
||||||
|
unsigned int uiByteNumber = uiBit >> 3; // divide by 8
|
||||||
|
assert (uiByteNumber < m_uiNumBytes);
|
||||||
|
unsigned char uc = m_pucData[uiByteNumber];
|
||||||
|
unsigned int uiBitSet = uc & (1 << (uiBit & 7));
|
||||||
|
return uiBitSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void LBitField_Dynamic_IT::SetBit(unsigned int uiBit, unsigned int bSet)
|
||||||
|
{
|
||||||
|
assert (m_pucData);
|
||||||
|
unsigned int uiByteNumber = uiBit >> 3; // divide by 8
|
||||||
|
assert (uiByteNumber < m_uiNumBytes);
|
||||||
|
unsigned char uc = m_pucData[uiByteNumber];
|
||||||
|
unsigned int uiMask = 1 << (uiBit & 7);
|
||||||
|
if (bSet)
|
||||||
|
{
|
||||||
|
uc = uc | uiMask;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uc &= ~uiMask;
|
||||||
|
}
|
||||||
|
m_pucData[uiByteNumber] = uc;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace end
|
9
ldob.h
Normal file
9
ldob.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "scene/3d/spatial.h"
|
||||||
|
|
||||||
|
class LDob
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ObjectID m_ID;
|
||||||
|
};
|
16
lportal.cpp
16
lportal.cpp
@ -22,11 +22,21 @@
|
|||||||
#include "core/engine.h"
|
#include "core/engine.h"
|
||||||
#include "lroom.h"
|
#include "lroom.h"
|
||||||
|
|
||||||
|
|
||||||
|
bool LPortal::m_bRunning = false;
|
||||||
|
|
||||||
void LPortal::print(String sz)
|
void LPortal::print(String sz)
|
||||||
{
|
{
|
||||||
// print_line(sz);
|
if (m_bRunning)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print_line(sz);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LPortal::NameStartsWith(Node * pNode, String szSearch)
|
bool LPortal::NameStartsWith(Node * pNode, String szSearch)
|
||||||
{
|
{
|
||||||
int sl = szSearch.length();
|
int sl = szSearch.length();
|
||||||
@ -99,7 +109,7 @@ LPortal::eClipResult LPortal::ClipWithPlane(const Plane &p) const
|
|||||||
{
|
{
|
||||||
float d = p.distance_to(m_ptsWorld[n]);
|
float d = p.distance_to(m_ptsWorld[n]);
|
||||||
|
|
||||||
if (d >= 0.0)
|
if (d >= 0.0f)
|
||||||
nOutside++;
|
nOutside++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,7 +234,7 @@ void LPortal::SortVertsClockwise()
|
|||||||
double SmallestAngle = -1;
|
double SmallestAngle = -1;
|
||||||
int Smallest = -1;
|
int Smallest = -1;
|
||||||
|
|
||||||
for (unsigned int m=n+1; m<nPoints; m++)
|
for (int m=n+1; m<nPoints; m++)
|
||||||
{
|
{
|
||||||
if (p.distance_to(verts[m]) > 0.0f)
|
if (p.distance_to(verts[m]) > 0.0f)
|
||||||
// if (p.WhichSideNDLCompatible(m_Verts[m], 0.0f) != CoPlane::NEGATIVE_SIDE)
|
// if (p.WhichSideNDLCompatible(m_Verts[m], 0.0f) != CoPlane::NEGATIVE_SIDE)
|
||||||
|
@ -36,6 +36,7 @@ class LPortal : public Spatial {
|
|||||||
GDCLASS(LPortal, Spatial);
|
GDCLASS(LPortal, Spatial);
|
||||||
|
|
||||||
friend class LRoom;
|
friend class LRoom;
|
||||||
|
friend class LRoomManager;
|
||||||
private:
|
private:
|
||||||
|
|
||||||
enum eClipResult
|
enum eClipResult
|
||||||
@ -80,12 +81,13 @@ private:
|
|||||||
|
|
||||||
void SortVertsClockwise();
|
void SortVertsClockwise();
|
||||||
void ReverseWindingOrder();
|
void ReverseWindingOrder();
|
||||||
|
|
||||||
// useful funcs
|
|
||||||
public:
|
public:
|
||||||
|
// useful funcs
|
||||||
static bool NameStartsWith(Node * pNode, String szSearch);
|
static bool NameStartsWith(Node * pNode, String szSearch);
|
||||||
static String FindNameAfter(Node * pNode, String szStart);
|
static String FindNameAfter(Node * pNode, String szStart);
|
||||||
static void print(String sz);
|
static void print(String sz);
|
||||||
|
protected:
|
||||||
|
static bool m_bRunning;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
188
lroom.cpp
188
lroom.cpp
@ -22,7 +22,7 @@
|
|||||||
#include "core/engine.h"
|
#include "core/engine.h"
|
||||||
#include "scene/3d/mesh_instance.h"
|
#include "scene/3d/mesh_instance.h"
|
||||||
#include "lportal.h"
|
#include "lportal.h"
|
||||||
#include "CoBitField_Dynamic.h"
|
#include "lbitfield_dynamic.h"
|
||||||
#include "lroom_manager.h"
|
#include "lroom_manager.h"
|
||||||
|
|
||||||
void LRoom::print(String sz)
|
void LRoom::print(String sz)
|
||||||
@ -33,9 +33,157 @@ void LRoom::print(String sz)
|
|||||||
|
|
||||||
LRoom::LRoom() {
|
LRoom::LRoom() {
|
||||||
m_LocalRoomID = -1;
|
m_LocalRoomID = -1;
|
||||||
|
m_uiFrameTouched = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, const LCamera &cam, const LVector<Plane> &planes, Core::CoBitField_Dynamic &BF_visible, ObjectID portalID_from)
|
|
||||||
|
|
||||||
|
void LRoom::AddDOB(Spatial * pDOB)
|
||||||
|
{
|
||||||
|
LDob dob;
|
||||||
|
dob.m_ID = pDOB->get_instance_id();
|
||||||
|
|
||||||
|
m_DOBs.push_back(dob);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LRoom::RemoveDOB(Node * pDOB)
|
||||||
|
{
|
||||||
|
ObjectID id = pDOB->get_instance_id();
|
||||||
|
|
||||||
|
for (int n=0; n<m_DOBs.size(); n++)
|
||||||
|
{
|
||||||
|
if (m_DOBs[n].m_ID == id)
|
||||||
|
{
|
||||||
|
m_DOBs.remove(n);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// returns -1 if no change, or the objectID of the linked room
|
||||||
|
LRoom * LRoom::UpdateDOB(Spatial * pDOB)
|
||||||
|
{
|
||||||
|
const Vector3 &pt = pDOB->get_global_transform().origin;
|
||||||
|
|
||||||
|
const float slop = 0.2f;
|
||||||
|
|
||||||
|
// the camera can't have slop because we might end up front side of a door without entering the room,
|
||||||
|
// hence can't see into the room through the portal!
|
||||||
|
// if (bCamera)
|
||||||
|
// slop = 0.0f;
|
||||||
|
|
||||||
|
// check each portal - has the object crossed it into the neighbouring room?
|
||||||
|
int nPortals = m_portal_IDs.size();
|
||||||
|
for (int p=0; p<nPortals; p++)
|
||||||
|
{
|
||||||
|
ObjectID id = m_portal_IDs[p];
|
||||||
|
|
||||||
|
// get the portal
|
||||||
|
Object *pObj = ObjectDB::get_instance(id);
|
||||||
|
|
||||||
|
// assuming is a portal
|
||||||
|
LPortal * pPortal = Object::cast_to<LPortal>(pObj);
|
||||||
|
|
||||||
|
if (!pPortal)
|
||||||
|
{
|
||||||
|
WARN_PRINT_ONCE("LRoom::UpdateDynamicObject : Not a portal");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float dist = pPortal->m_Plane.distance_to(pt);
|
||||||
|
|
||||||
|
if (dist > slop)
|
||||||
|
{
|
||||||
|
print("DOB at pos " + pt + " ahead of portal " + pPortal->get_name() + " by " + String(Variant(dist)));
|
||||||
|
|
||||||
|
// move into the adjoining room
|
||||||
|
return pPortal->GetLinkedRoom();
|
||||||
|
|
||||||
|
// LRoom * pNewRoom = pPortal->GetLinkedRoom();
|
||||||
|
// if (pNewRoom)
|
||||||
|
// {
|
||||||
|
// // detach from this room and add to the new room
|
||||||
|
// remove_child(pDynObj);
|
||||||
|
// pNewRoom->add_child(pDynObj);
|
||||||
|
// // only allow one transition per frame
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// WARN_PRINT_ONCE("LRoom::UpdateDynamicObject : portal linked room is NULL");
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// assumes that the object is within, or just outside the bounds of the room...
|
||||||
|
// if not the results will be 'interesting'.
|
||||||
|
// Works simply by detecting crossing portals
|
||||||
|
bool LRoom::UpdateDynamicObject(Node * pDynObj)
|
||||||
|
{
|
||||||
|
Spatial * pSpatial = Object::cast_to<Spatial>(pDynObj);
|
||||||
|
if (!pSpatial)
|
||||||
|
{
|
||||||
|
WARN_PRINT_ONCE("LRoom::UpdateDynamicObject : object is not a spatial");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Vector3 &pt = pSpatial->get_global_transform().origin;
|
||||||
|
|
||||||
|
const float slop = 0.2f;
|
||||||
|
|
||||||
|
// check each portal - has the object crossed it into the neighbouring room?
|
||||||
|
int nPortals = m_portal_IDs.size();
|
||||||
|
for (int p=0; p<nPortals; p++)
|
||||||
|
{
|
||||||
|
ObjectID id = m_portal_IDs[p];
|
||||||
|
|
||||||
|
// get the portal
|
||||||
|
Object *pObj = ObjectDB::get_instance(id);
|
||||||
|
|
||||||
|
// assuming is a portal
|
||||||
|
LPortal * pPortal = Object::cast_to<LPortal>(pObj);
|
||||||
|
|
||||||
|
if (!pPortal)
|
||||||
|
{
|
||||||
|
WARN_PRINT_ONCE("LRoom::UpdateDynamicObject : Not a portal");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float dist = pPortal->m_Plane.distance_to(pt);
|
||||||
|
|
||||||
|
if (dist > slop)
|
||||||
|
{
|
||||||
|
print("DOB at pos " + pt + " ahead of portal " + pPortal->get_name() + " by " + String(Variant(dist)));
|
||||||
|
|
||||||
|
// move into the adjoining room
|
||||||
|
LRoom * pNewRoom = pPortal->GetLinkedRoom();
|
||||||
|
if (pNewRoom)
|
||||||
|
{
|
||||||
|
// detach from this room and add to the new room
|
||||||
|
remove_child(pDynObj);
|
||||||
|
pNewRoom->add_child(pDynObj);
|
||||||
|
// only allow one transition per frame
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WARN_PRINT_ONCE("LRoom::UpdateDynamicObject : portal linked room is NULL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, const LCamera &cam, const LVector<Plane> &planes, Lawn::LBitField_Dynamic &BF_visible, ObjectID portalID_from)
|
||||||
{
|
{
|
||||||
// prevent too much depth
|
// prevent too much depth
|
||||||
if (depth >= 8)
|
if (depth >= 8)
|
||||||
@ -46,6 +194,10 @@ void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, cons
|
|||||||
|
|
||||||
print("DetermineVisibility_Recursive from " + get_name());
|
print("DetermineVisibility_Recursive from " + get_name());
|
||||||
|
|
||||||
|
// set the frame counter
|
||||||
|
assert (manager.m_uiFrameCounter > m_uiFrameTouched);
|
||||||
|
m_uiFrameTouched = manager.m_uiFrameCounter;
|
||||||
|
|
||||||
// show this room and add to visible list of rooms
|
// show this room and add to visible list of rooms
|
||||||
show();
|
show();
|
||||||
BF_visible.SetBit(m_LocalRoomID, true);
|
BF_visible.SetBit(m_LocalRoomID, true);
|
||||||
@ -126,22 +278,32 @@ void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, cons
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Vector3 &portal_normal = pPortal->m_Plane.normal;
|
// have we already handled the room on this frame?
|
||||||
print("\ttesting portal " + pPortal->get_name() + " normal " + portal_normal);
|
// get the room pointed to by the portal
|
||||||
|
LRoom * pLinkedRoom = pPortal->GetLinkedRoom();
|
||||||
|
if (pLinkedRoom->m_uiFrameTouched == manager.m_uiFrameCounter)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// const Vector3 &portal_normal = pPortal->m_Plane.normal;
|
||||||
|
// print("\ttesting portal " + pPortal->get_name() + " normal " + portal_normal);
|
||||||
|
|
||||||
// direction with the camera? (might not need to check)
|
// direction with the camera? (might not need to check)
|
||||||
float dot = cam.m_ptDir.dot(portal_normal);
|
// float dot = cam.m_ptDir.dot(portal_normal);
|
||||||
if (dot <= 0.0f)
|
// if (dot <= -0.0f) // 0.0
|
||||||
{
|
// {
|
||||||
Variant vd = dot;
|
// Variant vd = dot;
|
||||||
print("\t\tportal culled (wrong direction) dot is " + String(vd));
|
// print("\t\tportal culled (wrong direction) dot is " + String(vd));
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// is it culled by the planes?
|
// is it culled by the planes?
|
||||||
LPortal::eClipResult overall_res = LPortal::eClipResult::CLIP_INSIDE;
|
LPortal::eClipResult overall_res = LPortal::eClipResult::CLIP_INSIDE;
|
||||||
|
|
||||||
for (int l=0; l<planes.size(); l++)
|
// for portals, we want to ignore the near clipping plane, as we might be right on the edge of a doorway
|
||||||
|
// and still want to look through the portal.
|
||||||
|
// So we are starting this loop from 1, ASSUMING that plane zero is the near clipping plane.
|
||||||
|
// If it isn't we would need a different strategy
|
||||||
|
for (int l=1; l<planes.size(); l++)
|
||||||
{
|
{
|
||||||
LPortal::eClipResult res = pPortal->ClipWithPlane(planes[l]);
|
LPortal::eClipResult res = pPortal->ClipWithPlane(planes[l]);
|
||||||
|
|
||||||
@ -179,8 +341,6 @@ void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, cons
|
|||||||
// add the planes for the portal
|
// add the planes for the portal
|
||||||
pPortal->AddPlanes(cam.m_ptPos, new_planes);
|
pPortal->AddPlanes(cam.m_ptPos, new_planes);
|
||||||
|
|
||||||
// get the room pointed to by the portal
|
|
||||||
LRoom * pLinkedRoom = pPortal->GetLinkedRoom();
|
|
||||||
if (pLinkedRoom)
|
if (pLinkedRoom)
|
||||||
pLinkedRoom->DetermineVisibility_Recursive(manager, depth + 1, cam, new_planes, BF_visible, id);
|
pLinkedRoom->DetermineVisibility_Recursive(manager, depth + 1, cam, new_planes, BF_visible, id);
|
||||||
|
|
||||||
|
21
lroom.h
21
lroom.h
@ -29,9 +29,10 @@
|
|||||||
|
|
||||||
#include "scene/3d/spatial.h"
|
#include "scene/3d/spatial.h"
|
||||||
#include "lvector.h"
|
#include "lvector.h"
|
||||||
|
#include "ldob.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Core {class CoBitField_Dynamic;}
|
namespace Lawn {class LBitField_Dynamic;}
|
||||||
|
|
||||||
class LPortal;
|
class LPortal;
|
||||||
class LRoomManager;
|
class LRoomManager;
|
||||||
@ -55,13 +56,21 @@ private:
|
|||||||
// a quick list of object IDs of child portals of this room
|
// a quick list of object IDs of child portals of this room
|
||||||
Vector<ObjectID> m_portal_IDs;
|
Vector<ObjectID> m_portal_IDs;
|
||||||
|
|
||||||
|
// godot vector for now .. can be lvector
|
||||||
|
Vector<LDob> m_DOBs;
|
||||||
|
|
||||||
|
// Just very rough, room centre for determining start rooms of dobs
|
||||||
|
Vector3 m_ptCentre;
|
||||||
|
|
||||||
// in the Room Manager, NOT the godot object ID
|
// in the Room Manager, NOT the godot object ID
|
||||||
int m_LocalRoomID;
|
int m_LocalRoomID;
|
||||||
|
|
||||||
|
// frame counter when last touched .. prevents handling rooms multiple times
|
||||||
|
unsigned int m_uiFrameTouched;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
public:
|
|
||||||
// initial setup, allows importing portals as meshes from modelling program,
|
// initial setup, allows importing portals as meshes from modelling program,
|
||||||
// which will be auto converted to LPortals with this method
|
// which will be auto converted to LPortals with this method
|
||||||
void DetectPortalMeshes();
|
void DetectPortalMeshes();
|
||||||
@ -70,8 +79,14 @@ public:
|
|||||||
void MakePortalQuickList();
|
void MakePortalQuickList();
|
||||||
|
|
||||||
// main function
|
// main function
|
||||||
void DetermineVisibility_Recursive(LRoomManager &manager, int depth, const LCamera &cam, const LVector<Plane> &planes, Core::CoBitField_Dynamic &BF_visible, ObjectID portalID_from = 0);
|
void DetermineVisibility_Recursive(LRoomManager &manager, int depth, const LCamera &cam, const LVector<Plane> &planes, Lawn::LBitField_Dynamic &BF_visible, ObjectID portalID_from = 0);
|
||||||
|
|
||||||
|
// dynamic objects
|
||||||
|
// bool UpdateDynamicObject(Node * pDynObj);
|
||||||
|
|
||||||
|
void AddDOB(Spatial * pDOB);
|
||||||
|
bool RemoveDOB(Node * pDOB);
|
||||||
|
LRoom * UpdateDOB(Spatial * pDOB);
|
||||||
// specific
|
// specific
|
||||||
public:
|
public:
|
||||||
LRoom();
|
LRoom();
|
||||||
|
@ -23,14 +23,204 @@
|
|||||||
#include "lroom.h"
|
#include "lroom.h"
|
||||||
#include "core/engine.h"
|
#include "core/engine.h"
|
||||||
#include "scene/3d/camera.h"
|
#include "scene/3d/camera.h"
|
||||||
|
#include "scene/3d/mesh_instance.h"
|
||||||
|
|
||||||
LRoomManager::LRoomManager()
|
LRoomManager::LRoomManager()
|
||||||
{
|
{
|
||||||
m_room_curr = 0;
|
// m_room_curr = 0;
|
||||||
m_cameraID = 0;
|
m_cameraID = 0;
|
||||||
|
m_uiFrameCounter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LRoomManager::FindClosestRoom(const Vector3 &pt) const
|
||||||
|
{
|
||||||
|
//print_line("FindClosestRoom");
|
||||||
|
int closest = -1;
|
||||||
|
float closest_dist = FLT_MAX;
|
||||||
|
|
||||||
|
for (int n=0; n<m_room_IDs.size(); n++)
|
||||||
|
{
|
||||||
|
LRoom * pRoom = GetRoomNum(n);
|
||||||
|
if (!pRoom)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
float d = pt.distance_squared_to(pRoom->m_ptCentre);
|
||||||
|
// print_line("\troom " + itos(n) + " dist " + String(Variant(d)));
|
||||||
|
|
||||||
|
if (d < closest_dist)
|
||||||
|
{
|
||||||
|
closest = n;
|
||||||
|
closest_dist = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return closest;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LRoom * LRoomManager::GetRoomNum(int i) const
|
||||||
|
{
|
||||||
|
assert (i < m_room_IDs.size());
|
||||||
|
Object *pObj = ObjectDB::get_instance(m_room_IDs[i]);
|
||||||
|
if (!pObj)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
LRoom * pRoom = Object::cast_to<LRoom>(pObj);
|
||||||
|
if (!pRoom)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return pRoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LRoomManager::GetRoomNumFromLRoom(LRoom * pRoom) const
|
||||||
|
{
|
||||||
|
// slow .. use metadata for this
|
||||||
|
int search_id = pRoom->get_instance_id();
|
||||||
|
|
||||||
|
for (int n=0; n<m_room_IDs.size(); n++)
|
||||||
|
{
|
||||||
|
if (m_room_IDs[n] == search_id)
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LRoomManager::Obj_SetRoomNum(Node * pNode, int num)
|
||||||
|
{
|
||||||
|
pNode->set_meta("_lroom", num);
|
||||||
|
|
||||||
|
assert (Obj_GetRoomNum(pNode) == num);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LRoomManager::Obj_GetRoomNum(Node * pNode) const
|
||||||
|
{
|
||||||
|
//assert (pNode->has_meta("_lroom"));
|
||||||
|
Variant v = pNode->get_meta("_lroom");
|
||||||
|
if (v.get_type() == Variant::NIL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
LRoom * LRoomManager::GetRoomFromDOB(Node * pNode) const
|
||||||
|
{
|
||||||
|
int iRoom = Obj_GetRoomNum(pNode);
|
||||||
|
if (iRoom == -1)
|
||||||
|
{
|
||||||
|
WARN_PRINT_ONCE("LRoomManager::GetRoomFromDOB : metadata is empty");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LRoom * pRoom = GetRoomNum(iRoom);
|
||||||
|
if (pRoom == 0)
|
||||||
|
{
|
||||||
|
WARN_PRINT_ONCE("LRoomManager::GetRoomFromDOB : pRoom is NULL");
|
||||||
|
}
|
||||||
|
return pRoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LRoomManager::register_dob(Node * pDOB)
|
||||||
|
{
|
||||||
|
print_line("register_dob " + pDOB->get_name());
|
||||||
|
|
||||||
|
Spatial * pSpat = Object::cast_to<Spatial>(pDOB);
|
||||||
|
if (!pSpat)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Vector3 pt = pSpat->get_global_transform().origin;
|
||||||
|
|
||||||
|
int iRoomNum = FindClosestRoom(pt);
|
||||||
|
print_line("register_dob closest room " + itos(iRoomNum));
|
||||||
|
|
||||||
|
if (iRoomNum == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
LRoom * pRoom = GetRoomNum(iRoomNum);
|
||||||
|
if (!pRoom)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pRoom->AddDOB(pSpat);
|
||||||
|
|
||||||
|
// save the room ID on the dob metadata
|
||||||
|
Obj_SetRoomNum(pSpat, iRoomNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LRoomManager::update_dob(Node * pDOB)
|
||||||
|
{
|
||||||
|
// find the room the object is attached to
|
||||||
|
LRoom * pRoom = GetRoomFromDOB(pDOB);
|
||||||
|
if (!pRoom)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Spatial * pSpat = Object::cast_to<Spatial>(pDOB);
|
||||||
|
if (!pSpat)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// is it the camera?
|
||||||
|
//bool bCamera = pDOB->get_instance_id() == m_cameraID;
|
||||||
|
|
||||||
|
LRoom * pNewRoom = pRoom->UpdateDOB(pSpat);
|
||||||
|
|
||||||
|
if (pNewRoom)
|
||||||
|
{
|
||||||
|
// remove from the list in old room and add to list in new room, and change the metadata
|
||||||
|
int iRoomNum = GetRoomNumFromLRoom(pNewRoom);
|
||||||
|
|
||||||
|
pRoom->RemoveDOB(pDOB);
|
||||||
|
pNewRoom->AddDOB(pSpat);
|
||||||
|
|
||||||
|
// save the room ID on the dob metadata
|
||||||
|
Obj_SetRoomNum(pSpat, iRoomNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LRoomManager::teleport_dob(Node * pDOB)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void LRoomManager::unregister_dob(Node * pDOB)
|
||||||
|
{
|
||||||
|
LRoom * pRoom = GetRoomFromDOB(pDOB);
|
||||||
|
pRoom->RemoveDOB(pDOB);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
bool LRoomManager::update_object(Node * pObj)
|
||||||
|
{
|
||||||
|
// find the room the object is attached to
|
||||||
|
Node * pParent = pObj->get_parent();
|
||||||
|
LRoom * pRoom = Object::cast_to<LRoom>(pParent);
|
||||||
|
if (!pRoom)
|
||||||
|
{
|
||||||
|
WARN_PRINT_ONCE("LRoomManager::update_object : object parent is not an LRoom");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bChanged = pRoom->UpdateDynamicObject(pObj);
|
||||||
|
|
||||||
|
// special .. for camera keep the camera room ID up to date
|
||||||
|
// could alternatively just use the parent of the camera?
|
||||||
|
// if (bChanged)
|
||||||
|
// {
|
||||||
|
// if (pObj->get_instance_id() == m_cameraID)
|
||||||
|
// {
|
||||||
|
// m_room_curr = pObj->get_parent()->get_instance_id();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
return bChanged;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void LRoomManager::set_camera(Node * pCam)
|
void LRoomManager::set_camera(Node * pCam)
|
||||||
{
|
{
|
||||||
@ -47,16 +237,21 @@ void LRoomManager::set_camera(Node * pCam)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_cameraID = pCam->get_instance_id();
|
m_cameraID = pCam->get_instance_id();
|
||||||
|
|
||||||
|
// use this temporarily to force debug
|
||||||
|
LPortal::m_bRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert empties and meshes to rooms and portals
|
// convert empties and meshes to rooms and portals
|
||||||
void LRoomManager::convert()
|
void LRoomManager::convert()
|
||||||
{
|
{
|
||||||
|
LPortal::m_bRunning = false;
|
||||||
print_line("running convert");
|
print_line("running convert");
|
||||||
|
|
||||||
Convert_Rooms();
|
Convert_Rooms();
|
||||||
Convert_Portals();
|
Convert_Portals();
|
||||||
Find_Rooms();
|
Find_Rooms();
|
||||||
|
LPortal::m_bRunning = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LRoomManager::Find_Rooms()
|
void LRoomManager::Find_Rooms()
|
||||||
@ -78,6 +273,7 @@ void LRoomManager::Find_Rooms()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
m_room_curr = 0;
|
m_room_curr = 0;
|
||||||
|
|
||||||
// just set current room to first room
|
// just set current room to first room
|
||||||
@ -86,6 +282,7 @@ void LRoomManager::Find_Rooms()
|
|||||||
m_room_curr = m_room_IDs[0];
|
m_room_curr = m_room_IDs[0];
|
||||||
print_line("first room ID is " + itos(m_room_curr));
|
print_line("first room ID is " + itos(m_room_curr));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// make sure bitfield is right size for number of rooms
|
// make sure bitfield is right size for number of rooms
|
||||||
m_BF_visible_rooms.Create(m_room_IDs.size());
|
m_BF_visible_rooms.Create(m_room_IDs.size());
|
||||||
@ -179,20 +376,55 @@ bool LRoomManager::Convert_Room(Spatial * pNode)
|
|||||||
// make the transform of the L room match the original spatial
|
// make the transform of the L room match the original spatial
|
||||||
pNew->set_transform(pNode->get_transform());
|
pNew->set_transform(pNode->get_transform());
|
||||||
|
|
||||||
|
// New .. room is at origin, all the child nodes are now transformed
|
||||||
|
// so everything is in world space ... makes dynamic objects changing rooms easier
|
||||||
|
//Transform tr_orig = pNode->get_transform();
|
||||||
|
|
||||||
int nChildren = pNode->get_child_count();
|
int nChildren = pNode->get_child_count();
|
||||||
|
|
||||||
|
LAABB bb_room;
|
||||||
|
bb_room.SetToMaxOpposite();
|
||||||
|
|
||||||
for (int n=0; n<nChildren; n++)
|
for (int n=0; n<nChildren; n++)
|
||||||
{
|
{
|
||||||
// reverse count
|
// reverse count
|
||||||
int c = nChildren - n - 1;
|
int c = nChildren - n - 1;
|
||||||
|
|
||||||
Node * pChild = pNode->get_child(c);
|
Node * pChild = pNode->get_child(c);
|
||||||
|
|
||||||
|
// change the transform of the child to take away the room transform
|
||||||
|
// Spatial * pSChild = Object::cast_to<Spatial>(pChild);
|
||||||
|
// Transform tr_world;
|
||||||
|
// if (pSChild)
|
||||||
|
// {
|
||||||
|
// tr_world = pSChild->get_global_transform();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// update bound to find centre of room roughly
|
||||||
|
VisualInstance * pVI = Object::cast_to<VisualInstance>(pChild);
|
||||||
|
if (pVI)
|
||||||
|
{
|
||||||
|
AABB bb = pVI->get_transformed_aabb();
|
||||||
|
bb_room.ExpandToEnclose(bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pNode->remove_child(pChild);
|
pNode->remove_child(pChild);
|
||||||
|
|
||||||
// add the child to the new node
|
// add the child to the new node
|
||||||
pNew->add_child(pChild);
|
pNew->add_child(pChild);
|
||||||
|
|
||||||
|
|
||||||
|
// if (pSChild)
|
||||||
|
// {
|
||||||
|
// pSChild->set_transform(tr_world);
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pNew->m_ptCentre = bb_room.FindCentre();
|
||||||
|
print_line(String(pNew->get_name()) + " centre " + pNew->m_ptCentre);
|
||||||
|
|
||||||
// all moved .. now finally delete the empty
|
// all moved .. now finally delete the empty
|
||||||
remove_child(pNode);
|
remove_child(pNode);
|
||||||
pNode->queue_delete();
|
pNode->queue_delete();
|
||||||
@ -208,22 +440,41 @@ void LRoomManager::FrameUpdate()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if not started
|
m_uiFrameCounter++;
|
||||||
if (!m_room_curr)
|
|
||||||
|
// get the camera desired and make into lcamera
|
||||||
|
Camera * pCamera = 0;
|
||||||
|
if (m_cameraID)
|
||||||
|
{
|
||||||
|
Object *pObj = ObjectDB::get_instance(m_cameraID);
|
||||||
|
pCamera = Object::cast_to<Camera>(pObj);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// camera not set
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// camera not a camera??
|
||||||
|
if (!pCamera)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// if not started
|
||||||
|
// if (!m_room_curr)
|
||||||
|
// return;
|
||||||
|
|
||||||
// determine visibility
|
// determine visibility
|
||||||
Object *pObj = ObjectDB::get_instance(m_room_curr);
|
// Object *pObj = ObjectDB::get_instance(m_room_curr);
|
||||||
|
LRoom * pRoom = GetRoomFromDOB(pCamera);
|
||||||
|
// Node * pObj = pCamera->get_parent();
|
||||||
|
|
||||||
if (!pObj)
|
// if (!pObj)
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
LRoom * pRoom = Object::cast_to<LRoom>(pObj);
|
// LRoom * pRoom = Object::cast_to<LRoom>(pObj);
|
||||||
if (!pRoom)
|
if (!pRoom)
|
||||||
{
|
{
|
||||||
WARN_PRINT_ONCE("LRoomManager::FrameUpdate : curr room is not an LRoom");
|
WARN_PRINT_ONCE("LRoomManager::FrameUpdate : curr room is not an LRoom");
|
||||||
print_line("curr room is not an LRoom");
|
//print_line("LRoomManager::FrameUpdate : curr room is not an LRoom");
|
||||||
m_room_curr = 0;
|
// m_room_curr = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,19 +493,14 @@ void LRoomManager::FrameUpdate()
|
|||||||
planes.clear();
|
planes.clear();
|
||||||
|
|
||||||
// get the camera desired and make into lcamera
|
// get the camera desired and make into lcamera
|
||||||
if (m_cameraID)
|
assert (pCamera);
|
||||||
|
// if (pCamera)
|
||||||
{
|
{
|
||||||
Object *pObj = ObjectDB::get_instance(m_cameraID);
|
Transform tr = pCamera->get_global_transform();
|
||||||
|
cam.m_ptPos = tr.origin;
|
||||||
|
cam.m_ptDir = tr.basis.get_row(2); // or possibly get_axis .. z is what we want
|
||||||
|
|
||||||
Camera * pCamera = Object::cast_to<Camera>(pObj);
|
planes.copy_from(pCamera->get_frustum());
|
||||||
if (pCamera)
|
|
||||||
{
|
|
||||||
Transform tr = pCamera->get_global_transform();
|
|
||||||
cam.m_ptPos = tr.origin;
|
|
||||||
cam.m_ptDir = tr.basis.get_row(2); // or possibly get_axis .. z is what we want
|
|
||||||
|
|
||||||
planes.copy_from(pCamera->get_frustum());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pRoom->DetermineVisibility_Recursive(*this, 0, cam, planes, m_BF_visible_rooms);
|
pRoom->DetermineVisibility_Recursive(*this, 0, cam, planes, m_BF_visible_rooms);
|
||||||
@ -276,6 +522,9 @@ void LRoomManager::FrameUpdate()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LPortal::m_bRunning = true;
|
||||||
|
|
||||||
|
|
||||||
// only do once for now
|
// only do once for now
|
||||||
// m_room_curr = 0;
|
// m_room_curr = 0;
|
||||||
}
|
}
|
||||||
@ -317,7 +566,14 @@ void LRoomManager::_notification(int p_what) {
|
|||||||
|
|
||||||
void LRoomManager::_bind_methods()
|
void LRoomManager::_bind_methods()
|
||||||
{
|
{
|
||||||
ClassDB::bind_method(D_METHOD("convert"), &LRoomManager::convert);
|
ClassDB::bind_method(D_METHOD("rooms_convert"), &LRoomManager::convert);
|
||||||
ClassDB::bind_method(D_METHOD("set_camera"), &LRoomManager::set_camera);
|
ClassDB::bind_method(D_METHOD("rooms_set_camera"), &LRoomManager::set_camera);
|
||||||
|
// ClassDB::bind_method(D_METHOD("update_object"), &LRoomManager::update_object);
|
||||||
|
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("dob_register"), &LRoomManager::register_dob);
|
||||||
|
ClassDB::bind_method(D_METHOD("dob_unregister"), &LRoomManager::unregister_dob);
|
||||||
|
ClassDB::bind_method(D_METHOD("dob_update"), &LRoomManager::update_dob);
|
||||||
|
ClassDB::bind_method(D_METHOD("dob_teleport"), &LRoomManager::teleport_dob);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,46 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "scene/3d/spatial.h"
|
#include "scene/3d/spatial.h"
|
||||||
#include "CoBitField_Dynamic.h"
|
#include "lbitfield_dynamic.h"
|
||||||
#include "lplanes_pool.h"
|
#include "lplanes_pool.h"
|
||||||
|
|
||||||
|
|
||||||
|
class LRoom;
|
||||||
|
|
||||||
|
// simple min max aabb
|
||||||
|
class LAABB
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Vector3 m_ptMins;
|
||||||
|
Vector3 m_ptMaxs;
|
||||||
|
void SetToMaxOpposite()
|
||||||
|
{
|
||||||
|
float ma = FLT_MAX;
|
||||||
|
float mi = FLT_MIN;
|
||||||
|
m_ptMins = Vector3(ma, ma, ma);
|
||||||
|
m_ptMaxs = Vector3(mi, mi, mi);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
Vector3 FindCentre() const
|
||||||
|
{
|
||||||
|
Vector3 pt;
|
||||||
|
pt.x = (m_ptMaxs.x - m_ptMins.x) * 0.5f;
|
||||||
|
pt.y = (m_ptMaxs.y - m_ptMins.y) * 0.5f;
|
||||||
|
pt.z = (m_ptMaxs.z - m_ptMins.z) * 0.5f;
|
||||||
|
pt += m_ptMins;
|
||||||
|
return pt;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class LRoomManager : public Spatial {
|
class LRoomManager : public Spatial {
|
||||||
GDCLASS(LRoomManager, Spatial);
|
GDCLASS(LRoomManager, Spatial);
|
||||||
|
|
||||||
@ -38,14 +75,18 @@ class LRoomManager : public Spatial {
|
|||||||
// a quick list of object IDs of child rooms
|
// a quick list of object IDs of child rooms
|
||||||
Vector<ObjectID> m_room_IDs;
|
Vector<ObjectID> m_room_IDs;
|
||||||
|
|
||||||
ObjectID m_room_curr;
|
// ObjectID m_room_curr;
|
||||||
ObjectID m_cameraID;
|
ObjectID m_cameraID;
|
||||||
|
|
||||||
// keep track of which rooms are visible, so we can hide ones that aren't hit that were previously on
|
// keep track of which rooms are visible, so we can hide ones that aren't hit that were previously on
|
||||||
Core::CoBitField_Dynamic m_BF_visible_rooms;
|
Lawn::LBitField_Dynamic m_BF_visible_rooms;
|
||||||
Vector<int> m_VisibleRoomList[2];
|
Vector<int> m_VisibleRoomList[2];
|
||||||
int m_CurrentVisibleRoomList;
|
int m_CurrentVisibleRoomList;
|
||||||
|
|
||||||
|
// keep a frame counter, to mark when objects have been hit by the visiblity algorithm
|
||||||
|
// already to prevent multiple hits on rooms and objects
|
||||||
|
unsigned int m_uiFrameCounter;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LRoomManager();
|
LRoomManager();
|
||||||
|
|
||||||
@ -56,17 +97,35 @@ public:
|
|||||||
// 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 set_camera(Node * pCam);
|
void set_camera(Node * pCam);
|
||||||
|
|
||||||
|
// updating dynamic objects in case they move out of their current room
|
||||||
|
void register_dob(Node * pDOB);
|
||||||
|
void unregister_dob(Node * pDOB);
|
||||||
|
bool update_dob(Node * pDOB);
|
||||||
|
bool teleport_dob(Node * pDOB);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
|
|
||||||
LPlanesPool m_Pool;
|
LPlanesPool m_Pool;
|
||||||
private:
|
private:
|
||||||
|
// one time conversion and setup
|
||||||
void Convert_Rooms();
|
void Convert_Rooms();
|
||||||
bool Convert_Room(Spatial * pNode);
|
bool Convert_Room(Spatial * pNode);
|
||||||
void Convert_Portals();
|
void Convert_Portals();
|
||||||
void Find_Rooms();
|
void Find_Rooms();
|
||||||
|
|
||||||
|
// helper funcs
|
||||||
|
LRoom * GetRoomNum(int i) const;
|
||||||
|
LRoom * GetRoomFromDOB(Node * pNode) const;
|
||||||
|
int GetRoomNumFromLRoom(LRoom * pRoom) const;
|
||||||
|
int FindClosestRoom(const Vector3 &pt) const;
|
||||||
|
|
||||||
|
int Obj_GetRoomNum(Node * pNode) const;
|
||||||
|
void Obj_SetRoomNum(Node * pNode, int num);
|
||||||
|
|
||||||
|
|
||||||
void FrameUpdate();
|
void FrameUpdate();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ public:
|
|||||||
}
|
}
|
||||||
const T& operator[](unsigned int ui) const
|
const T& operator[](unsigned int ui) const
|
||||||
{
|
{
|
||||||
assert (ui < m_iSize);
|
assert (ui < (unsigned int) m_iSize);
|
||||||
return m_Vec[ui];
|
return m_Vec[ui];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ public:
|
|||||||
|
|
||||||
void set(unsigned int ui, const T &t)
|
void set(unsigned int ui, const T &t)
|
||||||
{
|
{
|
||||||
assert (ui < m_iSize);
|
assert (ui < (unsigned int) m_iSize);
|
||||||
m_Vec.set(ui, t);
|
m_Vec.set(ui, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user