diff --git a/lbound.cpp b/lbound.cpp index ddb9c1f..1685134 100644 --- a/lbound.cpp +++ b/lbound.cpp @@ -52,14 +52,14 @@ float LBound::GetSmallestPenetrationDistance(const Vector3 &pt) const } -bool LBound::IsPointWithin(const Vector3 &pt) const +bool LBound::IsPointWithin(const Vector3 &pt, float epsilon) const { for (int n=0; n 0.0f) + if (d > epsilon) return false; } diff --git a/lbound.h b/lbound.h index 360cf67..411ce37 100644 --- a/lbound.h +++ b/lbound.h @@ -30,7 +30,7 @@ class LBound { public: - bool IsPointWithin(const Vector3 &pt) const; + bool IsPointWithin(const Vector3 &pt, float epsilon = 0.0f) const; // get distance behind all planes and return the smallest.. // if inside this will be negative, if outside, positive diff --git a/lroom.cpp b/lroom.cpp index e270d49..f3cd675 100644 --- a/lroom.cpp +++ b/lroom.cpp @@ -99,6 +99,20 @@ LRoom * LRoom::DOB_Update(LRoomManager &manager, Spatial * pDOB) if (bCamera) slop = 0.0f; + // deal with the case that the DOB has moved way outside the room + if (!m_Bound.IsPointWithin(pt, 1.0f)) + { + // revert to expensive method (may have been teleported etc) + int iRoomNum = manager.FindClosestRoom(pt); + //print_line("dob_teleport closest room " + itos(iRoomNum)); + + if (iRoomNum == -1) + return 0; + + + return manager.GetRoom(iRoomNum); + } + // the camera can't have slop because we might end up front side of a door without entering the room, // hence can't see into the room through the portal! // if (bCamera) diff --git a/lroom_converter.cpp b/lroom_converter.cpp index 2137f6d..59957ca 100644 --- a/lroom_converter.cpp +++ b/lroom_converter.cpp @@ -219,7 +219,7 @@ void LRoomConverter::Convert_Room_FindObjects_Recursive(Node * pParent, LRoom &l // ignore invisible Spatial * pSpatialChild = Object::cast_to(pChild); - if (pSpatialChild && (pSpatialChild->is_visible_in_tree() == false)) + if (pSpatialChild && (Convert_IsVisibleInRooms(pSpatialChild) == false)) { pSpatialChild->queue_delete(); continue; @@ -287,6 +287,29 @@ void LRoomConverter::Convert_Room_FindObjects_Recursive(Node * pParent, LRoom &l } +bool LRoomConverter::Convert_IsVisibleInRooms(const Node * pNode) const +{ + const Spatial * pS = Object::cast_to(pNode); + const Spatial * pRoomList = Object::cast_to(LROOMLIST); + + while (pS) + { + if (!pS->is_visible()) + { + return false; + } + + pS = pS->get_parent_spatial(); + + // terminate + if (pS == pRoomList) + return true; + } + + return true; +} + + // areaID could be -1 if unset bool LRoomConverter::Convert_Room(Spatial * pNode, int lroomID, int areaID) { diff --git a/lroom_converter.h b/lroom_converter.h index a8e29be..893eaaf 100644 --- a/lroom_converter.h +++ b/lroom_converter.h @@ -94,6 +94,7 @@ private: bool Convert_Room(Spatial * pNode, int lroomID, int areaID); void Convert_Room_FindObjects_Recursive(Node * pParent, LRoom &lroom, LAABB &bb_room); void Convert_Room_SetDefaultCullMask_Recursive(Node * pParent); + bool Convert_IsVisibleInRooms(const Node * pNode) const; void Convert_Portals(); void Convert_Bounds();