diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 56750eef0b..1dbe1f821f 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -17,6 +17,8 @@ namespace { + + template void insertCellRefList (T& cellRefList, ESMS::CellStore &cell) { @@ -37,6 +39,38 @@ void insertCellRefList (T& cellRefList, ESMS::CellStore &cell) */ } } + } +} +template +void insertCellRefList(MWRender::RenderingManager& rendering, MWWorld::Environment& environment, + T& cellRefList, ESMS::CellStore &cell, MWWorld::PhysicsSystem& physics) +{ + if (!cellRefList.list.empty()) + { + const MWWorld::Class& class_ = + MWWorld::Class::get (MWWorld::Ptr (&*cellRefList.list.begin(), &cell)); + + for (typename T::List::iterator it = cellRefList.list.begin(); + it != cellRefList.list.end(); it++) + { + if (it->mData.getCount() || it->mData.isEnabled()) + { + MWWorld::Ptr ptr (&*it, &cell); + + try + { + + class_.insertObjectRendering(ptr, rendering); + class_.insertObject(ptr, physics, environment); + class_.enable (ptr, environment); + } + catch (const std::exception& e) + { + std::string error ("error during rendering: "); + std::cerr << error + e.what() << std::endl; + } + } + } } } @@ -46,11 +80,11 @@ void insertCellRefList (T& cellRefList, ESMS::CellStore &cell) namespace MWWorld { - void Scene::unloadCell (CellRenderCollection::iterator iter) + void Scene::unloadCell (CellStoreCollection::iterator iter) { ListHandles functor; Ptr::CellStore* cellstore = *iter; - + cellstore->forEach(functor); { // silence annoying g++ warning @@ -73,9 +107,10 @@ namespace MWWorld mWorld->getLocalScripts().addCell (cell); // This connects the cell data with the rendering scene. - mActiveCells.push_back(cell); + mActiveCells.insert(cell); mRendering.getObjects().buildStaticGeometry(*cell); + insertCell(*cell, mEnvironment); } @@ -96,7 +131,7 @@ namespace MWWorld // remove active mEnvironment.mMechanicsManager->removeActor (mWorld->getPlayer().getPlayer()); - CellRenderCollection::iterator active = mActiveCells.begin(); + CellStoreCollection::iterator active = mActiveCells.begin(); Ptr::CellStore* cellstore = *active; while (active!=mActiveCells.end()) @@ -120,12 +155,12 @@ namespace MWWorld for (int x=X-1; x<=X+1; ++x) for (int y=Y-1; y<=Y+1; ++y) { - CellRenderCollection::iterator iter = mActiveCells.begin(); + CellStoreCollection::iterator iter = mActiveCells.begin(); Ptr::CellStore* cellstore = *iter; while (iter!=mActiveCells.end()) { - assert (!(iter->first->cell->data.flags & ESM::Cell::Interior)); + assert (!(cellstore->cell->data.flags & ESM::Cell::Interior)); if (x==cellstore->cell->data.gridX && y==cellstore->cell->data.gridY) @@ -143,7 +178,7 @@ namespace MWWorld } // find current cell - CellRenderCollection::iterator iter = mActiveCells.begin(); + CellStoreCollection::iterator iter = mActiveCells.begin(); cellstore = *active; while (iter!=mActiveCells.end()) @@ -171,18 +206,14 @@ namespace MWWorld } //We need the ogre renderer and a scene node. - Scene::Scene (Environment& environment, World *world, MWRender::RenderingManager& rendering, Ogre::SceneNode *mwRoot, PhysicsSystem *physics) + Scene::Scene (Environment& environment, World *world, MWRender::RenderingManager& rendering, PhysicsSystem *physics) : mRendering(rendering), mCurrentCell (0), mCellChanged (false), mEnvironment (environment), mWorld(world), mPhysics(physics) { - mMwRoot = mwRoot; } Scene::~Scene() { - /*for (CellRenderCollection::iterator iter (mActiveCells.begin()); - iter!=mActiveCells.end(); ++iter) - delete iter->second;*/ } bool Scene::hasCellChanged() const @@ -190,7 +221,7 @@ namespace MWWorld return mCellChanged; } - const Scene::CellRenderCollection& Scene::getActiveCells() const + const Scene::CellStoreCollection& Scene::getActiveCells() const { return mActiveCells; } @@ -198,7 +229,7 @@ namespace MWWorld void Scene::changeToInteriorCell (const std::string& cellName, const ESM::Position& position) { // remove active - CellRenderCollection::iterator active = mActiveCells.begin(); + CellStoreCollection::iterator active = mActiveCells.begin(); while (active!=mActiveCells.end()) { @@ -271,7 +302,34 @@ void Scene::insertCell(ESMS::CellStore &cell) insertCellRefList (cell.probes, cell); insertCellRefList (cell.repairs, cell); insertCellRefList (cell.statics, cell); - insertCellRefList (cell.weapons, cell); + insertCellRefList(cell.weapons, cell); } +void Scene::insertCell(ESMS::CellStore &cell, + MWWorld::Environment& environment) +{ + // Loop through all references in the cell + insertCellRefList(mRendering, environment, cell.activators, cell, *mPhysics); + insertCellRefList(mRendering, environment, cell.potions, cell, *mPhysics); + insertCellRefList(mRendering, environment, cell.appas, cell, *mPhysics); + insertCellRefList(mRendering, environment, cell.armors, cell, *mPhysics); + insertCellRefList(mRendering, environment, cell.books, cell, *mPhysics); + insertCellRefList(mRendering, environment, cell.clothes, cell, *mPhysics); + insertCellRefList(mRendering, environment, cell.containers, cell, *mPhysics); + insertCellRefList(mRendering, environment, cell.creatures, cell, *mPhysics); + insertCellRefList(mRendering, environment, cell.doors, cell, *mPhysics); + insertCellRefList(mRendering, environment, cell.ingreds, cell, *mPhysics); + insertCellRefList(mRendering, environment, cell.creatureLists, cell, *mPhysics); + insertCellRefList(mRendering, environment, cell.itemLists, cell, *mPhysics); + insertCellRefList(mRendering, environment, cell.lights, cell, *mPhysics); + insertCellRefList(mRendering, environment, cell.lockpicks, cell, *mPhysics); + insertCellRefList(mRendering, environment, cell.miscItems, cell, *mPhysics); + insertCellRefList(mRendering, environment, cell.npcs, cell, *mPhysics); + insertCellRefList(mRendering, environment, cell.probes, cell, *mPhysics); + insertCellRefList(mRendering, environment, cell.repairs, cell, *mPhysics); + insertCellRefList(mRendering, environment, cell.statics, cell, *mPhysics); + insertCellRefList(mRendering, environment, cell.weapons, cell, *mPhysics); +} + + } diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index f95c133705..c5183b58c8 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -14,6 +14,7 @@ #include "ptr.hpp" #include "globals.hpp" #include "../mwrender/renderingmanager.hpp" +#include "../mwrender/renderinginterface.hpp" #include namespace Ogre @@ -52,14 +53,14 @@ namespace MWWorld public: - typedef std::list CellRenderCollection; + typedef std::set CellStoreCollection; private: //OEngine::Render::OgreRenderer& mRenderer; Ogre::SceneNode *mMwRoot; Ptr::CellStore* mCurrentCell; // the cell, the player is in - CellRenderCollection mActiveCells; + CellStoreCollection mActiveCells; bool mCellChanged; Environment& mEnvironment; World *mWorld; @@ -68,13 +69,15 @@ namespace MWWorld void playerCellChange (Ptr::CellStore *cell, const ESM::Position& position, bool adjustPlayerPos = true); + + public: - Scene (Environment& environment, World *world, MWRender::RenderingManager& rendering, Ogre::SceneNode *mwRoot, PhysicsSystem *physics); + Scene (Environment& environment, World *world, MWRender::RenderingManager& rendering, PhysicsSystem *physics); ~Scene(); - void unloadCell (CellRenderCollection::iterator iter); + void unloadCell (CellStoreCollection::iterator iter); void loadCell (Ptr::CellStore *cell); @@ -84,7 +87,7 @@ namespace MWWorld Ptr::CellStore* getCurrentCell (); - const CellRenderCollection& getActiveCells () const; + const CellStoreCollection& getActiveCells () const; bool hasCellChanged() const; ///< Has the player moved to a different cell, since the last frame? @@ -100,6 +103,7 @@ namespace MWWorld // std::string getFacedHandle(); void insertCell(ESMS::CellStore &cell); + void insertCell(ESMS::CellStore &cell, MWWorld::Environment& environment); }; } diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 12a6d26fd0..3993468c0e 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -130,20 +130,6 @@ namespace MWWorld return Ptr(); } - /* - MWRender::CellRender *World::searchRender (Ptr::CellStore *store) - { - for (Scene::CellRenderCollection::const_iterator iter (mWorldScene->getActiveCells().begin()); - iter!=mWorldScene->getActiveCells().end(); ++iter) - { - Ptr::CellStore* cellstore = *iter; - if(store == cellstore){ - //return iter->second; - } - } - - return 0; - }*/ int World::getDaysPerMonth (int month) const { @@ -211,7 +197,7 @@ namespace MWWorld mPhysEngine = physEng; - mWorldScene = new Scene(environment, this, mRendering, mRendering.getRoot(), mPhysics); + mWorldScene = new Scene(environment, this, mRendering, mPhysics); } @@ -308,7 +294,7 @@ namespace MWWorld } // active cells - for (Scene::CellRenderCollection::const_iterator iter (mWorldScene->getActiveCells().begin()); + for (Scene::CellStoreCollection::const_iterator iter (mWorldScene->getActiveCells().begin()); iter!=mWorldScene->getActiveCells().end(); ++iter) { Ptr::CellStore* cellstore = *iter; @@ -334,7 +320,7 @@ namespace MWWorld if (mPlayer->getPlayer().getRefData().getHandle()==handle) return mPlayer->getPlayer(); - for (Scene::CellRenderCollection::const_iterator iter (mWorldScene->getActiveCells().begin()); + for (Scene::CellStoreCollection::const_iterator iter (mWorldScene->getActiveCells().begin()); iter!=mWorldScene->getActiveCells().end(); ++iter) { Ptr::CellStore* cellstore = *iter; @@ -355,17 +341,9 @@ namespace MWWorld //render->enable (reference.getRefData().getHandle()); - for (Scene::CellRenderCollection::const_iterator iter (mWorldScene->getActiveCells().begin()); - iter!=mWorldScene->getActiveCells().end(); ++iter) - { - Ptr::CellStore* cellstore = *iter; - if(reference.getCell() == cellstore){ - Class::get (reference).enable (reference, mEnvironment); - break; - } - } - - + if(mWorldScene->getActiveCells().find (reference.getCell()) != mWorldScene->getActiveCells().end()) + Class::get (reference).enable (reference, mEnvironment); + } } @@ -378,16 +356,10 @@ namespace MWWorld //render->disable (reference.getRefData().getHandle()); - for (Scene::CellRenderCollection::const_iterator iter (mWorldScene->getActiveCells().begin()); - iter!=mWorldScene->getActiveCells().end(); ++iter) - { - Ptr::CellStore* cellstore = *iter; - if(reference.getCell() == cellstore){ - Class::get (reference).disable (reference, mEnvironment); - mEnvironment.mSoundManager->stopSound3D (reference); - break; - } - } + if(mWorldScene->getActiveCells().find (reference.getCell())!=mWorldScene->getActiveCells().end()){ + Class::get (reference).disable (reference, mEnvironment); + mEnvironment.mSoundManager->stopSound3D (reference); + } } @@ -548,19 +520,14 @@ namespace MWWorld ptr.getRefData().setCount (0); - for (Scene::CellRenderCollection::const_iterator iter (mWorldScene->getActiveCells().begin()); - iter!=mWorldScene->getActiveCells().end(); ++iter) - { - Ptr::CellStore* cellstore = *iter; - if(ptr.getCell() == cellstore){ + if (mWorldScene->getActiveCells().find (ptr.getCell())!=mWorldScene->getActiveCells().end()){ Class::get (ptr).disable (ptr, mEnvironment); mEnvironment.mSoundManager->stopSound3D (ptr); mPhysics->removeObject (ptr.getRefData().getHandle()); + mRendering.removeObject(ptr); mLocalScripts.remove (ptr); - break; - } } diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index 4a26fd11af..ea775453ac 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -88,7 +88,6 @@ namespace MWWorld Ptr getPtrViaHandle (const std::string& handle, Ptr::CellStore& cellStore); - //MWRender::CellRender *searchRender (Ptr::CellStore *store); int getDaysPerMonth (int month) const; @@ -133,9 +132,11 @@ namespace MWWorld Ptr getPtrViaHandle (const std::string& handle); ///< Return a pointer to a liveCellRef with the given Ogre handle. - + + /// \todo enable reference in the OGRE scene void enable (Ptr reference); - + + /// \todo 5disable reference in the OGRE scene void disable (Ptr reference); void advanceTime (double hours);