mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-10-31 13:26:43 +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(); | ||||
|         mSceneMgr->addRenderQueueListener(mOverlaySystem); | ||||
| 
 | ||||
|         CSVWorld::PhysicsSystem::instance()->addSceneManager(mSceneMgr, this); | ||||
|         CSVWorld::PhysicsSystem::instance()->addSceneManager(mSceneMgr); | ||||
| 
 | ||||
|         QTimer *timer = new QTimer (this); | ||||
| 
 | ||||
|  | @ -166,6 +166,8 @@ namespace CSVRender | |||
| 
 | ||||
|     SceneWidget::~SceneWidget() | ||||
|     { | ||||
|         CSVWorld::PhysicsSystem::instance()->removeSceneManager(mSceneMgr); | ||||
| 
 | ||||
|         if (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
 | ||||
|     //CSVWorld::PhysicsSystem::instance()->moveObject(sceneNode, pos, xr*yr*zr);
 | ||||
|     std::string mesh = CSVWorld::PhysicsSystem::instance()->sceneNodeToMesh(sceneNode); | ||||
|     CSVWorld::PhysicsSystem::instance()->removeObject(sceneNode); | ||||
|     CSVWorld::PhysicsSystem::instance()->addObject(mesh, sceneNode, refId, cellref.mScale, pos, xr*yr*zr); | ||||
|     CSVWorld::PhysicsSystem::instance()->replaceObject(mesh, sceneNode, refId, cellref.mScale, pos, xr*yr*zr); | ||||
| 
 | ||||
|     // update all SceneWidgets and their SceneManagers
 | ||||
|     emit signalAsModified(); | ||||
|  |  | |||
|  | @ -65,7 +65,6 @@ namespace CSVWorld | |||
|         // update physics, only one physics model per referenceId
 | ||||
|         if(mEngine->getRigidBody(referenceId, true) == NULL) | ||||
|         { | ||||
| 
 | ||||
|             mEngine->createAndAdjustRigidBody(mesh, | ||||
|                     referenceId, scale, position, rotation, | ||||
|                     0,    // scaledBoxTranslation
 | ||||
|  | @ -74,27 +73,32 @@ namespace CSVWorld | |||
|                     placeable); | ||||
| 
 | ||||
|             // 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(); | ||||
|             for(; iter != mSceneManagers.end(); ++iter) | ||||
|             { | ||||
|                 std::string name = refIdToSceneNode(referenceId, *iter); | ||||
|                 if(name != sceneNodeName && (*iter)->hasSceneNode(name)) | ||||
|                 { | ||||
|                     // FIXME: rotation or scale not updated
 | ||||
|                         // FIXME: rotation or scale not updated
 | ||||
|                     (*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 != "") | ||||
|         { | ||||
|             mEngine->removeRigidBody(referenceId); | ||||
|             mEngine->deleteRigidBody(referenceId); | ||||
|             mSceneNodeToRefId.erase(sceneNodeName); | ||||
|             mSceneNodeToMesh.erase(sceneNodeName); | ||||
| 
 | ||||
|             // find which SceneManager has this object
 | ||||
|             Ogre::SceneManager *sceneManager = NULL; | ||||
|             std::list<Ogre::SceneManager *>::const_iterator iter = mSceneManagers.begin(); | ||||
|             for(; iter != mSceneManagers.end(); ++iter) | ||||
|  | @ -109,6 +113,17 @@ namespace CSVWorld | |||
|             if(!sceneManager) | ||||
|                 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 = | ||||
|                 mRefIdToSceneNode.begin(); | ||||
|             for(; itRef != mRefIdToSceneNode.end(); ++itRef) | ||||
|  | @ -116,12 +131,27 @@ namespace CSVWorld | |||
|                 if((*itRef).second.find(sceneManager) != (*itRef).second.end()) | ||||
|                 { | ||||
|                     (*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, | ||||
|             const Ogre::Vector3 &position, const Ogre::Quaternion &rotation) | ||||
|     { | ||||
|  | @ -228,11 +258,24 @@ namespace CSVWorld | |||
|         return mSceneNodeToMesh[sceneNodeName]; | ||||
|     } | ||||
| 
 | ||||
|     void PhysicsSystem::addSceneManager(Ogre::SceneManager *sceneMgr, CSVRender::SceneWidget * scene) | ||||
|     void PhysicsSystem::addSceneManager(Ogre::SceneManager *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) | ||||
|     { | ||||
|         // 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::string> mSceneNodeToMesh; | ||||
|             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; | ||||
|             std::multimap<std::string, Ogre::SceneManager *> mTerrain; | ||||
| 
 | ||||
|  | @ -46,14 +45,20 @@ namespace CSVWorld | |||
| 
 | ||||
|             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, | ||||
|                     const std::string &sceneNodeName, const std::string &referenceId, float scale, | ||||
|                     const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, | ||||
|                     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, | ||||
|                     const Ogre::Vector3 &position, const Ogre::Quaternion &rotation); | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue