1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-21 12:23:53 +00:00

Fix deleting objects and scenewidgets.

This commit is contained in:
cc9cii 2014-11-01 07:29:16 +11:00
parent ade7f09203
commit d6e67b248f
4 changed files with 63 additions and 14 deletions

View file

@ -66,7 +66,7 @@ namespace CSVRender
mOverlaySystem = OverlaySystem::instance().get(); mOverlaySystem = OverlaySystem::instance().get();
mSceneMgr->addRenderQueueListener(mOverlaySystem); mSceneMgr->addRenderQueueListener(mOverlaySystem);
CSVWorld::PhysicsSystem::instance()->addSceneManager(mSceneMgr, this); CSVWorld::PhysicsSystem::instance()->addSceneManager(mSceneMgr);
QTimer *timer = new QTimer (this); QTimer *timer = new QTimer (this);
@ -166,6 +166,8 @@ namespace CSVRender
SceneWidget::~SceneWidget() SceneWidget::~SceneWidget()
{ {
CSVWorld::PhysicsSystem::instance()->removeSceneManager(mSceneMgr);
if (mWindow) if (mWindow)
Ogre::Root::getSingleton().destroyRenderTarget (mWindow); Ogre::Root::getSingleton().destroyRenderTarget (mWindow);

View file

@ -916,8 +916,7 @@ void CSVRender::WorldspaceWidget::placeObject(const std::string sceneNode, const
// FIXME: adjustRigidBody() seems to lose objects, work around by deleting and recreating objects // FIXME: adjustRigidBody() seems to lose objects, work around by deleting and recreating objects
//CSVWorld::PhysicsSystem::instance()->moveObject(sceneNode, pos, xr*yr*zr); //CSVWorld::PhysicsSystem::instance()->moveObject(sceneNode, pos, xr*yr*zr);
std::string mesh = CSVWorld::PhysicsSystem::instance()->sceneNodeToMesh(sceneNode); std::string mesh = CSVWorld::PhysicsSystem::instance()->sceneNodeToMesh(sceneNode);
CSVWorld::PhysicsSystem::instance()->removeObject(sceneNode); CSVWorld::PhysicsSystem::instance()->replaceObject(mesh, sceneNode, refId, cellref.mScale, pos, xr*yr*zr);
CSVWorld::PhysicsSystem::instance()->addObject(mesh, sceneNode, refId, cellref.mScale, pos, xr*yr*zr);
// update all SceneWidgets and their SceneManagers // update all SceneWidgets and their SceneManagers
emit signalAsModified(); emit signalAsModified();

View file

@ -65,7 +65,6 @@ namespace CSVWorld
// update physics, only one physics model per referenceId // update physics, only one physics model per referenceId
if(mEngine->getRigidBody(referenceId, true) == NULL) if(mEngine->getRigidBody(referenceId, true) == NULL)
{ {
mEngine->createAndAdjustRigidBody(mesh, mEngine->createAndAdjustRigidBody(mesh,
referenceId, scale, position, rotation, referenceId, scale, position, rotation,
0, // scaledBoxTranslation 0, // scaledBoxTranslation
@ -74,27 +73,32 @@ namespace CSVWorld
placeable); placeable);
// update other scene managers if they have the referenceId (may have moved) // update other scene managers if they have the referenceId (may have moved)
// FIXME: this bit not needed if object has not moved
iter = mSceneManagers.begin(); iter = mSceneManagers.begin();
for(; iter != mSceneManagers.end(); ++iter) for(; iter != mSceneManagers.end(); ++iter)
{ {
std::string name = refIdToSceneNode(referenceId, *iter); std::string name = refIdToSceneNode(referenceId, *iter);
if(name != sceneNodeName && (*iter)->hasSceneNode(name)) if(name != sceneNodeName && (*iter)->hasSceneNode(name))
{ {
// FIXME: rotation or scale not updated // FIXME: rotation or scale not updated
(*iter)->getSceneNode(name)->setPosition(position); (*iter)->getSceneNode(name)->setPosition(position);
} }
} }
} }
} }
void PhysicsSystem::removeObject(const std::string &sceneNodeName) // normal delete (e.g closing a scene subview)
// TODO: should think about using some kind of reference counting within RigidBody
void PhysicsSystem::removeObject(const std::string &sceneNodeName, bool force)
{ {
std::string referenceId = sceneNodeToRefId(sceneNodeName); std::string referenceId = mSceneNodeToRefId[sceneNodeName];
if(referenceId != "") if(referenceId != "")
{ {
mEngine->removeRigidBody(referenceId); mSceneNodeToRefId.erase(sceneNodeName);
mEngine->deleteRigidBody(referenceId); mSceneNodeToMesh.erase(sceneNodeName);
// find which SceneManager has this object
Ogre::SceneManager *sceneManager = NULL; Ogre::SceneManager *sceneManager = NULL;
std::list<Ogre::SceneManager *>::const_iterator iter = mSceneManagers.begin(); std::list<Ogre::SceneManager *>::const_iterator iter = mSceneManagers.begin();
for(; iter != mSceneManagers.end(); ++iter) for(; iter != mSceneManagers.end(); ++iter)
@ -109,6 +113,17 @@ namespace CSVWorld
if(!sceneManager) if(!sceneManager)
return; // FIXME: maybe this should be an exception return; // FIXME: maybe this should be an exception
// illustration: erase the object "K" from the object map
//
// RidigBody SubView Ogre
// --------------- -------------- -------------
// ReferenceId "A" (SceneManager X SceneNode "J")
// (SceneManager Y SceneNode "K") <--- erase
// (SceneManager Z SceneNode "L")
//
// ReferenceId "B" (SceneManager X SceneNode "M")
// (SceneManager Y SceneNode "N") <--- notice not deleted
// (SceneManager Z SceneNode "O")
std::map<std::string, std::map<Ogre::SceneManager *, std::string> >::iterator itRef = std::map<std::string, std::map<Ogre::SceneManager *, std::string> >::iterator itRef =
mRefIdToSceneNode.begin(); mRefIdToSceneNode.begin();
for(; itRef != mRefIdToSceneNode.end(); ++itRef) for(; itRef != mRefIdToSceneNode.end(); ++itRef)
@ -116,12 +131,27 @@ namespace CSVWorld
if((*itRef).second.find(sceneManager) != (*itRef).second.end()) if((*itRef).second.find(sceneManager) != (*itRef).second.end())
{ {
(*itRef).second.erase(sceneManager); (*itRef).second.erase(sceneManager);
return; break;
} }
} }
// should the physics model be deleted?
if(force || mRefIdToSceneNode.find(referenceId) == mRefIdToSceneNode.end())
{
mEngine->removeRigidBody(referenceId);
mEngine->deleteRigidBody(referenceId);
}
} }
} }
void PhysicsSystem::replaceObject(const std::string &mesh,
const std::string &sceneNodeName, const std::string &referenceId, float scale,
const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, bool placeable)
{
removeObject(sceneNodeName, true); // force delete
addObject(mesh, sceneNodeName, referenceId, scale, position, rotation, placeable);
}
void PhysicsSystem::moveObject(const std::string &sceneNodeName, void PhysicsSystem::moveObject(const std::string &sceneNodeName,
const Ogre::Vector3 &position, const Ogre::Quaternion &rotation) const Ogre::Vector3 &position, const Ogre::Quaternion &rotation)
{ {
@ -228,11 +258,24 @@ namespace CSVWorld
return mSceneNodeToMesh[sceneNodeName]; return mSceneNodeToMesh[sceneNodeName];
} }
void PhysicsSystem::addSceneManager(Ogre::SceneManager *sceneMgr, CSVRender::SceneWidget * scene) void PhysicsSystem::addSceneManager(Ogre::SceneManager *sceneMgr)
{ {
mSceneManagers.push_back(sceneMgr); mSceneManagers.push_back(sceneMgr);
} }
void PhysicsSystem::removeSceneManager(Ogre::SceneManager *sceneMgr)
{
std::list<Ogre::SceneManager *>::iterator iter = mSceneManagers.begin();
for(; iter != mSceneManagers.end(); ++iter)
{
if(*iter == sceneMgr)
{
mSceneManagers.erase(iter);
break;
}
}
}
void PhysicsSystem::toggleDebugRendering(Ogre::SceneManager *sceneMgr) void PhysicsSystem::toggleDebugRendering(Ogre::SceneManager *sceneMgr)
{ {
// FIXME: should check if sceneMgr is in the list // FIXME: should check if sceneMgr is in the list

View file

@ -35,7 +35,6 @@ namespace CSVWorld
std::map<std::string, std::map<Ogre::SceneManager *, std::string> > mRefIdToSceneNode; std::map<std::string, std::map<Ogre::SceneManager *, std::string> > mRefIdToSceneNode;
std::map<std::string, std::string> mSceneNodeToMesh; std::map<std::string, std::string> mSceneNodeToMesh;
std::list<Ogre::SceneManager *> mSceneManagers; // FIXME: change to list per OEngine std::list<Ogre::SceneManager *> mSceneManagers; // FIXME: change to list per OEngine
std::list<CSVRender::SceneWidget *> mSceneWidgets; // FIXME: change to list per OEngine
OEngine::Physic::PhysicEngine* mEngine; OEngine::Physic::PhysicEngine* mEngine;
std::multimap<std::string, Ogre::SceneManager *> mTerrain; std::multimap<std::string, Ogre::SceneManager *> mTerrain;
@ -46,14 +45,20 @@ namespace CSVWorld
static PhysicsSystem *instance(); static PhysicsSystem *instance();
void addSceneManager(Ogre::SceneManager *sceneMgr, CSVRender::SceneWidget * scene); void addSceneManager(Ogre::SceneManager *sceneMgr);
void removeSceneManager(Ogre::SceneManager *sceneMgr);
void addObject(const std::string &mesh, void addObject(const std::string &mesh,
const std::string &sceneNodeName, const std::string &referenceId, float scale, const std::string &sceneNodeName, const std::string &referenceId, float scale,
const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation,
bool placeable=false); bool placeable=false);
void removeObject(const std::string &sceneNodeName); void removeObject(const std::string &sceneNodeName, bool force = false);
void replaceObject(const std::string &mesh,
const std::string &sceneNodeName, const std::string &referenceId, float scale,
const Ogre::Vector3 &position, const Ogre::Quaternion &rotation,
bool placeable=false);
void moveObject(const std::string &sceneNodeName, void moveObject(const std::string &sceneNodeName,
const Ogre::Vector3 &position, const Ogre::Quaternion &rotation); const Ogre::Vector3 &position, const Ogre::Quaternion &rotation);