From 3d5945fd5fdbe53c4912d93661cf36f3a2bb4a5e Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Tue, 14 Jan 2020 11:17:59 +0000 Subject: [PATCH] Camera dob updated in frame update --- lbound.cpp | 12 +++++++++--- lbound.h | 2 +- ldebug.h | 13 ++++++++++--- ldob.cpp | 7 +++++++ lportal_all.cpp | 4 ++++ lroom_converter.cpp | 8 ++++++++ lroom_manager.cpp | 32 ++++++++++++++++++++++++++++---- ltrace.cpp | 2 +- 8 files changed, 68 insertions(+), 12 deletions(-) diff --git a/lbound.cpp b/lbound.cpp index 2cd5061..ddb9c1f 100644 --- a/lbound.cpp +++ b/lbound.cpp @@ -27,18 +27,24 @@ // get distance behind all planes and return the smallest.. // if inside this will be negative, if outside, positive -float LBound::GetClosestDistance(const Vector3 &pt) const +float LBound::GetSmallestPenetrationDistance(const Vector3 &pt) const { assert (m_Planes.size()); - float closest = FLT_MAX; + float closest = -FLT_MAX; for (int n=0; n 0.1f) // some large epsilon .. we would rather classify in a nearby cell than not in any cell + { + // outside the convex hull, don't use + return FLT_MAX; + } + + if (d > closest) closest = d; } diff --git a/lbound.h b/lbound.h index 214c6eb..360cf67 100644 --- a/lbound.h +++ b/lbound.h @@ -34,7 +34,7 @@ public: // get distance behind all planes and return the smallest.. // if inside this will be negative, if outside, positive - float GetClosestDistance(const Vector3 &pt) const; + float GetSmallestPenetrationDistance(const Vector3 &pt) const; // the bound is optional .. not all rooms have a bound bool IsActive() const {return m_Planes.size() != 0;} diff --git a/ldebug.h b/ldebug.h index 10b4339..2c2babb 100644 --- a/ldebug.h +++ b/ldebug.h @@ -25,10 +25,10 @@ #ifdef DEBUG_ENABLED #pragma message ("LPortal DEBUG_ENABLED") -#define LPRINT_RUN(a, b) {String sz;\ +#define LPRINT_RUN(a, b) {if (!Lawn::LDebug::m_bRunning) {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);\ diff --git a/ldob.cpp b/ldob.cpp index 5a74677..2a53ec5 100644 --- a/ldob.cpp +++ b/ldob.cpp @@ -51,16 +51,23 @@ void LHidable::Show(bool bShow) if (m_bDetach) { + //String sz = ""; if (bShow) { + //sz = "show "; // add to tree m_pParent->add_child(m_pNode); } else { + //sz = "hide "; // remove from tree m_pParent->remove_child(m_pNode); } + //sz += m_pParent->get_name(); + //sz += "->"; + //sz += m_pNode->get_name(); + //print_line(sz); } else { diff --git a/lportal_all.cpp b/lportal_all.cpp index da2f78a..9af97ff 100644 --- a/lportal_all.cpp +++ b/lportal_all.cpp @@ -1,10 +1,14 @@ // defines +// extra verbose print_lines +//#define LDEBUG_VERBOSE + // frame debug strings #define LDEBUG_CAMERA #define LDEBUG_LIGHTS #define LDEBUG_LIGHT_AFFECTED_ROOMS + //#define LDEBUG_UNMERGE // single compilation unit diff --git a/lroom_converter.cpp b/lroom_converter.cpp index b5dba4e..2137f6d 100644 --- a/lroom_converter.cpp +++ b/lroom_converter.cpp @@ -423,6 +423,14 @@ void LRoomConverter::GetWorldVertsFromMesh(const MeshInstance &mi, Vector rmesh = mi.get_mesh(); Array arrays = rmesh->surface_get_arrays(0); + + // possible to have a meshinstance with no geometry .. don't want to crash + if (!arrays.size()) + { + WARN_PRINT_ONCE("Warning : LRoomConverter::GetWorldVertsFromMesh MeshInstance with no mesh, ignoring"); + return; + } + PoolVector p_vertices = arrays[VS::ARRAY_VERTEX]; // convert to world space diff --git a/lroom_manager.cpp b/lroom_manager.cpp index 4c18146..4ac51c4 100644 --- a/lroom_manager.cpp +++ b/lroom_manager.cpp @@ -116,7 +116,7 @@ int LRoomManager::FindClosestRoom(const Vector3 &pt) const if (lroom.m_AABB.has_point(pt)) { // is it within the convex hull? - float dist = lroom.m_Bound.GetClosestDistance(pt); + float dist = lroom.m_Bound.GetSmallestPenetrationDistance(pt); // find the lowest within distance of the nearby room convex hulls if (dist < within_dist) @@ -417,7 +417,7 @@ bool LRoomManager::dob_register(Node * pDOB, float radius) return false; } - LPRINT(3, "dob_register " + pDOB->get_name()); + LPRINT(3, "dob_register " + pDOB->get_name() + " instance ID " + itos(pDOB->get_instance_id())); Spatial * pSpat = Object::cast_to(pDOB); if (!pSpat) @@ -454,6 +454,8 @@ int LRoomManager::dob_update(Node * pDOB) int iRoomNum = pNewRoom->m_RoomID; // get dob data to move to new room + //unsigned int uidob_instance_id = pDOB->get_instance_id(); + unsigned int dob_id = pRoom->DOB_Find(pDOB); // if (dob_id == -1) // { @@ -517,6 +519,8 @@ bool LRoomManager::dob_teleport_hint(Node * pDOB, Node * pRoom) bool LRoomManager::DobTeleport(Spatial * pDOB, int iNewRoomID) { + print_line("teleporting " + pDOB->get_name() + " to room " + itos(iNewRoomID)); + // old room LRoom * pOldRoom = GetRoomFromDOB(pDOB); if (!pOldRoom) @@ -535,6 +539,12 @@ bool LRoomManager::DobTeleport(Spatial * pDOB, int iNewRoomID) if (!pNewRoom) return false; + // special case, if teleporting within the same room, no op + // (if we do try and move from same room to same room we get data corruption because of + // const ref) + if (pOldRoom == pNewRoom) + return true; + // detach from old room, add to new room // get dob data to move to new room unsigned int dob_id = pOldRoom->DOB_Find(pDOB); @@ -1202,7 +1212,16 @@ bool LRoomManager::rooms_set_camera(Node * pCam) return false; } - m_ID_camera = pCam->get_instance_id(); + int id = pCam->get_instance_id(); + + // was this a change in camera? + if (id != m_ID_camera) + { + m_ID_camera = id; + + // make sure the camera room is correct by doing a teleport + dob_teleport(pCam); + } // new .. select the cull layer // 1 is for showing objects outside the room system @@ -1567,7 +1586,7 @@ bool LRoomManager::FrameUpdate() // 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)); + LPRINT_RUN(5, "\nFRAME " + itos(m_uiFrameCounter)); FrameUpdate_Prepare(); @@ -1578,6 +1597,11 @@ bool LRoomManager::FrameUpdate() { Object *pObj = ObjectDB::get_instance(m_ID_camera); pCamera = Object::cast_to(pObj); + + // always doing dob update here for camera, this ensures it is not one frame behind + // depending on scene tree, which can cause camera lroom id to be the old one after crossing + // a portal plane, causing a flicker on changing room... + dob_update(pCamera); } else // camera not set .. do nothing diff --git a/ltrace.cpp b/ltrace.cpp index cf1d49c..8d739fd 100644 --- a/ltrace.cpp +++ b/ltrace.cpp @@ -443,7 +443,7 @@ void LTrace::Trace_Recursive(int depth, LRoom &room, const LVector &plane // plane the camera is on! If it is behind, the portal can be seen through, if in front, it can't! :) float dist_cam = port.m_Plane.distance_to(m_pCamera->m_ptPos); LPRINT_RUN(2, "\tPORTAL " + itos (port_num) + " (" + itos(port_id) + ") " + port.get_name()); - if (dist_cam > 0.0f) + if (dist_cam >= 0.0f) // was > { LPRINT_RUN(2, "\t\tCULLED (back facing)"); continue;