From 18eac7e8106430a3f2075eb484243b308c4228f2 Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Thu, 2 Apr 2020 13:36:53 +0100 Subject: [PATCH] New API for dobs To fix bug where get_global_transform doesn't work with dobs outside the tree, there is a new API --- config.pyc | Bin 0 -> 397 bytes ldebug.h | 2 +- ldob.cpp | 1 + ldob.h | 9 +- ldoblist.cpp | 179 +++++++++++++++++ ldoblist.h | 58 ++++++ lportal_all.cpp | 4 + lroom.cpp | 45 ++--- lroom.h | 15 +- lroom_converter.cpp | 2 +- lroom_manager.cpp | 460 ++++++++++++++++++++++++++++++-------------- lroom_manager.h | 54 +++--- ltrace.cpp | 6 +- 13 files changed, 625 insertions(+), 210 deletions(-) create mode 100644 config.pyc create mode 100644 ldoblist.cpp create mode 100644 ldoblist.h diff --git a/config.pyc b/config.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6df6e879b09c515e99093e416c27bd8b35a962a8 GIT binary patch literal 397 zcmb79JqyAx5WTb_t>Eh7ALtA|FfKLn6??7GXw67O+e|iDOHDd)?*{ zby}Ls>#GegHZrq?(p7{xI5Kn0mT{#-D{~XeMroVLn5()dFU#g;L#*?xKAqcA3fg68 zD=lr=Ym_Bound.IsPointWithin(pos, 1.0f)) + bChangedRoom = true; + } + + // if changed room definitely? + if (bChangedRoom) + { + // revert to expensive method (may have been teleported etc) + new_room_id = manager.FindClosestRoom(pos); + + if (new_room_id != old_room_id) + return true; + else + return false; + } + + + assert (pCurrentRoom); + + // check each portal - has the object crossed it into the neighbouring room? + for (int p=0; pm_iNumPortals; p++) + { + const LPortal &port = manager.m_Portals[pCurrentRoom->m_iFirstPortal + p]; + + float dist = port.m_Plane.distance_to(pos); + + if (dist > slop) + { + LPRINT(0, "DOB at pos " + pos + " ahead of portal " + port.get_name() + " by " + String(Variant(dist))); + + new_room_id = manager.Portal_GetLinkedRoom(port).m_RoomID; + return true; + } + } + + return false; +} + +void LDobList::UpdateVisibility(LRoomManager &manager, Spatial * pDOBSpatial, int dob_id) +{ + LDob &dob = GetDob(dob_id); + + // get the room + LRoom * pRoom = manager.GetRoom(dob.m_iRoomID); + bool bRoomVisible = pRoom->IsVisible(); + + Spatial * pDOB = pDOBSpatial; + + bool bDobVis = pDOB->is_visible_in_tree(); + if (bDobVis != bRoomVisible) + { + //String sz = "DOB " + pDOB->get_name() + "\t"; + + if (bRoomVisible) + { + pDOB->show(); + //sz += "coming into view"; + } + else + { + pDOB->hide(); + //sz += "exiting view"; + } + + //print_line(sz); + } + + +} + + + +int LDobList::UpdateDob(LRoomManager &manager, int dob_id, const Vector3 &pos) +{ + LDob &dob = GetDob(dob_id); + + // get the VI for showing / hiding + Spatial * pSpat = (Spatial *) dob.GetVI(); + + int old_room, new_room; + + if (FindDOBOldAndNewRoom(manager, dob_id, pos, old_room, new_room)) + { + dob.m_iRoomID = new_room; + } + + if (dob_id != manager.m_DOB_id_camera) + UpdateVisibility(manager, pSpat, dob_id); + + return dob.m_iRoomID; +} + +/* + // get _global_transform DOES NOT WORK when detached from scene tree (or hidden) + const Vector3 &pt = pDOB->get_global_transform().origin; + + // is it the camera? + bool bCamera = pDOB->get_instance_id() == manager.m_ID_camera; + float slop = 0.2f; + if (bCamera) + slop = 0.0f; + else + { +// print_line("dob position : " + String(Variant(pt))); + } + + // 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; + + // could be no change of room... + if (iRoomNum == m_RoomID) + 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) +// slop = 0.0f; + + // check each portal - has the object crossed it into the neighbouring room? + for (int p=0; p slop) + { + 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); + } + } + + return 0; + */ + diff --git a/ldoblist.h b/ldoblist.h new file mode 100644 index 0000000..6b4b824 --- /dev/null +++ b/ldoblist.h @@ -0,0 +1,58 @@ +#pragma once + +#include "lvector.h" +#include "ldob.h" + +class LRoomManager; + +class LDobList +{ +public: + // getting + LDob &GetDob(int n) {return m_List[n];} + const LDob &GetDob(int n) const {return m_List[n];} + + // request delete + int Request(); + void DeleteDob(int id); + + // funcs + int UpdateDob(LRoomManager &manager, int dob_id, const Vector3 &pos); + void UpdateVisibility(LRoomManager &manager, Spatial * pDOBSpatial, int dob_id); + +private: + bool FindDOBOldAndNewRoom(LRoomManager &manager, int dob_id, const Vector3 &pos, int &old_room_id, int &new_room_id); + + LVector m_List; +}; + + +///////////////////////////////////////////////////////// + +inline void LDobList::DeleteDob(int id) +{ + GetDob(id).m_bSlotTaken = false; +} + + +inline int LDobList::Request() +{ + for (int n=0; nm_bSlotTaken = true; + p->m_iRoomID = -1; + + return m_List.size()-1; +} diff --git a/lportal_all.cpp b/lportal_all.cpp index 9af97ff..e948642 100644 --- a/lportal_all.cpp +++ b/lportal_all.cpp @@ -7,13 +7,17 @@ #define LDEBUG_CAMERA #define LDEBUG_LIGHTS #define LDEBUG_LIGHT_AFFECTED_ROOMS +//#define LDEBUG_DOB_VISIBILITY +#define LPORTAL_DOBS_NO_SOFTSHOW +//#define LPORTAL_DOBS_AUTO_UPDATE //#define LDEBUG_UNMERGE // single compilation unit #include "register_types.cpp" #include "ldebug.cpp" +#include "ldoblist.cpp" #include "lroom.cpp" #include "lroom_manager.cpp" #include "lroom_converter.cpp" diff --git a/lroom.cpp b/lroom.cpp index 117f8bd..8998781 100644 --- a/lroom.cpp +++ b/lroom.cpp @@ -55,19 +55,19 @@ Spatial * LRoom::GetGodotRoom() const } - -void LRoom::DOB_Add(const LDob &dob) +/* +void LRoom::DOB_Add(int id) { - m_DOBs.push_back(dob); + m_DOB_ids.push_back(id); } -unsigned int LRoom::DOB_Find(Node * pDOB) const +unsigned int LRoom::DOB_Find(int id) const { - ObjectID id = pDOB->get_instance_id(); +// ObjectID id = pDOB->get_instance_id(); - for (int n=0; nget_global_transform().origin; // is it the camera? @@ -98,6 +99,10 @@ LRoom * LRoom::DOB_Update(LRoomManager &manager, Spatial * pDOB) float slop = 0.2f; if (bCamera) slop = 0.0f; + else + { +// print_line("dob position : " + String(Variant(pt))); + } // deal with the case that the DOB has moved way outside the room if (!m_Bound.IsPointWithin(pt, 1.0f)) @@ -139,7 +144,7 @@ LRoom * LRoom::DOB_Update(LRoomManager &manager, Spatial * pDOB) return 0; } - +*/ // instead of directly showing and hiding objects we now set their layer, // and the camera will hide them with a cull mask. This is so that @@ -316,6 +321,7 @@ void LRoom::FinalizeVisibility(LRoomManager &manager) //print_line("FinalizeVisibility room " + get_name() + " NumSOBs " + itos(m_SOBs.size()) + ", NumDOBs " + itos(m_DOBs.size())); +#ifndef LPORTAL_DOBS_NO_SOFTSHOW for (int n=0; nhide(); } } -} - -// call when releasing a level, this should unregister all dobs within all rooms -void LRoom::Release(LRoomManager &manager) -{ - for (int n=0; nhide(); } } + */ } diff --git a/lroom.h b/lroom.h index 0695580..8de9261 100644 --- a/lroom.h +++ b/lroom.h @@ -58,7 +58,7 @@ public: int m_iNumSOBs; // dynamic objects - LVector m_DOBs; + //LVector m_DOB_ids; // local lights affecting this room LVector m_LocalLights; @@ -105,9 +105,6 @@ public: // allows us to show / hide all dobs as the room visibility changes void Room_MakeVisible(bool bVisible); - // call when releasing a level, this should unregister all dobs within all rooms - void Release(LRoomManager &manager); - // show godot room and all linked dobs and all sobs void Debug_ShowAll(bool bActive); @@ -118,11 +115,11 @@ public: // naive version, adds all the non visible objects in visible rooms as shadow casters void AddShadowCasters(LRoomManager &manager); - void DOB_Add(const LDob &dob); - const LDob &DOB_Get(unsigned int ui) const {return m_DOBs[ui];} - unsigned int DOB_Find(Node * pDOB) const; - bool DOB_Remove(unsigned int ui); - LRoom * DOB_Update(LRoomManager &manager, Spatial * pDOB); +// void DOB_Add(int id); +// int DOB_GetID(unsigned int ui) const {return m_DOB_ids[ui];} +// unsigned int DOB_Find(int id) const; +// bool DOB_Remove(unsigned int ui); +// LRoom * DOB_Update(LRoomManager &manager, Spatial * pDOB); LRoom(); Spatial * GetGodotRoom() const; diff --git a/lroom_converter.cpp b/lroom_converter.cpp index 59957ca..ad89d2b 100644 --- a/lroom_converter.cpp +++ b/lroom_converter.cpp @@ -336,7 +336,7 @@ bool LRoomConverter::Convert_Room(Spatial * pNode, int lroomID, int areaID) // 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->Meta_SetRoomNum(pNode, lroomID); +// LMAN->Meta_SetRoomNum(pNode, lroomID); // create a new LRoom to exchange the children over to, and delete the original empty lroom.m_szName = szRoom; diff --git a/lroom_manager.cpp b/lroom_manager.cpp index c6cac18..ac89ae4 100644 --- a/lroom_manager.cpp +++ b/lroom_manager.cpp @@ -42,7 +42,8 @@ return false;\ LRoomManager::LRoomManager() { - m_ID_camera = 0; +// m_ID_camera = 0; + m_DOB_id_camera = -1; m_ID_DebugPlanes = 0; m_ID_DebugBounds = 0; m_ID_DebugLights = 0; @@ -183,6 +184,8 @@ int LRoomManager::Meta_GetLightID(Node * pNode) const } +/* + CANT BE TRUSTED void LRoomManager::Meta_SetRoomNum(Node * pNode, int num) { pNode->set_meta("_lroom", num); @@ -199,33 +202,10 @@ int LRoomManager::Meta_GetRoomNum(Node * pNode) const return v; } - -LRoom * LRoomManager::GetRoomFromDOB(Node * pNode) -{ - int iRoom = Meta_GetRoomNum(pNode); - if (iRoom < 0) - { - if (iRoom == -1) - { - WARN_PRINT_ONCE("LRoomManager::GetRoomFromDOB : metadata is empty"); - } - - if (iRoom == -2) - { - WARN_PRINT_ONCE("LRoomManager::GetRoomFromDOB : are you updating an unregistered DOB?"); - } - return 0; - } - - LRoom * pRoom = GetRoom(iRoom); - if (pRoom == 0) - { - WARN_PRINT_ONCE("LRoomManager::GetRoomFromDOB : pRoom is NULL"); - } - return pRoom; -} +*/ +/* // register but let LPortal know which room the dob should start in bool LRoomManager::dob_register_hint(Node * pDOB, float radius, Node * pRoom) { @@ -258,7 +238,7 @@ bool LRoomManager::dob_register_hint(Node * pDOB, float radius, Node * pRoom) return DobRegister(pSpat, radius, iRoom); } - +*/ void LRoomManager::CreateDebug() { @@ -373,7 +353,7 @@ ObjectID LRoomManager::DobRegister_FindVIRecursive(Node * pNode) const return 0; } -bool LRoomManager::DobRegister(Spatial * pDOB, float radius, int iRoom) +int LRoomManager::DobRegister(Spatial * pDOB, const Vector3 &pos, float radius, int iRoom) { //LPRINT(3, "register_dob " + pDOB->get_name()); @@ -383,38 +363,56 @@ bool LRoomManager::DobRegister(Spatial * pDOB, float radius, int iRoom) return false; } - LRoom * pRoom = GetRoom(iRoom); - if (!pRoom) - return false; + int did = m_DobList.Request(); + LDob &dob = m_DobList.GetDob(did); - // The dob is derived from spatial, but the visual instances may be children of the dob - // rather than the node itself .. we need visual instances for layer culling for shadows - LDob dob; + dob.m_iRoomID = iRoom; dob.m_ID_Spatial = pDOB->get_instance_id(); dob.m_fRadius = radius; +// LRoom * pRoom = GetRoom(iRoom); +// if (!pRoom) +// return false; + + // The dob is derived from spatial, but the visual instances may be children of the dob + // rather than the node itself .. we need visual instances for layer culling for shadows +// LDob dob; +// dob.m_ID_Spatial = pDOB->get_instance_id(); +// dob.m_fRadius = radius; + dob.m_ID_VI = DobRegister_FindVIRecursive(pDOB); - pRoom->DOB_Add(dob); +// pRoom->DOB_Add(dob); // save the room ID on the dob metadata - Meta_SetRoomNum(pDOB, iRoom); +// Meta_SetRoomNum(pDOB, iRoom); + +#ifdef LPORTAL_DOBS_NO_SOFTSHOW + VisualInstance * pVI = dob.GetVI(); + if (pVI) + { + uint32_t mask = 0; + mask = LRoom::LAYER_MASK_CAMERA | LRoom::LAYER_MASK_LIGHT; + LRoom::SoftShow(pVI, mask); + } +#endif // change visibility - DobChangeVisibility(pDOB, 0, pRoom); + m_DobList.UpdateDob(*this, did, pos); +// DobUpdateVisibility(pDOB, pRoom); - return true; + return did; } -bool LRoomManager::dob_register(Node * pDOB, float radius) +int LRoomManager::dob_register(Node * pDOB, const Vector3 &pos, float radius) { CHECK_ROOM_LIST if (!pDOB) { WARN_PRINT_ONCE("dob_register : pDOB is NULL"); - return false; + return -1; } LPRINT(3, "dob_register " + pDOB->get_name() + " instance ID " + itos(pDOB->get_instance_id())); @@ -423,30 +421,30 @@ bool LRoomManager::dob_register(Node * pDOB, float radius) if (!pSpat) { WARN_PRINT_ONCE("dob_register : DOB is not a spatial"); - return false; + return -1; } - Vector3 pt = pSpat->get_global_transform().origin; +// Vector3 pt = pSpat->get_global_transform().origin; - int iRoomNum = FindClosestRoom(pt); + int iRoomNum = FindClosestRoom(pos); LPRINT(2, "dob_register closest room " + itos(iRoomNum)); - return DobRegister(pSpat, radius, iRoomNum); + return DobRegister(pSpat, pos, radius, iRoomNum); } -int LRoomManager::dob_update(Node * pDOB) +/* +// where pRoom is current room +int LRoomManager::DobUpdate(Spatial * pDOB_Spatial, LRoom * pRoom) { - // find the room the object is attached to - LRoom * pRoom = GetRoomFromDOB(pDOB); - if (!pRoom) - return -1; + LRoom * pNewRoom = pRoom->DOB_Update(*this, pDOB_Spatial); - Spatial * pSpat = Object::cast_to(pDOB); - if (!pSpat) - return -1; +// // update visibility +// if (pNewRoom) +// DobUpdateVisibility(pSpat, pNewRoom); +// else +// DobUpdateVisibility(pSpat, pRoom); - LRoom * pNewRoom = pRoom->DOB_Update(*this, pSpat); if (pNewRoom) { @@ -456,7 +454,7 @@ int LRoomManager::dob_update(Node * pDOB) // 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); + unsigned int dob_id = pRoom->DOB_Find(pDOB_Spatial); // if (dob_id == -1) // { // WARN_PRINT_ONCE("DOB is not found in room"); @@ -464,6 +462,8 @@ int LRoomManager::dob_update(Node * pDOB) // } assert (dob_id != -1); + print_line("dob " + itos(dob_id) + " entering room " + pNewRoom->get_name()); + // copy across data before removing const LDob &data = pRoom->DOB_Get(dob_id); pNewRoom->DOB_Add(data); @@ -472,19 +472,75 @@ int LRoomManager::dob_update(Node * pDOB) pRoom->DOB_Remove(dob_id); // change visibility - DobChangeVisibility(pSpat, pRoom, pNewRoom); + DobUpdateVisibility(pDOB_Spatial, pNewRoom); // save the room ID on the dob metadata - Meta_SetRoomNum(pSpat, iRoomNum); + Meta_SetRoomNum(pDOB_Spatial, iRoomNum); // new room number return iRoomNum; } +//#ifdef LDEBUG_DOB_VISIBILITY +//#pragma message ("LPortal LDEBUG_DOB_VISIBILITY, dobs will flicker when hidden") +// bool bVis = pRoom->IsVisible(); + +// bool bSpatVisible = pSpat->is_visible_in_tree(); +// if (bVis != bSpatVisible) +// { +// WARN_PRINT("DOB visibility incorrect"); +// } + +// bool bShow = true; + +// if (!bVis) +// { +// if ((Engine::get_singleton()->get_frames_drawn() % 2) == 0) +// { +// pSpat->show(); +// } +// else +// { +// pSpat->hide(); +// } +// } +// else +// { +// pSpat->show(); +// } +//#endif + + // still in the same room return pRoom->m_RoomID; } +*/ +int LRoomManager::dob_update(int dob_id, const Vector3 &pos) +{ +#ifdef LPORTAL_DOBS_AUTO_UPDATE + return -1; +#endif + + + + return m_DobList.UpdateDob(*this, dob_id, pos); + + + + // find the room the object is attached to +// LRoom * pRoom = GetRoomFromDOB(pDOB); +// if (!pRoom) +// return -1; + +// Spatial * pSpat = Object::cast_to(pDOB); +// if (!pSpat) +// return -1; + +// return DobUpdate(pSpat, pRoom); +} + +/* bool LRoomManager::dob_teleport_hint(Node * pDOB, Node * pRoom) { CHECK_ROOM_LIST @@ -515,8 +571,9 @@ bool LRoomManager::dob_teleport_hint(Node * pDOB, Node * pRoom) return DobTeleport(pSpat, iRoom); } +*/ - +/* bool LRoomManager::DobTeleport(Spatial * pDOB, int iNewRoomID) { LPRINT(5, "teleporting " + pDOB->get_name() + " to room " + itos(iNewRoomID)); @@ -561,50 +618,55 @@ bool LRoomManager::DobTeleport(Spatial * pDOB, int iNewRoomID) Meta_SetRoomNum(pDOB, iNewRoomID); // change visibility - DobChangeVisibility(pDOB, pOldRoom, pNewRoom); + DobUpdateVisibility(pDOB, pNewRoom); return true; } - +*/ // not tested... +/* bool LRoomManager::dob_teleport(Node * pDOB) { CHECK_ROOM_LIST - Spatial * pSpat = Object::cast_to(pDOB); - if (!pSpat) - return false; + return true; - Vector3 pt = pSpat->get_global_transform().origin; +// Spatial * pSpat = Object::cast_to(pDOB); +// if (!pSpat) +// return false; - int iRoomNum = FindClosestRoom(pt); - //print_line("dob_teleport closest room " + itos(iRoomNum)); +// Vector3 pt = pSpat->get_global_transform().origin; - if (iRoomNum == -1) - return false; +// int iRoomNum = FindClosestRoom(pt); +// //print_line("dob_teleport closest room " + itos(iRoomNum)); - return DobTeleport(pSpat, iRoomNum); +// if (iRoomNum == -1) +// return false; + +// return DobTeleport(pSpat, iRoomNum); } +*/ - -bool LRoomManager::dob_unregister(Node * pDOB) +bool LRoomManager::dob_unregister(int dob_id) { CHECK_ROOM_LIST - LRoom * pRoom = GetRoomFromDOB(pDOB); +// LRoom * pRoom = GetRoomFromDOB(pDOB); - // change the meta data on the DOB .. this will catch trying to update an unregistered DOB - Meta_SetRoomNum(pDOB, -2); +// // change the meta data on the DOB .. this will catch trying to update an unregistered DOB +// Meta_SetRoomNum(pDOB, -2); - if (pRoom) - { - unsigned int dob_id = pRoom->DOB_Find(pDOB); - return pRoom->DOB_Remove(dob_id); - } +// if (pRoom) +// { +// unsigned int dob_id = pRoom->DOB_Find(pDOB); +// return pRoom->DOB_Remove(dob_id); +// } - return false; + m_DobList.DeleteDob(dob_id); + + return true; } @@ -729,7 +791,13 @@ bool LRoomManager::Light_FindCasters(int lightID) void LRoomManager::Light_UpdateTransform(LLight &light, const Light &glight) const { -// assert (glight.is_in_tree()); + if (!glight.get_parent()) + { + WARN_PRINT_ONCE("LRoomManager::Light_UpdateTransform Light is not in tree"); + return; + } + + // get global transform only works if glight is in the tree Transform tr = glight.get_global_transform(); light.m_Source.m_ptPos = tr.origin; light.m_Source.m_ptDir = -tr.basis.get_axis(2); // or possibly get_axis .. z is what we want @@ -815,14 +883,13 @@ bool LRoomManager::LightCreate(Light * pLight, int roomID, String szArea) } -bool LRoomManager::dynamic_light_register(Node * pLightNode, float radius) +int LRoomManager::dynamic_light_register(Node * pLightNode, float radius) { CHECK_ROOM_LIST - if (!pLightNode) { WARN_PRINT_ONCE("dynamic_light_register : pLightNode is NULL"); - return false; + return -1; } ObjectID light_id = pLightNode->get_instance_id(); @@ -834,31 +901,85 @@ bool LRoomManager::dynamic_light_register(Node * pLightNode, float radius) { m_Lights[n].m_Source.m_eClass = LSource::SC_DYNAMIC; + + // do an update on the light + //dynamic_light_update(n, pos, dir); + // store the light ID in the metadata for the node - Meta_SetLightID(pLightNode, n); - return true; + //Meta_SetLightID(pLightNode, n); + return n; } } - return false; -} - -bool LRoomManager::dynamic_light_register_hint(Node * pLightNode, float radius, Node * pRoom) -{ - // NYI - - return true; + return -1; } -bool LRoomManager::dynamic_light_unregister(Node * pLightNode) +bool LRoomManager::dynamic_light_unregister(int light_id) { // NYI return true; } -int LRoomManager::dynamic_light_update(Node * pLightNode) // returns room within +// returns room within or -1 if no dob +int LRoomManager::dynamic_light_update(int light_id, const Vector3 &pos, const Vector3 &dir) // returns room within { + // doesn't now matter if not in tree as position and dir are passed directly + if ((unsigned int) light_id >= (unsigned int) m_Lights.size()) + { + WARN_PRINT_ONCE("dynamic_light_update : meta light ID out of range"); + return -1; + } + + LLight &light = m_Lights[light_id]; + + int iRoom = light.m_Source.m_RoomID; + if (iRoom == -1) + { + WARN_PRINT_ONCE("dynamic_light_update : can't update global light"); + return -1; + } + + light.m_Source.m_ptPos = pos; + light.m_Source.m_ptDir = dir.normalized(); + + // update dob + if (light.m_DOB_id != -1) + { + int iNewRoom = m_DobList.UpdateDob(*this, light.m_DOB_id, pos); + light.m_Source.m_RoomID = iNewRoom; + } + + // update with a new Trace (we are assuming update is only called if the light has moved) + // remove the old local lights + for (int n=0; nRemoveLocalLight(light_id); + } + light.ClearAffectedRooms(); + + + // now do a new trace, and add all the rooms that are hit + m_Trace.Trace_Light(*this, light, LTrace::LR_ROOMS); + + // we should now have a list of the rooms hit in m_LightRender.m_Temp_Visible_Rooms + for (int n=0; nAddLocalLight(light_id); + + } + + // this may or may not have changed + return light.m_Source.m_RoomID; + + /* if (!pLightNode) { WARN_PRINT_ONCE("dynamic_light_update : pLightNode is NULL"); @@ -949,6 +1070,8 @@ int LRoomManager::dynamic_light_update(Node * pLightNode) // returns room within // this may or may not have changed return light.m_Source.m_RoomID; + */ + return 0; } void LRoomManager::DebugString_Light_AffectedRooms(int light_id) @@ -973,7 +1096,7 @@ void LRoomManager::DebugString_Light_AffectedRooms(int light_id) } -bool LRoomManager::light_register(Node * pLightNode, String szArea) +bool LRoomManager::global_light_register(Node * pLightNode, String szArea) { //CHECK_ROOM_LIST @@ -1002,33 +1125,39 @@ bool LRoomManager::light_register(Node * pLightNode, String szArea) return LightCreate(pLight, -1, szArea); } - -void LRoomManager::DobChangeVisibility(Spatial * pDOB, const LRoom * pOld, const LRoom * pNew) +/* +void LRoomManager::DobUpdateVisibility(int dob_id) { - bool bVisOld = false; - bool bVisNew = false; + LDob &dob = m_DobList.GetDob(dob_id); - if (pOld) - bVisOld = pOld->IsVisible(); +// return; - if (pNew) - bVisNew = pNew->IsVisible(); + bool bRoomVis = pRoom->IsVisible(); + bool bDobVis = pDOB->is_visible_in_tree(); - - if (bVisOld != bVisNew) + if (bDobVis != bRoomVis) { - if (!bVisOld) + String sz = "DOB " + pDOB->get_name() + "\t"; + + if (bRoomVis) + { pDOB->show(); + sz += "coming into view"; + } else + { pDOB->hide(); + sz += "exiting view"; + } + + print_line(sz); } - } +*/ - -int LRoomManager::dob_get_room_id(Node * pDOB) +int LRoomManager::dob_get_room_id(int dob_id) { - return Meta_GetRoomNum(pDOB); + return m_DobList.GetDob(dob_id).m_iRoomID; } // helpers to enable the client to manage switching on and off physics and AI @@ -1192,15 +1321,14 @@ void LRoomManager::rooms_log_frame() } -bool LRoomManager::rooms_set_camera(Node * pCam) +bool LRoomManager::rooms_set_camera(int dob_id, Node * pCam) { CHECK_ROOM_LIST // is it the first setting of the camera? if so hide all - if (m_ID_camera == 0) + if (m_DOB_id_camera == -1) ShowAll(false); - m_ID_camera = 0; if (!pCam) return false; @@ -1212,15 +1340,17 @@ bool LRoomManager::rooms_set_camera(Node * pCam) return false; } - int id = pCam->get_instance_id(); + +// int id = pCam->get_instance_id(); // was this a change in camera? - if (id != m_ID_camera) + if (m_DOB_id_camera != dob_id) { - m_ID_camera = id; + m_DOB_id_camera = dob_id; + //m_ID_camera = id; // make sure the camera room is correct by doing a teleport - dob_teleport(pCam); + //dob_teleport(pCam); } // new .. select the cull layer @@ -1458,17 +1588,18 @@ void LRoomManager::rooms_release() rooms_set_active(false); // unregister all the dobs - for (int n=0; n(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 return false; + } + + LDob &dob = m_DobList.GetDob(m_DOB_id_camera); + pCamera = Object::cast_to(dob.GetSpatial()); // camera not a camera?? shouldn't happen but we'll check if (!pCamera) return false; + //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(m_DOB_id_camera, pCamera->get_global_transform().origin); + + //dob_update(pCamera); + + // Which room is the camera currently in? - LRoom * pRoom = GetRoomFromDOB(pCamera); + LRoom * pRoom = GetRoom(dob.m_iRoomID); if (!pRoom) { @@ -2073,21 +2215,21 @@ void LRoomManager::_bind_methods() // 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 - ClassDB::bind_method(D_METHOD("dob_register", "dob", "radius"), &LRoomManager::dob_register); - ClassDB::bind_method(D_METHOD("dob_unregister", "dob"), &LRoomManager::dob_unregister); - ClassDB::bind_method(D_METHOD("dob_update", "dob"), &LRoomManager::dob_update); - ClassDB::bind_method(D_METHOD("dob_teleport", "dob"), &LRoomManager::dob_teleport); + ClassDB::bind_method(D_METHOD("dob_register", "node", "pos", "radius"), &LRoomManager::dob_register); + ClassDB::bind_method(D_METHOD("dob_unregister", "dob_id"), &LRoomManager::dob_unregister); + ClassDB::bind_method(D_METHOD("dob_update", "dob_id", "pos"), &LRoomManager::dob_update); +// ClassDB::bind_method(D_METHOD("dob_teleport", "dob"), &LRoomManager::dob_teleport); - ClassDB::bind_method(D_METHOD("dob_register_hint", "dob", "radius", "room"), &LRoomManager::dob_register_hint); - ClassDB::bind_method(D_METHOD("dob_teleport_hint", "dob", "room"), &LRoomManager::dob_teleport_hint); +// ClassDB::bind_method(D_METHOD("dob_register_hint", "dob", "radius", "room"), &LRoomManager::dob_register_hint); +// ClassDB::bind_method(D_METHOD("dob_teleport_hint", "dob", "room"), &LRoomManager::dob_teleport_hint); ClassDB::bind_method(D_METHOD("dob_get_room_id", "dob"), &LRoomManager::dob_get_room_id); - ClassDB::bind_method(D_METHOD("light_register", "light", "area"), &LRoomManager::light_register); + ClassDB::bind_method(D_METHOD("global_light_register", "light", "area"), &LRoomManager::global_light_register); ClassDB::bind_method(D_METHOD("dynamic_light_register", "light", "radius"), &LRoomManager::dynamic_light_register); - ClassDB::bind_method(D_METHOD("dynamic_light_register_hint", "light", "radius", "room"), &LRoomManager::dynamic_light_register_hint); +// ClassDB::bind_method(D_METHOD("dynamic_light_register_hint", "light", "radius", "room"), &LRoomManager::dynamic_light_register_hint); ClassDB::bind_method(D_METHOD("dynamic_light_unregister", "light"), &LRoomManager::dynamic_light_unregister); ClassDB::bind_method(D_METHOD("dynamic_light_update", "light"), &LRoomManager::dynamic_light_update); @@ -2261,3 +2403,35 @@ void LRoomManager::rooms_set_debug_frame_string(bool bActive) { m_bDebugFrameString = bActive; } + + + +//void LRoomManager::DobsAutoUpdate() +//{ +// // go through each room, each dob +// for (int n=0; n &planes) void LTrace::CullDOBs(LRoom &room, const LVector &planes) { // NYI this isn't efficient, there may be more than 1 portal to the same room - +/* // cull DOBs int nDOBs = room.m_DOBs.size(); @@ -145,7 +145,7 @@ void LTrace::CullDOBs(LRoom &room, const LVector &planes) } } } // for through dobs - +*/ } @@ -601,6 +601,8 @@ void LTrace::FirstTouch(LRoom &room) // m_pVisible_Rooms->push_back(room.m_RoomID); // hide all dobs + /* for (int n=0; n