forked from teamnwah/openmw-tes3coop
		
	Fix memory leak when multiple documents in 3D edit. Support multiple physics engine per document.
This commit is contained in:
		
							parent
							
								
									03abd69b4f
								
							
						
					
					
						commit
						f051fb65ff
					
				
					 7 changed files with 106 additions and 18 deletions
				
			
		|  | @ -2,7 +2,6 @@ | |||
| 
 | ||||
| #include <iostream> | ||||
| 
 | ||||
| #include <OgreRoot.h> | ||||
| #include <openengine/bullet/BulletShapeLoader.h> | ||||
| 
 | ||||
| #include "../render/worldspacewidget.hpp" | ||||
|  | @ -58,15 +57,9 @@ namespace CSVWorld | |||
|             mSceneWidgets.erase(it); | ||||
|         } | ||||
| 
 | ||||
|         // cleanup global resources
 | ||||
|         // cleanup global resources used by OEngine
 | ||||
|         if(mPhysics.empty()) | ||||
|         { | ||||
|             // delete the extra resources created in removeDebugDraw
 | ||||
|             if (Ogre::MaterialManager::getSingleton().resourceExists("BtOgre/DebugLines")) | ||||
|                 Ogre::MaterialManager::getSingleton().remove("BtOgre/DebugLines"); | ||||
|             if (Ogre::ResourceGroupManager::getSingleton().resourceGroupExists("BtOgre")) | ||||
|                 Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup("BtOgre"); | ||||
| 
 | ||||
|             delete OEngine::Physic::BulletShapeManager::getSingletonPtr(); | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ | |||
| #include <OgreCamera.h> | ||||
| #include <OgreSceneManager.h> | ||||
| 
 | ||||
| #include "physicsengine.hpp" | ||||
| #include <openengine/bullet/physic.hpp> | ||||
| #include <components/nifbullet/bulletnifloader.hpp> | ||||
| #include "../../model/settings/usersettings.hpp" | ||||
| #include "../render/elements.hpp" | ||||
|  | @ -15,7 +15,9 @@ namespace CSVWorld | |||
| { | ||||
|     PhysicsSystem::PhysicsSystem() | ||||
|     { | ||||
|         mEngine = new PhysicsEngine(); | ||||
|         // Create physics. shapeLoader is deleted by the physic engine
 | ||||
|         NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader(); | ||||
|         mEngine = new OEngine::Physic::PhysicEngine(shapeLoader); | ||||
|     } | ||||
| 
 | ||||
|     PhysicsSystem::~PhysicsSystem() | ||||
|  | @ -51,6 +53,8 @@ namespace CSVWorld | |||
|         { | ||||
|             mEngine->createAndAdjustRigidBody(mesh, | ||||
|                     referenceId, scale, position, rotation, | ||||
|                     0,    // scaledBoxTranslation
 | ||||
|                     0,    // boxRotation
 | ||||
|                     true, // raycasting
 | ||||
|                     placeable); | ||||
|         } | ||||
|  | @ -139,7 +143,7 @@ namespace CSVWorld | |||
| 
 | ||||
|             // create a new physics object
 | ||||
|             mEngine->createAndAdjustRigidBody(mesh, referenceId, scale, position, rotation, | ||||
|                     true, placeable); | ||||
|                     0, 0, true, placeable); | ||||
| 
 | ||||
|             // update other scene managers if they have the referenceId
 | ||||
|             // FIXME: rotation or scale not updated
 | ||||
|  |  | |||
|  | @ -12,6 +12,14 @@ namespace Ogre | |||
|     class Camera; | ||||
| } | ||||
| 
 | ||||
| namespace OEngine | ||||
| { | ||||
|     namespace Physic | ||||
|     { | ||||
|         class PhysicEngine; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| namespace CSVRender | ||||
| { | ||||
|     class SceneWidget; | ||||
|  | @ -19,15 +27,13 @@ namespace CSVRender | |||
| 
 | ||||
| namespace CSVWorld | ||||
| { | ||||
|     class PhysicsEngine; | ||||
| 
 | ||||
|     class PhysicsSystem | ||||
|     { | ||||
|             std::map<std::string, std::string> mSceneNodeToRefId; | ||||
|             std::map<std::string, std::map<Ogre::SceneManager *, std::string> > mRefIdToSceneNode; | ||||
|             std::map<std::string, std::string> mSceneNodeToMesh; | ||||
|             std::map<Ogre::SceneManager*, CSVRender::SceneWidget *> mSceneWidgets; | ||||
|             PhysicsEngine* mEngine; | ||||
|             OEngine::Physic::PhysicEngine* mEngine; | ||||
|             std::multimap<std::string, Ogre::SceneManager *> mTerrain; | ||||
| 
 | ||||
|         public: | ||||
|  |  | |||
|  | @ -14,6 +14,7 @@ | |||
| #include <openengine/bullet/physic.hpp> | ||||
| #include <openengine/bullet/BtOgreExtras.h> | ||||
| #include <openengine/ogre/renderer.hpp> | ||||
| #include <openengine/bullet/BulletShapeLoader.h> | ||||
| 
 | ||||
| #include <components/nifbullet/bulletnifloader.hpp> | ||||
| 
 | ||||
|  | @ -498,6 +499,7 @@ namespace MWWorld | |||
|         if (mWaterCollisionObject.get()) | ||||
|             mEngine->mDynamicsWorld->removeCollisionObject(mWaterCollisionObject.get()); | ||||
|         delete mEngine; | ||||
|         delete OEngine::Physic::BulletShapeManager::getSingletonPtr(); | ||||
|     } | ||||
| 
 | ||||
|     OEngine::Physic::PhysicEngine* PhysicsSystem::getEngine() | ||||
|  |  | |||
|  | @ -212,8 +212,10 @@ public: | |||
| 
 | ||||
|     ~DebugDrawer() | ||||
|     { | ||||
|                 Ogre::MaterialManager::getSingleton().remove("BtOgre/DebugLines"); | ||||
|                 Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup("BtOgre"); | ||||
|         if (Ogre::MaterialManager::getSingleton().resourceExists("BtOgre/DebugLines")) | ||||
|             Ogre::MaterialManager::getSingleton().remove("BtOgre/DebugLines"); | ||||
|         if (Ogre::ResourceGroupManager::getSingleton().resourceGroupExists("BtOgre")) | ||||
|             Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup("BtOgre"); | ||||
|         delete mLineDrawer; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -114,7 +114,7 @@ namespace Physic | |||
|         { | ||||
|             mEngine->mDynamicsWorld->removeRigidBody(mBody); | ||||
|             delete mBody; | ||||
|         }   | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void PhysicActor::enableCollisionMode(bool collision) | ||||
|  | @ -356,7 +356,8 @@ namespace Physic | |||
|         delete broadphase; | ||||
|         delete mShapeLoader; | ||||
| 
 | ||||
|         delete BulletShapeManager::getSingletonPtr(); | ||||
|         // Moved the cleanup to mwworld/physicssystem
 | ||||
|         //delete BulletShapeManager::getSingletonPtr();
 | ||||
|     } | ||||
| 
 | ||||
|     void PhysicEngine::addHeightField(float* heights, | ||||
|  | @ -863,5 +864,76 @@ namespace Physic | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     int PhysicEngine::toggleDebugRendering(Ogre::SceneManager *sceneMgr) | ||||
|     { | ||||
|         if(!sceneMgr) | ||||
|             return 0; | ||||
| 
 | ||||
|         std::map<Ogre::SceneManager *, BtOgre::DebugDrawer *>::iterator iter = | ||||
|             mDebugDrawers.find(sceneMgr); | ||||
|         if(iter != mDebugDrawers.end()) // found scene manager
 | ||||
|         { | ||||
|             if((*iter).second) | ||||
|             { | ||||
|                 // set a new drawer each time (maybe with a different scene manager)
 | ||||
|                 mDynamicsWorld->setDebugDrawer(mDebugDrawers[sceneMgr]); | ||||
|                 if(!mDebugDrawers[sceneMgr]->getDebugMode()) | ||||
|                     mDebugDrawers[sceneMgr]->setDebugMode(1 /*mDebugDrawFlags*/); | ||||
|                 else | ||||
|                     mDebugDrawers[sceneMgr]->setDebugMode(0); | ||||
|                 mDynamicsWorld->debugDrawWorld(); | ||||
| 
 | ||||
|                 return mDebugDrawers[sceneMgr]->getDebugMode(); | ||||
|             } | ||||
|         } | ||||
|         return 0; | ||||
|     } | ||||
| 
 | ||||
|     void PhysicEngine::stepDebug(Ogre::SceneManager *sceneMgr) | ||||
|     { | ||||
|         if(!sceneMgr) | ||||
|             return; | ||||
| 
 | ||||
|         std::map<Ogre::SceneManager *, BtOgre::DebugDrawer *>::iterator iter = | ||||
|             mDebugDrawers.find(sceneMgr); | ||||
|         if(iter != mDebugDrawers.end()) // found scene manager
 | ||||
|         { | ||||
|             if((*iter).second) | ||||
|                 (*iter).second->step(); | ||||
|             else | ||||
|                 return; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void PhysicEngine::createDebugDraw(Ogre::SceneManager *sceneMgr) | ||||
|     { | ||||
|         if(mDebugDrawers.find(sceneMgr) == mDebugDrawers.end()) | ||||
|         { | ||||
|             mDebugSceneNodes[sceneMgr] = sceneMgr->getRootSceneNode()->createChildSceneNode(); | ||||
|             mDebugDrawers[sceneMgr] = new BtOgre::DebugDrawer(mDebugSceneNodes[sceneMgr], mDynamicsWorld); | ||||
|             mDebugDrawers[sceneMgr]->setDebugMode(0); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void PhysicEngine::removeDebugDraw(Ogre::SceneManager *sceneMgr) | ||||
|     { | ||||
|         std::map<Ogre::SceneManager *, BtOgre::DebugDrawer *>::iterator iter = | ||||
|             mDebugDrawers.find(sceneMgr); | ||||
|         if(iter != mDebugDrawers.end()) | ||||
|         { | ||||
|             delete (*iter).second; | ||||
|             mDebugDrawers.erase(iter); | ||||
|         } | ||||
| 
 | ||||
|         std::map<Ogre::SceneManager *, Ogre::SceneNode *>::iterator it = | ||||
|             mDebugSceneNodes.find(sceneMgr); | ||||
|         if(it != mDebugSceneNodes.end()) | ||||
|         { | ||||
|             std::string sceneNodeName = (*it).second->getName(); | ||||
|             if(sceneMgr->hasSceneNode(sceneNodeName)) | ||||
|                 sceneMgr->destroySceneNode(sceneNodeName); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -348,6 +348,15 @@ namespace Physic | |||
|         bool isDebugCreated; | ||||
|         bool mDebugActive; | ||||
| 
 | ||||
|         // for OpenCS with multiple engines per document
 | ||||
|         std::map<Ogre::SceneManager *, BtOgre::DebugDrawer *> mDebugDrawers; | ||||
|         std::map<Ogre::SceneManager *, Ogre::SceneNode *> mDebugSceneNodes; | ||||
| 
 | ||||
|         int toggleDebugRendering(Ogre::SceneManager *sceneMgr); | ||||
|         void stepDebug(Ogre::SceneManager *sceneMgr); | ||||
|         void createDebugDraw(Ogre::SceneManager *sceneMgr); | ||||
|         void removeDebugDraw(Ogre::SceneManager *sceneMgr); | ||||
| 
 | ||||
|     private: | ||||
|         PhysicEngine(const PhysicEngine&); | ||||
|         PhysicEngine& operator=(const PhysicEngine&); | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue