From 5328853445fbe2dc7b35df12e06167b973ea803e Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Thu, 8 Mar 2012 01:03:46 +0400 Subject: [PATCH 01/19] Feature #37 (In Progress) Render Path Grid added "togglepathgrid" script command --- CMakeLists.txt | 10 +++++-- apps/openmw/mwscript/docs/vmformat.txt | 5 ++-- apps/openmw/mwscript/miscextensions.cpp | 36 +++++++++++++++++++------ apps/openmw/mwworld/world.hpp | 15 ++++++----- 4 files changed, 47 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e116d875..60731c092 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -255,8 +255,14 @@ if (APPLE) "${APP_BUNDLE_DIR}/Contents/Resources/OpenMW.icns" COPYONLY) # prepare plugins - if (${CMAKE_BUILD_TYPE} MATCHES "Release" OR - ${CMAKE_BUILD_TYPE} MATCHES "RelWithDebugInfo") + if (${CMAKE_BUILD_TYPE} MATCHES "Release") + set(OPENMW_RELEASE_BUILD 1) + endif() + if (${CMAKE_BUILD_TYPE} MATCHES "Release") + set(OPENMW_RELEASE_BUILD 1) + endif() + + if (${OPENMW_RELEASE_BUILD}) set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_REL}) else() set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_DBG}) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 09b0c0482..efdc63a2d 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -115,10 +115,11 @@ op 0x2000136: GetPCCell op 0x2000137: GetButtonPressed op 0x2000138: SkipAnim op 0x2000139: SkipAnim, expplicit reference -op 0x200013b: twf +op 0x200013b: ToggleWireframe op 0x200013c: FadeIn op 0x200013d: FadeOut op 0x200013e: FadeTo op 0x200013f: GetCurrentWeather op 0x2000140: ChangeWeather -opcodes 0x2000141-0x3ffffff unused +op 0x2000141: TogglePathgrid +opcodes 0x2000142-0x3ffffff unused diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 5bfffd3a2..45189e698 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -106,7 +106,7 @@ namespace MWScript "Collision Mesh Rendering -> On" : "Collision Mesh Rendering -> Off"); } }; - + class OpToggleWireframe : public Interpreter::Opcode0 { public: @@ -123,7 +123,23 @@ namespace MWScript "Wireframe Rendering -> On" : "Wireframe Rendering -> Off"); } }; - + + class OpTogglePathgrind : public Interpreter::Opcode0 + { + public: + virtual void execute (Interpreter::Runtime& runtime) + { + InterpreterContext& context = + static_cast (runtime.getContext()); + + bool enabled = + context.getWorld().toggleRenderMode (MWWorld::World::Render_Wireframe); + + context.report (enabled ? + "Path Grid rendering -> On" : "Path Grid Rendering -> Off"); + } + }; + class OpFadeIn : public Interpreter::Opcode0 { public: @@ -135,11 +151,11 @@ namespace MWScript Interpreter::Type_Float time = runtime[0].mFloat; runtime.pop(); - + context.getWorld().getFader()->fadeIn(time); } }; - + class OpFadeOut : public Interpreter::Opcode0 { public: @@ -151,11 +167,11 @@ namespace MWScript Interpreter::Type_Float time = runtime[0].mFloat; runtime.pop(); - + context.getWorld().getFader()->fadeOut(time); } }; - + class OpFadeTo : public Interpreter::Opcode0 { public: @@ -167,10 +183,10 @@ namespace MWScript Interpreter::Type_Float alpha = runtime[0].mFloat; runtime.pop(); - + Interpreter::Type_Float time = runtime[0].mFloat; runtime.pop(); - + context.getWorld().getFader()->fadeTo(alpha, time); } }; @@ -187,6 +203,7 @@ namespace MWScript const int opcodeFadeIn = 0x200013c; const int opcodeFadeOut = 0x200013d; const int opcodeFadeTo = 0x200013e; + const int opcodeTogglePathgrid = 0x2000141; void registerExtensions (Compiler::Extensions& extensions) { @@ -204,6 +221,8 @@ namespace MWScript extensions.registerInstruction ("fadein", "f", opcodeFadeIn); extensions.registerInstruction ("fadeout", "f", opcodeFadeOut); extensions.registerInstruction ("fadeto", "ff", opcodeFadeTo); + extensions.registerInstruction ("togglepathgrid", "", opcodeTogglePathgrid); + extensions.registerInstruction ("tpg", "", opcodeTogglePathgrid); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -220,6 +239,7 @@ namespace MWScript interpreter.installSegment5 (opcodeFadeIn, new OpFadeIn); interpreter.installSegment5 (opcodeFadeOut, new OpFadeOut); interpreter.installSegment5 (opcodeFadeTo, new OpFadeTo); + interpreter.installSegment5 (opcodeTogglePathgrid, new OpTogglePathgrind); } } } diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index 71cca3545..bd62be415 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -63,13 +63,14 @@ namespace MWWorld enum RenderMode { Render_CollisionDebug, - Render_Wireframe + Render_Wireframe, + Render_Pathgrid }; private: MWRender::RenderingManager* mRendering; - + MWWorld::WeatherManager* mWeatherManager; MWWorld::Scene *mWorldScene; @@ -106,13 +107,13 @@ namespace MWWorld Environment& environment, const std::string& encoding); ~World(); - + OEngine::Render::Fader* getFader(); Ptr::CellStore *getExterior (int x, int y); Ptr::CellStore *getInterior (const std::string& name); - + void adjustSky(); MWWorld::Player& getPlayer(); @@ -125,7 +126,7 @@ namespace MWWorld bool hasCellChanged() const; ///< Has the player moved to a different cell, since the last frame? - + bool isCellExterior() const; bool isCellQuasiExterior() const; @@ -163,9 +164,9 @@ namespace MWWorld bool toggleSky(); ///< \return Resulting mode - + void changeWeather(const std::string& region, const unsigned int id); - + int getCurrentWeather() const; int getMasserPhase() const; From 6357adffcf11da817d449a4aefd61a0f026cd89e Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Thu, 8 Mar 2012 01:09:06 +0400 Subject: [PATCH 02/19] Fixed typo --- apps/openmw/mwscript/miscextensions.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 45189e698..36b8df70b 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -124,7 +124,7 @@ namespace MWScript } }; - class OpTogglePathgrind : public Interpreter::Opcode0 + class OpTogglePathgrid : public Interpreter::Opcode0 { public: virtual void execute (Interpreter::Runtime& runtime) @@ -239,7 +239,7 @@ namespace MWScript interpreter.installSegment5 (opcodeFadeIn, new OpFadeIn); interpreter.installSegment5 (opcodeFadeOut, new OpFadeOut); interpreter.installSegment5 (opcodeFadeTo, new OpFadeTo); - interpreter.installSegment5 (opcodeTogglePathgrid, new OpTogglePathgrind); + interpreter.installSegment5 (opcodeTogglePathgrid, new OpTogglePathgrid); } } } From 11f957a64d677d0b1bed3574dc61eb378e090261 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Thu, 8 Mar 2012 10:46:34 +0400 Subject: [PATCH 03/19] Feature #37 (In Progress) Render Path Grid cubes for path grid points strange crash when trying to get path grids from Debugging --- apps/openmw/mwrender/debugging.cpp | 124 +++++++++++++++++++++- apps/openmw/mwrender/debugging.hpp | 35 ++++-- apps/openmw/mwrender/renderingmanager.cpp | 31 +++--- apps/openmw/mwrender/renderingmanager.hpp | 18 ++-- apps/openmw/mwscript/miscextensions.cpp | 2 +- components/esm_store/cell_store.hpp | 4 + components/esm_store/reclists.hpp | 8 +- 7 files changed, 186 insertions(+), 36 deletions(-) diff --git a/apps/openmw/mwrender/debugging.cpp b/apps/openmw/mwrender/debugging.cpp index 60b299acd..f1e601af5 100644 --- a/apps/openmw/mwrender/debugging.cpp +++ b/apps/openmw/mwrender/debugging.cpp @@ -12,27 +12,141 @@ #include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone #include "../mwworld/ptr.hpp" #include +#include #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; + } + } + } +} diff --git a/apps/openmw/mwrender/debugging.hpp b/apps/openmw/mwrender/debugging.hpp index b48cfaee2..2258fec21 100644 --- a/apps/openmw/mwrender/debugging.hpp +++ b/apps/openmw/mwrender/debugging.hpp @@ -4,6 +4,7 @@ #include #include #include +#include "../mwworld/ptr.hpp" #include #include @@ -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 CellList; + + CellList mActiveCells; + + Ogre::SceneNode *mPathGridRoot; + Ogre::SceneNode *mInteriorPathgridNode; + + typedef std::map, 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); + }; } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 7b58a80d7..94197108d 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -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 &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); } diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index d84ee43e0..9be389272 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -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 &mCell); - + /// configure fog according to cell void configureFog(ESMS::CellStore &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; }; } diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 36b8df70b..425fa3727 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -133,7 +133,7 @@ namespace MWScript static_cast (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"); diff --git a/components/esm_store/cell_store.hpp b/components/esm_store/cell_store.hpp index c4bcf84d8..4f5b6b6ec 100644 --- a/components/esm_store/cell_store.hpp +++ b/components/esm_store/cell_store.hpp @@ -123,6 +123,8 @@ namespace ESMS CellRefList statics; CellRefList 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; } } diff --git a/components/esm_store/reclists.hpp b/components/esm_store/reclists.hpp index 4aacf2332..da6e9b3d5 100644 --- a/components/esm_store/reclists.hpp +++ b/components/esm_store/reclists.hpp @@ -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 { From 4659076129de9185e3b0f6e7d11ff28c1fe9df61 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Sat, 10 Mar 2012 20:45:55 +0400 Subject: [PATCH 04/19] Feature #37 (In Progress) Render Path Grid workaround for strange ESMStore bug --- apps/openmw/mwrender/debugging.cpp | 7 ++++--- apps/openmw/mwrender/debugging.hpp | 6 ++++-- apps/openmw/mwrender/renderingmanager.cpp | 2 +- components/esm_store/cell_store.hpp | 4 ---- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwrender/debugging.cpp b/apps/openmw/mwrender/debugging.cpp index f1e601af5..8df4850db 100644 --- a/apps/openmw/mwrender/debugging.cpp +++ b/apps/openmw/mwrender/debugging.cpp @@ -10,6 +10,7 @@ #include "OgreTextureManager.h" #include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone +#include "../mwworld/environment.hpp" #include "../mwworld/ptr.hpp" #include #include @@ -19,8 +20,8 @@ using namespace MWRender; using namespace Ogre; -Debugging::Debugging(const ESMS::ESMStore &store, SceneManager* sceneMgr, OEngine::Physic::PhysicEngine *engine) : - mStore(store), mSceneMgr(sceneMgr), mEngine(engine), pathgridEnabled(false) +Debugging::Debugging(MWWorld::Environment &env, SceneManager* sceneMgr, OEngine::Physic::PhysicEngine *engine) : + mEnvironment(env), mSceneMgr(sceneMgr), mEngine(engine), pathgridEnabled(false) { } @@ -83,7 +84,7 @@ void Debugging::togglePathgrid() void Debugging::togglePathgridForCell(MWWorld::Ptr::CellStore *store, bool enabled) { - ESM::Pathgrid *pathgrid = mStore.pathgrids.search(*store->cell); + ESM::Pathgrid *pathgrid = mEnvironment.mWorld->getStore().pathgrids.search(*store->cell); if (!pathgrid) { std::cout << "No path grid :(" << std::endl; diff --git a/apps/openmw/mwrender/debugging.hpp b/apps/openmw/mwrender/debugging.hpp index 2258fec21..2b47eb773 100644 --- a/apps/openmw/mwrender/debugging.hpp +++ b/apps/openmw/mwrender/debugging.hpp @@ -23,6 +23,7 @@ namespace Ogre namespace MWWorld { class World; + class Environment; } namespace MWRender @@ -33,7 +34,8 @@ namespace MWRender { OEngine::Physic::PhysicEngine* mEngine; Ogre::SceneManager* mSceneMgr; - const ESMS::ESMStore& mStore; + MWWorld::Environment& mEnvironment; + //const ESMS::ESMStore& mStore; // Path grid stuff bool pathgridEnabled; @@ -53,7 +55,7 @@ namespace MWRender void togglePathgridForCell(MWWorld::Ptr::CellStore *store, bool enabled); public: - Debugging(const ESMS::ESMStore &store, Ogre::SceneManager *mSceneMgr, OEngine::Physic::PhysicEngine* engine); + Debugging(MWWorld::Environment &env, Ogre::SceneManager *mSceneMgr, OEngine::Physic::PhysicEngine* engine); bool toggleRenderMode (int mode); void cellAdded(MWWorld::Ptr::CellStore* store); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 94197108d..4cb8b42fa 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -24,7 +24,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const { mRendering.createScene("PlayerCam", 55, 5); - mDebugging = new Debugging(environment.mWorld->getStore(), mRendering.getScene(), engine); + mDebugging = new Debugging(environment, mRendering.getScene(), engine); // Set default mipmap level (NB some APIs ignore this) TextureManager::getSingleton().setDefaultNumMipmaps(5); diff --git a/components/esm_store/cell_store.hpp b/components/esm_store/cell_store.hpp index 4f5b6b6ec..c4bcf84d8 100644 --- a/components/esm_store/cell_store.hpp +++ b/components/esm_store/cell_store.hpp @@ -123,8 +123,6 @@ namespace ESMS CellRefList statics; CellRefList weapons; - ESM::Pathgrid *pathgrid; - void load (const ESMStore &store, ESMReader &esm) { if (mState!=State_Loaded) @@ -136,8 +134,6 @@ namespace ESMS loadRefs (store, esm); - pathgrid = store.pathgrids.search(*cell); - mState = State_Loaded; } } From 387c84e60631399ac86dcd24e4b5cd53e4bd510d Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Sun, 11 Mar 2012 18:46:32 +0400 Subject: [PATCH 05/19] small fix in CMakeLists, thx ace13 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 60731c092..ce0354290 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -258,7 +258,7 @@ if (APPLE) if (${CMAKE_BUILD_TYPE} MATCHES "Release") set(OPENMW_RELEASE_BUILD 1) endif() - if (${CMAKE_BUILD_TYPE} MATCHES "Release") + if (${CMAKE_BUILD_TYPE} MATCHES "RelWithDebugInfo") set(OPENMW_RELEASE_BUILD 1) endif() From f292a5a7ca8295d61b6bf6c9f6fd9850b750ae6c Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Mon, 12 Mar 2012 02:12:56 +0400 Subject: [PATCH 06/19] Feature #37 (In Progress) Render Path Grid now using mwRoot instead of ogre's root, so no more messing with coordinates. --- apps/openmw/mwrender/debugging.cpp | 55 ++++++++++++++--------- apps/openmw/mwrender/debugging.hpp | 8 ++-- apps/openmw/mwrender/renderingmanager.cpp | 4 +- components/esm_store/reclists.hpp | 4 -- 4 files changed, 40 insertions(+), 31 deletions(-) diff --git a/apps/openmw/mwrender/debugging.cpp b/apps/openmw/mwrender/debugging.cpp index 8df4850db..ebaab5703 100644 --- a/apps/openmw/mwrender/debugging.cpp +++ b/apps/openmw/mwrender/debugging.cpp @@ -2,12 +2,8 @@ #include -#include "OgreRoot.h" -#include "OgreRenderWindow.h" -#include "OgreSceneManager.h" -#include "OgreViewport.h" -#include "OgreCamera.h" -#include "OgreTextureManager.h" +#include +#include #include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone #include "../mwworld/environment.hpp" @@ -20,8 +16,11 @@ using namespace MWRender; using namespace Ogre; -Debugging::Debugging(MWWorld::Environment &env, SceneManager* sceneMgr, OEngine::Physic::PhysicEngine *engine) : - mEnvironment(env), mSceneMgr(sceneMgr), mEngine(engine), pathgridEnabled(false) +Debugging::Debugging(SceneNode *mwRoot, MWWorld::Environment &env, OEngine::Physic::PhysicEngine *engine) : + mMwRoot(mwRoot), mEnvironment(env), mEngine(engine), + mSceneMgr(mwRoot->getCreator()), + pathgridEnabled(false), + mInteriorPathgridNode(NULL), mPathGridRoot(NULL) { } @@ -65,7 +64,7 @@ void Debugging::togglePathgrid() if (pathgridEnabled) { // add path grid meshes to already loaded cells - mPathGridRoot = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + mPathGridRoot = mMwRoot->createChildSceneNode(); for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); it++) { togglePathgridForCell(*it, true); @@ -79,6 +78,7 @@ void Debugging::togglePathgrid() } mPathGridRoot->removeAndDestroyAllChildren(); mSceneMgr->destroySceneNode(mPathGridRoot); + mPathGridRoot = NULL; } } @@ -87,25 +87,24 @@ void Debugging::togglePathgridForCell(MWWorld::Ptr::CellStore *store, bool enabl ESM::Pathgrid *pathgrid = mEnvironment.mWorld->getStore().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; + /// \todo replace tests like this with isExterior method of ESM::Cell after merging with terrain branch 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; + cellPathGridPos.y = 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); + Vector3 position(it->x, it->y, it->z); SceneNode* pointNode = cellPathGrid->createChildSceneNode(position); pointNode->setScale(0.5, 0.5, 0.5); Entity *pointMesh = mSceneMgr->createEntity(SceneManager::PT_CUBE); @@ -124,18 +123,13 @@ void Debugging::togglePathgridForCell(MWWorld::Ptr::CellStore *store, bool enabl } 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); + destroyCellPathgridNode(it->second); mExteriorPathgridNodes.erase(it); } } @@ -143,11 +137,28 @@ void Debugging::togglePathgridForCell(MWWorld::Ptr::CellStore *store, bool enabl { if (mInteriorPathgridNode) { - mPathGridRoot->removeChild(mInteriorPathgridNode); - mInteriorPathgridNode->removeAndDestroyAllChildren(); - mSceneMgr->destroySceneNode(mInteriorPathgridNode); + destroyCellPathgridNode(mInteriorPathgridNode); mInteriorPathgridNode = NULL; } } } } + +void Debugging::destroyCellPathgridNode(SceneNode *node) +{ + mPathGridRoot->removeChild(node); + + SceneNode::ChildNodeIterator childIt = node->getChildIterator(); + while (childIt.hasMoreElements()) + { + SceneNode *child = static_cast(childIt.getNext()); + SceneNode::ObjectIterator objIt = child->getAttachedObjectIterator(); + while (objIt.hasMoreElements()) + { + MovableObject *mesh = static_cast(objIt.getNext()); + child->getCreator()->destroyMovableObject(mesh); + } + } + node->removeAndDestroyAllChildren(); + mSceneMgr->destroySceneNode(node); +} diff --git a/apps/openmw/mwrender/debugging.hpp b/apps/openmw/mwrender/debugging.hpp index 2b47eb773..eb592b98d 100644 --- a/apps/openmw/mwrender/debugging.hpp +++ b/apps/openmw/mwrender/debugging.hpp @@ -33,9 +33,8 @@ namespace MWRender class Debugging { OEngine::Physic::PhysicEngine* mEngine; - Ogre::SceneManager* mSceneMgr; + Ogre::SceneManager *mSceneMgr; MWWorld::Environment& mEnvironment; - //const ESMS::ESMStore& mStore; // Path grid stuff bool pathgridEnabled; @@ -46,6 +45,7 @@ namespace MWRender CellList mActiveCells; + Ogre::SceneNode *mMwRoot; Ogre::SceneNode *mPathGridRoot; Ogre::SceneNode *mInteriorPathgridNode; @@ -54,8 +54,10 @@ namespace MWRender void togglePathgridForCell(MWWorld::Ptr::CellStore *store, bool enabled); + void destroyCellPathgridNode(Ogre::SceneNode *node); + public: - Debugging(MWWorld::Environment &env, Ogre::SceneManager *mSceneMgr, OEngine::Physic::PhysicEngine* engine); + Debugging(Ogre::SceneNode* mwRoot, MWWorld::Environment &env, OEngine::Physic::PhysicEngine *engine); bool toggleRenderMode (int mode); void cellAdded(MWWorld::Ptr::CellStore* store); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 4cb8b42fa..888012280 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -24,8 +24,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const { mRendering.createScene("PlayerCam", 55, 5); - mDebugging = new Debugging(environment, mRendering.getScene(), engine); - // Set default mipmap level (NB some APIs ignore this) TextureManager::getSingleton().setDefaultNumMipmaps(5); @@ -57,6 +55,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode); mSun = 0; + + mDebugging = new Debugging(mMwRoot, environment, engine); } RenderingManager::~RenderingManager () diff --git a/components/esm_store/reclists.hpp b/components/esm_store/reclists.hpp index da6e9b3d5..f2c07dda5 100644 --- a/components/esm_store/reclists.hpp +++ b/components/esm_store/reclists.hpp @@ -428,12 +428,10 @@ 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; } } @@ -449,8 +447,6 @@ namespace ESMS 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 { From 3a705baa29c9887057a20ee5f4586121e53efee9 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Wed, 14 Mar 2012 03:06:56 +0400 Subject: [PATCH 07/19] Feature #37 (In Progress) Render Path Grid added simple pathgrid edges --- apps/openmw/mwrender/debugging.cpp | 162 +++++++++++++++++++---------- apps/openmw/mwrender/debugging.hpp | 6 +- 2 files changed, 113 insertions(+), 55 deletions(-) diff --git a/apps/openmw/mwrender/debugging.cpp b/apps/openmw/mwrender/debugging.cpp index ebaab5703..3b01d4b36 100644 --- a/apps/openmw/mwrender/debugging.cpp +++ b/apps/openmw/mwrender/debugging.cpp @@ -13,15 +13,51 @@ #include "player.hpp" -using namespace MWRender; using namespace Ogre; +namespace MWRender +{ + +static const std::string PATHGRID_LINE_MATERIAL = "pathgridLineMaterial"; +static const std::string DEBUGGING_GROUP = "debugging"; + +ManualObject *createPathgridLine(SceneManager* sceneMgr, const Vector3& from, const Vector3& to) +{ + ManualObject *line = sceneMgr->createManualObject(); + if (MaterialManager::getSingleton().getByName(PATHGRID_LINE_MATERIAL, DEBUGGING_GROUP).isNull()) + { + MaterialPtr lineMatPtr = MaterialManager::getSingleton().create(PATHGRID_LINE_MATERIAL, DEBUGGING_GROUP); + lineMatPtr->setReceiveShadows(false); + lineMatPtr->getTechnique(0)->setLightingEnabled(true); + lineMatPtr->getTechnique(0)->getPass(0)->setDiffuse(1,1,0,0); + lineMatPtr->getTechnique(0)->getPass(0)->setAmbient(1,1,0); + lineMatPtr->getTechnique(0)->getPass(0)->setSelfIllumination(1,1,0); + } + + line->begin(PATHGRID_LINE_MATERIAL, Ogre::RenderOperation::OT_LINE_LIST); + line->position(from); + line->position(to); + line->end(); + + return line; +} + +ManualObject *createPathgridPoint(SceneManager* sceneMgr, const Vector3& pos) +{ +} + Debugging::Debugging(SceneNode *mwRoot, MWWorld::Environment &env, OEngine::Physic::PhysicEngine *engine) : mMwRoot(mwRoot), mEnvironment(env), mEngine(engine), mSceneMgr(mwRoot->getCreator()), pathgridEnabled(false), mInteriorPathgridNode(NULL), mPathGridRoot(NULL) { + ResourceGroupManager::getSingleton().createResourceGroup(DEBUGGING_GROUP); +} + +Debugging::~Debugging() +{ + ResourceGroupManager::getSingleton().destroyResourceGroup(DEBUGGING_GROUP); } @@ -47,7 +83,7 @@ void Debugging::cellAdded(MWWorld::Ptr::CellStore *store) std::cout << "Cell added to debugging" << std::endl; mActiveCells.push_back(store); if (pathgridEnabled) - togglePathgridForCell(store, true); + enableCellPathgrid(store); } void Debugging::cellRemoved(MWWorld::Ptr::CellStore *store) @@ -55,7 +91,7 @@ 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); + disableCellPathgrid(store); } void Debugging::togglePathgrid() @@ -67,14 +103,14 @@ void Debugging::togglePathgrid() mPathGridRoot = mMwRoot->createChildSceneNode(); for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); it++) { - togglePathgridForCell(*it, true); + enableCellPathgrid(*it); } } else { // remove path grid meshes from already loaded cells for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); it++) { - togglePathgridForCell(*it, false); + disableCellPathgrid(*it); } mPathGridRoot->removeAndDestroyAllChildren(); mSceneMgr->destroySceneNode(mPathGridRoot); @@ -82,7 +118,7 @@ void Debugging::togglePathgrid() } } -void Debugging::togglePathgridForCell(MWWorld::Ptr::CellStore *store, bool enabled) +void Debugging::enableCellPathgrid(MWWorld::Ptr::CellStore *store) { ESM::Pathgrid *pathgrid = mEnvironment.mWorld->getStore().pathgrids.search(*store->cell); if (!pathgrid) @@ -90,56 +126,65 @@ void Debugging::togglePathgridForCell(MWWorld::Ptr::CellStore *store, bool enabl return; } - if (enabled) + Vector3 cellPathGridPos; + /// \todo replace tests like this with isExterior method of ESM::Cell after merging with terrain branch + if (!(store->cell->data.flags & ESM::Cell::Interior)) { - Vector3 cellPathGridPos; - /// \todo replace tests like this with isExterior method of ESM::Cell after merging with terrain branch - 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.y = 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->y, it->z); - SceneNode* pointNode = cellPathGrid->createChildSceneNode(position); - pointNode->setScale(0.5, 0.5, 0.5); - Entity *pointMesh = mSceneMgr->createEntity(SceneManager::PT_CUBE); - pointNode->attachObject(pointMesh); - } + /// \todo Replace with ESM::Land::REAL_SIZE after merging with terrain branch + cellPathGridPos.x = store->cell->data.gridX * 8192; + cellPathGridPos.y = 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->y, it->z); + 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; - } + ESM::Pathgrid::EdgeList edges = pathgrid->edges; + for(ESM::Pathgrid::EdgeList::const_iterator it = edges.begin(); + it != edges.end(); it++) + { + ESM::Pathgrid::Edge edge = *it; + ESM::Pathgrid::Point p1 = points[edge.v0], p2 = points[edge.v1]; + cellPathGrid->attachObject(createPathgridLine(cellPathGrid->getCreator(), + Vector3(p1.x, p1.y, p1.z), + Vector3(p2.x, p2.y, p2.z))); + } + + if (!(store->cell->data.flags & ESM::Cell::Interior)) + { + mExteriorPathgridNodes[std::make_pair(store->cell->data.gridX, store->cell->data.gridY)] = cellPathGrid; } else { - if (!(store->cell->data.flags & ESM::Cell::Interior)) + assert(mInteriorPathgridNode == NULL); + mInteriorPathgridNode = cellPathGrid; + } +} + +void Debugging::disableCellPathgrid(MWWorld::Ptr::CellStore *store) +{ + 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()) { - ExteriorPathgridNodes::iterator it = - mExteriorPathgridNodes.find(std::make_pair(store->cell->data.gridX, store->cell->data.gridY)); - if (it != mExteriorPathgridNodes.end()) - { - destroyCellPathgridNode(it->second); - mExteriorPathgridNodes.erase(it); - } + destroyCellPathgridNode(it->second); + mExteriorPathgridNodes.erase(it); } - else + } + else + { + if (mInteriorPathgridNode) { - if (mInteriorPathgridNode) - { - destroyCellPathgridNode(mInteriorPathgridNode); - mInteriorPathgridNode = NULL; - } + destroyCellPathgridNode(mInteriorPathgridNode); + mInteriorPathgridNode = NULL; } } } @@ -148,17 +193,26 @@ void Debugging::destroyCellPathgridNode(SceneNode *node) { mPathGridRoot->removeChild(node); + /// \todo should object be killed by hand or removeAndDestroyAllChildren is sufficient? SceneNode::ChildNodeIterator childIt = node->getChildIterator(); while (childIt.hasMoreElements()) { SceneNode *child = static_cast(childIt.getNext()); - SceneNode::ObjectIterator objIt = child->getAttachedObjectIterator(); - while (objIt.hasMoreElements()) - { - MovableObject *mesh = static_cast(objIt.getNext()); - child->getCreator()->destroyMovableObject(mesh); - } + destroyAttachedObjects(child); } + destroyAttachedObjects(node); node->removeAndDestroyAllChildren(); mSceneMgr->destroySceneNode(node); } + +void Debugging::destroyAttachedObjects(SceneNode *node) +{ + SceneNode::ObjectIterator objIt = node->getAttachedObjectIterator(); + while (objIt.hasMoreElements()) + { + MovableObject *mesh = static_cast(objIt.getNext()); + node->getCreator()->destroyMovableObject(mesh); + } +} + +} diff --git a/apps/openmw/mwrender/debugging.hpp b/apps/openmw/mwrender/debugging.hpp index eb592b98d..cfa772330 100644 --- a/apps/openmw/mwrender/debugging.hpp +++ b/apps/openmw/mwrender/debugging.hpp @@ -52,12 +52,16 @@ namespace MWRender typedef std::map, Ogre::SceneNode *> ExteriorPathgridNodes; ExteriorPathgridNodes mExteriorPathgridNodes; - void togglePathgridForCell(MWWorld::Ptr::CellStore *store, bool enabled); + void enableCellPathgrid(MWWorld::Ptr::CellStore *store); + void disableCellPathgrid(MWWorld::Ptr::CellStore *store); + // utility void destroyCellPathgridNode(Ogre::SceneNode *node); + void destroyAttachedObjects(Ogre::SceneNode *node); public: Debugging(Ogre::SceneNode* mwRoot, MWWorld::Environment &env, OEngine::Physic::PhysicEngine *engine); + ~Debugging(); bool toggleRenderMode (int mode); void cellAdded(MWWorld::Ptr::CellStore* store); From a8e25bc32ce3c862b512b130531db24eb0f9f704 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Wed, 14 Mar 2012 15:03:04 +0400 Subject: [PATCH 08/19] Feature #37 (In Progress) Render Path Grid improved path grid point mesh (closer to vanilla MW) --- apps/openmw/mwrender/debugging.cpp | 96 +++++++++++++++++++++++------- apps/openmw/mwrender/debugging.hpp | 14 ++++- 2 files changed, 86 insertions(+), 24 deletions(-) diff --git a/apps/openmw/mwrender/debugging.cpp b/apps/openmw/mwrender/debugging.cpp index 3b01d4b36..aa98f433f 100644 --- a/apps/openmw/mwrender/debugging.cpp +++ b/apps/openmw/mwrender/debugging.cpp @@ -4,6 +4,8 @@ #include #include +#include +#include #include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone #include "../mwworld/environment.hpp" @@ -18,12 +20,15 @@ using namespace Ogre; namespace MWRender { +static const std::string PATHGRID_POINT_MATERIAL = "pathgridPointMaterial"; static const std::string PATHGRID_LINE_MATERIAL = "pathgridLineMaterial"; static const std::string DEBUGGING_GROUP = "debugging"; +static const int POINT_MESH_BASE = 80; -ManualObject *createPathgridLine(SceneManager* sceneMgr, const Vector3& from, const Vector3& to) +void Debugging::createGridMaterials() { - ManualObject *line = sceneMgr->createManualObject(); + if (mGridMatsCreated) return; + if (MaterialManager::getSingleton().getByName(PATHGRID_LINE_MATERIAL, DEBUGGING_GROUP).isNull()) { MaterialPtr lineMatPtr = MaterialManager::getSingleton().create(PATHGRID_LINE_MATERIAL, DEBUGGING_GROUP); @@ -34,6 +39,31 @@ ManualObject *createPathgridLine(SceneManager* sceneMgr, const Vector3& from, co lineMatPtr->getTechnique(0)->getPass(0)->setSelfIllumination(1,1,0); } + if (MaterialManager::getSingleton().getByName(PATHGRID_POINT_MATERIAL, DEBUGGING_GROUP).isNull()) + { + MaterialPtr pointMatPtr = MaterialManager::getSingleton().create(PATHGRID_POINT_MATERIAL, DEBUGGING_GROUP); + pointMatPtr->setReceiveShadows(false); + pointMatPtr->getTechnique(0)->setLightingEnabled(true); + pointMatPtr->getTechnique(0)->getPass(0)->setDiffuse(1,0,0,0); + pointMatPtr->getTechnique(0)->getPass(0)->setAmbient(1,0,0); + pointMatPtr->getTechnique(0)->getPass(0)->setSelfIllumination(1,0,0); + } + mGridMatsCreated = true; +} + +void Debugging::destroyGridMaterials() +{ + if (mGridMatsCreated) + { + MaterialManager::getSingleton().remove(PATHGRID_POINT_MATERIAL); + MaterialManager::getSingleton().remove(PATHGRID_LINE_MATERIAL); + mGridMatsCreated = false; + } +} + +MovableObject *Debugging::createPathgridLine(const Vector3& from, const Vector3& to) +{ + ManualObject *line = mSceneMgr->createManualObject(); line->begin(PATHGRID_LINE_MATERIAL, Ogre::RenderOperation::OT_LINE_LIST); line->position(from); line->position(to); @@ -42,21 +72,47 @@ ManualObject *createPathgridLine(SceneManager* sceneMgr, const Vector3& from, co return line; } -ManualObject *createPathgridPoint(SceneManager* sceneMgr, const Vector3& pos) +MovableObject *Debugging::createPathgridPoint() { + ManualObject *point = mSceneMgr->createManualObject(); + point->begin(PATHGRID_POINT_MATERIAL, Ogre::RenderOperation::OT_TRIANGLE_FAN); + float height = POINT_MESH_BASE /*/ sqrtf(2)*/; + point->position(0, 0, height); + point->position(-POINT_MESH_BASE, -POINT_MESH_BASE, 0); + point->position(POINT_MESH_BASE, -POINT_MESH_BASE, 0); + point->position(POINT_MESH_BASE, POINT_MESH_BASE, 0); + point->position(-POINT_MESH_BASE, POINT_MESH_BASE, 0); + point->position(-POINT_MESH_BASE, -POINT_MESH_BASE, 0); + point->end(); + point->begin(PATHGRID_POINT_MATERIAL, Ogre::RenderOperation::OT_TRIANGLE_FAN); + point->position(0, 0, -height); + point->position(-POINT_MESH_BASE, -POINT_MESH_BASE, 0); + point->position(-POINT_MESH_BASE, POINT_MESH_BASE, 0); + point->position(POINT_MESH_BASE, POINT_MESH_BASE, 0); + point->position(POINT_MESH_BASE, -POINT_MESH_BASE, 0); + point->position(-POINT_MESH_BASE, -POINT_MESH_BASE, 0); + point->end(); + + return point; } Debugging::Debugging(SceneNode *mwRoot, MWWorld::Environment &env, OEngine::Physic::PhysicEngine *engine) : mMwRoot(mwRoot), mEnvironment(env), mEngine(engine), mSceneMgr(mwRoot->getCreator()), - pathgridEnabled(false), - mInteriorPathgridNode(NULL), mPathGridRoot(NULL) + mPathgridEnabled(false), + mInteriorPathgridNode(NULL), mPathGridRoot(NULL), + mGridMatsCreated(false) { ResourceGroupManager::getSingleton().createResourceGroup(DEBUGGING_GROUP); } Debugging::~Debugging() { + if (mPathgridEnabled) + { + togglePathgrid(); + } + ResourceGroupManager::getSingleton().destroyResourceGroup(DEBUGGING_GROUP); } @@ -72,7 +128,7 @@ bool Debugging::toggleRenderMode (int mode){ return mEngine->isDebugCreated; case MWWorld::World::Render_Pathgrid: togglePathgrid(); - return pathgridEnabled; + return mPathgridEnabled; } return false; @@ -82,7 +138,7 @@ void Debugging::cellAdded(MWWorld::Ptr::CellStore *store) { std::cout << "Cell added to debugging" << std::endl; mActiveCells.push_back(store); - if (pathgridEnabled) + if (mPathgridEnabled) enableCellPathgrid(store); } @@ -90,15 +146,17 @@ 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) + if (mPathgridEnabled) disableCellPathgrid(store); } void Debugging::togglePathgrid() { - pathgridEnabled = !pathgridEnabled; - if (pathgridEnabled) + mPathgridEnabled = !mPathgridEnabled; + if (mPathgridEnabled) { + createGridMaterials(); + // add path grid meshes to already loaded cells mPathGridRoot = mMwRoot->createChildSceneNode(); for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); it++) @@ -106,7 +164,8 @@ void Debugging::togglePathgrid() enableCellPathgrid(*it); } } - else { + else + { // remove path grid meshes from already loaded cells for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); it++) { @@ -115,16 +174,14 @@ void Debugging::togglePathgrid() mPathGridRoot->removeAndDestroyAllChildren(); mSceneMgr->destroySceneNode(mPathGridRoot); mPathGridRoot = NULL; + destroyGridMaterials(); } } void Debugging::enableCellPathgrid(MWWorld::Ptr::CellStore *store) { ESM::Pathgrid *pathgrid = mEnvironment.mWorld->getStore().pathgrids.search(*store->cell); - if (!pathgrid) - { - return; - } + if (!pathgrid) return; Vector3 cellPathGridPos; /// \todo replace tests like this with isExterior method of ESM::Cell after merging with terrain branch @@ -141,8 +198,7 @@ void Debugging::enableCellPathgrid(MWWorld::Ptr::CellStore *store) Vector3 position(it->x, it->y, it->z); SceneNode* pointNode = cellPathGrid->createChildSceneNode(position); pointNode->setScale(0.5, 0.5, 0.5); - Entity *pointMesh = mSceneMgr->createEntity(SceneManager::PT_CUBE); - pointNode->attachObject(pointMesh); + pointNode->attachObject(createPathgridPoint()); } ESM::Pathgrid::EdgeList edges = pathgrid->edges; @@ -151,8 +207,7 @@ void Debugging::enableCellPathgrid(MWWorld::Ptr::CellStore *store) { ESM::Pathgrid::Edge edge = *it; ESM::Pathgrid::Point p1 = points[edge.v0], p2 = points[edge.v1]; - cellPathGrid->attachObject(createPathgridLine(cellPathGrid->getCreator(), - Vector3(p1.x, p1.y, p1.z), + cellPathGrid->attachObject(createPathgridLine(Vector3(p1.x, p1.y, p1.z), Vector3(p2.x, p2.y, p2.z))); } @@ -193,7 +248,6 @@ void Debugging::destroyCellPathgridNode(SceneNode *node) { mPathGridRoot->removeChild(node); - /// \todo should object be killed by hand or removeAndDestroyAllChildren is sufficient? SceneNode::ChildNodeIterator childIt = node->getChildIterator(); while (childIt.hasMoreElements()) { @@ -211,7 +265,7 @@ void Debugging::destroyAttachedObjects(SceneNode *node) while (objIt.hasMoreElements()) { MovableObject *mesh = static_cast(objIt.getNext()); - node->getCreator()->destroyMovableObject(mesh); + mSceneMgr->destroyMovableObject(mesh); } } diff --git a/apps/openmw/mwrender/debugging.hpp b/apps/openmw/mwrender/debugging.hpp index cfa772330..c8c19fb8c 100644 --- a/apps/openmw/mwrender/debugging.hpp +++ b/apps/openmw/mwrender/debugging.hpp @@ -37,20 +37,20 @@ namespace MWRender MWWorld::Environment& mEnvironment; // Path grid stuff - bool pathgridEnabled; + bool mPathgridEnabled; void togglePathgrid(); typedef std::vector CellList; - CellList mActiveCells; Ogre::SceneNode *mMwRoot; + Ogre::SceneNode *mPathGridRoot; - Ogre::SceneNode *mInteriorPathgridNode; typedef std::map, Ogre::SceneNode *> ExteriorPathgridNodes; ExteriorPathgridNodes mExteriorPathgridNodes; + Ogre::SceneNode *mInteriorPathgridNode; void enableCellPathgrid(MWWorld::Ptr::CellStore *store); void disableCellPathgrid(MWWorld::Ptr::CellStore *store); @@ -59,6 +59,14 @@ namespace MWRender void destroyCellPathgridNode(Ogre::SceneNode *node); void destroyAttachedObjects(Ogre::SceneNode *node); + // materials + bool mGridMatsCreated; + void createGridMaterials(); + void destroyGridMaterials(); + + // path grid meshes + Ogre::MovableObject* createPathgridLine(const Ogre::Vector3& from, const Ogre::Vector3& to); + Ogre::MovableObject* createPathgridPoint(); public: Debugging(Ogre::SceneNode* mwRoot, MWWorld::Environment &env, OEngine::Physic::PhysicEngine *engine); ~Debugging(); From 523648dbb1d14a5ff6d354cda81803950128e899 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Sat, 31 Mar 2012 14:50:10 +0400 Subject: [PATCH 09/19] Merge branch 'master' into pgrd-rendering Conflicts: apps/openmw/mwrender/debugging.cpp --- apps/openmw/engine.cpp | 9 +- apps/openmw/mwrender/debugging.cpp | 6 +- components/bsa/bsa_archive.cpp | 168 +++++++++++-------------- components/files/collections.cpp | 5 + components/files/collections.hpp | 2 + components/nifogre/ogre_nif_loader.cpp | 2 +- libs/openengine/bullet/physic.cpp | 10 +- libs/openengine/bullet/physic.hpp | 3 + 8 files changed, 103 insertions(+), 102 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 441c22769..38050e53b 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -204,13 +204,18 @@ OMW::Engine::~Engine() void OMW::Engine::loadBSA() { const Files::MultiDirCollection& bsa = mFileCollections.getCollection (".bsa"); - std::string dataDirectory; + for (Files::MultiDirCollection::TIter iter(bsa.begin()); iter!=bsa.end(); ++iter) { std::cout << "Adding " << iter->second.string() << std::endl; Bsa::addBSA(iter->second.string()); + } - dataDirectory = iter->second.parent_path().string(); + const Files::PathContainer& dataDirs = mFileCollections.getPaths(); + std::string dataDirectory; + for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter) + { + dataDirectory = iter->string(); std::cout << "Data dir " << dataDirectory << std::endl; Bsa::addDir(dataDirectory, mFSStrict); } diff --git a/apps/openmw/mwrender/debugging.cpp b/apps/openmw/mwrender/debugging.cpp index aa98f433f..ea7f143bb 100644 --- a/apps/openmw/mwrender/debugging.cpp +++ b/apps/openmw/mwrender/debugging.cpp @@ -121,11 +121,7 @@ bool Debugging::toggleRenderMode (int mode){ switch (mode) { case MWWorld::World::Render_CollisionDebug: - - // TODO use a proper function instead of accessing the member variable - // directly. - mEngine->setDebugRenderingMode (!mEngine->isDebugCreated); - return mEngine->isDebugCreated; + return mEngine->toggleDebugRendering(); case MWWorld::World::Render_Pathgrid: togglePathgrid(); return mPathgridEnabled; diff --git a/components/bsa/bsa_archive.cpp b/components/bsa/bsa_archive.cpp index 80d92dd52..41bff7e40 100644 --- a/components/bsa/bsa_archive.cpp +++ b/components/bsa/bsa_archive.cpp @@ -45,6 +45,20 @@ struct ciLessBoost : std::binary_function } }; +struct pathComparer +{ +private: + int m_start, m_size; + +public: + pathComparer(int start, int size) : m_start(start), m_size(size) { } + + bool operator() (const std::string& first, const std::string& other) + { + return lexicographical_compare(first.substr(m_start,m_size), other.substr(m_start,m_size), boost::algorithm::is_iless()); + } +}; + static bool fsstrict = false; /// An OGRE Archive wrapping a BSAFile archive @@ -55,16 +69,59 @@ class DirArchive: public Ogre::FileSystemArchive std::map, ciLessBoost> m; unsigned int cutoff; - bool comparePortion(std::string file1, std::string file2, int start, int size) const + bool findFile(const String& filename, std::string& copy) const { - for(int i = start; i < start+size; i++) { - char one = file1.at(i); - char two = file2.at(i); - if(tolower(one) != tolower(two) ) + String passed = filename; + if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<' + || filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':' + || filename.at(filename.length() - 1) == '|') + { + passed = filename.substr(0, filename.length() - 2); + } + if(filename.at(filename.length() - 2) == '>') + passed = filename.substr(0, filename.length() - 6); + copy = passed; + } + + std::replace(copy.begin(), copy.end(), '\\', '/'); + + if(copy.at(0) == '/') + copy.erase(0, 1); + + if(fsstrict == true) + return true; + + std::string folder; + int delimiter = 0; + size_t lastSlash = copy.rfind('/'); + if (lastSlash != std::string::npos) + { + folder = copy.substr(0, lastSlash); + delimiter = lastSlash+1; + } + + std::vector current; + { + std::map,ciLessBoost>::const_iterator found = m.find(folder); + + if (found == m.end()) + { return false; + } + else + current = found->second; } - return true; + + pathComparer comp(delimiter, copy.size() - delimiter-1); + std::vector::iterator find = std::lower_bound(current.begin(), current.end(), copy, comp); + if (find != current.end() && !comp(copy, current.front())) + { + copy = *find; + return true; + } + + return false; } public: @@ -83,16 +140,14 @@ class DirArchive: public Ogre::FileSystemArchive //need to cut off first boost::filesystem::directory_iterator dir_iter(d), dir_end; std::vector filesind; - boost::filesystem::path f; for(;dir_iter != dir_end; dir_iter++) { if(boost::filesystem::is_directory(*dir_iter)) populateMap(*dir_iter); else { - - f = *dir_iter; - std::string s = f.string(); + std::string s = dir_iter->path().string(); + std::replace(s.begin(), s.end(), '\\', '/'); std::string small; if(cutoff < s.size()) @@ -103,14 +158,17 @@ class DirArchive: public Ogre::FileSystemArchive filesind.push_back(small); } } + std::sort(filesind.begin(), filesind.end(), ciLessBoost()); + std::string small; std::string original = d.string(); + std::replace(original.begin(), original.end(), '\\', '/'); if(cutoff < original.size()) small = original.substr(cutoff, original.size() - cutoff); else small = original.substr(cutoff - 1, original.size() - cutoff); - m[small] = filesind; + m[small] = filesind; } bool isCaseSensitive() const { return fsstrict; } @@ -120,97 +178,21 @@ class DirArchive: public Ogre::FileSystemArchive void unload() {} bool exists(const String& filename) { - std::string copy = filename; - - - - for (unsigned int i = 0; i < filename.size(); i++) - { - if(copy.at(i) == '\\' ){ - copy.replace(i, 1, "/"); - } - } - - - if(copy.at(0) == '\\' || copy.at(0) == '/') - { - copy.erase(0, 1); - } - if(fsstrict == true) - { - //std::cout << "fsstrict " << copy << "\n"; + std::string copy; + + if (findFile(filename, copy)) return FileSystemArchive::exists(copy); - } - - - int last = copy.size() - 1; - int i = last; - - for (;last >= 0; i--) - { - if(copy.at(i) == '/' || copy.at(i) == '\\') - break; - } - - std::string folder = copy.substr(0, i); //folder with no slash - - std::vector& current = m[folder]; - - for(std::vector::iterator iter = current.begin(); iter != current.end(); iter++) - { - if(comparePortion(*iter, copy, i + 1, copy.size() - i -1) == true){ - return FileSystemArchive::exists(*iter); - } - } - return false; } DataStreamPtr open(const String& filename, bool readonly = true) const { - std::map, ciLessBoost> mlocal = m; - std::string copy = filename; - + std::string copy; - - for (unsigned int i = 0; i < filename.size(); i++) - { - if(copy.at(i) == '\\' ){ - copy.replace(i, 1, "/"); - } - } - - - if(copy.at(0) == '\\' || copy.at(0) == '/') - { - copy.erase(0, 1); - } - - if(fsstrict == true) - { + if (findFile(filename, copy)) return FileSystemArchive::open(copy, readonly); - } - - - int last = copy.size() - 1; - int i = last; - - for (;last >= 0; i--) - { - if(copy.at(i) == '/' || copy.at(i) == '\\') - break; - } - - std::string folder = copy.substr(0, i); //folder with no slash - std::vector current = mlocal[folder]; - - for(std::vector::iterator iter = current.begin(); iter != current.end(); iter++) - { - if(comparePortion(*iter, copy, i + 1, copy.size() - i -1) == true){ - return FileSystemArchive::open(*iter, readonly); - } - } + DataStreamPtr p; return p; } diff --git a/components/files/collections.cpp b/components/files/collections.cpp index 424b558e6..50340dca4 100644 --- a/components/files/collections.cpp +++ b/components/files/collections.cpp @@ -30,4 +30,9 @@ namespace Files return iter->second; } + + const Files::PathContainer& Collections::getPaths() const + { + return mDirectories; + } } diff --git a/components/files/collections.hpp b/components/files/collections.hpp index 1ddca9a5b..70aaec55e 100644 --- a/components/files/collections.hpp +++ b/components/files/collections.hpp @@ -21,6 +21,8 @@ namespace Files /// leading dot and must be all lower-case. const MultiDirCollection& getCollection(const std::string& extension) const; + const Files::PathContainer& getPaths() const; + private: typedef std::map MultiDirCollectionContainer; Files::PathContainer mDirectories; diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index f943231d0..2ab6ae621 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -1368,7 +1368,7 @@ void NIFLoader::loadResource(Resource *resource) if (!vfs->isFile(resourceName)) { - warn("File not found."); + warn("File "+resourceName+" not found."); return; } diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 8b9f3dfec..cc1f907a0 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -151,7 +151,8 @@ namespace Physic - PhysicEngine::PhysicEngine(BulletShapeLoader* shapeLoader) + PhysicEngine::PhysicEngine(BulletShapeLoader* shapeLoader) : + mDebugActive(0) { // Set up the collision configuration and dispatcher collisionConfiguration = new btDefaultCollisionConfiguration(); @@ -203,6 +204,13 @@ namespace Physic createDebugRendering(); } mDebugDrawer->setDebugMode(mode); + mDebugActive = mode; + } + + bool PhysicEngine::toggleDebugRendering() + { + setDebugRenderingMode(!mDebugActive); + return mDebugActive; } PhysicEngine::~PhysicEngine() diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 57ffe9130..16dac96f4 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -199,6 +199,8 @@ namespace Physic */ void setDebugRenderingMode(int mode); + bool toggleDebugRendering(); + /** * Return the closest object hit by a ray. If there are no objects, it will return ("",-1). */ @@ -230,6 +232,7 @@ namespace Physic //debug rendering BtOgre::DebugDrawer* mDebugDrawer; bool isDebugCreated; + bool mDebugActive; }; }} From 006e1cde850ea81e44b4758934a300ec2aae2018 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Sat, 31 Mar 2012 14:56:54 +0400 Subject: [PATCH 10/19] some updates after terrain merge --- apps/openmw/mwrender/debugging.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwrender/debugging.cpp b/apps/openmw/mwrender/debugging.cpp index ea7f143bb..179c6e0a4 100644 --- a/apps/openmw/mwrender/debugging.cpp +++ b/apps/openmw/mwrender/debugging.cpp @@ -180,12 +180,10 @@ void Debugging::enableCellPathgrid(MWWorld::Ptr::CellStore *store) if (!pathgrid) return; Vector3 cellPathGridPos; - /// \todo replace tests like this with isExterior method of ESM::Cell after merging with terrain branch - if (!(store->cell->data.flags & ESM::Cell::Interior)) + if (store->cell->isExterior()) { - /// \todo Replace with ESM::Land::REAL_SIZE after merging with terrain branch - cellPathGridPos.x = store->cell->data.gridX * 8192; - cellPathGridPos.y = store->cell->data.gridY * 8192; + cellPathGridPos.x = store->cell->data.gridX * ESM::Land::REAL_SIZE; + cellPathGridPos.y = store->cell->data.gridY * ESM::Land::REAL_SIZE; } SceneNode *cellPathGrid = mPathGridRoot->createChildSceneNode(cellPathGridPos); ESM::Pathgrid::PointList points = pathgrid->points; @@ -207,7 +205,7 @@ void Debugging::enableCellPathgrid(MWWorld::Ptr::CellStore *store) Vector3(p2.x, p2.y, p2.z))); } - if (!(store->cell->data.flags & ESM::Cell::Interior)) + if (store->cell->isExterior()) { mExteriorPathgridNodes[std::make_pair(store->cell->data.gridX, store->cell->data.gridY)] = cellPathGrid; } @@ -220,7 +218,7 @@ void Debugging::enableCellPathgrid(MWWorld::Ptr::CellStore *store) void Debugging::disableCellPathgrid(MWWorld::Ptr::CellStore *store) { - if (!(store->cell->data.flags & ESM::Cell::Interior)) + if (store->cell->isExterior()) { ExteriorPathgridNodes::iterator it = mExteriorPathgridNodes.find(std::make_pair(store->cell->data.gridX, store->cell->data.gridY)); From 5e829362cb2d7cb12b14c3316f854da5920aa6ea Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Sat, 31 Mar 2012 16:22:55 +0400 Subject: [PATCH 11/19] Feature #37 (In Progress) Render Path Grid more similar to vanilla path grid rendering --- apps/openmw/mwrender/debugging.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/debugging.cpp b/apps/openmw/mwrender/debugging.cpp index 179c6e0a4..f768de661 100644 --- a/apps/openmw/mwrender/debugging.cpp +++ b/apps/openmw/mwrender/debugging.cpp @@ -201,8 +201,13 @@ void Debugging::enableCellPathgrid(MWWorld::Ptr::CellStore *store) { ESM::Pathgrid::Edge edge = *it; ESM::Pathgrid::Point p1 = points[edge.v0], p2 = points[edge.v1]; - cellPathGrid->attachObject(createPathgridLine(Vector3(p1.x, p1.y, p1.z), - Vector3(p2.x, p2.y, p2.z))); + + Vector3 direction = (Vector3(p2.x, p2.y, p2.z) - Vector3(p1.x, p1.y, p1.z)); + Vector3 lineDisplacement = direction.crossProduct(Vector3::UNIT_Z).normalisedCopy(); + lineDisplacement = lineDisplacement * POINT_MESH_BASE/2 + + Vector3(0, 0, 10); // move lines up a little, so they will be less covered by meshes/landscape + cellPathGrid->attachObject(createPathgridLine(Vector3(p1.x, p1.y, p1.z) + lineDisplacement, + Vector3(p2.x, p2.y, p2.z) + lineDisplacement)); } if (store->cell->isExterior()) From 4e63f89829fbd0d64f6b782c60849f0776987ed8 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 1 Apr 2012 13:09:30 +0200 Subject: [PATCH 12/19] silence an error regarding faced handle --- apps/openmw/engine.cpp | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 441c22769..2da5456e6 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -82,12 +82,20 @@ void OMW::Engine::updateFocusReport (float duration) if (!handle.empty()) { - MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle); + // the faced handle is not updated immediately, so on a cell change it might + // point to an object that doesn't exist anymore + // therefore, we are catching the "Unknown Ogre handle" exception that occurs in this case + try + { + MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle); - if (!ptr.isEmpty()){ - name = MWWorld::Class::get (ptr).getName (ptr); + if (!ptr.isEmpty()){ + name = MWWorld::Class::get (ptr).getName (ptr); + } } + catch (std::runtime_error& e) + {} } if (name!=mFocusName) @@ -415,10 +423,21 @@ void OMW::Engine::activate() if (handle.empty()) return; - MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle); + // the faced handle is not updated immediately, so on a cell change it might + // point to an object that doesn't exist anymore + // therefore, we are catching the "Unknown Ogre handle" exception that occurs in this case + MWWorld::Ptr ptr; + try + { + ptr = mEnvironment.mWorld->getPtrViaHandle (handle); - if (ptr.isEmpty()) + if (ptr.isEmpty()) + return; + } + catch (std::runtime_error&) + { return; + } MWScript::InterpreterContext interpreterContext (mEnvironment, &ptr.getRefData().getLocals(), ptr); From 80456778be3e51e177626e1e28da2fa907251658 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 1 Apr 2012 14:22:04 +0200 Subject: [PATCH 13/19] fix for pickup up transparent objects, workaround for doors --- apps/openmw/mwrender/occlusionquery.cpp | 42 ++++++++++++++++++++-- apps/openmw/mwrender/occlusionquery.hpp | 8 +++++ apps/openmw/mwworld/world.cpp | 46 ++++++++++++++++++++----- 3 files changed, 85 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwrender/occlusionquery.cpp b/apps/openmw/mwrender/occlusionquery.cpp index cc3464c64..6215a6f19 100644 --- a/apps/openmw/mwrender/occlusionquery.cpp +++ b/apps/openmw/mwrender/occlusionquery.cpp @@ -5,6 +5,7 @@ #include #include #include +#include using namespace MWRender; using namespace Ogre; @@ -12,7 +13,7 @@ using namespace Ogre; OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNode* sunNode) : mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mSingleObjectQuery(0), mActiveQuery(0), mDoQuery(0), mSunVisibility(0), mQuerySingleObjectStarted(false), mTestResult(false), - mQuerySingleObjectRequested(false), mWasVisible(false), mObjectWasVisible(false), mDoQuery2(false) + mQuerySingleObjectRequested(false), mWasVisible(false), mObjectWasVisible(false) { mRendering = renderer; mSunNode = sunNode; @@ -82,7 +83,6 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod mRendering->getScene()->addRenderObjectListener(this); mRendering->getScene()->addRenderQueueListener(this); mDoQuery = true; - mDoQuery2 = true; } OcclusionQuery::~OcclusionQuery() @@ -190,7 +190,6 @@ void OcclusionQuery::update(float duration) // Stop occlusion queries until we get their information // (may not happen on the same frame they are requested in) mDoQuery = false; - mDoQuery2 = false; if (!mSunTotalAreaQuery->isStillOutstanding() && !mSunVisibleAreaQuery->isStillOutstanding() @@ -252,3 +251,40 @@ bool OcclusionQuery::getTestResult() return mTestResult; } + +bool OcclusionQuery::isPotentialOccluder(Ogre::SceneNode* node) +{ + bool result = false; + for (unsigned int i=0; i < node->numAttachedObjects(); ++i) + { + MovableObject* ob = node->getAttachedObject(i); + std::string type = ob->getMovableType(); + if (type == "Entity") + { + Entity* ent = static_cast(ob); + for (unsigned int j=0; j < ent->getNumSubEntities(); ++j) + { + // if any sub entity has a material with depth write off, + // consider the object as not an occluder + MaterialPtr mat = ent->getSubEntity(j)->getMaterial(); + + Material::TechniqueIterator techIt = mat->getTechniqueIterator(); + while (techIt.hasMoreElements()) + { + Technique* tech = techIt.getNext(); + Technique::PassIterator passIt = tech->getPassIterator(); + while (passIt.hasMoreElements()) + { + Pass* pass = passIt.getNext(); + + if (pass->getDepthWriteEnabled() == false) + return false; + else + result = true; + } + } + } + } + } + return result; +} diff --git a/apps/openmw/mwrender/occlusionquery.hpp b/apps/openmw/mwrender/occlusionquery.hpp index ebdc51311..934d963ac 100644 --- a/apps/openmw/mwrender/occlusionquery.hpp +++ b/apps/openmw/mwrender/occlusionquery.hpp @@ -46,6 +46,14 @@ namespace MWRender */ bool occlusionTestPending(); + /** + * Checks if the objects held by this scenenode + * can be considered as potential occluders + * (which might not be the case when transparency is involved) + * @param Scene node + */ + bool isPotentialOccluder(Ogre::SceneNode* node); + /** * @return true if the object tested in the last request was occluded */ diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 6f03fa37f..47e608624 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -750,15 +750,16 @@ namespace MWWorld // figure out which object we want to test against std::vector < std::pair < float, std::string > > results = mPhysics->getFacedObjects(); - // ignore the player - for (std::vector < std::pair < float, std::string > >::iterator it = results.begin(); - it != results.end(); ++it) + // ignore the player and other things we're not interested in + std::vector < std::pair < float, std::string > >::iterator it = results.begin(); + while (it != results.end()) { - if ( (*it).second == mPlayer->getPlayer().getRefData().getHandle() ) + if ( (*it).second == mPlayer->getPlayer().getRefData().getHandle()) { - results.erase(it); - break; + it = results.erase(it); } + else + ++it; } if (results.size() == 0) @@ -774,6 +775,7 @@ namespace MWWorld btVector3 p = mPhysics->getRayPoint(results.front().first); Ogre::Vector3 pos(p.x(), p.z(), -p.y()); Ogre::SceneNode* node = mFaced1.getRefData().getBaseNode(); + query->occlusionTest(pos, node); } else @@ -784,10 +786,38 @@ namespace MWWorld mFaced2 = getPtrViaHandle(results[1].second); mNumFacing = 2; + //std::cout << "Num facing 2 : " << mFaced1Name << " " << mFaced2Name << std::endl; + //std::cout << "Type 1 " << mFaced1.getTypeName() << " " << mFaced2.getTypeName() << std::endl; + btVector3 p = mPhysics->getRayPoint(results[1].first); Ogre::Vector3 pos(p.x(), p.z(), -p.y()); - Ogre::SceneNode* node = mFaced2.getRefData().getBaseNode(); - query->occlusionTest(pos, node); + Ogre::SceneNode* node1 = mFaced1.getRefData().getBaseNode(); + Ogre::SceneNode* node2 = mFaced2.getRefData().getBaseNode(); + + // no need to test if the first node is not occluder + if (!query->isPotentialOccluder(node1) && (mFaced1.getTypeName().find("Static") == std::string::npos)) + { + mFacedHandle = mFaced1Name; + //std::cout << "node1 Not an occluder" << std::endl; + return; + } + + // no need to test if the second object is static (thus cannot be activated) + if (mFaced2.getTypeName().find("Static") != std::string::npos) + { + mFacedHandle = mFaced1Name; + return; + } + + // work around door problems + if (mFaced1.getTypeName().find("Static") != std::string::npos + && mFaced2.getTypeName().find("Door") != std::string::npos) + { + mFacedHandle = mFaced2Name; + return; + } + + query->occlusionTest(pos, node2); } } } From df8e0bbff2533a5d9b9c1ef11ca2f4589663b1ed Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 1 Apr 2012 14:53:41 +0200 Subject: [PATCH 14/19] player check --- apps/openmw/mwworld/world.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 47e608624..9ca31b5d3 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -754,7 +754,7 @@ namespace MWWorld std::vector < std::pair < float, std::string > >::iterator it = results.begin(); while (it != results.end()) { - if ( (*it).second == mPlayer->getPlayer().getRefData().getHandle()) + if ( getPtrViaHandle((*it).second) == mPlayer->getPlayer() ) { it = results.erase(it); } @@ -776,6 +776,9 @@ namespace MWWorld Ogre::Vector3 pos(p.x(), p.z(), -p.y()); Ogre::SceneNode* node = mFaced1.getRefData().getBaseNode(); + //std::cout << "Num facing 1 : " << mFaced1Name << std::endl; + //std::cout << "Type 1 " << mFaced1.getTypeName() << std::endl; + query->occlusionTest(pos, node); } else @@ -786,8 +789,8 @@ namespace MWWorld mFaced2 = getPtrViaHandle(results[1].second); mNumFacing = 2; - //std::cout << "Num facing 2 : " << mFaced1Name << " " << mFaced2Name << std::endl; - //std::cout << "Type 1 " << mFaced1.getTypeName() << " " << mFaced2.getTypeName() << std::endl; + std::cout << "Num facing 2 : " << mFaced1Name << " " << mFaced2Name << std::endl; + std::cout << "Type 1 " << mFaced1.getTypeName() << " " << mFaced2.getTypeName() << std::endl; btVector3 p = mPhysics->getRayPoint(results[1].first); Ogre::Vector3 pos(p.x(), p.z(), -p.y()); From cab412c225703cfda26efc5d20be8fc9bfde4c5f Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Sun, 1 Apr 2012 17:27:18 +0400 Subject: [PATCH 15/19] Feature #37 (In Progress) Render Path Grid optimisation, now it takes only two batches per cell. --- apps/openmw/mwrender/debugging.cpp | 134 ++++++++++++++++------------- apps/openmw/mwrender/debugging.hpp | 4 +- 2 files changed, 75 insertions(+), 63 deletions(-) diff --git a/apps/openmw/mwrender/debugging.cpp b/apps/openmw/mwrender/debugging.cpp index f768de661..730370ae1 100644 --- a/apps/openmw/mwrender/debugging.cpp +++ b/apps/openmw/mwrender/debugging.cpp @@ -23,7 +23,7 @@ namespace MWRender static const std::string PATHGRID_POINT_MATERIAL = "pathgridPointMaterial"; static const std::string PATHGRID_LINE_MATERIAL = "pathgridLineMaterial"; static const std::string DEBUGGING_GROUP = "debugging"; -static const int POINT_MESH_BASE = 80; +static const int POINT_MESH_BASE = 40; void Debugging::createGridMaterials() { @@ -61,39 +61,80 @@ void Debugging::destroyGridMaterials() } } -MovableObject *Debugging::createPathgridLine(const Vector3& from, const Vector3& to) +ManualObject *Debugging::createPathgridLines(const ESM::Pathgrid *pathgrid) { - ManualObject *line = mSceneMgr->createManualObject(); - line->begin(PATHGRID_LINE_MATERIAL, Ogre::RenderOperation::OT_LINE_LIST); - line->position(from); - line->position(to); - line->end(); + ManualObject *result = mSceneMgr->createManualObject(); - return line; + result->begin(PATHGRID_LINE_MATERIAL, RenderOperation::OT_LINE_LIST); + for(ESM::Pathgrid::EdgeList::const_iterator it = pathgrid->edges.begin(); + it != pathgrid->edges.end(); + it++) + { + const ESM::Pathgrid::Edge &edge = *it; + const ESM::Pathgrid::Point &p1 = pathgrid->points[edge.v0], &p2 = pathgrid->points[edge.v1]; + Vector3 direction = (Vector3(p2.x, p2.y, p2.z) - Vector3(p1.x, p1.y, p1.z)); + Vector3 lineDisplacement = direction.crossProduct(Vector3::UNIT_Z).normalisedCopy(); + lineDisplacement = lineDisplacement * POINT_MESH_BASE/2 + Vector3(0, 0, 10); // move lines up a little, so they will be less covered by meshes/landscape + result->position(Vector3(p1.x, p1.y, p1.z) + lineDisplacement); + result->position(Vector3(p2.x, p2.y, p2.z) + lineDisplacement); + } + result->end(); + + return result; } -MovableObject *Debugging::createPathgridPoint() +ManualObject *Debugging::createPathgridPoints(const ESM::Pathgrid *pathgrid) { - ManualObject *point = mSceneMgr->createManualObject(); - point->begin(PATHGRID_POINT_MATERIAL, Ogre::RenderOperation::OT_TRIANGLE_FAN); - float height = POINT_MESH_BASE /*/ sqrtf(2)*/; - point->position(0, 0, height); - point->position(-POINT_MESH_BASE, -POINT_MESH_BASE, 0); - point->position(POINT_MESH_BASE, -POINT_MESH_BASE, 0); - point->position(POINT_MESH_BASE, POINT_MESH_BASE, 0); - point->position(-POINT_MESH_BASE, POINT_MESH_BASE, 0); - point->position(-POINT_MESH_BASE, -POINT_MESH_BASE, 0); - point->end(); - point->begin(PATHGRID_POINT_MATERIAL, Ogre::RenderOperation::OT_TRIANGLE_FAN); - point->position(0, 0, -height); - point->position(-POINT_MESH_BASE, -POINT_MESH_BASE, 0); - point->position(-POINT_MESH_BASE, POINT_MESH_BASE, 0); - point->position(POINT_MESH_BASE, POINT_MESH_BASE, 0); - point->position(POINT_MESH_BASE, -POINT_MESH_BASE, 0); - point->position(-POINT_MESH_BASE, -POINT_MESH_BASE, 0); - point->end(); - - return point; + ManualObject *result = mSceneMgr->createManualObject(); + const float height = POINT_MESH_BASE /*/ sqrtf(2)*/; + + result->begin(PATHGRID_POINT_MATERIAL, RenderOperation::OT_TRIANGLE_STRIP); + + bool first = true; + uint32 startIndex = 0; + for(ESM::Pathgrid::PointList::const_iterator it = pathgrid->points.begin(); + it != pathgrid->points.end(); + it++, startIndex += 6) + { + Vector3 pointPos(it->x, it->y, it->z); + + if (!first) + { + // degenerate triangle from previous octahedron + result->index(startIndex - 4); // 2nd point of previous octahedron + result->index(startIndex); // start point of current octahedron + } + + result->position(pointPos + Vector3(0, 0, height)); // 0 + result->position(pointPos + Vector3(-POINT_MESH_BASE, -POINT_MESH_BASE, 0)); // 1 + result->position(pointPos + Vector3(POINT_MESH_BASE, -POINT_MESH_BASE, 0)); // 2 + result->position(pointPos + Vector3(POINT_MESH_BASE, POINT_MESH_BASE, 0)); // 3 + result->position(pointPos + Vector3(-POINT_MESH_BASE, POINT_MESH_BASE, 0)); // 4 + result->position(pointPos + Vector3(0, 0, -height)); // 5 + + result->index(startIndex + 0); + result->index(startIndex + 1); + result->index(startIndex + 2); + result->index(startIndex + 5); + result->index(startIndex + 3); + result->index(startIndex + 4); + // degenerates + result->index(startIndex + 4); + result->index(startIndex + 5); + result->index(startIndex + 5); + // end degenerates + result->index(startIndex + 1); + result->index(startIndex + 4); + result->index(startIndex + 0); + result->index(startIndex + 3); + result->index(startIndex + 2); + + first = false; + } + + result->end(); + + return result; } Debugging::Debugging(SceneNode *mwRoot, MWWorld::Environment &env, OEngine::Physic::PhysicEngine *engine) : @@ -179,36 +220,15 @@ void Debugging::enableCellPathgrid(MWWorld::Ptr::CellStore *store) ESM::Pathgrid *pathgrid = mEnvironment.mWorld->getStore().pathgrids.search(*store->cell); if (!pathgrid) return; - Vector3 cellPathGridPos; + Vector3 cellPathGridPos(0, 0, 0); if (store->cell->isExterior()) { cellPathGridPos.x = store->cell->data.gridX * ESM::Land::REAL_SIZE; cellPathGridPos.y = store->cell->data.gridY * ESM::Land::REAL_SIZE; } 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->y, it->z); - SceneNode* pointNode = cellPathGrid->createChildSceneNode(position); - pointNode->setScale(0.5, 0.5, 0.5); - pointNode->attachObject(createPathgridPoint()); - } - - ESM::Pathgrid::EdgeList edges = pathgrid->edges; - for(ESM::Pathgrid::EdgeList::const_iterator it = edges.begin(); - it != edges.end(); it++) - { - ESM::Pathgrid::Edge edge = *it; - ESM::Pathgrid::Point p1 = points[edge.v0], p2 = points[edge.v1]; - - Vector3 direction = (Vector3(p2.x, p2.y, p2.z) - Vector3(p1.x, p1.y, p1.z)); - Vector3 lineDisplacement = direction.crossProduct(Vector3::UNIT_Z).normalisedCopy(); - lineDisplacement = lineDisplacement * POINT_MESH_BASE/2 + - Vector3(0, 0, 10); // move lines up a little, so they will be less covered by meshes/landscape - cellPathGrid->attachObject(createPathgridLine(Vector3(p1.x, p1.y, p1.z) + lineDisplacement, - Vector3(p2.x, p2.y, p2.z) + lineDisplacement)); - } + cellPathGrid->attachObject(createPathgridLines(pathgrid)); + cellPathGrid->attachObject(createPathgridPoints(pathgrid)); if (store->cell->isExterior()) { @@ -246,15 +266,7 @@ void Debugging::disableCellPathgrid(MWWorld::Ptr::CellStore *store) void Debugging::destroyCellPathgridNode(SceneNode *node) { mPathGridRoot->removeChild(node); - - SceneNode::ChildNodeIterator childIt = node->getChildIterator(); - while (childIt.hasMoreElements()) - { - SceneNode *child = static_cast(childIt.getNext()); - destroyAttachedObjects(child); - } destroyAttachedObjects(node); - node->removeAndDestroyAllChildren(); mSceneMgr->destroySceneNode(node); } diff --git a/apps/openmw/mwrender/debugging.hpp b/apps/openmw/mwrender/debugging.hpp index c8c19fb8c..ebf3884dc 100644 --- a/apps/openmw/mwrender/debugging.hpp +++ b/apps/openmw/mwrender/debugging.hpp @@ -65,8 +65,8 @@ namespace MWRender void destroyGridMaterials(); // path grid meshes - Ogre::MovableObject* createPathgridLine(const Ogre::Vector3& from, const Ogre::Vector3& to); - Ogre::MovableObject* createPathgridPoint(); + Ogre::ManualObject *createPathgridLines(const ESM::Pathgrid *pathgrid); + Ogre::ManualObject *createPathgridPoints(const ESM::Pathgrid *pathgrid); public: Debugging(Ogre::SceneNode* mwRoot, MWWorld::Environment &env, OEngine::Physic::PhysicEngine *engine); ~Debugging(); From 30d6c880ffd0ed4253ca368324a76eaeb9b24ed4 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Sun, 1 Apr 2012 17:51:37 +0400 Subject: [PATCH 16/19] Feature #37 (In Progress) Render Path Grid tuned sized a bit --- apps/openmw/mwrender/debugging.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwrender/debugging.cpp b/apps/openmw/mwrender/debugging.cpp index 730370ae1..6182258bb 100644 --- a/apps/openmw/mwrender/debugging.cpp +++ b/apps/openmw/mwrender/debugging.cpp @@ -23,7 +23,7 @@ namespace MWRender static const std::string PATHGRID_POINT_MATERIAL = "pathgridPointMaterial"; static const std::string PATHGRID_LINE_MATERIAL = "pathgridLineMaterial"; static const std::string DEBUGGING_GROUP = "debugging"; -static const int POINT_MESH_BASE = 40; +static const int POINT_MESH_BASE = 35; void Debugging::createGridMaterials() { @@ -74,7 +74,8 @@ ManualObject *Debugging::createPathgridLines(const ESM::Pathgrid *pathgrid) const ESM::Pathgrid::Point &p1 = pathgrid->points[edge.v0], &p2 = pathgrid->points[edge.v1]; Vector3 direction = (Vector3(p2.x, p2.y, p2.z) - Vector3(p1.x, p1.y, p1.z)); Vector3 lineDisplacement = direction.crossProduct(Vector3::UNIT_Z).normalisedCopy(); - lineDisplacement = lineDisplacement * POINT_MESH_BASE/2 + Vector3(0, 0, 10); // move lines up a little, so they will be less covered by meshes/landscape + lineDisplacement = lineDisplacement * POINT_MESH_BASE + + Vector3(0, 0, 10); // move lines up a little, so they will be less covered by meshes/landscape result->position(Vector3(p1.x, p1.y, p1.z) + lineDisplacement); result->position(Vector3(p2.x, p2.y, p2.z) + lineDisplacement); } @@ -86,7 +87,7 @@ ManualObject *Debugging::createPathgridLines(const ESM::Pathgrid *pathgrid) ManualObject *Debugging::createPathgridPoints(const ESM::Pathgrid *pathgrid) { ManualObject *result = mSceneMgr->createManualObject(); - const float height = POINT_MESH_BASE /*/ sqrtf(2)*/; + const float height = POINT_MESH_BASE * sqrtf(2); result->begin(PATHGRID_POINT_MATERIAL, RenderOperation::OT_TRIANGLE_STRIP); From cec9562282b89c9e3e15e35e8e7daf7ebf095cce Mon Sep 17 00:00:00 2001 From: "Alexander \"Ace\" Olofsson" Date: Sun, 1 Apr 2012 20:29:00 +0200 Subject: [PATCH 17/19] Fixing an ambigous symbol --- apps/openmw/mwworld/weather.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 9a918c2fb..09fd20076 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -34,7 +34,7 @@ const float WeatherGlobals::mThunderFrequency = .4; const float WeatherGlobals::mThunderThreshold = 0.6; const float WeatherGlobals::mThunderSoundDelay = 0.25; -WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environment* env) : +WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, MWWorld::Environment* env) : mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0), mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0) { From 2147210ad7ab001b8789689b6e0556dba4c95183 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 1 Apr 2012 12:46:49 -0700 Subject: [PATCH 18/19] Don't set an underwater environment when there's no water --- apps/openmw/mwsound/soundmanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp index a96aac6c5..1c6e548b6 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanager.cpp @@ -407,7 +407,7 @@ namespace MWSound if(!isMusicPlaying()) startRandomTitle(); - MWWorld::Ptr::CellStore *current = mEnvironment.mWorld->getPlayer().getPlayer().getCell(); + const ESM::Cell *cell = mEnvironment.mWorld->getPlayer().getPlayer().getCell()->cell; Ogre::Camera *cam = mEnvironment.mWorld->getPlayer().getRenderer()->getCamera(); Ogre::Vector3 nPos, nDir, nUp; nPos = cam->getRealPosition(); @@ -415,7 +415,7 @@ namespace MWSound nUp = cam->getRealUp(); Environment env = Env_Normal; - if(nPos.y < current->cell->water) + if((cell->data.flags&cell->HasWater) && nPos.y < cell->water) env = Env_Underwater; // The output handler is expecting vectors oriented like the game From 63e0e820499757a6bbbbf453778756f3e430a455 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 1 Apr 2012 15:02:07 -0700 Subject: [PATCH 19/19] Implement an Audiere-based decoder --- CMakeLists.txt | 8 ++ apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwsound/audiere_decoder.cpp | 122 ++++++++++++++++++++++++ apps/openmw/mwsound/audiere_decoder.hpp | 42 ++++++++ apps/openmw/mwsound/soundmanager.cpp | 11 ++- 5 files changed, 182 insertions(+), 3 deletions(-) create mode 100644 apps/openmw/mwsound/audiere_decoder.cpp create mode 100644 apps/openmw/mwsound/audiere_decoder.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 538e6a2fb..5d9ef04af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,7 @@ option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries # Sound source selection option(USE_FFMPEG "use ffmpeg for sound" OFF) +option(USE_AUDIERE "use audiere for sound" OFF) option(USE_MPG123 "use mpg123 + libsndfile for sound" ON) find_program(DPKG_PROGRAM dpkg DOC "dpkg program of Debian-based systems") @@ -133,6 +134,13 @@ if (USE_FFMPEG) set(SOUND_DEFINE ${SOUND_DEFINE} -DOPENMW_USE_FFMPEG) endif (USE_FFMPEG) +if (USE_AUDIERE) + find_package(Audiere REQUIRED) + set(SOUND_INPUT_INCLUDES ${SOUND_INPUT_INCLUDES} ${AUDIERE_INCLUDE_DIR}) + set(SOUND_INPUT_LIBRARY ${SOUND_INPUT_LIBRARY} ${AUDIERE_LIBRARY}) + set(SOUND_DEFINE ${SOUND_DEFINE} -DOPENMW_USE_AUDIERE) +endif (USE_AUDIERE) + if (USE_MPG123) find_package(MPG123 REQUIRED) find_package(SNDFILE REQUIRED) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 3dabc9ac8..873c23a9b 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -39,7 +39,7 @@ add_openmw_dir (mwscript ) add_openmw_dir (mwsound - soundmanager openal_output mpgsnd_decoder ffmpeg_decoder + soundmanager openal_output audiere_decoder mpgsnd_decoder ffmpeg_decoder ) add_openmw_dir (mwworld diff --git a/apps/openmw/mwsound/audiere_decoder.cpp b/apps/openmw/mwsound/audiere_decoder.cpp new file mode 100644 index 000000000..acc2e5283 --- /dev/null +++ b/apps/openmw/mwsound/audiere_decoder.cpp @@ -0,0 +1,122 @@ +#ifdef OPENMW_USE_AUDIERE + +#include +#include + +#include "audiere_decoder.hpp" + + +static void fail(const std::string &msg) +{ throw std::runtime_error("Audiere exception: "+msg); } + +namespace MWSound +{ + +class OgreFile : public audiere::File +{ + Ogre::DataStreamPtr mStream; + + ADR_METHOD(int) read(void* buffer, int size) + { + return mStream->read(buffer, size); + } + + ADR_METHOD(bool) seek(int position, SeekMode mode) + { + if(mode == CURRENT) + mStream->seek(mStream->tell()+position); + else if(mode == BEGIN) + mStream->seek(position); + else if(mode == END) + mStream->seek(mStream->size()+position); + else + return false; + + return true; + } + + ADR_METHOD(int) tell() + { + return mStream->tell(); + } + + size_t refs; + virtual void ref() { ++refs; } + virtual void unref() + { + if(--refs == 0) + delete this; + } + +public: + OgreFile(const Ogre::DataStreamPtr &stream) + : mStream(stream), refs(1) + { } + virtual ~OgreFile() { } +}; + + +void Audiere_Decoder::open(const std::string &fname) +{ + close(); + + audiere::FilePtr file(new OgreFile(mResourceMgr.openResource(fname))); + mSoundSource = audiere::OpenSampleSource(file); + + int channels, srate; + audiere::SampleFormat format; + + mSoundSource->getFormat(channels, srate, format); + if(format == audiere::SF_S16) + mSampleType = SampleType_Int16; + else if(format == audiere::SF_U8) + mSampleType = SampleType_UInt8; + else + fail("Unsupported sample type"); + + if(channels == 1) + mChannelConfig = ChannelConfig_Mono; + else if(channels == 2) + mChannelConfig = ChannelConfig_Stereo; + else + fail("Unsupported channel count"); + + mSampleRate = srate; +} + +void Audiere_Decoder::close() +{ + mSoundSource = NULL; +} + +void Audiere_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) +{ + *samplerate = mSampleRate; + *chans = mChannelConfig; + *type = mSampleType; +} + +size_t Audiere_Decoder::read(char *buffer, size_t bytes) +{ + int size = bytesToFrames(bytes, mChannelConfig, mSampleType); + size = mSoundSource->read(size, buffer); + return framesToBytes(size, mChannelConfig, mSampleType); +} + +void Audiere_Decoder::rewind() +{ + mSoundSource->reset(); +} + +Audiere_Decoder::Audiere_Decoder() +{ +} + +Audiere_Decoder::~Audiere_Decoder() +{ + close(); +} + +} + +#endif diff --git a/apps/openmw/mwsound/audiere_decoder.hpp b/apps/openmw/mwsound/audiere_decoder.hpp new file mode 100644 index 000000000..0ad026d51 --- /dev/null +++ b/apps/openmw/mwsound/audiere_decoder.hpp @@ -0,0 +1,42 @@ +#ifndef GAME_SOUND_AUDIERE_DECODER_H +#define GAME_SOUND_AUDIERE_DECODER_H + +#include + +#include "audiere.h" + +#include "sound_decoder.hpp" + + +namespace MWSound +{ + class Audiere_Decoder : public Sound_Decoder + { + audiere::SampleSourcePtr mSoundSource; + int mSampleRate; + SampleType mSampleType; + ChannelConfig mChannelConfig; + + virtual void open(const std::string &fname); + virtual void close(); + + virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type); + + virtual size_t read(char *buffer, size_t bytes); + virtual void rewind(); + + Audiere_Decoder& operator=(const Audiere_Decoder &rhs); + Audiere_Decoder(const Audiere_Decoder &rhs); + + Audiere_Decoder(); + public: + virtual ~Audiere_Decoder(); + + friend class SoundManager; + }; +#ifndef DEFAULT_DECODER +#define DEFAULT_DECODER (::MWSound::Audiere_Decoder) +#endif +}; + +#endif diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp index 1c6e548b6..145390e3e 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanager.cpp @@ -18,8 +18,8 @@ #include "openal_output.hpp" #define SOUND_OUT "OpenAL" -/* Set up the sound manager to use FFMPEG or MPG123+libsndfile for input. The - * OPENMW_USE_x macros are set in CMakeLists.txt. +/* Set up the sound manager to use FFMPEG, MPG123+libsndfile, or Audiere for + * input. The OPENMW_USE_x macros are set in CMakeLists.txt. */ #ifdef OPENMW_USE_FFMPEG #include "ffmpeg_decoder.hpp" @@ -28,6 +28,13 @@ #endif #endif +#ifdef OPENMW_USE_AUDIERE +#include "audiere_decoder.hpp" +#ifndef SOUND_IN +#define SOUND_IN "Audiere" +#endif +#endif + #ifdef OPENMW_USE_MPG123 #include "mpgsnd_decoder.hpp" #ifndef SOUND_IN