mirror of
https://github.com/Relintai/godot-lportal.git
synced 2024-11-11 10:52:09 +01:00
First working test version
This commit is contained in:
parent
829dcb8e13
commit
726412a97b
93
CoBitField_Dynamic.cpp
Normal file
93
CoBitField_Dynamic.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
#include "CoBitField_Dynamic.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
namespace Core { // namespace start
|
||||
|
||||
void CoBitField_Dynamic::Initialize() {assert (0 && "CoBitField_Dynamic : Does not support Initialize, use IT version");}
|
||||
void CoBitField_Dynamic::Terminate() {assert (0 && "CoBitField_Dynamic : Does not support Terminate, use IT version");}
|
||||
|
||||
|
||||
void CoBitField_Dynamic_IT::Initialize()
|
||||
{
|
||||
Initialize_Do();
|
||||
}
|
||||
|
||||
void CoBitField_Dynamic_IT::Terminate()
|
||||
{
|
||||
Terminate_Do();
|
||||
}
|
||||
|
||||
|
||||
void CoBitField_Dynamic_IT::Initialize_Do()
|
||||
{
|
||||
memset (this, 0, sizeof (CoBitField_Dynamic));
|
||||
}
|
||||
|
||||
void CoBitField_Dynamic_IT::Terminate_Do()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void CoBitField_Dynamic_IT::CopyFrom(const CoBitField_Dynamic_IT &source)
|
||||
{
|
||||
Create(source.GetNumBits(), false);
|
||||
memcpy(m_pucData, source.GetData(), source.GetNumBytes());
|
||||
}
|
||||
|
||||
|
||||
void CoBitField_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 CoBitField_Dynamic_IT::Destroy()
|
||||
{
|
||||
if (m_pucData)
|
||||
{
|
||||
delete[] m_pucData;
|
||||
m_pucData = 0;
|
||||
}
|
||||
|
||||
memset (this, 0, sizeof (CoBitField_Dynamic));
|
||||
}
|
||||
|
||||
|
||||
void CoBitField_Dynamic_IT::Blank(bool bSetOrZero)
|
||||
{
|
||||
if (bSetOrZero)
|
||||
{
|
||||
memset(m_pucData, 255, m_uiNumBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(m_pucData, 0, m_uiNumBytes);
|
||||
}
|
||||
}
|
||||
|
||||
void CoBitField_Dynamic_IT::Invert()
|
||||
{
|
||||
for (unsigned int n=0; n<m_uiNumBytes; n++)
|
||||
{
|
||||
m_pucData[n] = ~m_pucData[n];
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
} // namespace end
|
91
CoBitField_Dynamic.h
Normal file
91
CoBitField_Dynamic.h
Normal file
@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace Core { // namespace start
|
||||
|
||||
class CoBitField_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.
|
||||
CoBitField_Dynamic_IT& operator=(const CoBitField_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 CoBitField_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 CoBitField_Dynamic : public CoBitField_Dynamic_IT
|
||||
{
|
||||
public:
|
||||
// call initialize and terminate automatically
|
||||
CoBitField_Dynamic(unsigned int uiNumBits) {Initialize_Do(); Create(uiNumBits);}
|
||||
CoBitField_Dynamic() {Initialize_Do();}
|
||||
~CoBitField_Dynamic() {Terminate_Do();}
|
||||
|
||||
// disallow explicit calls
|
||||
void Initialize();
|
||||
void Terminate();
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
inline unsigned int CoBitField_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 CoBitField_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
|
1
SCsub
1
SCsub
@ -6,6 +6,7 @@ sources = [
|
||||
"lroom.cpp",
|
||||
"lroom_manager.cpp",
|
||||
"lportal.cpp",
|
||||
"CoBitField_Dynamic.cpp",
|
||||
]
|
||||
|
||||
module_env = env.Clone()
|
||||
|
47
lportal.cpp
47
lportal.cpp
@ -22,6 +22,10 @@
|
||||
#include "core/engine.h"
|
||||
#include "lroom.h"
|
||||
|
||||
void LPortal::print(String sz)
|
||||
{
|
||||
// print_line(sz);
|
||||
}
|
||||
|
||||
bool LPortal::NameStartsWith(Node * pNode, String szSearch)
|
||||
{
|
||||
@ -50,12 +54,31 @@ String LPortal::FindNameAfter(Node * pNode, String szStart)
|
||||
String name = pNode->get_name();
|
||||
szRes = name.substr(szStart.length());
|
||||
|
||||
print_line("\t\tNameAfter is " + szRes);
|
||||
print("\t\tNameAfter is " + szRes);
|
||||
return szRes;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
// add clipping planes to the vector formed by each portal edge and the camera
|
||||
void LPortal::AddPlanes(const Vector3 &ptCam, Vector<Plane> &planes) const
|
||||
{
|
||||
// short version
|
||||
const Vector<Vector3> &pts = m_ptsWorld;
|
||||
|
||||
int nPoints = pts.size();
|
||||
// ERR_FAIL_COND(nPoints < 3);
|
||||
|
||||
Plane p;
|
||||
|
||||
for (int n=1; n<nPoints; n++)
|
||||
{
|
||||
p = Plane(ptCam, pts[n], pts[n-1]);
|
||||
planes.push_back(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LPortal::eClipResult LPortal::ClipWithPlane(const Plane &p) const
|
||||
{
|
||||
int nOutside = 0;
|
||||
@ -93,7 +116,7 @@ void LPortal::Link(LRoom * pParentRoom)
|
||||
|
||||
String szRoom = FindNameAfter(this, "lportal_");
|
||||
|
||||
print_line("LPortal::Link to room " + szRoom);
|
||||
print("LPortal::Link to room " + szRoom);
|
||||
|
||||
// find the room group
|
||||
Spatial * pGroup = Object::cast_to<Spatial>(pParentRoom->get_parent());
|
||||
@ -139,13 +162,13 @@ void LPortal::CreateGeometry(PoolVector<Vector3> p_vertices)
|
||||
m_ptsLocal.resize(nPoints);
|
||||
m_ptsWorld.resize(nPoints);
|
||||
|
||||
print_line("\tLPortal::CreateGeometry nPoints : " + itos(nPoints));
|
||||
print("\tLPortal::CreateGeometry nPoints : " + itos(nPoints));
|
||||
|
||||
for (int n=0; n<nPoints; n++)
|
||||
{
|
||||
m_ptsLocal.set(n, p_vertices[n]);
|
||||
Variant pt = p_vertices[n];
|
||||
print_line("\t\t" + itos(n) + "\t: " + pt);
|
||||
print("\t\t" + itos(n) + "\t: " + pt);
|
||||
}
|
||||
|
||||
SortVertsClockwise();
|
||||
@ -250,12 +273,12 @@ void LPortal::CalculateLocalPoints()
|
||||
|
||||
Transform tr = get_transform();
|
||||
|
||||
print_line("\tCalculateLocalPoints");
|
||||
print("\tCalculateLocalPoints");
|
||||
for (int n=0; n<nPoints; n++)
|
||||
{
|
||||
m_ptsLocal.set(n, tr.xform_inv(m_ptsWorld[n]));
|
||||
Variant pt = m_ptsLocal[n];
|
||||
print_line("\t\t" + itos(n) + "\t: " + pt);
|
||||
print("\t\t" + itos(n) + "\t: " + pt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,18 +290,18 @@ void LPortal::CalculateWorldPoints()
|
||||
|
||||
Transform tr = get_global_transform();
|
||||
|
||||
print_line("\tCalculateWorldPoints");
|
||||
print("\tCalculateWorldPoints");
|
||||
for (int n=0; n<nPoints; n++)
|
||||
{
|
||||
m_ptsWorld.set(n, tr.xform(m_ptsLocal[n]));
|
||||
Variant pt = m_ptsWorld[n];
|
||||
print_line("\t\t" + itos(n) + "\t: " + pt);
|
||||
print("\t\t" + itos(n) + "\t: " + pt);
|
||||
}
|
||||
}
|
||||
|
||||
void LPortal::CopyReversedGeometry(const LPortal &source)
|
||||
{
|
||||
print_line("CopyReversedGeometry");
|
||||
print("CopyReversedGeometry");
|
||||
// points are the same but reverse winding order
|
||||
int nPoints = source.m_ptsWorld.size();
|
||||
|
||||
@ -289,7 +312,7 @@ void LPortal::CopyReversedGeometry(const LPortal &source)
|
||||
{
|
||||
m_ptsWorld.set(n, source.m_ptsWorld[nPoints - n - 1]);
|
||||
Variant pt = m_ptsWorld[n];
|
||||
print_line("\t\t" + itos(n) + "\t: " + pt);
|
||||
print("\t\t" + itos(n) + "\t: " + pt);
|
||||
}
|
||||
|
||||
CalculateLocalPoints();
|
||||
@ -306,7 +329,7 @@ void LPortal::PlaneFromPoints()
|
||||
// create plane from points
|
||||
m_Plane = Plane(m_ptsWorld[0], m_ptsWorld[1], m_ptsWorld[2]);
|
||||
|
||||
print_line("Plane normal world space : " + m_Plane);
|
||||
print("Plane normal world space : " + m_Plane);
|
||||
|
||||
// Plane opp = Plane(m_ptsWorld[2], m_ptsWorld[1], m_ptsWorld[0]);
|
||||
// print_line("Plane opposite : " + opp);
|
||||
@ -315,7 +338,7 @@ void LPortal::PlaneFromPoints()
|
||||
|
||||
bool LPortal::AddRoom(NodePath path)
|
||||
{
|
||||
print_line("LPortal::AddRoom path is " + path);
|
||||
print("LPortal::AddRoom path is " + path);
|
||||
|
||||
if (has_node(path))
|
||||
{
|
||||
|
12
lportal.h
12
lportal.h
@ -29,16 +29,6 @@
|
||||
|
||||
#include "scene/3d/spatial.h"
|
||||
|
||||
|
||||
// Smooth node allows fixed timestep interpolation without having to write any code.
|
||||
// It requires a proxy node (which is moved on physics tick), e.g. a rigid body or manually moved spatial..
|
||||
// and instead of having MeshInstance as a child of this, you add Smooth node to another part of the scene graph,
|
||||
// make the MeshInstance a child of the smooth node, then choose the proxy as the target for the smooth node.
|
||||
|
||||
// Note that in the special case of manually moving the proxy to a completely new location, you should call
|
||||
// 'teleport' on the smooth node after setting the proxy node transform. This will ensure that the current AND
|
||||
// previous transform records are reset, so it moves instantaneously.
|
||||
|
||||
class LRoom;
|
||||
|
||||
class LPortal : public Spatial {
|
||||
@ -62,6 +52,7 @@ protected:
|
||||
static void _bind_methods();
|
||||
|
||||
LPortal::eClipResult ClipWithPlane(const Plane &p) const;
|
||||
void AddPlanes(const Vector3 &ptCam, Vector<Plane> &planes) const;
|
||||
|
||||
public:
|
||||
// normal determined by winding order
|
||||
@ -93,6 +84,7 @@ private:
|
||||
public:
|
||||
static bool NameStartsWith(Node * pNode, String szSearch);
|
||||
static String FindNameAfter(Node * pNode, String szStart);
|
||||
static void print(String sz);
|
||||
};
|
||||
|
||||
|
||||
|
84
lroom.cpp
84
lroom.cpp
@ -22,24 +22,82 @@
|
||||
#include "core/engine.h"
|
||||
#include "scene/3d/mesh_instance.h"
|
||||
#include "lportal.h"
|
||||
#include "CoBitField_Dynamic.h"
|
||||
|
||||
|
||||
LRoom::LRoom() {
|
||||
void LRoom::print(String sz)
|
||||
{
|
||||
// print_line(sz);
|
||||
}
|
||||
|
||||
void LRoom::DetermineVisibility_Recursive(int depth, const LCamera &cam, const Vector<Plane> &planes, ObjectID portalID_from)
|
||||
LRoom::LRoom() {
|
||||
m_LocalRoomID = -1;
|
||||
}
|
||||
|
||||
void LRoom::DetermineVisibility_Recursive(int depth, const LCamera &cam, const Vector<Plane> &planes, Core::CoBitField_Dynamic &BF_visible, ObjectID portalID_from)
|
||||
{
|
||||
// prevent too much depth
|
||||
if (depth >= 8)
|
||||
{
|
||||
print_line("\t\t\tDEPTH LIMIT REACHED");
|
||||
print("\t\t\tDEPTH LIMIT REACHED");
|
||||
return;
|
||||
}
|
||||
|
||||
print_line("DetermineVisibility_Recursive from " + get_name());
|
||||
print("DetermineVisibility_Recursive from " + get_name());
|
||||
|
||||
// show this room and add to visible list of rooms
|
||||
show();
|
||||
BF_visible.SetBit(m_LocalRoomID, true);
|
||||
|
||||
// clip all objects in this room to the clipping planes
|
||||
// NYI
|
||||
for (int n=0; n<get_child_count(); n++)
|
||||
{
|
||||
// ignore portals
|
||||
Node * pNode = get_child(n);
|
||||
LPortal * pPortal = Object::cast_to<LPortal>(pNode);
|
||||
if (pPortal)
|
||||
continue;
|
||||
|
||||
VisualInstance * pObj = Object::cast_to<VisualInstance>(pNode);
|
||||
if (pObj)
|
||||
{
|
||||
Vector3 pt = pObj->get_global_transform().origin;
|
||||
|
||||
bool bShow = true;
|
||||
|
||||
|
||||
// estimate the radius .. for now
|
||||
AABB bb = pObj->get_transformed_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)
|
||||
pObj->show();
|
||||
else
|
||||
pObj->hide();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// go through each portal out of here
|
||||
int nPortals = m_portal_IDs.size();
|
||||
@ -67,14 +125,14 @@ void LRoom::DetermineVisibility_Recursive(int depth, const LCamera &cam, const V
|
||||
}
|
||||
|
||||
const Vector3 &portal_normal = pPortal->m_Plane.normal;
|
||||
print_line("\ttesting portal " + pPortal->get_name() + " normal " + portal_normal);
|
||||
print("\ttesting portal " + pPortal->get_name() + " normal " + portal_normal);
|
||||
|
||||
// direction with the camera? (might not need to check)
|
||||
float dot = cam.m_ptDir.dot(portal_normal);
|
||||
if (dot <= 0.0f)
|
||||
{
|
||||
Variant vd = dot;
|
||||
print_line("\t\tportal culled (wrong direction) dot is " + String(vd));
|
||||
print("\t\tportal culled (wrong direction) dot is " + String(vd));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -102,7 +160,7 @@ void LRoom::DetermineVisibility_Recursive(int depth, const LCamera &cam, const V
|
||||
// this portal is culled
|
||||
if (overall_res == LPortal::eClipResult::CLIP_OUTSIDE)
|
||||
{
|
||||
print_line("\t\tportal culled (outside planes)");
|
||||
print("\t\tportal culled (outside planes)");
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -110,12 +168,12 @@ void LRoom::DetermineVisibility_Recursive(int depth, const LCamera &cam, const V
|
||||
Vector<Plane> new_planes = planes;
|
||||
|
||||
// add the planes for the portal
|
||||
// NYI
|
||||
pPortal->AddPlanes(cam.m_ptPos, new_planes);
|
||||
|
||||
// get the room pointed to by the portal
|
||||
LRoom * pLinkedRoom = pPortal->GetLinkedRoom();
|
||||
if (pLinkedRoom)
|
||||
pLinkedRoom->DetermineVisibility_Recursive(depth + 1, cam, new_planes, id);
|
||||
pLinkedRoom->DetermineVisibility_Recursive(depth + 1, cam, new_planes, BF_visible, id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,7 +183,7 @@ void LRoom::DetermineVisibility_Recursive(int depth, const LCamera &cam, const V
|
||||
// which will be auto converted to LPortals with this method
|
||||
void LRoom::DetectPortalMeshes()
|
||||
{
|
||||
print_line("DetectPortalMeshes");
|
||||
print("DetectPortalMeshes");
|
||||
|
||||
bool bFoundOne = true;
|
||||
|
||||
@ -158,7 +216,7 @@ void LRoom::DetectPortalMeshes()
|
||||
|
||||
void LRoom::DetectedPortalMesh(MeshInstance * pMeshInstance, String szLinkRoom)
|
||||
{
|
||||
print_line("\tDetected PortalMesh");
|
||||
print("\tDetected PortalMesh");
|
||||
|
||||
Ref<Mesh> rmesh = pMeshInstance->get_mesh();
|
||||
|
||||
|
16
lroom.h
16
lroom.h
@ -30,14 +30,7 @@
|
||||
#include "scene/3d/spatial.h"
|
||||
|
||||
|
||||
// Smooth node allows fixed timestep interpolation without having to write any code.
|
||||
// It requires a proxy node (which is moved on physics tick), e.g. a rigid body or manually moved spatial..
|
||||
// and instead of having MeshInstance as a child of this, you add Smooth node to another part of the scene graph,
|
||||
// make the MeshInstance a child of the smooth node, then choose the proxy as the target for the smooth node.
|
||||
|
||||
// Note that in the special case of manually moving the proxy to a completely new location, you should call
|
||||
// 'teleport' on the smooth node after setting the proxy node transform. This will ensure that the current AND
|
||||
// previous transform records are reset, so it moves instantaneously.
|
||||
namespace Core {class CoBitField_Dynamic;}
|
||||
|
||||
class LPortal;
|
||||
class MeshInstance;
|
||||
@ -55,10 +48,14 @@ class LRoom : public Spatial {
|
||||
GDCLASS(LRoom, Spatial);
|
||||
|
||||
friend class LPortal;
|
||||
friend class LRoomManager;
|
||||
private:
|
||||
// a quick list of object IDs of child portals of this room
|
||||
Vector<ObjectID> m_portal_IDs;
|
||||
|
||||
// in the Room Manager, NOT the godot object ID
|
||||
int m_LocalRoomID;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
@ -71,7 +68,7 @@ public:
|
||||
void MakePortalQuickList();
|
||||
|
||||
// main function
|
||||
void DetermineVisibility_Recursive(int depth, const LCamera &cam, const Vector<Plane> &planes, ObjectID portalID_from = 0);
|
||||
void DetermineVisibility_Recursive(int depth, const LCamera &cam, const Vector<Plane> &planes, Core::CoBitField_Dynamic &BF_visible, ObjectID portalID_from = 0);
|
||||
|
||||
// specific
|
||||
public:
|
||||
@ -83,6 +80,7 @@ private:
|
||||
// void SetupPortal(LPortal * pPortal);
|
||||
void MakeOppositePortal(LPortal * pPortalFrom, LRoom * pRoomTo);
|
||||
void DetectedPortalMesh(MeshInstance * pMeshInstance, String szLinkRoom);
|
||||
static void print(String sz);
|
||||
};
|
||||
|
||||
|
||||
|
@ -22,13 +22,32 @@
|
||||
#include "lportal.h"
|
||||
#include "lroom.h"
|
||||
#include "core/engine.h"
|
||||
#include "scene/3d/camera.h"
|
||||
|
||||
LRoomManager::LRoomManager()
|
||||
{
|
||||
m_room_curr = 0;
|
||||
m_cameraID = 0;
|
||||
}
|
||||
|
||||
|
||||
void LRoomManager::set_camera(Node * pCam)
|
||||
{
|
||||
m_cameraID = 0;
|
||||
|
||||
if (!pCam)
|
||||
return;
|
||||
|
||||
Camera * pCamera = Object::cast_to<Camera>(pCam);
|
||||
if (!pCamera)
|
||||
{
|
||||
WARN_PRINT("Not a camera");
|
||||
return;
|
||||
}
|
||||
|
||||
m_cameraID = pCam->get_instance_id();
|
||||
}
|
||||
|
||||
// convert empties and meshes to rooms and portals
|
||||
void LRoomManager::convert()
|
||||
{
|
||||
@ -52,7 +71,10 @@ void LRoomManager::Find_Rooms()
|
||||
// don't want to handle already converted rooms
|
||||
LRoom * pRoom = Object::cast_to<LRoom>(pChild);
|
||||
if (pRoom)
|
||||
{
|
||||
pRoom->m_LocalRoomID = m_room_IDs.size();
|
||||
m_room_IDs.push_back(pRoom->get_instance_id());
|
||||
}
|
||||
}
|
||||
|
||||
m_room_curr = 0;
|
||||
@ -63,6 +85,9 @@ void LRoomManager::Find_Rooms()
|
||||
m_room_curr = m_room_IDs[0];
|
||||
print_line("first room ID is " + itos(m_room_curr));
|
||||
}
|
||||
|
||||
// make sure bitfield is right size for number of rooms
|
||||
m_BF_visible_rooms.Create(m_room_IDs.size());
|
||||
}
|
||||
|
||||
void LRoomManager::Convert_Rooms()
|
||||
@ -176,6 +201,12 @@ bool LRoomManager::Convert_Room(Spatial * pNode)
|
||||
|
||||
void LRoomManager::FrameUpdate()
|
||||
{
|
||||
if (Engine::get_singleton()->is_editor_hint())
|
||||
{
|
||||
WARN_PRINT_ONCE("LRoomManager::FrameUpdate should not be called in editor");
|
||||
return;
|
||||
}
|
||||
|
||||
// if not started
|
||||
if (!m_room_curr)
|
||||
return;
|
||||
@ -195,18 +226,51 @@ void LRoomManager::FrameUpdate()
|
||||
return;
|
||||
}
|
||||
|
||||
m_BF_visible_rooms.Blank();
|
||||
|
||||
LCamera cam;
|
||||
cam.m_ptPos = Vector3(0, 0, 0);
|
||||
cam.m_ptDir = Vector3 (-1, 0, 0);
|
||||
|
||||
Vector<Plane> planes;
|
||||
|
||||
pRoom->DetermineVisibility_Recursive(0, cam, planes);
|
||||
// get the camera desired and make into lcamera
|
||||
if (m_cameraID)
|
||||
{
|
||||
Object *pObj = ObjectDB::get_instance(m_cameraID);
|
||||
|
||||
Camera * pCamera = Object::cast_to<Camera>(pObj);
|
||||
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 = pCamera->get_frustum();
|
||||
}
|
||||
}
|
||||
|
||||
pRoom->DetermineVisibility_Recursive(0, cam, planes, m_BF_visible_rooms);
|
||||
|
||||
|
||||
// finally hide all the rooms that are currently visible but not in the visible bitfield as having been hit
|
||||
// NOTE this could be more efficient
|
||||
for (int n=0; n<m_room_IDs.size(); n++)
|
||||
{
|
||||
Object *pObj = ObjectDB::get_instance(m_room_IDs[n]);
|
||||
|
||||
LRoom * pRoom = Object::cast_to<LRoom>(pObj);
|
||||
if (pRoom)
|
||||
{
|
||||
if (!m_BF_visible_rooms.GetBit(n))
|
||||
{
|
||||
pRoom->hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// only do once for now
|
||||
m_room_curr = 0;
|
||||
// m_room_curr = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -219,6 +283,8 @@ void LRoomManager::_notification(int p_what) {
|
||||
// SetProcessing();
|
||||
if (!Engine::get_singleton()->is_editor_hint())
|
||||
set_process_internal(true);
|
||||
else
|
||||
set_process_internal(false);
|
||||
|
||||
// // we can't translate string name of Target to a node until we are in the tree
|
||||
// ResolveTargetPath();
|
||||
@ -245,5 +311,6 @@ void LRoomManager::_notification(int p_what) {
|
||||
void LRoomManager::_bind_methods()
|
||||
{
|
||||
ClassDB::bind_method(D_METHOD("convert"), &LRoomManager::convert);
|
||||
ClassDB::bind_method(D_METHOD("set_camera"), &LRoomManager::set_camera);
|
||||
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
*/
|
||||
|
||||
#include "scene/3d/spatial.h"
|
||||
#include "CoBitField_Dynamic.h"
|
||||
|
||||
class LRoomManager : public Spatial {
|
||||
GDCLASS(LRoomManager, Spatial);
|
||||
@ -35,12 +36,19 @@ class LRoomManager : public Spatial {
|
||||
Vector<ObjectID> m_room_IDs;
|
||||
|
||||
ObjectID m_room_curr;
|
||||
ObjectID m_cameraID;
|
||||
|
||||
// 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;
|
||||
// Vector<int> m_VisibleRoomList[2];
|
||||
// int m_CurrentVisibleRoomList;
|
||||
|
||||
public:
|
||||
LRoomManager();
|
||||
|
||||
// convert empties and meshes to rooms and portals
|
||||
void convert();
|
||||
void set_camera(Node * pCam);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
Loading…
Reference in New Issue
Block a user