From 07abb9dee2aba5ed161c22f3ec45031f9fdb183a Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Fri, 1 May 2009 20:34:23 +0000 Subject: [PATCH] BGE performance: - Vast performance increase when removing scene containing large number of objects: the sensor/controller map was updated for each deleted object, causing massive slow down when the number of objects was large (O(n^2)). - Use reference when scanning the sensor map => avoid useless copy. - Remove dynamically the object bounding box from the DBVT when the object is invisible => faster culling. --- .../gameengine/GameLogic/SCA_LogicManager.cpp | 29 +++++++++++++------ .../gameengine/GameLogic/SCA_LogicManager.h | 8 +++-- source/gameengine/Ketsji/KX_GameObject.cpp | 2 ++ source/gameengine/Ketsji/KX_KetsjiEngine.h | 4 +-- source/gameengine/Ketsji/KX_Scene.cpp | 2 ++ 5 files changed, 32 insertions(+), 13 deletions(-) diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp index b584b37180f..0b549ded474 100644 --- a/source/gameengine/GameLogic/SCA_LogicManager.cpp +++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp @@ -79,6 +79,13 @@ SCA_LogicManager::~SCA_LogicManager() m_activeActuators.clear(); } +// this function is a performance helper when the scene is destoyed +// without it, the map updated for each object... a massive slow down when there are +// large number of objects. By clearing the map upfront we avoid the waster of time. +void SCA_LogicManager::RemoveSensorMap() +{ + m_sensorcontrollermapje.clear(); +} /* // this kind of fixes bug 398 but breakes games, so better leave it out for now. @@ -171,12 +178,16 @@ void* SCA_LogicManager::FindBlendObjByGameMeshName(const STR_String& gamemeshnam void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor) { - controllerlist contlist = m_sensorcontrollermapje[sensor]; - for (controllerlist::const_iterator c= contlist.begin();!(c==contlist.end());c++) + sensormap_t::const_iterator mit = m_sensorcontrollermapje.find(sensor); + if (mit != m_sensorcontrollermapje.end()) { - (*c)->UnlinkSensor(sensor); + const controllerlist& contlist = mit->second; + for (controllerlist::const_iterator c= contlist.begin();!(c==contlist.end());c++) + { + (*c)->UnlinkSensor(sensor); + } + m_sensorcontrollermapje.erase(sensor); } - m_sensorcontrollermapje.erase(sensor); sensor->UnregisterToManager(); } @@ -184,7 +195,7 @@ void SCA_LogicManager::RemoveController(SCA_IController* controller) { controller->UnlinkAllSensors(); controller->UnlinkAllActuators(); - std::map::iterator sit; + sensormap_t::iterator sit; for (sit = m_sensorcontrollermapje.begin();!(sit==m_sensorcontrollermapje.end());++sit) { (*sit).second.remove(controller); @@ -197,10 +208,10 @@ void SCA_LogicManager::RemoveDestroyedActuator(SCA_IActuator* actuator) m_removedActuators.push_back(SmartActuatorPtr(actuator,0)); // take care that no controller can use this actuator again ! - std::map::const_iterator sit; + sensormap_t::const_iterator sit; for (sit = m_sensorcontrollermapje.begin();!(sit==m_sensorcontrollermapje.end());++sit) { - controllerlist contlist = (*sit).second; + const controllerlist& contlist = sit->second; for (list::const_iterator c= contlist.begin();!(c==contlist.end());c++) { (*c)->UnlinkActuator(actuator); @@ -237,8 +248,8 @@ void SCA_LogicManager::BeginFrame(double curtime, double fixedtime) !(is==m_activatedsensors.end());is++) { SCA_ISensor* sensor = *is; - controllerlist contlist = m_sensorcontrollermapje[sensor]; - for (list::const_iterator c= contlist.begin(); + const controllerlist& contlist = m_sensorcontrollermapje[sensor]; + for (list::const_iterator c= contlist.begin(); !(c==contlist.end());c++) { SCA_IController* contr = *c;//controllerarray->at(c); diff --git a/source/gameengine/GameLogic/SCA_LogicManager.h b/source/gameengine/GameLogic/SCA_LogicManager.h index 50383879d8f..17971c219e5 100644 --- a/source/gameengine/GameLogic/SCA_LogicManager.h +++ b/source/gameengine/GameLogic/SCA_LogicManager.h @@ -47,7 +47,8 @@ #include "KX_HashedPtr.h" using namespace std; -typedef list controllerlist; +typedef std::list controllerlist; +typedef std::map sensormap_t; /** * This manager handles sensor, controllers and actuators. @@ -101,7 +102,7 @@ class SCA_LogicManager set m_activeActuators; set m_triggeredControllerSet; - map m_sensorcontrollermapje; + sensormap_t m_sensorcontrollermapje; // need to find better way for this // also known as FactoryManager... @@ -116,6 +117,9 @@ class SCA_LogicManager public: SCA_LogicManager(); virtual ~SCA_LogicManager(); + // can ONLY be used during scene destruction, avoid massive slow down when scene has many many objects + void RemoveSensorMap(); + //void SetKeyboardManager(SCA_KeyboardManager* keyboardmgr) { m_keyboardmgr=keyboardmgr;} void RegisterEventManager(SCA_EventManager* eventmgr); void RegisterToSensor(SCA_IController* controller, diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index fa95a89135b..22b9c940178 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -628,6 +628,8 @@ KX_GameObject::SetVisible( { if (GetSGNode()) { m_bVisible = v; + if (m_pGraphicController) + m_pGraphicController->Activate(m_bVisible); if (recursive) setVisible_recursive(GetSGNode(), v); } diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 791c5d24daa..528465b6c2c 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -287,11 +287,11 @@ public: /** * Gets the maximum number of logic frame before render frame */ - static int KX_KetsjiEngine::GetMaxLogicFrame(); + static int GetMaxLogicFrame(); /** * Sets the maximum number of logic frame before render frame */ - static void KX_KetsjiEngine::SetMaxLogicFrame(int frame); + static void SetMaxLogicFrame(int frame); /** * Gets the framerate for playing animations. (actions and ipos) diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 36486440c00..171ed5d130f 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -208,6 +208,8 @@ KX_Scene::~KX_Scene() // It's still there but we remove all properties here otherwise some // reference might be hanging and causing late release of objects RemoveAllDebugProperties(); + // early removal of sensor map to avoid massive slow down when there are many objects + m_logicmgr->RemoveSensorMap(); while (GetRootParentList()->GetCount() > 0) {