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:
parent
ade7f09203
commit
d6e67b248f
4 changed files with 63 additions and 14 deletions
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue