From 487363a020f3dc941ed6338a6fcbf77f11e59d6d Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Wed, 18 Sep 2019 11:04:02 +0100 Subject: [PATCH] More debugging support Can activate and deactive lportal now. Debugging visibility for a frame can be requested. Level of logging can be selected. --- lbound.cpp | 24 +++++ lbound.h | 24 +++++ ldebug.cpp | 18 ++++ ldebug.h | 35 ++++++ ldob.cpp | 24 +++++ ldob.h | 25 +++++ lportal.cpp | 23 +--- lportal.h | 2 - lportal_all.cpp | 1 + lroom.cpp | 95 ++++++++++------- lroom.h | 7 +- lroom_converter.cpp | 50 +++++---- lroom_converter.h | 28 ++++- lroom_manager.cpp | 252 ++++++++++++++++++++++++++++++++++++++++---- lroom_manager.h | 30 ++++++ 15 files changed, 530 insertions(+), 108 deletions(-) create mode 100644 ldebug.cpp create mode 100644 ldebug.h diff --git a/lbound.cpp b/lbound.cpp index c24186b..2cd5061 100644 --- a/lbound.cpp +++ b/lbound.cpp @@ -1,3 +1,27 @@ +// Copyright (c) 2019 Lawnjelly + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +/** + @author lawnjelly +*/ + #include "lbound.h" diff --git a/lbound.h b/lbound.h index 4a1835d..214c6eb 100644 --- a/lbound.h +++ b/lbound.h @@ -1,4 +1,28 @@ #pragma once +// Copyright (c) 2019 Lawnjelly + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +/** + @author lawnjelly +*/ + #include "lvector.h" diff --git a/ldebug.cpp b/ldebug.cpp new file mode 100644 index 0000000..61b9f78 --- /dev/null +++ b/ldebug.cpp @@ -0,0 +1,18 @@ +#include "ldebug.h" + +namespace Lawn +{ + +int LDebug::m_iLoggingLevel = 0; // 2 +int LDebug::m_iWarningLevel = 0; +int LDebug::m_iTabDepth = 0; +bool LDebug::m_bRunning = false; + + +void LDebug::print(String sz) +{ + print_line(sz); +} + + +} // namespace diff --git a/ldebug.h b/ldebug.h new file mode 100644 index 0000000..1e96cdf --- /dev/null +++ b/ldebug.h @@ -0,0 +1,35 @@ +#pragma once + +#define LPRINT_RUN(a, b) {String sz;\ +for (int n=0; n= Lawn::LDebug::m_iLoggingLevel)\ +{\ +Lawn::LDebug::print(b);\ +}\ +} + +#define LWARN(a, b) if (a >= Lawn::LDebug::m_iWarningLevel)\ +{\ +Lawn::LDebug::print(String("\tWARNING : ") + b);\ +} + + +namespace Lawn +{ + +class LDebug +{ +public: + static void print(String sz); + static int m_iLoggingLevel; + static int m_iWarningLevel; + static bool m_bRunning; + + static int m_iTabDepth; +}; + +} // namespace diff --git a/ldob.cpp b/ldob.cpp index 0c9962d..a032375 100644 --- a/ldob.cpp +++ b/ldob.cpp @@ -1,3 +1,27 @@ +// Copyright (c) 2019 Lawnjelly + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +/** + @author lawnjelly +*/ + #include "ldob.h" #include "scene/3d/mesh_instance.h" diff --git a/ldob.h b/ldob.h index af833ba..cfabf2f 100644 --- a/ldob.h +++ b/ldob.h @@ -1,5 +1,30 @@ #pragma once +// Copyright (c) 2019 Lawnjelly + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +/** + @author lawnjelly +*/ + + #include "scene/3d/spatial.h" class VisualInstance; diff --git a/lportal.cpp b/lportal.cpp index a26175d..dfd4672 100644 --- a/lportal.cpp +++ b/lportal.cpp @@ -21,24 +21,7 @@ #include "lportal.h" #include "core/engine.h" #include "lroom.h" - - -//#define LPORTAL_VERBOSE - -bool LPortal::m_bRunning = false; - -void LPortal::print(String sz) -{ -#ifdef LPORTAL_VERBOSE - if (m_bRunning) - { - } - else - { - print_line(sz); - } -#endif -} +#include "ldebug.h" bool LPortal::NameStartsWith(Node * pNode, String szSearch) @@ -132,9 +115,7 @@ LPortal::eClipResult LPortal::ClipWithPlane(const Plane &p) const if (nOutside == nPoints) { -#ifdef LPORTAL_VERBOSE - print("LPortal::ClipWithPlane : Outside plane " + p); -#endif + LPRINT_RUN(2, "\t\tOutside plane " + p); return CLIP_OUTSIDE; } diff --git a/lportal.h b/lportal.h index ec5771e..6d0c256 100644 --- a/lportal.h +++ b/lportal.h @@ -75,8 +75,6 @@ public: // useful funcs static bool NameStartsWith(Node * pNode, String szSearch); static String FindNameAfter(Node * pNode, String szStart); - static void print(String sz); - static bool m_bRunning; }; diff --git a/lportal_all.cpp b/lportal_all.cpp index 1c88758..fe22c7a 100644 --- a/lportal_all.cpp +++ b/lportal_all.cpp @@ -1,5 +1,6 @@ // single compilation unit #include "register_types.cpp" +#include "ldebug.cpp" #include "lroom.cpp" #include "lroom_manager.cpp" #include "lroom_converter.cpp" diff --git a/lroom.cpp b/lroom.cpp index 61e75d4..8d16a5c 100644 --- a/lroom.cpp +++ b/lroom.cpp @@ -24,15 +24,8 @@ #include "lportal.h" #include "lbitfield_dynamic.h" #include "lroom_manager.h" +#include "ldebug.h" -//#define LROOM_VERBOSE - -void LRoom::print(String sz) -{ -#ifdef LROOM_VERBOSE - LPortal::print(sz); -#endif -} LRoom::LRoom() { m_RoomID = -1; @@ -116,9 +109,7 @@ LRoom * LRoom::DOB_Update(LRoomManager &manager, Spatial * pDOB) if (dist > slop) { -#ifdef LROOM_VERBOSE - print("DOB at pos " + pt + " ahead of portal " + port.get_name() + " by " + String(Variant(dist))); -#endif + LPRINT(0, "DOB at pos " + pt + " ahead of portal " + port.get_name() + " by " + String(Variant(dist))); // we want to move into the adjoining room return &manager.Portal_GetLinkedRoom(port); @@ -184,6 +175,29 @@ void LRoom::Hide_All() } } +// show godot room and all linked dobs and all sobs +void LRoom::Show_All() +{ + GetGodotRoom()->show(); + + for (int n=0; nshow(); + } + + for (int n=0; nshow(); + } +} + + void LRoom::FirstTouch(LRoomManager &manager) { // set the frame counter @@ -205,17 +219,17 @@ void LRoom::FirstTouch(LRoomManager &manager) void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, const LCamera &cam, const LVector &planes, int portalID_from) { // prevent too much depth - if (depth >= 8) + if (depth > 8) { -#ifdef LROOM_VERBOSE - print("\t\t\tDEPTH LIMIT REACHED"); -#endif + LPRINT_RUN(2, "\t\t\tDEPTH LIMIT REACHED"); + WARN_PRINT_ONCE("LPortal Depth Limit reached (seeing through > 8 portals)"); return; } -#ifdef LROOM_VERBOSE - print("DetermineVisibility_Recursive from " + get_name()); -#endif + // for debugging + Lawn::LDebug::m_iTabDepth = depth; + LPRINT_RUN(2, ""); + LPRINT_RUN(2, "ROOM '" + get_name() + "' planes " + itos(planes.size()) + " portals " + itos(m_iNumPortals) ); // only handle one touch per frame so far (one portal into room) //assert (manager.m_uiFrameCounter > m_uiFrameTouched); @@ -269,7 +283,7 @@ void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, cons if (bShow) sob.m_bVisible = true; - } + } // for through sobs #else @@ -334,7 +348,6 @@ void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, cons bool bShow = true; const Vector3 &pt = pObj->get_global_transform().origin; - //print_line("\t\t\tculling dob " + pObj->get_name()); float radius = dob.m_fRadius; for (int p=0; pget_name() + " visible"); dob.m_bVisible = true; + } + else + { + LPRINT_RUN(1, "\tDOB " + pObj->get_name() + " culled"); + } } - } + } // for through dobs // look through portals - for (int p=0; pDetermineVisibility_Recursive(manager, depth + 1, cam, new_planes, port_id); + // for debugging need to reset tab depth + Lawn::LDebug::m_iTabDepth = depth; + } // we no longer need these planes manager.m_Pool.Free(uiPoolMem); @@ -464,7 +486,8 @@ void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, cons // slow anyway because of the number of planes to test. WARN_PRINT_ONCE("Planes pool is empty"); } - } + + } // for p through portals } diff --git a/lroom.h b/lroom.h index 463cadc..b41b338 100644 --- a/lroom.h +++ b/lroom.h @@ -93,8 +93,13 @@ protected: void FirstTouch(LRoomManager &manager); // hide godot room and all linked dobs + // USED AT RUNTIME void Hide_All(); + // show godot room and all linked dobs and all sobs + // ONLY USED IN DEBUGGING to turn LPortal on and off + void Show_All(); + // hide all the objects not hit on this frame .. instead of calling godot hide without need // (it might be expensive) void FinalizeVisibility(LRoomManager &manager); @@ -110,8 +115,6 @@ public: LRoom(); Spatial * GetGodotRoom() const; -private: - static void print(String sz); }; diff --git a/lroom_converter.cpp b/lroom_converter.cpp index 691dda8..4e609fa 100644 --- a/lroom_converter.cpp +++ b/lroom_converter.cpp @@ -24,23 +24,19 @@ #include "lportal.h" #include "scene/3d/mesh_instance.h" #include "core/math/quick_hull.h" +#include "ldebug.h" // save typing, I am lazy #define LMAN m_pManager -void LRoomConverter::print(String sz) -{ - // easy to turn on and off debugging - print_line(sz); -} void LRoomConverter::Convert(LRoomManager &manager) { // This just is simply used to set how much debugging output .. more during conversion, less during running // except when requested by explicitly clearing this flag. - LPortal::m_bRunning = false; - print_line("running convert"); + Lawn::LDebug::m_bRunning = false; + LPRINT(5, "running convert"); LMAN = &manager; int count = CountRooms(); @@ -59,16 +55,17 @@ void LRoomConverter::Convert(LRoomManager &manager) Convert_Rooms(); Convert_Portals(); Convert_Bounds(); - LPortal::m_bRunning = true; // temp rooms no longer needed m_TempRooms.clear(true); + + Lawn::LDebug::m_bRunning = true; } void LRoomConverter::Convert_Rooms() { - print_line("Convert_Rooms"); + LPRINT(5,"Convert_Rooms"); // first find all room empties and convert to LRooms int count = 0; @@ -120,7 +117,7 @@ void LRoomConverter::Convert_Room_FindObjects_Recursive(Node * pParent, LRoom &l VisualInstance * pVI = Object::cast_to(pChild); if (pVI) { - print("\t\tFound VI : " + pVI->get_name()); + LPRINT(2, "\t\tFound VI : " + pVI->get_name()); // update bound to find centre of room roughly @@ -151,7 +148,7 @@ bool LRoomConverter::Convert_Room(Spatial * pNode, int lroomID) String szFullName = pNode->get_name(); String szRoom = LPortal::FindNameAfter(pNode, "room_"); - print_line("Convert_Room : " + szFullName); + LPRINT(4, "Convert_Room : " + szFullName); // get a reference to the lroom we are writing to LRoom &lroom = LMAN->m_Rooms[lroomID]; @@ -160,6 +157,11 @@ bool LRoomConverter::Convert_Room(Spatial * pNode, int lroomID) lroom.m_GodotID = pNode->get_instance_id(); lroom.m_RoomID = lroomID; + // save the room ID on the godot room metadata + // This is used when registering DOBs and teleporting them with hints + // i.e. the Godot room is used to lookup the room ID of the startroom. + LMAN->Obj_SetRoomNum(pNode, lroomID); + // create a new LRoom to exchange the children over to, and delete the original empty lroom.m_szName = szRoom; @@ -178,7 +180,7 @@ bool LRoomConverter::Convert_Room(Spatial * pNode, int lroomID) lroom.m_AABB.position = bb_room.m_ptMins; lroom.m_AABB.size = bb_room.m_ptMaxs - bb_room.m_ptMins; - print_line("\t" + String(lroom.m_szName) + " centre " + lroom.m_ptCentre); + LPRINT(2, "\t\t\t" + String(lroom.m_szName) + " centre " + lroom.m_ptCentre); return true; } @@ -218,7 +220,7 @@ bool LRoomConverter::Bound_AddPlaneIfUnique(LVector &planes, const Plane bool LRoomConverter::Convert_Bound(LRoom &lroom, MeshInstance * pMI) { - print("\t\tConvert_Bound : " + pMI->get_name()); + LPRINT(2, "\tCONVERT_BOUND : '" + pMI->get_name() + "' for room '" + lroom.get_name() + "'"); // some godot jiggery pokery to get the mesh verts in local space Ref rmesh = pMI->get_mesh(); @@ -250,7 +252,7 @@ bool LRoomConverter::Convert_Bound(LRoom &lroom, MeshInstance * pMI) Bound_AddPlaneIfUnique(lroom.m_Bound.m_Planes, p); } - print("\t\t\tcontained " + itos(lroom.m_Bound.m_Planes.size()) + " planes."); + LPRINT(2, "\t\t\tcontained " + itos(lroom.m_Bound.m_Planes.size()) + " planes."); return true; } } @@ -294,7 +296,8 @@ void LRoomConverter::Convert_Portals() { for (int pass=0; pass<3; pass++) { - print_line("Convert_Portals pass " + itos(pass)); + LPRINT(2, "Convert_Portals pass " + itos(pass)); + LPRINT(2, ""); for (int n=0; nm_Rooms.size(); n++) { @@ -338,7 +341,7 @@ int LRoomConverter::CountRooms() // go through the nodes hanging off the room looking for those that are meshes to mark portal locations void LRoomConverter::LRoom_DetectPortalMeshes(LRoom &lroom, LTempRoom &troom) { - print("DetectPortalMeshes from room " + lroom.get_name()); + LPRINT(2, "DETECT_PORTALS from room " + lroom.get_name()); Spatial * pGRoom = lroom.GetGodotRoom(); assert (pGRoom); @@ -415,13 +418,13 @@ void LRoomConverter::LRoom_MakePortalFinalList(LRoom &lroom, LTempRoom &troom) // found a portal mesh! create a matching LPortal void LRoomConverter::LRoom_DetectedPortalMesh(LRoom &lroom, LTempRoom &troom, MeshInstance * pMeshInstance, String szLinkRoom) { - print("\tDetected PortalMesh to " + szLinkRoom); + LPRINT(2, "\tdetected to " + szLinkRoom); // which room does this portal want to link to? int iLinkRoom = FindRoom_ByName(szLinkRoom); if (iLinkRoom == -1) { - print("\t\tWARNING : portal to room " + szLinkRoom + ", room not found"); + LWARN(5, "portal to room " + szLinkRoom + ", room not found"); //WARN_PRINTS("portal to room " + szLinkRoom + ", room not found"); return; } @@ -440,7 +443,7 @@ void LRoomConverter::LRoom_DetectedPortalMesh(LRoom &lroom, LTempRoom &troom, Me lport.CreateGeometry(p_vertices, pMeshInstance->get_global_transform()); - print("\t\t\tnum portals now " + itos(troom.m_Portals.size())); +// LPRINT(2, "\t\t\tnum portals now " + itos(troom.m_Portals.size())); } @@ -448,20 +451,21 @@ void LRoomConverter::LRoom_DetectedPortalMesh(LRoom &lroom, LTempRoom &troom, Me // will automatically create a mirror portal the other way. void LRoomConverter::LRoom_MakePortalsTwoWay(LRoom &lroom, LTempRoom &troom, int iRoomNum) { - print("LRoomConverter::LRoom_MakePortalsTwoWay from room " + lroom.get_name() + ", contains " + itos (troom.m_Portals.size()) + " portals"); + LPRINT(2, "MAKE_PORTALS_TWOWAY from room " + lroom.get_name()); + LPRINT(2, "\tcontains " + itos (troom.m_Portals.size()) + " portals"); for (int n=0; n +*/ + + #include "scene/3d/spatial.h" #include "lvector.h" #include "lportal.h" @@ -94,7 +119,4 @@ private: bool Bound_AddPlaneIfUnique(LVector &planes, const Plane &p); - static void print(String sz); - - }; diff --git a/lroom_manager.cpp b/lroom_manager.cpp index 64af617..c9c9a43 100644 --- a/lroom_manager.cpp +++ b/lroom_manager.cpp @@ -23,11 +23,15 @@ #include "scene/3d/camera.h" #include "scene/3d/mesh_instance.h" #include "lroom_converter.h" +#include "ldebug.h" LRoomManager::LRoomManager() { m_cameraID = 0; m_uiFrameCounter = 0; + m_iLoggingLevel = 2; + m_bActive = true; + m_bFrustumOnly = false; // to know which rooms to hide we keep track of which were shown this, and the previous frame m_pCurr_VisibleRoomList = &m_VisibleRoomList_A; @@ -149,38 +153,106 @@ LRoom * LRoomManager::GetRoomFromDOB(Node * pNode) } -bool LRoomManager::dob_register(Node * pDOB, float radius) +// register but let LPortal know which room the dob should start in +bool LRoomManager::dob_register_hint(Node * pDOB, float radius, Node * pRoom) { - print_line("register_dob " + pDOB->get_name()); + if (!pDOB) + { + WARN_PRINT_ONCE("dob_register_hint : pDOB is NULL"); + return false; + } + + LPRINT(3, "dob_register_hint " + pDOB->get_name()); + + if (!pRoom) + { + WARN_PRINT_ONCE("dob_register_hint : pRoom is NULL"); + return false; + } + + + int iRoom = Obj_GetRoomNum(pRoom); Spatial * pSpat = Object::cast_to(pDOB); if (!pSpat) + { + WARN_PRINT_ONCE("dob_register_hint : DOB is not a spatial"); return false; + } - Vector3 pt = pSpat->get_global_transform().origin; - int iRoomNum = FindClosestRoom(pt); - print_line("register_dob closest room " + itos(iRoomNum)); + return DobRegister(pSpat, radius, iRoom); +} - if (iRoomNum == -1) + +bool LRoomManager::DobRegister(Spatial * pDOB, float radius, int iRoom) +{ + //LPRINT(3, "register_dob " + pDOB->get_name()); + + if (iRoom == -1) + { + WARN_PRINT_ONCE("LRoomManager::DobRegister : room ID is -1"); return false; + } - LRoom * pRoom = GetRoom(iRoomNum); + LRoom * pRoom = GetRoom(iRoom); if (!pRoom) return false; LDob dob; - dob.m_ID = pSpat->get_instance_id(); + dob.m_ID = pDOB->get_instance_id(); dob.m_fRadius = radius; pRoom->DOB_Add(dob); // save the room ID on the dob metadata - Obj_SetRoomNum(pSpat, iRoomNum); + Obj_SetRoomNum(pDOB, iRoom); return true; } +bool LRoomManager::dob_register(Node * pDOB, float radius) +{ + if (!pDOB) + { + WARN_PRINT_ONCE("dob_register : pDOB is NULL"); + return false; + } + + LPRINT(3, "dob_register " + pDOB->get_name()); + + Spatial * pSpat = Object::cast_to(pDOB); + if (!pSpat) + { + WARN_PRINT_ONCE("dob_register : DOB is not a spatial"); + return false; + } + + Vector3 pt = pSpat->get_global_transform().origin; + + int iRoomNum = FindClosestRoom(pt); + LPRINT(2, "dob_register closest room " + itos(iRoomNum)); + + return DobRegister(pSpat, radius, iRoomNum); +// if (iRoomNum == -1) +// return false; + +// LRoom * pRoom = GetRoom(iRoomNum); +// if (!pRoom) +// return false; + +// LDob dob; +// dob.m_ID = pSpat->get_instance_id(); +// dob.m_fRadius = radius; + +// pRoom->DOB_Add(dob); + +// // save the room ID on the dob metadata +// Obj_SetRoomNum(pSpat, iRoomNum); +// return true; +} + + int LRoomManager::dob_update(Node * pDOB) { // find the room the object is attached to @@ -223,27 +295,53 @@ int LRoomManager::dob_update(Node * pDOB) return pRoom->m_RoomID; } -// not tested... -bool LRoomManager::dob_teleport(Node * pDOB) +bool LRoomManager::dob_teleport_hint(Node * pDOB, Node * pRoom) { + if (!pDOB) + { + WARN_PRINT_ONCE("dob_teleport_hint : pDOB is NULL"); + return false; + } + + LPRINT(1, "dob_teleport_hint " + pDOB->get_name()); + + if (!pRoom) + { + WARN_PRINT_ONCE("dob_teleport_hint : pRoom is NULL"); + return false; + } + + + int iRoom = Obj_GetRoomNum(pRoom); + Spatial * pSpat = Object::cast_to(pDOB); if (!pSpat) + { + WARN_PRINT_ONCE("dob_teleport_hint : DOB is not a spatial"); return false; + } + return DobTeleport(pSpat, iRoom); +} + + +bool LRoomManager::DobTeleport(Spatial * pDOB, int iNewRoomID) +{ // old room LRoom * pOldRoom = GetRoomFromDOB(pDOB); if (!pOldRoom) + { + WARN_PRINT_ONCE("LRoomManager::DobTeleport : pOldRoom is NULL"); return false; + } - Vector3 pt = pSpat->get_global_transform().origin; - - int iRoomNum = FindClosestRoom(pt); - //print_line("dob_teleport closest room " + itos(iRoomNum)); - - if (iRoomNum == -1) + if (iNewRoomID == -1) + { + WARN_PRINT_ONCE("LRoomManager::DobTeleport : iNewRoomID is -1"); return false; + } - LRoom * pNewRoom = GetRoom(iRoomNum); + LRoom * pNewRoom = GetRoom(iNewRoomID); if (!pNewRoom) return false; @@ -260,12 +358,58 @@ bool LRoomManager::dob_teleport(Node * pDOB) pOldRoom->DOB_Remove(dob_id); // save the room ID on the dob metadata - Obj_SetRoomNum(pSpat, iRoomNum); + Obj_SetRoomNum(pDOB, iNewRoomID); return true; } +// not tested... +bool LRoomManager::dob_teleport(Node * pDOB) +{ + Spatial * pSpat = Object::cast_to(pDOB); + if (!pSpat) + return false; + + Vector3 pt = pSpat->get_global_transform().origin; + + int iRoomNum = FindClosestRoom(pt); + //print_line("dob_teleport closest room " + itos(iRoomNum)); + + if (iRoomNum == -1) + return false; + + return DobTeleport(pSpat, iRoomNum); + +// // old room +// LRoom * pOldRoom = GetRoomFromDOB(pDOB); +// if (!pOldRoom) +// return false; + + +// LRoom * pNewRoom = GetRoom(iRoomNum); +// if (!pNewRoom) +// return false; + +// // detach from old room, add to new room +// // get dob data to move to new room +// unsigned int dob_id = pOldRoom->DOB_Find(pDOB); +// assert (dob_id != -1); + +// // copy across data before removing +// const LDob &data = pOldRoom->DOB_Get(dob_id); +// pNewRoom->DOB_Add(data); + +// // remove from old room +// pOldRoom->DOB_Remove(dob_id); + +// // save the room ID on the dob metadata +// Obj_SetRoomNum(pSpat, iRoomNum); + +// return true; +} + + bool LRoomManager::dob_unregister(Node * pDOB) { @@ -296,6 +440,43 @@ Node * LRoomManager::rooms_get_room(int room_id) } +// turn on and off culling for debugging +void LRoomManager::rooms_set_active(bool bActive) +{ + if (bActive == m_bActive) + return; + + m_bActive = bActive; + + if (m_bActive) + { + // clear these to ensure the system is initialized + m_pCurr_VisibleRoomList->clear(); + m_pPrev_VisibleRoomList->clear(); + } + + // show all + for (int n=0; nget_instance_id(); // use this temporarily to force debug - LPortal::m_bRunning = false; +// rooms_log_frame(); } // convert empties and meshes to rooms and portals @@ -325,6 +506,12 @@ void LRoomManager::rooms_convert() } +// debugging emulate view frustum +void LRoomManager::FrameUpdate_FrustumOnly() +{ + // NYI +} + void LRoomManager::FrameUpdate() { if (Engine::get_singleton()->is_editor_hint()) @@ -333,9 +520,22 @@ void LRoomManager::FrameUpdate() return; } + // could turn off internal processing? not that important + if (!m_bActive) + return; + + if (m_bFrustumOnly) + { + // debugging emulate view frustum + FrameUpdate_FrustumOnly(); + return; + } + // we keep a frame counter to prevent visiting things multiple times on the same frame in recursive functions m_uiFrameCounter++; + LPRINT(5, "\nFRAME " + itos(m_uiFrameCounter)); + // clear the visible room list to write to each frame m_pCurr_VisibleRoomList->clear(); @@ -444,7 +644,7 @@ void LRoomManager::FrameUpdate() // hide all the DOB // when running, emit less debugging output so as not to choke the IDE - LPortal::m_bRunning = true; + Lawn::LDebug::m_bRunning = true; } @@ -472,6 +672,12 @@ void LRoomManager::_bind_methods() ClassDB::bind_method(D_METHOD("rooms_set_camera"), &LRoomManager::rooms_set_camera); ClassDB::bind_method(D_METHOD("rooms_get_room"), &LRoomManager::rooms_get_room); + // debugging + ClassDB::bind_method(D_METHOD("rooms_set_logging"), &LRoomManager::rooms_set_logging); + ClassDB::bind_method(D_METHOD("rooms_log_frame"), &LRoomManager::rooms_log_frame); + ClassDB::bind_method(D_METHOD("rooms_set_active"), &LRoomManager::rooms_set_active); + + // functions to add dynamic objects to the culling system // Note that these should not be placed directly in rooms, the system will 'soft link' to them // so they can be held, e.g. in pools elsewhere in the scene graph @@ -480,5 +686,9 @@ void LRoomManager::_bind_methods() ClassDB::bind_method(D_METHOD("dob_update"), &LRoomManager::dob_update); ClassDB::bind_method(D_METHOD("dob_teleport"), &LRoomManager::dob_teleport); + ClassDB::bind_method(D_METHOD("dob_register_hint"), &LRoomManager::dob_register_hint); + ClassDB::bind_method(D_METHOD("dob_teleport_hint"), &LRoomManager::dob_teleport_hint); + + ClassDB::bind_method(D_METHOD("dob_get_room_id"), &LRoomManager::dob_get_room_id); } diff --git a/lroom_manager.h b/lroom_manager.h index aba1aa3..abad719 100644 --- a/lroom_manager.h +++ b/lroom_manager.h @@ -59,6 +59,12 @@ class LRoomManager : public Spatial { // already to prevent multiple hits on rooms and objects unsigned int m_uiFrameCounter; + // for debugging, can turn LPortal on and off + bool m_bActive; + + // for debugging, can emulate view frustum culling + bool m_bFrustumOnly; + public: LRoomManager(); @@ -73,11 +79,23 @@ public: // (can be used to find the name etc of a room ID returned by dob_update) Node * rooms_get_room(int room_id); + // turn on and off culling for debugging + void rooms_set_active(bool bActive); + + // 0 to 6 .. defaults to 4 which is (2) in our priorities (i.e. 6 - level) + void rooms_set_logging(int level); + + // provide debugging output on the next frame + void rooms_log_frame(); + // Dynamic objects .. cameras, players, boxes etc // These are defined by their ability to move from room to room. // You can still move static objects within the same room (e.g. elevators, moving platforms) // as these don't require checks for changing rooms. bool dob_register(Node * pDOB, float radius); + // register but let LPortal know which room the dob should start in + bool dob_register_hint(Node * pDOB, float radius, Node * pRoom); + bool dob_unregister(Node * pDOB); // returns the room ID within @@ -86,6 +104,8 @@ public: // if we are moving the DOB possibly through multiple rooms, then teleport rather than detect // portal crossings bool dob_teleport(Node * pDOB); + bool dob_teleport_hint(Node * pDOB, Node * pRoom); + // helper func, not needed usually as dob_update returns the room int dob_get_room_id(Node * pDOB); @@ -97,7 +117,14 @@ protected: // The recursive visibility function needs to allocate loads of planes. // We use a pool for this instead of allocating on the fly. LPlanesPool m_Pool; + + // 0 to 5 + int m_iLoggingLevel; private: + // internal + bool DobRegister(Spatial * pDOB, float radius, int iRoom); + bool DobTeleport(Spatial * pDOB, int iNewRoomID); + // helper funcs const LRoom * GetRoom(int i) const; @@ -114,6 +141,9 @@ private: // this is where we do all the culling void FrameUpdate(); + // debugging emulate view frustum + void FrameUpdate_FrustumOnly(); + // find which room is linked by a portal LRoom &Portal_GetLinkedRoom(const LPortal &port);