mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 16:56:42 +00:00 
			
		
		
		
	Feature #37 (In Progress) Render Path Grid
cubes for path grid points strange crash when trying to get path grids from Debugging
This commit is contained in:
		
							parent
							
								
									6357adffcf
								
							
						
					
					
						commit
						11f957a64d
					
				
					 7 changed files with 186 additions and 36 deletions
				
			
		|  | @ -12,27 +12,141 @@ | |||
| #include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone
 | ||||
| #include "../mwworld/ptr.hpp" | ||||
| #include <components/esm/loadstat.hpp> | ||||
| #include <components/esm/loadpgrd.hpp> | ||||
| 
 | ||||
| #include "player.hpp" | ||||
| 
 | ||||
| using namespace MWRender; | ||||
| using namespace Ogre; | ||||
| 
 | ||||
| Debugging::Debugging(OEngine::Physic::PhysicEngine* engine){ | ||||
| 	eng = engine; | ||||
| Debugging::Debugging(const ESMS::ESMStore &store, SceneManager* sceneMgr, OEngine::Physic::PhysicEngine *engine) : | ||||
|     mStore(store), mSceneMgr(sceneMgr), mEngine(engine), pathgridEnabled(false) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| bool Debugging::toggleRenderMode (int mode){ | ||||
| 	 switch (mode) | ||||
|     switch (mode) | ||||
|     { | ||||
|         case MWWorld::World::Render_CollisionDebug: | ||||
| 
 | ||||
|             // TODO use a proper function instead of accessing the member variable
 | ||||
|             // directly.
 | ||||
|             eng->setDebugRenderingMode (!eng->isDebugCreated); | ||||
|             return eng->isDebugCreated; | ||||
|             mEngine->setDebugRenderingMode (!mEngine->isDebugCreated); | ||||
|             return mEngine->isDebugCreated; | ||||
|         case MWWorld::World::Render_Pathgrid: | ||||
|             togglePathgrid(); | ||||
|             return pathgridEnabled; | ||||
|     } | ||||
| 
 | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| void Debugging::cellAdded(MWWorld::Ptr::CellStore *store) | ||||
| { | ||||
|     std::cout << "Cell added to debugging" << std::endl; | ||||
|     mActiveCells.push_back(store); | ||||
|     if (pathgridEnabled) | ||||
|         togglePathgridForCell(store, true); | ||||
| } | ||||
| 
 | ||||
| void Debugging::cellRemoved(MWWorld::Ptr::CellStore *store) | ||||
| { | ||||
|     mActiveCells.erase(std::remove(mActiveCells.begin(), mActiveCells.end(), store), mActiveCells.end()); | ||||
|     std::cout << "Cell removed from debugging, active cells count: " << mActiveCells.size() << std::endl; | ||||
|     if (pathgridEnabled) | ||||
|         togglePathgridForCell(store, false); | ||||
| } | ||||
| 
 | ||||
| void Debugging::togglePathgrid() | ||||
| { | ||||
|     pathgridEnabled = !pathgridEnabled; | ||||
|     if (pathgridEnabled) | ||||
|     { | ||||
|         // add path grid meshes to already loaded cells
 | ||||
|         mPathGridRoot = mSceneMgr->getRootSceneNode()->createChildSceneNode(); | ||||
|         for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); it++) | ||||
|         { | ||||
|             togglePathgridForCell(*it, true); | ||||
|         } | ||||
|     } | ||||
|     else { | ||||
|         // remove path grid meshes from already loaded cells
 | ||||
|         for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); it++) | ||||
|         { | ||||
|             togglePathgridForCell(*it, false); | ||||
|         } | ||||
|         mPathGridRoot->removeAndDestroyAllChildren(); | ||||
|         mSceneMgr->destroySceneNode(mPathGridRoot); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Debugging::togglePathgridForCell(MWWorld::Ptr::CellStore *store, bool enabled) | ||||
| { | ||||
|     ESM::Pathgrid *pathgrid = mStore.pathgrids.search(*store->cell); | ||||
|     if (!pathgrid) | ||||
|     { | ||||
|         std::cout << "No path grid :(" << std::endl; | ||||
|         return; | ||||
|     } | ||||
|     std::cout << "Path grid exists!" << std::endl; | ||||
| 
 | ||||
|     if (enabled) | ||||
|     { | ||||
|         Vector3 cellPathGridPos; | ||||
|         if (!(store->cell->data.flags & ESM::Cell::Interior)) | ||||
|         { | ||||
|             /// \todo Replace with ESM::Land::REAL_SIZE after merging with terrain branch
 | ||||
|             cellPathGridPos.x = store->cell->data.gridX * 8192; | ||||
|             cellPathGridPos.z = -store->cell->data.gridY * 8192; | ||||
|         } | ||||
|         SceneNode *cellPathGrid = mPathGridRoot->createChildSceneNode(cellPathGridPos); | ||||
|         ESM::Pathgrid::PointList points = pathgrid->points; | ||||
|         for (ESM::Pathgrid::PointList::iterator it = points.begin(); it != points.end(); it++) | ||||
|         { | ||||
|             Vector3 position(it->x, it->z, -it->y); | ||||
|             SceneNode* pointNode = cellPathGrid->createChildSceneNode(position); | ||||
|             pointNode->setScale(0.5, 0.5, 0.5); | ||||
|             Entity *pointMesh = mSceneMgr->createEntity(SceneManager::PT_CUBE); | ||||
|             pointNode->attachObject(pointMesh); | ||||
|         } | ||||
| 
 | ||||
|         if (!(store->cell->data.flags & ESM::Cell::Interior)) | ||||
|         { | ||||
|             mExteriorPathgridNodes[std::make_pair(store->cell->data.gridX, store->cell->data.gridY)] = cellPathGrid; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             assert(mInteriorPathgridNode == NULL); | ||||
|             mInteriorPathgridNode = cellPathGrid; | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         /// \todo Don't forget to destroy cubes too!
 | ||||
|         SceneNode *cellPathGridNode; | ||||
|         if (!(store->cell->data.flags & ESM::Cell::Interior)) | ||||
|         { | ||||
|             ExteriorPathgridNodes::iterator it = | ||||
|                     mExteriorPathgridNodes.find(std::make_pair(store->cell->data.gridX, store->cell->data.gridY)); | ||||
|             if (it != mExteriorPathgridNodes.end()) | ||||
|             { | ||||
|                 cellPathGridNode = it->second; | ||||
|                 mPathGridRoot->removeChild(cellPathGridNode); | ||||
|                 cellPathGridNode->removeAndDestroyAllChildren(); | ||||
|                 mSceneMgr->destroySceneNode(cellPathGridNode); | ||||
|                 mExteriorPathgridNodes.erase(it); | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             if (mInteriorPathgridNode) | ||||
|             { | ||||
|                 mPathGridRoot->removeChild(mInteriorPathgridNode); | ||||
|                 mInteriorPathgridNode->removeAndDestroyAllChildren(); | ||||
|                 mSceneMgr->destroySceneNode(mInteriorPathgridNode); | ||||
|                 mInteriorPathgridNode = NULL; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| #include <utility> | ||||
| #include <openengine/ogre/renderer.hpp> | ||||
| #include <openengine/bullet/physic.hpp> | ||||
| #include "../mwworld/ptr.hpp" | ||||
| 
 | ||||
| #include <vector> | ||||
| #include <string> | ||||
|  | @ -28,14 +29,36 @@ namespace MWRender | |||
| { | ||||
|     class Player; | ||||
| 
 | ||||
| 	class Debugging{ | ||||
| 	OEngine::Physic::PhysicEngine* eng; | ||||
|     class Debugging | ||||
|     { | ||||
|         OEngine::Physic::PhysicEngine* mEngine; | ||||
|         Ogre::SceneManager* mSceneMgr; | ||||
|         const ESMS::ESMStore& mStore; | ||||
| 
 | ||||
|         // Path grid stuff
 | ||||
|         bool pathgridEnabled; | ||||
| 
 | ||||
| 	public: | ||||
| 		Debugging(OEngine::Physic::PhysicEngine* engine); | ||||
| 		bool toggleRenderMode (int mode); | ||||
| 	}; | ||||
|         void togglePathgrid(); | ||||
| 
 | ||||
|         typedef std::vector<MWWorld::Ptr::CellStore *> CellList; | ||||
| 
 | ||||
|         CellList mActiveCells; | ||||
| 
 | ||||
|         Ogre::SceneNode *mPathGridRoot; | ||||
|         Ogre::SceneNode *mInteriorPathgridNode; | ||||
| 
 | ||||
|         typedef std::map<std::pair<int,int>, Ogre::SceneNode *> ExteriorPathgridNodes; | ||||
|         ExteriorPathgridNodes mExteriorPathgridNodes; | ||||
| 
 | ||||
|         void togglePathgridForCell(MWWorld::Ptr::CellStore *store, bool enabled); | ||||
| 
 | ||||
|     public: | ||||
|         Debugging(const ESMS::ESMStore &store, Ogre::SceneManager *mSceneMgr, OEngine::Physic::PhysicEngine* engine); | ||||
|         bool toggleRenderMode (int mode); | ||||
| 
 | ||||
|         void cellAdded(MWWorld::Ptr::CellStore* store); | ||||
|         void cellRemoved(MWWorld::Ptr::CellStore* store); | ||||
|     }; | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -20,10 +20,12 @@ using namespace Ogre; | |||
| namespace MWRender { | ||||
| 
 | ||||
| RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine, MWWorld::Environment& environment) | ||||
| :mRendering(_rend), mObjects(mRendering), mActors(mRendering, environment), mAmbientMode(0), mDebugging(engine) | ||||
|     :mRendering(_rend), mObjects(mRendering), mActors(mRendering, environment), mAmbientMode(0) | ||||
| { | ||||
|     mRendering.createScene("PlayerCam", 55, 5); | ||||
| 
 | ||||
|     mDebugging = new Debugging(environment.mWorld->getStore(), mRendering.getScene(), engine); | ||||
| 
 | ||||
|     // Set default mipmap level (NB some APIs ignore this)
 | ||||
|     TextureManager::getSingleton().setDefaultNumMipmaps(5); | ||||
| 
 | ||||
|  | @ -40,7 +42,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const | |||
|     mMwRoot->pitch(Degree(-90)); | ||||
|     mObjects.setMwRoot(mMwRoot); | ||||
|     mActors.setMwRoot(mMwRoot); | ||||
|          | ||||
| 
 | ||||
|     //used to obtain ingame information of ogre objects (which are faced or selected)
 | ||||
|     mRaySceneQuery = mRendering.getScene()->createRayQuery(Ray()); | ||||
| 
 | ||||
|  | @ -49,7 +51,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const | |||
|     Ogre::SceneNode *cameraYawNode = playerNode->createChildSceneNode(); | ||||
|     Ogre::SceneNode *cameraPitchNode = cameraYawNode->createChildSceneNode(); | ||||
|     cameraPitchNode->attachObject(mRendering.getCamera()); | ||||
|      | ||||
| 
 | ||||
|     //mSkyManager = 0;
 | ||||
|     mSkyManager = new SkyManager(mMwRoot, mRendering.getCamera()); | ||||
| 
 | ||||
|  | @ -62,6 +64,7 @@ RenderingManager::~RenderingManager () | |||
|     //TODO: destroy mSun?
 | ||||
|     delete mPlayer; | ||||
|     delete mSkyManager; | ||||
|     delete mDebugging; | ||||
| } | ||||
| 
 | ||||
| MWRender::SkyManager* RenderingManager::getSkyManager() | ||||
|  | @ -88,11 +91,13 @@ OEngine::Render::Fader* RenderingManager::getFader() | |||
| void RenderingManager::removeCell (MWWorld::Ptr::CellStore *store){ | ||||
|     mObjects.removeCell(store); | ||||
|     mActors.removeCell(store); | ||||
|     mDebugging->cellRemoved(store); | ||||
| } | ||||
| 
 | ||||
| void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store) | ||||
| { | ||||
|     mObjects.buildStaticGeometry (*store); | ||||
|     mDebugging->cellAdded(store); | ||||
| } | ||||
| 
 | ||||
| void RenderingManager::addObject (const MWWorld::Ptr& ptr){ | ||||
|  | @ -133,9 +138,9 @@ void RenderingManager::moveObjectToCell (const MWWorld::Ptr& ptr, const Ogre::Ve | |||
| void RenderingManager::update (float duration){ | ||||
| 
 | ||||
|     mActors.update (duration); | ||||
|      | ||||
| 
 | ||||
|     mSkyManager->update(duration); | ||||
|      | ||||
| 
 | ||||
|     mRendering.update(duration); | ||||
| } | ||||
| 
 | ||||
|  | @ -166,7 +171,7 @@ void RenderingManager::skySetDate (int day, int month) | |||
| 
 | ||||
| int RenderingManager::skyGetMasserPhase() const | ||||
| { | ||||
|     | ||||
| 
 | ||||
|     return mSkyManager->getMasserPhase(); | ||||
| } | ||||
| 
 | ||||
|  | @ -182,8 +187,8 @@ void RenderingManager::skySetMoonColour (bool red){ | |||
| 
 | ||||
| bool RenderingManager::toggleRenderMode(int mode) | ||||
| { | ||||
|     if (mode == MWWorld::World::Render_CollisionDebug) | ||||
|         return mDebugging.toggleRenderMode(mode); | ||||
|     if (mode != MWWorld::World::Render_Wireframe) | ||||
|         return mDebugging->toggleRenderMode(mode); | ||||
|     else // if (mode == MWWorld::World::Render_Wireframe)
 | ||||
|     { | ||||
|         if (mRendering.getCamera()->getPolygonMode() == PM_SOLID) | ||||
|  | @ -208,13 +213,13 @@ void RenderingManager::configureFog(ESMS::CellStore<MWWorld::RefData> &mCell) | |||
| } | ||||
| 
 | ||||
| void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour) | ||||
| {   | ||||
| { | ||||
|   /// \todo make the viewing distance and fog start/end configurable
 | ||||
|   float low = 3000 / density; | ||||
|   float high = 6200 / density; | ||||
|      | ||||
| 
 | ||||
|   mRendering.getScene()->setFog (FOG_LINEAR, colour, 0, low, high); | ||||
|    | ||||
| 
 | ||||
|   mRendering.getCamera()->setFarClipDistance ( high ); | ||||
|   mRendering.getViewport()->setBackgroundColour (colour); | ||||
| } | ||||
|  | @ -310,10 +315,10 @@ void RenderingManager::sunDisable() | |||
| 
 | ||||
| void RenderingManager::setSunDirection(const Ogre::Vector3& direction) | ||||
| { | ||||
|     // direction * -1 (because 'direction' is camera to sun vector and not sun to camera), 
 | ||||
|     // direction * -1 (because 'direction' is camera to sun vector and not sun to camera),
 | ||||
|     // then convert from MW to ogre coordinates (swap y,z and make y negative)
 | ||||
|     if (mSun) mSun->setDirection(Vector3(-direction.x, -direction.z, direction.y)); | ||||
|      | ||||
| 
 | ||||
|     mSkyManager->setSunDirection(direction); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -66,7 +66,7 @@ class RenderingManager: private RenderingInterface { | |||
| 
 | ||||
|     void toggleLight(); | ||||
|     bool toggleRenderMode(int mode); | ||||
|      | ||||
| 
 | ||||
|     OEngine::Render::Fader* getFader(); | ||||
| 
 | ||||
|     void removeCell (MWWorld::Ptr::CellStore *store); | ||||
|  | @ -86,13 +86,13 @@ class RenderingManager: private RenderingInterface { | |||
|     void moveObjectToCell (const MWWorld::Ptr& ptr, const Ogre::Vector3& position, MWWorld::Ptr::CellStore *store); | ||||
| 
 | ||||
|     void update (float duration); | ||||
|      | ||||
| 
 | ||||
|     void setAmbientColour(const Ogre::ColourValue& colour); | ||||
|     void setSunColour(const Ogre::ColourValue& colour); | ||||
|     void setSunDirection(const Ogre::Vector3& direction); | ||||
|     void sunEnable(); | ||||
|     void sunDisable(); | ||||
|      | ||||
| 
 | ||||
|     void setGlare(bool glare); | ||||
|     void skyEnable (); | ||||
|     void skyDisable (); | ||||
|  | @ -102,13 +102,13 @@ class RenderingManager: private RenderingInterface { | |||
|     int skyGetSecundaPhase() const; | ||||
|     void skySetMoonColour (bool red); | ||||
|     void configureAmbient(ESMS::CellStore<MWWorld::RefData> &mCell); | ||||
|      | ||||
| 
 | ||||
|     /// configure fog according to cell
 | ||||
|     void configureFog(ESMS::CellStore<MWWorld::RefData> &mCell); | ||||
|      | ||||
| 
 | ||||
|     /// configure fog manually
 | ||||
|     void configureFog(const float density, const Ogre::ColourValue& colour); | ||||
|      | ||||
| 
 | ||||
|     void playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode, | ||||
|         int number = 1); | ||||
|     ///< Run animation for a MW-reference. Calls to this function for references that are currently not
 | ||||
|  | @ -124,9 +124,9 @@ class RenderingManager: private RenderingInterface { | |||
|   private: | ||||
| 
 | ||||
|     void setAmbientMode(); | ||||
|      | ||||
| 
 | ||||
|     SkyManager* mSkyManager; | ||||
|      | ||||
| 
 | ||||
|     OEngine::Render::OgreRenderer &mRendering; | ||||
| 
 | ||||
|     MWRender::Objects mObjects; | ||||
|  | @ -147,7 +147,7 @@ class RenderingManager: private RenderingInterface { | |||
|     OEngine::Physic::PhysicEngine* mPhysicsEngine; | ||||
| 
 | ||||
|     MWRender::Player *mPlayer; | ||||
|     MWRender::Debugging mDebugging; | ||||
|     MWRender::Debugging *mDebugging; | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -133,7 +133,7 @@ namespace MWScript | |||
|                     static_cast<InterpreterContext&> (runtime.getContext()); | ||||
| 
 | ||||
|                 bool enabled = | ||||
|                     context.getWorld().toggleRenderMode (MWWorld::World::Render_Wireframe); | ||||
|                     context.getWorld().toggleRenderMode (MWWorld::World::Render_Pathgrid); | ||||
| 
 | ||||
|                 context.report (enabled ? | ||||
|                     "Path Grid rendering -> On" : "Path Grid Rendering -> Off"); | ||||
|  |  | |||
|  | @ -123,6 +123,8 @@ namespace ESMS | |||
|     CellRefList<Static, D>            statics; | ||||
|     CellRefList<Weapon, D>            weapons; | ||||
| 
 | ||||
|     ESM::Pathgrid *pathgrid; | ||||
| 
 | ||||
|     void load (const ESMStore &store, ESMReader &esm) | ||||
|     { | ||||
|         if (mState!=State_Loaded) | ||||
|  | @ -134,6 +136,8 @@ namespace ESMS | |||
| 
 | ||||
|             loadRefs (store, esm); | ||||
| 
 | ||||
|             pathgrid = store.pathgrids.search(*cell); | ||||
| 
 | ||||
|             mState = State_Loaded; | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -428,14 +428,16 @@ namespace ESMS | |||
|           if (grid->data.x == 0 && grid->data.y == 0) | ||||
|           { | ||||
|               intGrids[grid->cell] = grid; | ||||
|               std::cout << "int grids size " << intGrids.size() << std::endl; | ||||
|           } | ||||
|           else | ||||
|           { | ||||
|               extGrids[std::make_pair(grid->data.x, grid->data.y)] = grid; | ||||
|               std::cout << "ext grids size " << extGrids.size() << std::endl; | ||||
|           } | ||||
|       } | ||||
| 
 | ||||
|       Pathgrid *find(int cellX, int cellY, std::string cellName) const | ||||
|       Pathgrid *find(int cellX, int cellY, const std::string &cellName) const | ||||
|       { | ||||
|           Pathgrid *result = search(cellX, cellY, cellName); | ||||
|           if (!result) | ||||
|  | @ -445,8 +447,10 @@ namespace ESMS | |||
|           return result; | ||||
|       } | ||||
| 
 | ||||
|       Pathgrid *search(int cellX, int cellY, std::string cellName) const | ||||
|       Pathgrid *search(int cellX, int cellY, const std::string &cellName) const | ||||
|       { | ||||
|           std::cout << "int grids size " << intGrids.size() << std::endl; | ||||
|           std::cout << "ext grids size " << extGrids.size() << std::endl; | ||||
|           Pathgrid *result = NULL; | ||||
|           if (cellX == 0 && cellY == 0) // possibly interior
 | ||||
|           { | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue