Import working, basic vis function

This commit is contained in:
lawnjelly 2019-09-12 11:07:43 +01:00 committed by GitHub
parent a58c29fafc
commit 829dcb8e13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 344 additions and 283 deletions

View File

@ -23,10 +23,6 @@
#include "lroom.h"
//#define SMOOTHCLASS Smooth
//#define SMOOTHNODE Spatial
//#include "smooth_body.inl"
bool LPortal::NameStartsWith(Node * pNode, String szSearch)
{
int sl = szSearch.length();
@ -37,7 +33,9 @@ bool LPortal::NameStartsWith(Node * pNode, String szSearch)
if (l < sl)
return false;
String szStart = name.substr(sl);
String szStart = name.substr(0, sl);
//print_line("\t\tNameStartsWith szStart is " + szStart);
if (szStart == szSearch)
return true;
@ -46,11 +44,13 @@ bool LPortal::NameStartsWith(Node * pNode, String szSearch)
}
String LPortal::FindNameAfter(Node * pNode, int CharsToMiss)
String LPortal::FindNameAfter(Node * pNode, String szStart)
{
String szRes;
String name = pNode->get_name();
szRes = name.substr(CharsToMiss);
szRes = name.substr(szStart.length());
print_line("\t\tNameAfter is " + szRes);
return szRes;
}
@ -85,13 +85,15 @@ LPortal::eClipResult LPortal::ClipWithPlane(const Plane &p) const
void LPortal::Link(LRoom * pParentRoom)
{
// should start with 'portal_'
if (!NameStartsWith(this, "portal_"))
if (!NameStartsWith(this, "lportal_"))
{
WARN_PRINT("Portal name should begin with lportal_");
return;
}
String szRoom = FindNameAfter(this, 8);
String szRoom = FindNameAfter(this, "lportal_");
print_line("LPortal::Link to room " + szRoom);
// find the room group
Spatial * pGroup = Object::cast_to<Spatial>(pParentRoom->get_parent());
@ -134,27 +136,163 @@ void LPortal::CreateGeometry(PoolVector<Vector3> p_vertices)
int nPoints = p_vertices.size();
ERR_FAIL_COND(nPoints < 3);
m_ptsLocal.resize(nPoints);
m_ptsWorld.resize(nPoints);
print_line("\tLPortal::CreateGeometry nPoints : " + itos(nPoints));
for (int n=0; n<nPoints; n++)
{
m_ptsWorld.set(n, p_vertices[n]);
m_ptsLocal.set(n, p_vertices[n]);
Variant pt = p_vertices[n];
print_line("\t\t" + itos(n) + "\t: " + pt);
}
SortVertsClockwise();
CalculateWorldPoints();
PlaneFromPoints();
}
// assume first 3 determine the desired normal
void LPortal::SortVertsClockwise()
{
Vector<Vector3> &verts = m_ptsLocal;
// find normal
Plane plane = Plane(verts[0], verts[1], verts[2]);
Vector3 ptNormal = plane.normal;
// find centroid
int nPoints = verts.size();
Vector3 ptCentre = Vector3(0, 0, 0);
for (int n=0; n<nPoints; n++)
{
ptCentre += verts[n];
}
ptCentre /= nPoints;
// now algorithm
for (int n=0; n<nPoints-2; n++)
{
Vector3 a = verts[n] - ptCentre;
a.normalize();
Plane p = Plane(verts[n], ptCentre, ptCentre + ptNormal);
double SmallestAngle = -1;
int Smallest = -1;
for (unsigned int m=n+1; m<nPoints; m++)
{
if (p.distance_to(verts[m]) > 0.0f)
// if (p.WhichSideNDLCompatible(m_Verts[m], 0.0f) != CoPlane::NEGATIVE_SIDE)
{
Vector3 b = m_ptsLocal[m] - ptCentre;
b.normalize();
double Angle = a.dot(b);
if (Angle > SmallestAngle)
{
SmallestAngle = Angle;
Smallest = m;
}
} // which side
} // for m
// swap smallest and n+1 vert
if (Smallest != -1)
{
Vector3 temp = verts[Smallest];
verts.set(Smallest, verts[n+1]);
verts.set(n+1, temp);
}
} // for n
// the vertices are now sorted, but may be in the opposite order to that wanted.
// we detect this by calculating the normal of the poly, then flipping the order if the normal is pointing
// the wrong way.
plane = Plane(verts[0], verts[1], verts[2]);
if (ptNormal.dot(plane.normal) < 0.0f)
{
// reverse order of verts
ReverseWindingOrder();
}
}
void LPortal::ReverseWindingOrder()
{
Vector<Vector3> &verts = m_ptsLocal;
Vector<Vector3> copy = verts;
for (int n=0; n<verts.size(); n++)
{
verts.set(n, copy[verts.size() - n - 1]);
}
}
// local from world and local transform
void LPortal::CalculateLocalPoints()
{
int nPoints = m_ptsLocal.size();
ERR_FAIL_COND(m_ptsLocal.size() != m_ptsWorld.size());
Transform tr = get_transform();
print_line("\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);
}
}
// world from local and transform
void LPortal::CalculateWorldPoints()
{
int nPoints = m_ptsLocal.size();
ERR_FAIL_COND(m_ptsLocal.size() != m_ptsWorld.size());
Transform tr = get_global_transform();
print_line("\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);
}
}
void LPortal::CopyReversedGeometry(const LPortal &source)
{
print_line("CopyReversedGeometry");
// points are the same but reverse winding order
int nPoints = source.m_ptsWorld.size();
m_ptsLocal.resize(nPoints);
m_ptsWorld.resize(nPoints);
for (int n=0; n<nPoints; n++)
{
m_ptsWorld.set(n, source.m_ptsWorld[nPoints - n - 1]);
Variant pt = m_ptsWorld[n];
print_line("\t\t" + itos(n) + "\t: " + pt);
}
CalculateLocalPoints();
PlaneFromPoints();
}
@ -167,11 +305,18 @@ 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);
// Plane opp = Plane(m_ptsWorld[2], m_ptsWorld[1], m_ptsWorld[0]);
// print_line("Plane opposite : " + opp);
}
bool LPortal::AddRoom(NodePath path)
{
print_line("LPortal::AddRoom path is " + path);
if (has_node(path))
{
LRoom * pNode = Object::cast_to<LRoom>(get_node(path));
@ -202,6 +347,10 @@ bool LPortal::AddRoom(NodePath path)
return false;
}
}
else
{
WARN_PRINTS("portal link room not found : " + path);
}
return false;
}
@ -211,97 +360,26 @@ LPortal::LPortal() {
m_room_ID = 0;
}
LRoom * LPortal::GetLinkedRoom() const
{
Object *pObj = ObjectDB::get_instance(m_room_ID);
if (!pObj)
return 0;
LRoom * pRoom = Object::cast_to<LRoom>(pObj);
if (!pRoom)
{
WARN_PRINT_ONCE("LRoomManager::FrameUpdate : curr room is not an LRoom");
}
return pRoom;
}
void LPortal::_bind_methods() {
// BIND_ENUM_CONSTANT(MODE_LOCAL);
// BIND_ENUM_CONSTANT(MODE_GLOBAL);
// ClassDB::bind_method(D_METHOD("teleport"), &SMOOTHCLASS::teleport);
// ClassDB::bind_method(D_METHOD("set_enabled"), &SMOOTHCLASS::set_enabled);
// ClassDB::bind_method(D_METHOD("is_enabled"), &SMOOTHCLASS::is_enabled);
// ClassDB::bind_method(D_METHOD("set_smooth_translate"), &SMOOTHCLASS::set_interpolate_translation);
// ClassDB::bind_method(D_METHOD("get_smooth_translate"), &SMOOTHCLASS::get_interpolate_translation);
// ClassDB::bind_method(D_METHOD("set_smooth_rotate"), &SMOOTHCLASS::set_interpolate_rotation);
// ClassDB::bind_method(D_METHOD("get_smooth_rotate"), &SMOOTHCLASS::get_interpolate_rotation);
// ClassDB::bind_method(D_METHOD("set_smooth_scale"), &SMOOTHCLASS::set_interpolate_scale);
// ClassDB::bind_method(D_METHOD("get_smooth_scale"), &SMOOTHCLASS::get_interpolate_scale);
// ClassDB::bind_method(D_METHOD("set_input_mode", "mode"), &SMOOTHCLASS::set_input_mode);
// ClassDB::bind_method(D_METHOD("get_input_mode"), &SMOOTHCLASS::get_input_mode);
// ClassDB::bind_method(D_METHOD("set_output_mode", "mode"), &SMOOTHCLASS::set_output_mode);
// ClassDB::bind_method(D_METHOD("get_output_mode"), &SMOOTHCLASS::get_output_mode);
// ClassDB::bind_method(D_METHOD("set_target", "target"), &SMOOTHCLASS::set_target);
// ClassDB::bind_method(D_METHOD("set_target_path", "path"), &SMOOTHCLASS::set_target_path);
// ClassDB::bind_method(D_METHOD("get_target_path"), &SMOOTHCLASS::get_target_path);
// ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
// ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target"), "set_target_path", "get_target_path");
// ADD_GROUP("Components", "");
// ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_translate"), "set_smooth_translate", "get_smooth_translate");
// ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_rotate"), "set_smooth_rotate", "get_smooth_rotate");
// ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_scale"), "set_smooth_scale", "get_smooth_scale");
// ADD_GROUP("Coords", "");
// ADD_PROPERTY(PropertyInfo(Variant::INT, "input", PROPERTY_HINT_ENUM, "Local,Global"), "set_input_mode", "get_input_mode");
// ADD_PROPERTY(PropertyInfo(Variant::INT, "output", PROPERTY_HINT_ENUM, "Local,Global"), "set_output_mode", "get_output_mode");
// ADD_PROPERTY(PropertyInfo(Variant::BOOL, "lerp"), "set_lerp", "get_lerp");
// finish the bind with custom stuff
//BIND_ENUM_CONSTANT(METHOD_SLERP);
//BIND_ENUM_CONSTANT(METHOD_LERP);
//ClassDB::bind_method(D_METHOD("set_method", "method"), &Room::set_method);
//ClassDB::bind_method(D_METHOD("get_method"), &Room::get_method);
//ADD_GROUP("Misc", "");
//ADD_PROPERTY(PropertyInfo(Variant::INT, "method", PROPERTY_HINT_ENUM, "Slerp,Lerp"), "set_method", "get_method");
}
//void Smooth::set_method(eMethod p_method)
//{
//ChangeFlags(SF_LERP, p_method == METHOD_LERP);
//}
//Smooth::eMethod Smooth::get_method() const
//{
//if (TestFlags(SF_LERP))
//return METHOD_LERP;
//return METHOD_SLERP;
//}
//bool Smooth::FindVisibility() const
//{
// const Spatial *s = this;
// int count = 0;
// while (s) {
// if (!s->data.visible)
// {
// print_line(itos(count++) + " hidden");
// return false;
// }
// else
// {
// print_line(itos(count++) + " visible");
// }
// s = s->data.parent;
// }
// return true;
//}

View File

@ -66,20 +66,15 @@ protected:
public:
// normal determined by winding order
Vector<Vector3> m_ptsWorld;
Vector<Vector3> m_ptsLocal;
Plane m_Plane;
//enum eMethod
//{
//METHOD_SLERP,
//METHOD_LERP,
//};
ObjectID GetLinkedRoomID() const {return m_room_ID;}
LRoom * GetLinkedRoom() const;
LPortal();
// void set_method(eMethod p_method);
// eMethod get_method() const;
private:
// use the name of the portal to find a room to link to
void Link(LRoom * pParentRoom);
@ -88,16 +83,17 @@ private:
void CreateGeometry(PoolVector<Vector3> p_vertices);
void PlaneFromPoints();
void CalculateWorldPoints();
void CalculateLocalPoints();
void SortVertsClockwise();
void ReverseWindingOrder();
// useful funcs
public:
static bool NameStartsWith(Node * pNode, String szSearch);
static String FindNameAfter(Node * pNode, int CharsToMiss);
static String FindNameAfter(Node * pNode, String szStart);
};
//VARIANT_ENUM_CAST(Smooth::eMode);
//VARIANT_ENUM_CAST(Smooth::eMethod);
#endif

169
lroom.cpp
View File

@ -24,18 +24,20 @@
#include "lportal.h"
//#define SMOOTHCLASS Smooth
//#define SMOOTHNODE Spatial
//#include "smooth_body.inl"
LRoom::LRoom() {
// m_Flags = 0;
// SetFlags(SF_ENABLED | SF_TRANSLATE | SF_ROTATE);
}
void LRoom::DetermineVisibility_Recursive(LCamera &cam, const Vector<Plane> &planes, ObjectID portalID_from)
void LRoom::DetermineVisibility_Recursive(int depth, const LCamera &cam, const Vector<Plane> &planes, ObjectID portalID_from)
{
// prevent too much depth
if (depth >= 8)
{
print_line("\t\t\tDEPTH LIMIT REACHED");
return;
}
print_line("DetermineVisibility_Recursive from " + get_name());
// clip all objects in this room to the clipping planes
// NYI
@ -65,11 +67,16 @@ void LRoom::DetermineVisibility_Recursive(LCamera &cam, const Vector<Plane> &pla
}
const Vector3 &portal_normal = pPortal->m_Plane.normal;
print_line("\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));
continue;
}
// is it culled by the planes?
LPortal::eClipResult overall_res = LPortal::eClipResult::CLIP_INSIDE;
@ -94,7 +101,10 @@ void LRoom::DetermineVisibility_Recursive(LCamera &cam, const Vector<Plane> &pla
// this portal is culled
if (overall_res == LPortal::eClipResult::CLIP_OUTSIDE)
{
print_line("\t\tportal culled (outside planes)");
continue;
}
// else recurse into that portal
Vector<Plane> new_planes = planes;
@ -102,7 +112,10 @@ void LRoom::DetermineVisibility_Recursive(LCamera &cam, const Vector<Plane> &pla
// add the planes for the portal
// NYI
DetermineVisibility_Recursive(cam, new_planes, id);
// get the room pointed to by the portal
LRoom * pLinkedRoom = pPortal->GetLinkedRoom();
if (pLinkedRoom)
pLinkedRoom->DetermineVisibility_Recursive(depth + 1, cam, new_planes, id);
}
}
@ -112,6 +125,8 @@ void LRoom::DetermineVisibility_Recursive(LCamera &cam, const Vector<Plane> &pla
// which will be auto converted to LPortals with this method
void LRoom::DetectPortalMeshes()
{
print_line("DetectPortalMeshes");
bool bFoundOne = true;
while (bFoundOne)
@ -128,7 +143,7 @@ void LRoom::DetectPortalMeshes()
// name must start with portal_
if (LPortal::NameStartsWith(pMesh, "portal_"))
{
String szLinkRoom = LPortal::FindNameAfter(pMesh, 8);
String szLinkRoom = LPortal::FindNameAfter(pMesh, "portal_");
DetectedPortalMesh(pMesh, szLinkRoom);
bFoundOne = true;
}
@ -143,17 +158,21 @@ void LRoom::DetectPortalMeshes()
void LRoom::DetectedPortalMesh(MeshInstance * pMeshInstance, String szLinkRoom)
{
print_line("\tDetected PortalMesh");
Ref<Mesh> rmesh = pMeshInstance->get_mesh();
Array arrays = rmesh->surface_get_arrays(0);
PoolVector<Vector3> p_vertices = arrays[VS::ARRAY_VERTEX];
LPortal * pNew = memnew(LPortal);
pNew->set_name("lportal");
pNew->set_name("lportal_");
add_child(pNew);
pNew->set_transform(pMeshInstance->get_transform());
NodePath temppath = "../../" + szLinkRoom;
pNew->AddRoom(szLinkRoom);
pNew->AddRoom(temppath);
// create the portal geometry
pNew->CreateGeometry(p_vertices);
@ -231,132 +250,6 @@ void LRoom::MakeOppositePortal(LPortal * pPortalFrom, LRoom * pRoomTo)
void LRoom::_bind_methods() {
// BIND_ENUM_CONSTANT(MODE_LOCAL);
// BIND_ENUM_CONSTANT(MODE_GLOBAL);
// ClassDB::bind_method(D_METHOD("teleport"), &SMOOTHCLASS::teleport);
// ClassDB::bind_method(D_METHOD("set_enabled"), &SMOOTHCLASS::set_enabled);
// ClassDB::bind_method(D_METHOD("is_enabled"), &SMOOTHCLASS::is_enabled);
// ClassDB::bind_method(D_METHOD("set_smooth_translate"), &SMOOTHCLASS::set_interpolate_translation);
// ClassDB::bind_method(D_METHOD("get_smooth_translate"), &SMOOTHCLASS::get_interpolate_translation);
// ClassDB::bind_method(D_METHOD("set_smooth_rotate"), &SMOOTHCLASS::set_interpolate_rotation);
// ClassDB::bind_method(D_METHOD("get_smooth_rotate"), &SMOOTHCLASS::get_interpolate_rotation);
// ClassDB::bind_method(D_METHOD("set_smooth_scale"), &SMOOTHCLASS::set_interpolate_scale);
// ClassDB::bind_method(D_METHOD("get_smooth_scale"), &SMOOTHCLASS::get_interpolate_scale);
// ClassDB::bind_method(D_METHOD("set_input_mode", "mode"), &SMOOTHCLASS::set_input_mode);
// ClassDB::bind_method(D_METHOD("get_input_mode"), &SMOOTHCLASS::get_input_mode);
// ClassDB::bind_method(D_METHOD("set_output_mode", "mode"), &SMOOTHCLASS::set_output_mode);
// ClassDB::bind_method(D_METHOD("get_output_mode"), &SMOOTHCLASS::get_output_mode);
// ClassDB::bind_method(D_METHOD("set_target", "target"), &SMOOTHCLASS::set_target);
// ClassDB::bind_method(D_METHOD("set_target_path", "path"), &SMOOTHCLASS::set_target_path);
// ClassDB::bind_method(D_METHOD("get_target_path"), &SMOOTHCLASS::get_target_path);
// ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
// ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target"), "set_target_path", "get_target_path");
// ADD_GROUP("Components", "");
// ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_translate"), "set_smooth_translate", "get_smooth_translate");
// ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_rotate"), "set_smooth_rotate", "get_smooth_rotate");
// ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_scale"), "set_smooth_scale", "get_smooth_scale");
// ADD_GROUP("Coords", "");
// ADD_PROPERTY(PropertyInfo(Variant::INT, "input", PROPERTY_HINT_ENUM, "Local,Global"), "set_input_mode", "get_input_mode");
// ADD_PROPERTY(PropertyInfo(Variant::INT, "output", PROPERTY_HINT_ENUM, "Local,Global"), "set_output_mode", "get_output_mode");
// ADD_PROPERTY(PropertyInfo(Variant::BOOL, "lerp"), "set_lerp", "get_lerp");
// finish the bind with custom stuff
//BIND_ENUM_CONSTANT(METHOD_SLERP);
//BIND_ENUM_CONSTANT(METHOD_LERP);
//ClassDB::bind_method(D_METHOD("set_method", "method"), &LRoom::set_method);
//ClassDB::bind_method(D_METHOD("get_method"), &LRoom::get_method);
//ADD_GROUP("Misc", "");
//ADD_PROPERTY(PropertyInfo(Variant::INT, "method", PROPERTY_HINT_ENUM, "Slerp,Lerp"), "set_method", "get_method");
}
//void LRoom::SetupPortal(LPortal * pPortal)
//{
// ObjectID id = pPortal->get_instance_id();
// m_portal_IDs.push_back(id);
//}
//void LRoom::AddPortal(ObjectID id)
//{
//}
//bool LRoom::AddPortal(LPortal * pNode)
//{
// if (has_node(path))
// {
// LPortal * pNode = Object::cast_to<LPortal>(get_node(path));
// if (pNode)
// {
// ObjectID id = pNode->get_instance_id();
// m_portal_paths.push_back(path);
// m_portal_IDs.push_back(id);
// // add the room to the portal automatically
// NodePath self_path = get_path_to(this);
// pNode->AddRoom(self_path);
// return true;
// }
// else
// {
// WARN_PRINT("not a portal");
// return false;
// }
// }
// return false;
//}
//void Smooth::set_method(eMethod p_method)
//{
//ChangeFlags(SF_LERP, p_method == METHOD_LERP);
//}
//Smooth::eMethod Smooth::get_method() const
//{
//if (TestFlags(SF_LERP))
//return METHOD_LERP;
//return METHOD_SLERP;
//}
//bool Smooth::FindVisibility() const
//{
// const Spatial *s = this;
// int count = 0;
// while (s) {
// if (!s->data.visible)
// {
// print_line(itos(count++) + " hidden");
// return false;
// }
// else
// {
// print_line(itos(count++) + " visible");
// }
// s = s->data.parent;
// }
// return true;
//}

28
lroom.h
View File

@ -55,20 +55,7 @@ class LRoom : public Spatial {
GDCLASS(LRoom, Spatial);
friend class LPortal;
public:
// custom
private:
//class STransform
//{
//public:
//Transform m_Transform;
//Quat m_qtRotate;
//Vector3 m_ptScale;
//};
//Vector3 m_ptTranslateDiff;
// a quick list of object IDs of child portals of this room
Vector<ObjectID> m_portal_IDs;
@ -76,13 +63,6 @@ protected:
static void _bind_methods();
public:
//enum eMethod
//{
//METHOD_SLERP,
//METHOD_LERP,
//};
// bool AddPortal(LPortal * pNode);
// initial setup, allows importing portals as meshes from modelling program,
// which will be auto converted to LPortals with this method
void DetectPortalMeshes();
@ -91,25 +71,19 @@ public:
void MakePortalQuickList();
// main function
void DetermineVisibility_Recursive(LCamera &cam, const Vector<Plane> &planes, ObjectID portalID_from = 0);
void DetermineVisibility_Recursive(int depth, const LCamera &cam, const Vector<Plane> &planes, ObjectID portalID_from = 0);
// specific
public:
LRoom();
// void set_method(eMethod p_method);
// eMethod get_method() const;
private:
// void SetupPortal(LPortal * pPortal);
void MakeOppositePortal(LPortal * pPortalFrom, LRoom * pRoomTo);
void DetectedPortalMesh(MeshInstance * pMeshInstance, String szLinkRoom);
// void AddPortal(ObjectID id);
// void LerpBasis(const Basis &from, const Basis &to, Basis &res, float f) const;
};
//VARIANT_ENUM_CAST(Smooth::eMode);
//VARIANT_ENUM_CAST(Smooth::eMethod);
#endif

View File

@ -21,22 +21,54 @@
#include "lroom_manager.h"
#include "lportal.h"
#include "lroom.h"
#include "core/engine.h"
LRoomManager::LRoomManager()
{
m_room_curr = 0;
}
// convert empties and meshes to rooms and portals
void LRoomManager::Convert()
void LRoomManager::convert()
{
print_line("running convert");
Convert_Rooms();
Convert_Portals();
Find_Rooms();
}
void LRoomManager::Find_Rooms()
{
print_line ("Find_Rooms");
m_room_IDs.clear();
// first find all room empties and convert to LRooms
for (int n=0; n<get_child_count(); n++)
{
Node * pChild = get_child(n);
// don't want to handle already converted rooms
LRoom * pRoom = Object::cast_to<LRoom>(pChild);
if (pRoom)
m_room_IDs.push_back(pRoom->get_instance_id());
}
m_room_curr = 0;
// just set current room to first room
if (m_room_IDs.size())
{
m_room_curr = m_room_IDs[0];
print_line("first room ID is " + itos(m_room_curr));
}
}
void LRoomManager::Convert_Rooms()
{
print_line("Convert_Rooms");
bool bConvertedOne = true;
// instead of recursive routine
@ -54,9 +86,13 @@ void LRoomManager::Convert_Rooms()
if (pRoom)
continue;
if (LPortal::NameStartsWith(pChild, "room_"))
Spatial * pSpatialChild = Object::cast_to<Spatial>(pChild);
if (!pSpatialChild)
continue;
if (LPortal::NameStartsWith(pSpatialChild, "room_"))
{
if (Convert_Room(pChild))
if (Convert_Room(pSpatialChild))
bConvertedOne = true;
}
@ -71,6 +107,8 @@ void LRoomManager::Convert_Portals()
{
for (int pass=0; pass<3; pass++)
{
print_line("Convert_Portals pass " + itos(pass));
// first find all room empties and convert to LRooms
for (int n=0; n<get_child_count(); n++)
{
@ -99,17 +137,22 @@ void LRoomManager::Convert_Portals()
}
bool LRoomManager::Convert_Room(Node * pNode)
bool LRoomManager::Convert_Room(Spatial * pNode)
{
// get the room part of the name
String szFullName = pNode->get_name();
String szRoom = LPortal::FindNameAfter(pNode, 6);
String szRoom = LPortal::FindNameAfter(pNode, "room_");
print_line("Convert_Room : " + szFullName);
// create a new LRoom to exchange the children over to, and delete the original empty
LRoom * pNew = memnew(LRoom);
pNew->set_name(szRoom);
add_child(pNew);
// make the transform of the L room match the original spatial
pNew->set_transform(pNode->get_transform());
int nChildren = pNode->get_child_count();
for (int n=0; n<nChildren; n++)
@ -131,8 +174,76 @@ bool LRoomManager::Convert_Room(Node * pNode)
return true;
}
void LRoomManager::FrameUpdate()
{
// if not started
if (!m_room_curr)
return;
// determine visibility
Object *pObj = ObjectDB::get_instance(m_room_curr);
if (!pObj)
return;
LRoom * pRoom = Object::cast_to<LRoom>(pObj);
if (!pRoom)
{
WARN_PRINT_ONCE("LRoomManager::FrameUpdate : curr room is not an LRoom");
print_line("curr room is not an LRoom");
m_room_curr = 0;
return;
}
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);
// only do once for now
m_room_curr = 0;
}
void LRoomManager::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
// bool bVisible = is_visible_in_tree();
// ChangeFlags(SF_INVISIBLE, bVisible == false);
// SetProcessing();
if (!Engine::get_singleton()->is_editor_hint())
set_process_internal(true);
// // we can't translate string name of Target to a node until we are in the tree
// ResolveTargetPath();
} break;
// case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
// FixedUpdate();
// } break;
case NOTIFICATION_INTERNAL_PROCESS: {
FrameUpdate();
} break;
// case NOTIFICATION_VISIBILITY_CHANGED: {
// bool bVisible = is_visible_in_tree();
// ChangeFlags(SF_INVISIBLE, bVisible == false);
// SetProcessing();
//// if (bVisible)
//// print_line("now visible");
//// else
//// print_line("now hidden");
// } break;
}
}
void LRoomManager::_bind_methods()
{
ClassDB::bind_method(D_METHOD("convert"), &LRoomManager::convert);
}

View File

@ -31,19 +31,28 @@
class LRoomManager : public Spatial {
GDCLASS(LRoomManager, Spatial);
// a quick list of object IDs of child rooms
Vector<ObjectID> m_room_IDs;
ObjectID m_room_curr;
public:
LRoomManager();
// convert empties and meshes to rooms and portals
void Convert();
void convert();
protected:
static void _bind_methods();
void _notification(int p_what);
private:
void Convert_Rooms();
bool Convert_Room(Node * pNode);
bool Convert_Room(Spatial * pNode);
void Convert_Portals();
void Find_Rooms();
void FrameUpdate();
};
#endif