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" #include "lroom.h"
//#define SMOOTHCLASS Smooth
//#define SMOOTHNODE Spatial
//#include "smooth_body.inl"
bool LPortal::NameStartsWith(Node * pNode, String szSearch) bool LPortal::NameStartsWith(Node * pNode, String szSearch)
{ {
int sl = szSearch.length(); int sl = szSearch.length();
@ -37,7 +33,9 @@ bool LPortal::NameStartsWith(Node * pNode, String szSearch)
if (l < sl) if (l < sl)
return false; return false;
String szStart = name.substr(sl); String szStart = name.substr(0, sl);
//print_line("\t\tNameStartsWith szStart is " + szStart);
if (szStart == szSearch) if (szStart == szSearch)
return true; 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 szRes;
String name = pNode->get_name(); String name = pNode->get_name();
szRes = name.substr(CharsToMiss); szRes = name.substr(szStart.length());
print_line("\t\tNameAfter is " + szRes);
return szRes; return szRes;
} }
@ -85,13 +85,15 @@ LPortal::eClipResult LPortal::ClipWithPlane(const Plane &p) const
void LPortal::Link(LRoom * pParentRoom) void LPortal::Link(LRoom * pParentRoom)
{ {
// should start with 'portal_' // should start with 'portal_'
if (!NameStartsWith(this, "portal_")) if (!NameStartsWith(this, "lportal_"))
{ {
WARN_PRINT("Portal name should begin with lportal_"); WARN_PRINT("Portal name should begin with lportal_");
return; return;
} }
String szRoom = FindNameAfter(this, 8); String szRoom = FindNameAfter(this, "lportal_");
print_line("LPortal::Link to room " + szRoom);
// find the room group // find the room group
Spatial * pGroup = Object::cast_to<Spatial>(pParentRoom->get_parent()); 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(); int nPoints = p_vertices.size();
ERR_FAIL_COND(nPoints < 3); ERR_FAIL_COND(nPoints < 3);
m_ptsLocal.resize(nPoints);
m_ptsWorld.resize(nPoints); m_ptsWorld.resize(nPoints);
print_line("\tLPortal::CreateGeometry nPoints : " + itos(nPoints));
for (int n=0; n<nPoints; n++) 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(); 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) void LPortal::CopyReversedGeometry(const LPortal &source)
{ {
print_line("CopyReversedGeometry");
// points are the same but reverse winding order // points are the same but reverse winding order
int nPoints = source.m_ptsWorld.size(); int nPoints = source.m_ptsWorld.size();
m_ptsLocal.resize(nPoints);
m_ptsWorld.resize(nPoints); m_ptsWorld.resize(nPoints);
for (int n=0; n<nPoints; n++) for (int n=0; n<nPoints; n++)
{ {
m_ptsWorld.set(n, source.m_ptsWorld[nPoints - n - 1]); 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(); PlaneFromPoints();
} }
@ -167,11 +305,18 @@ void LPortal::PlaneFromPoints()
} }
// create plane from points // create plane from points
m_Plane = Plane(m_ptsWorld[0], m_ptsWorld[1], m_ptsWorld[2]); 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) bool LPortal::AddRoom(NodePath path)
{ {
print_line("LPortal::AddRoom path is " + path);
if (has_node(path)) if (has_node(path))
{ {
LRoom * pNode = Object::cast_to<LRoom>(get_node(path)); LRoom * pNode = Object::cast_to<LRoom>(get_node(path));
@ -202,6 +347,10 @@ bool LPortal::AddRoom(NodePath path)
return false; return false;
} }
} }
else
{
WARN_PRINTS("portal link room not found : " + path);
}
return false; return false;
} }
@ -211,97 +360,26 @@ LPortal::LPortal() {
m_room_ID = 0; 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() { 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: public:
// normal determined by winding order // normal determined by winding order
Vector<Vector3> m_ptsWorld; Vector<Vector3> m_ptsWorld;
Vector<Vector3> m_ptsLocal;
Plane m_Plane; Plane m_Plane;
//enum eMethod
//{
//METHOD_SLERP,
//METHOD_LERP,
//};
ObjectID GetLinkedRoomID() const {return m_room_ID;} ObjectID GetLinkedRoomID() const {return m_room_ID;}
LRoom * GetLinkedRoom() const;
LPortal(); LPortal();
// void set_method(eMethod p_method);
// eMethod get_method() const;
private: private:
// use the name of the portal to find a room to link to // use the name of the portal to find a room to link to
void Link(LRoom * pParentRoom); void Link(LRoom * pParentRoom);
@ -88,16 +83,17 @@ private:
void CreateGeometry(PoolVector<Vector3> p_vertices); void CreateGeometry(PoolVector<Vector3> p_vertices);
void PlaneFromPoints(); void PlaneFromPoints();
void CalculateWorldPoints();
void CalculateLocalPoints();
void SortVertsClockwise();
void ReverseWindingOrder();
// useful funcs // useful funcs
public: public:
static bool NameStartsWith(Node * pNode, String szSearch); 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 #endif

169
lroom.cpp
View File

@ -24,18 +24,20 @@
#include "lportal.h" #include "lportal.h"
//#define SMOOTHCLASS Smooth
//#define SMOOTHNODE Spatial
//#include "smooth_body.inl"
LRoom::LRoom() { 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 // clip all objects in this room to the clipping planes
// NYI // NYI
@ -65,11 +67,16 @@ void LRoom::DetermineVisibility_Recursive(LCamera &cam, const Vector<Plane> &pla
} }
const Vector3 &portal_normal = pPortal->m_Plane.normal; 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) // 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)
{
Variant vd = dot;
print_line("\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;
@ -94,7 +101,10 @@ void LRoom::DetermineVisibility_Recursive(LCamera &cam, const Vector<Plane> &pla
// this portal is culled // this portal is culled
if (overall_res == LPortal::eClipResult::CLIP_OUTSIDE) if (overall_res == LPortal::eClipResult::CLIP_OUTSIDE)
{
print_line("\t\tportal culled (outside planes)");
continue; continue;
}
// else recurse into that portal // else recurse into that portal
Vector<Plane> new_planes = planes; 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 // add the planes for the portal
// NYI // 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 // which will be auto converted to LPortals with this method
void LRoom::DetectPortalMeshes() void LRoom::DetectPortalMeshes()
{ {
print_line("DetectPortalMeshes");
bool bFoundOne = true; bool bFoundOne = true;
while (bFoundOne) while (bFoundOne)
@ -128,7 +143,7 @@ void LRoom::DetectPortalMeshes()
// name must start with portal_ // name must start with portal_
if (LPortal::NameStartsWith(pMesh, "portal_")) if (LPortal::NameStartsWith(pMesh, "portal_"))
{ {
String szLinkRoom = LPortal::FindNameAfter(pMesh, 8); String szLinkRoom = LPortal::FindNameAfter(pMesh, "portal_");
DetectedPortalMesh(pMesh, szLinkRoom); DetectedPortalMesh(pMesh, szLinkRoom);
bFoundOne = true; bFoundOne = true;
} }
@ -143,17 +158,21 @@ void LRoom::DetectPortalMeshes()
void LRoom::DetectedPortalMesh(MeshInstance * pMeshInstance, String szLinkRoom) void LRoom::DetectedPortalMesh(MeshInstance * pMeshInstance, String szLinkRoom)
{ {
print_line("\tDetected PortalMesh");
Ref<Mesh> rmesh = pMeshInstance->get_mesh(); Ref<Mesh> rmesh = pMeshInstance->get_mesh();
Array arrays = rmesh->surface_get_arrays(0); Array arrays = rmesh->surface_get_arrays(0);
PoolVector<Vector3> p_vertices = arrays[VS::ARRAY_VERTEX]; PoolVector<Vector3> p_vertices = arrays[VS::ARRAY_VERTEX];
LPortal * pNew = memnew(LPortal); LPortal * pNew = memnew(LPortal);
pNew->set_name("lportal"); pNew->set_name("lportal_");
add_child(pNew); add_child(pNew);
pNew->set_transform(pMeshInstance->get_transform());
NodePath temppath = "../../" + szLinkRoom; NodePath temppath = "../../" + szLinkRoom;
pNew->AddRoom(szLinkRoom); pNew->AddRoom(temppath);
// create the portal geometry // create the portal geometry
pNew->CreateGeometry(p_vertices); pNew->CreateGeometry(p_vertices);
@ -231,132 +250,6 @@ void LRoom::MakeOppositePortal(LPortal * pPortalFrom, LRoom * pRoomTo)
void LRoom::_bind_methods() { 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); GDCLASS(LRoom, Spatial);
friend class LPortal; friend class LPortal;
public:
// custom
private: 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 // a quick list of object IDs of child portals of this room
Vector<ObjectID> m_portal_IDs; Vector<ObjectID> m_portal_IDs;
@ -76,13 +63,6 @@ protected:
static void _bind_methods(); static void _bind_methods();
public: public:
//enum eMethod
//{
//METHOD_SLERP,
//METHOD_LERP,
//};
// bool AddPortal(LPortal * pNode);
// 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();
@ -91,25 +71,19 @@ public:
void MakePortalQuickList(); void MakePortalQuickList();
// main function // 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 // specific
public: public:
LRoom(); LRoom();
// void set_method(eMethod p_method);
// eMethod get_method() const;
private: private:
// void SetupPortal(LPortal * pPortal); // void SetupPortal(LPortal * pPortal);
void MakeOppositePortal(LPortal * pPortalFrom, LRoom * pRoomTo); void MakeOppositePortal(LPortal * pPortalFrom, LRoom * pRoomTo);
void DetectedPortalMesh(MeshInstance * pMeshInstance, String szLinkRoom); 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 #endif

View File

@ -21,22 +21,54 @@
#include "lroom_manager.h" #include "lroom_manager.h"
#include "lportal.h" #include "lportal.h"
#include "lroom.h" #include "lroom.h"
#include "core/engine.h"
LRoomManager::LRoomManager() LRoomManager::LRoomManager()
{ {
m_room_curr = 0;
} }
// convert empties and meshes to rooms and portals // convert empties and meshes to rooms and portals
void LRoomManager::Convert() void LRoomManager::convert()
{ {
print_line("running convert");
Convert_Rooms(); Convert_Rooms();
Convert_Portals(); 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() void LRoomManager::Convert_Rooms()
{ {
print_line("Convert_Rooms");
bool bConvertedOne = true; bool bConvertedOne = true;
// instead of recursive routine // instead of recursive routine
@ -54,9 +86,13 @@ void LRoomManager::Convert_Rooms()
if (pRoom) if (pRoom)
continue; 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; bConvertedOne = true;
} }
@ -71,6 +107,8 @@ void LRoomManager::Convert_Portals()
{ {
for (int pass=0; pass<3; pass++) for (int pass=0; pass<3; pass++)
{ {
print_line("Convert_Portals pass " + itos(pass));
// first find all room empties and convert to LRooms // first find all room empties and convert to LRooms
for (int n=0; n<get_child_count(); n++) 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 // get the room part of the name
String szFullName = pNode->get_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 // create a new LRoom to exchange the children over to, and delete the original empty
LRoom * pNew = memnew(LRoom); LRoom * pNew = memnew(LRoom);
pNew->set_name(szRoom); pNew->set_name(szRoom);
add_child(pNew); 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(); int nChildren = pNode->get_child_count();
for (int n=0; n<nChildren; n++) for (int n=0; n<nChildren; n++)
@ -131,8 +174,76 @@ bool LRoomManager::Convert_Room(Node * pNode)
return true; 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() void LRoomManager::_bind_methods()
{ {
ClassDB::bind_method(D_METHOD("convert"), &LRoomManager::convert);
} }

View File

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