mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 20:26:43 +00:00 
			
		
		
		
	Allow multiple scene managers per physics engine. Compiles but does not work properly.
This commit is contained in:
		
							parent
							
								
									0515159b74
								
							
						
					
					
						commit
						a2ac4c7650
					
				
					 4 changed files with 66 additions and 29 deletions
				
			
		|  | @ -66,7 +66,7 @@ namespace CSVRender | |||
|         mOverlaySystem = OverlaySystem::instance().get(); | ||||
|         mSceneMgr->addRenderQueueListener(mOverlaySystem); | ||||
| 
 | ||||
|         CSVWorld::PhysicsSystem::instance()->setSceneManager(mSceneMgr); | ||||
|         CSVWorld::PhysicsSystem::instance()->addSceneManager(mSceneMgr); | ||||
| 
 | ||||
|         QTimer *timer = new QTimer (this); | ||||
| 
 | ||||
|  |  | |||
|  | @ -716,8 +716,8 @@ void CSVRender::WorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event) | |||
|             // debug drawer.  Hence only the first subview that creates the debug drawer
 | ||||
|             // can view the debug lines.  Will need to keep a map in OEngine if multiple
 | ||||
|             // subviews are to be supported.
 | ||||
|             CSVWorld::PhysicsSystem::instance()->setSceneManager(getSceneManager()); | ||||
|             CSVWorld::PhysicsSystem::instance()->toggleDebugRendering(); | ||||
|             //CSVWorld::PhysicsSystem::instance()->setSceneManager(getSceneManager());
 | ||||
|             CSVWorld::PhysicsSystem::instance()->toggleDebugRendering(getSceneManager()); | ||||
|             flagAsModified(); | ||||
|         } | ||||
|     } | ||||
|  | @ -840,7 +840,7 @@ std::pair<std::string, Ogre::Vector3> CSVRender::WorldspaceWidget::terrainUnderC | |||
|     float y = (float) mouseY / getCamera()->getViewport()->getActualHeight(); | ||||
| 
 | ||||
