Fix memory leak when multiple documents in 3D edit. Support multiple physics engine per document.

loadfix
cc9cii 10 years ago
parent 03abd69b4f
commit f051fb65ff

@ -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…
Cancel
Save