|     std::pair<std::string, Ogre::Vector3> result = | ||||
|         CSVWorld::PhysicsSystem::instance()->castRay(x, y, NULL, NULL, getCamera()); | ||||
|         CSVWorld::PhysicsSystem::instance()->castRay(x, y, getSceneManager(), getCamera()); | ||||
|     if(result.first != "") | ||||
|     { | ||||
|         // FIXME: is there  a better way to distinguish terrain from objects?
 | ||||
|  | @ -863,7 +863,7 @@ std::pair<std::string, Ogre::Vector3> CSVRender::WorldspaceWidget::objectUnderCu | |||
|     float y = (float) mouseY / getCamera()->getViewport()->getActualHeight(); | ||||
| 
 | ||||
|     std::pair<std::string, Ogre::Vector3> result = | ||||
|         CSVWorld::PhysicsSystem::instance()->castRay(x, y, NULL, NULL, getCamera()); | ||||
|         CSVWorld::PhysicsSystem::instance()->castRay(x, y, getSceneManager(), getCamera()); | ||||
|     if(result.first != "") | ||||
|     { | ||||
|         // NOTE: anything not terrain is assumed to be an object
 | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ namespace CSVWorld | |||
| { | ||||
|     PhysicsSystem *PhysicsSystem::mPhysicsSystemInstance = 0; | ||||
| 
 | ||||
|     PhysicsSystem::PhysicsSystem(Ogre::SceneManager *sceneMgr) : mSceneMgr(sceneMgr) | ||||
|     PhysicsSystem::PhysicsSystem() : mSceneMgr(0) | ||||
|     { | ||||
|         assert(!mPhysicsSystemInstance); | ||||
|         mPhysicsSystemInstance = this; | ||||
|  | @ -36,20 +36,37 @@ namespace CSVWorld | |||
|         return mPhysicsSystemInstance; | ||||
|     } | ||||
| 
 | ||||
|     // FIXME: looks up the scene manager based on the scene node name (highly inefficient)
 | ||||
|     // NOTE: referenceId is assumed to be unique per document
 | ||||
|     // NOTE: searching is done here rather than after rayTest, so slower to load but
 | ||||
|     // faster to find (not verified w/ perf test)
 | ||||
|     void PhysicsSystem::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) | ||||
|     { | ||||
|         // NOTE: referenceId may not be unique when editing multiple documents concurrently
 | ||||
|         mSceneNodeToRefId[sceneNodeName] = referenceId; | ||||
|         mSceneNodeToMesh[sceneNodeName] = mesh; | ||||
|         bool foundSceneManager = false; | ||||
|         std::list<Ogre::SceneManager *>::const_iterator iter = mSceneManagers.begin(); | ||||
|         for(; iter != mSceneManagers.end(); ++iter) | ||||
|         { | ||||
|             if((*iter)->hasSceneNode(sceneNodeName)) | ||||
|             { | ||||
|                 mSceneNodeToRefId[sceneNodeName] = referenceId; | ||||
|                 mRefIdToSceneNode[referenceId][*iter] = sceneNodeName; | ||||
|                 mSceneNodeToMesh[sceneNodeName] = mesh; | ||||
|                 foundSceneManager = true; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         mEngine->createAndAdjustRigidBody(mesh, | ||||
|                 sceneNodeName, scale, position, rotation, | ||||
|                 0,    // scaledBoxTranslation
 | ||||
|                 0,    // boxRotation
 | ||||
|                 true, // raycasting
 | ||||
|                 placeable); | ||||
|         if(foundSceneManager) | ||||
|         { | ||||
|             mEngine->createAndAdjustRigidBody(mesh, | ||||
|                     referenceId, scale, position, rotation, | ||||
|                     0,    // scaledBoxTranslation
 | ||||
|                     0,    // boxRotation
 | ||||
|                     true, // raycasting
 | ||||
|                     placeable); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void PhysicsSystem::removeObject(const std::string &sceneNodeName) | ||||
|  | @ -76,13 +93,21 @@ namespace CSVWorld | |||
|         mEngine->removeHeightField(x, y); | ||||
|     } | ||||
| 
 | ||||
|     // sceneMgr: to lookup the scene node name from the object's referenceId
 | ||||
|     // camera: primarily used to get the visibility mask for the viewport
 | ||||
|     //
 | ||||
|     // returns the found object's scene node name and its position in the world space
 | ||||
|     //
 | ||||
|     // WARNING: far clip distance is a global setting, if it changes in future
 | ||||
|     //          this method will need to be updated
 | ||||
|     std::pair<std::string, Ogre::Vector3> PhysicsSystem::castRay(float mouseX, | ||||
|             float mouseY, Ogre::Vector3* normal, std::string* hit, Ogre::Camera *camera) | ||||
|             float mouseY, Ogre::SceneManager *sceneMgr, Ogre::Camera *camera) | ||||
|     { | ||||
|         if(!mSceneMgr || !camera || !camera->getViewport()) | ||||
|         // NOTE: there could be more than one camera for the scene manager
 | ||||
|         // TODO: check whether camera belongs to sceneMgr
 | ||||
|         if(!sceneMgr || !camera || !camera->getViewport()) | ||||
|             return std::make_pair("", Ogre::Vector3(0,0,0)); // FIXME: this should be an exception
 | ||||
| 
 | ||||
| 
 | ||||
|         // using a really small value seems to mess up with the projections
 | ||||
|         float nearClipDistance = camera->getNearClipDistance(); // save existing
 | ||||
|         camera->setNearClipDistance(10.0f);  // arbitrary number
 | ||||
|  | @ -102,14 +127,20 @@ namespace CSVWorld | |||
|         bool ignoreHeightMap = !(visibilityMask & (uint32_t)CSVRender::Element_Terrain); | ||||
|         bool ignoreObjects = !(visibilityMask & (uint32_t)CSVRender::Element_Reference); | ||||
| 
 | ||||
|         Ogre::Vector3 norm; | ||||
|         Ogre::Vector3 norm; // not used
 | ||||
|         std::pair<std::string, float> result = | ||||
|                                 mEngine->rayTest(_from, _to, !ignoreObjects, ignoreHeightMap, &norm); | ||||
| 
 | ||||
|         // result.first is the object's referenceId
 | ||||
|         if(result.first == "") | ||||
|             return std::make_pair("", Ogre::Vector3(0,0,0)); | ||||
|         else | ||||
|             return std::make_pair(result.first, ray.getPoint(farClipDist*result.second)); | ||||
|             return std::make_pair(refIdToSceneNode(result.first, sceneMgr), ray.getPoint(farClipDist*result.second)); | ||||
|     } | ||||
| 
 | ||||
|     std::string PhysicsSystem::refIdToSceneNode(std::string referenceId, Ogre::SceneManager *sceneMgr) | ||||
|     { | ||||
|         return mRefIdToSceneNode[referenceId][sceneMgr]; | ||||
|     } | ||||
| 
 | ||||
|     std::string PhysicsSystem::sceneNodeToRefId(std::string sceneNodeName) | ||||
|  | @ -122,17 +153,19 @@ namespace CSVWorld | |||
|         return mSceneNodeToMesh[sceneNodeName]; | ||||
|     } | ||||
| 
 | ||||
|     void PhysicsSystem::setSceneManager(Ogre::SceneManager *sceneMgr) | ||||
|     void PhysicsSystem::addSceneManager(Ogre::SceneManager *sceneMgr) | ||||
|     { | ||||
|         mSceneMgr = sceneMgr; | ||||
|         mEngine->setSceneManager(sceneMgr); // needed for toggleDebugRendering()
 | ||||
|         mSceneManagers.push_back(sceneMgr); | ||||
|     } | ||||
| 
 | ||||
|     void PhysicsSystem::toggleDebugRendering() | ||||
|     void PhysicsSystem::toggleDebugRendering(Ogre::SceneManager *sceneMgr) | ||||
|     { | ||||
|         // FIXME: should check if sceneMgr is in the list
 | ||||
|         if(!mSceneMgr) | ||||
|             return; // FIXME: maybe this should be an exception
 | ||||
| 
 | ||||
|         mEngine->setSceneManager(sceneMgr); | ||||
| 
 | ||||
|         CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); | ||||
|         if(!(userSettings.setting("debug/mouse-picking", QString("false")) == "true" ? true : false)) | ||||
|         { | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
| 
 | ||||
| #include <string> | ||||
| #include <map> | ||||
| #include <vector> | ||||
| #include <list> | ||||
| 
 | ||||
| namespace Ogre | ||||
| { | ||||
|  | @ -27,19 +27,21 @@ namespace CSVWorld | |||
|     { | ||||
|             static PhysicsSystem *mPhysicsSystemInstance; | ||||
|             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::list<Ogre::SceneManager *> mSceneManagers; // FIXME: change to list per OEngine
 | ||||
|             OEngine::Physic::PhysicEngine* mEngine; | ||||
| 
 | ||||
|             Ogre::SceneManager *mSceneMgr; | ||||
| 
 | ||||
|         public: | ||||
| 
 | ||||
|             PhysicsSystem(Ogre::SceneManager *sceneMgr = NULL); | ||||
|             PhysicsSystem(); | ||||
|             ~PhysicsSystem(); | ||||
| 
 | ||||
|             static PhysicsSystem *instance(); | ||||
| 
 | ||||
|             void setSceneManager(Ogre::SceneManager *sceneMgr); | ||||
|             void addSceneManager(Ogre::SceneManager *sceneMgr); | ||||
| 
 | ||||
|             void addObject(const std::string &mesh, | ||||
|                     const std::string &sceneNodeName, const std::string &referenceId, float scale, | ||||
|  | @ -56,10 +58,11 @@ namespace CSVWorld | |||
| 
 | ||||
|             void removeHeightField(int x, int y); | ||||
| 
 | ||||
|             void toggleDebugRendering(); | ||||
|             void toggleDebugRendering(Ogre::SceneManager *sceneMgr); | ||||
| 
 | ||||
|             // return the object's SceneNode name and position for the given SceneManager
 | ||||
|             std::pair<std::string, Ogre::Vector3> castRay(float mouseX, | ||||
|                     float mouseY, Ogre::Vector3* normal, std::string* hit, Ogre::Camera *camera); | ||||
|                     float mouseY, Ogre::SceneManager *sceneMgr, Ogre::Camera *camera); | ||||
| 
 | ||||
|             std::string sceneNodeToRefId(std::string sceneNodeName); | ||||
|             std::string sceneNodeToMesh(std::string sceneNodeName); | ||||
|  | @ -67,6 +70,7 @@ namespace CSVWorld | |||
|         private: | ||||
| 
 | ||||
|             void updateSelectionHighlight(std::string sceneNode, const Ogre::Vector3 &position); | ||||
|             std::string refIdToSceneNode(std::string referenceId, Ogre::SceneManager *sceneMgr); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue