diff --git a/apps/openmw/mwworld/backup/scene.cpp b/apps/openmw/mwworld/backup/scene.cpp new file mode 100644 index 0000000000..93b4a80f46 --- /dev/null +++ b/apps/openmw/mwworld/backup/scene.cpp @@ -0,0 +1,275 @@ +#include "scene.hpp" +#include "world.hpp" + +#include "../mwrender/interior.hpp" +#include "../mwrender/exterior.hpp" + +#include "../mwmechanics/mechanicsmanager.hpp" + +#include "../mwsound/soundmanager.hpp" + +#include "ptr.hpp" +#include "environment.hpp" +#include "player.hpp" +#include "class.hpp" + +#include "cellfunctors.hpp" + +namespace { + +template +void insertCellRefList (T& cellRefList, ESMS::CellStore &cell) +{ + 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); + /* TODO: call + * RenderingManager.insertObject + * class_.insertObjectPhysic + * class_.insertObjectMechanics + */ + } + } + } +} + +} + + +namespace MWWorld +{ + + void Scene::unloadCell (CellRenderCollection::iterator iter) + { + ListHandles functor; + iter->first->forEach(functor); + + { // silence annoying g++ warning + for (std::vector::const_iterator iter (functor.mHandles.begin()); + iter!=functor.mHandles.end(); ++iter) + mPhysics->removeObject (*iter); + } + + mWorld->getLocalScripts().clearCell (iter->first); + + mEnvironment.mMechanicsManager->dropActors (iter->first); + mEnvironment.mSoundManager->stopSound (iter->first); + delete iter->second; + mActiveCells.erase (iter); + } + + void Scene::loadCell (Ptr::CellStore *cell, MWRender::CellRender *render) + { + // register local scripts + mWorld->getLocalScripts().addCell (cell); + + // This connects the cell data with the rendering scene. + std::pair result = + mActiveCells.insert (std::make_pair (cell, render)); + + if (result.second) + { + // Load the cell and insert it into the renderer + result.first->second->show(); + } + } + + void Scene::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position, + bool adjustPlayerPos) + { + if (adjustPlayerPos) + mWorld->getPlayer().setPos (position.pos[0], position.pos[1], position.pos[2]); + + mWorld->getPlayer().setCell (cell); + // TODO orientation + mEnvironment.mMechanicsManager->addActor (mWorld->getPlayer().getPlayer()); + mEnvironment.mMechanicsManager->watchActor (mWorld->getPlayer().getPlayer()); + } + + void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos) + { + // remove active + mEnvironment.mMechanicsManager->removeActor (mWorld->getPlayer().getPlayer()); + + CellRenderCollection::iterator active = mActiveCells.begin(); + + while (active!=mActiveCells.end()) + { + if (!(active->first->cell->data.flags & ESM::Cell::Interior)) + { + if (std::abs (X-active->first->cell->data.gridX)<=1 && + std::abs (Y-active->first->cell->data.gridY)<=1) + { + // keep cells within the new 3x3 grid + ++active; + continue; + } + } + + unloadCell (active++); + } + + // Load cells + for (int x=X-1; x<=X+1; ++x) + for (int y=Y-1; y<=Y+1; ++y) + { + CellRenderCollection::iterator iter = mActiveCells.begin(); + + while (iter!=mActiveCells.end()) + { + assert (!(iter->first->cell->data.flags & ESM::Cell::Interior)); + + if (x==iter->first->cell->data.gridX && + y==iter->first->cell->data.gridY) + break; + + ++iter; + } + + if (iter==mActiveCells.end()) + { + Ptr::CellStore *cell = mWorld->getExterior(x, y); + + loadCell (cell, new MWRender::ExteriorCellRender (*cell, mEnvironment, mRendering.getOgreRenderer(), mMwRoot, mPhysics)); + } + } + + // find current cell + CellRenderCollection::iterator iter = mActiveCells.begin(); + + while (iter!=mActiveCells.end()) + { + assert (!(iter->first->cell->data.flags & ESM::Cell::Interior)); + + if (X==iter->first->cell->data.gridX && + Y==iter->first->cell->data.gridY) + break; + + ++iter; + } + + assert (iter!=mActiveCells.end()); + + mCurrentCell = iter->first; + + // adjust player + playerCellChange (mWorld->getExterior(X, Y), position, adjustPlayerPos); + + // Sky system + mWorld->adjustSky(); + + mCellChanged = true; + } + + //We need the ogre renderer and a scene node. + Scene::Scene (Environment& environment, World *world, MWRender::RenderingManager& rendering, Ogre::SceneNode *mwRoot, 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 + { + return mCellChanged; + } + + const Scene::CellRenderCollection& Scene::getActiveCells() const + { + return mActiveCells; + } + + void Scene::changeToInteriorCell (const std::string& cellName, const ESM::Position& position) + { + // remove active + CellRenderCollection::iterator active = mActiveCells.begin(); + + while (active!=mActiveCells.end()) + { + unloadCell (active++); + } + + // Load cell. + std::cout << "cellName:" << cellName << std::endl; + Ptr::CellStore *cell = mWorld->getInterior(cellName); + + loadCell (cell, new MWRender::InteriorCellRender (*cell, mEnvironment, mRendering.getOgreRenderer(), mMwRoot, mPhysics)); + + // adjust player + mCurrentCell = cell; + playerCellChange (cell, position); + + // Sky system + mWorld->adjustSky(); + + mCellChanged = true; + //currentRegion->name = ""; + } + + void Scene::changeToExteriorCell (const ESM::Position& position) + { + int x = 0; + int y = 0; + + mWorld->positionToIndex (position.pos[0], position.pos[1], x, y); + + changeCell (x, y, position, true); + } + + Ptr::CellStore* Scene::getCurrentCell () + { + return mCurrentCell; + } + + void Scene::markCellAsUnchanged() + { + mCellChanged = false; + } + +/*#include +#include +#include + +#include "../mwworld/class.hpp" +#include "../mwworld/ptr.hpp"*/ + +void Scene::insertCell(ESMS::CellStore &cell) +{ + // Loop through all references in the cell + insertCellRefList (cell.activators, cell); + insertCellRefList (cell.potions, cell); + insertCellRefList (cell.appas, cell); + insertCellRefList (cell.armors, cell); + insertCellRefList (cell.books, cell); + insertCellRefList (cell.clothes, cell); + insertCellRefList (cell.containers, cell); + insertCellRefList (cell.creatures, cell); + insertCellRefList (cell.doors, cell); + insertCellRefList (cell.ingreds, cell); + insertCellRefList (cell.creatureLists, cell); + insertCellRefList (cell.itemLists, cell); + insertCellRefList (cell.lights, cell); + insertCellRefList (cell.lockpicks, cell); + insertCellRefList (cell.miscItems, cell); + insertCellRefList (cell.npcs, cell); + insertCellRefList (cell.probes, cell); + insertCellRefList (cell.repairs, cell); + insertCellRefList (cell.statics, cell); + insertCellRefList (cell.weapons, cell); +} + +} diff --git a/apps/openmw/mwworld/backup/scene.hpp b/apps/openmw/mwworld/backup/scene.hpp new file mode 100644 index 0000000000..e170f01530 --- /dev/null +++ b/apps/openmw/mwworld/backup/scene.hpp @@ -0,0 +1,106 @@ +#ifndef GAME_MWWORLD_SCENE_H +#define GAME_MWWORLD_SCENE_H + +#include +#include + +#include + +#include + +#include "physicssystem.hpp" + +#include "refdata.hpp" +#include "ptr.hpp" +#include "globals.hpp" +#include "../mwrender/renderingmanager.hpp" +#include + +namespace Ogre +{ + class Vector3; +} + +namespace ESM +{ + struct Position; +} + +namespace Files +{ + class Collections; +} + +namespace Render +{ + class OgreRenderer; +} + +namespace MWRender +{ + class SkyManager; + class CellRender; +} + +namespace MWWorld +{ + class Environment; + class Player; + + class Scene + { + + public: + + typedef std::map CellRenderCollection; + + private: + + //OEngine::Render::OgreRenderer& mRenderer; + Ogre::SceneNode *mMwRoot; + Ptr::CellStore *mCurrentCell; // the cell, the player is in + CellRenderCollection mActiveCells; + bool mCellChanged; + Environment& mEnvironment; + World *mWorld; + PhysicsSystem *mPhysics; + MWRender::RenderingManager& mRendering; + + 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(); + + void unloadCell (CellRenderCollection::iterator iter); + + void loadCell (Ptr::CellStore *cell, MWRender::CellRender *render); + + void changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos); + ///< Move from exterior to interior or from interior cell to a different + /// interior cell. + + Ptr::CellStore* getCurrentCell (); + + const CellRenderCollection& getActiveCells () const; + + bool hasCellChanged() const; + ///< Has the player moved to a different cell, since the last frame? + + void changeToInteriorCell (const std::string& cellName, const ESM::Position& position); + ///< Move to interior cell. + + void changeToExteriorCell (const ESM::Position& position); + ///< Move to exterior cell. + + void markCellAsUnchanged(); + +// std::string getFacedHandle(); + + void insertCell(ESMS::CellStore &cell); + }; +} + +#endif diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 4f425ac65d..56750eef0b 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -49,7 +49,9 @@ namespace MWWorld void Scene::unloadCell (CellRenderCollection::iterator iter) { ListHandles functor; - iter->first->forEach(functor); + Ptr::CellStore* cellstore = *iter; + + cellstore->forEach(functor); { // silence annoying g++ warning for (std::vector::const_iterator iter (functor.mHandles.begin()); @@ -57,28 +59,24 @@ namespace MWWorld mPhysics->removeObject (*iter); } - mWorld->getLocalScripts().clearCell (iter->first); + mWorld->getLocalScripts().clearCell (cellstore); - mEnvironment.mMechanicsManager->dropActors (iter->first); - mEnvironment.mSoundManager->stopSound (iter->first); - delete iter->second; + mEnvironment.mMechanicsManager->dropActors (cellstore); + mEnvironment.mSoundManager->stopSound (cellstore); + //delete iter->second; mActiveCells.erase (iter); } - void Scene::loadCell (Ptr::CellStore *cell, MWRender::CellRender *render) + void Scene::loadCell (Ptr::CellStore *cell) { // register local scripts mWorld->getLocalScripts().addCell (cell); // This connects the cell data with the rendering scene. - std::pair result = - mActiveCells.insert (std::make_pair (cell, render)); - - if (result.second) - { - // Load the cell and insert it into the renderer - result.first->second->show(); - } + mActiveCells.push_back(cell); + + mRendering.getObjects().buildStaticGeometry(*cell); + } void Scene::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position, @@ -99,16 +97,18 @@ namespace MWWorld mEnvironment.mMechanicsManager->removeActor (mWorld->getPlayer().getPlayer()); CellRenderCollection::iterator active = mActiveCells.begin(); - + Ptr::CellStore* cellstore = *active; + while (active!=mActiveCells.end()) { - if (!(active->first->cell->data.flags & ESM::Cell::Interior)) + if (!(cellstore->cell->data.flags & ESM::Cell::Interior)) { - if (std::abs (X-active->first->cell->data.gridX)<=1 && - std::abs (Y-active->first->cell->data.gridY)<=1) + if (std::abs (X-cellstore->cell->data.gridX)<=1 && + std::abs (Y-cellstore->cell->data.gridY)<=1) { // keep cells within the new 3x3 grid ++active; + cellstore = *active; continue; } } @@ -121,13 +121,14 @@ namespace MWWorld for (int y=Y-1; y<=Y+1; ++y) { CellRenderCollection::iterator iter = mActiveCells.begin(); + Ptr::CellStore* cellstore = *iter; while (iter!=mActiveCells.end()) { assert (!(iter->first->cell->data.flags & ESM::Cell::Interior)); - if (x==iter->first->cell->data.gridX && - y==iter->first->cell->data.gridY) + if (x==cellstore->cell->data.gridX && + y==cellstore->cell->data.gridY) break; ++iter; @@ -137,19 +138,20 @@ namespace MWWorld { Ptr::CellStore *cell = mWorld->getExterior(x, y); - loadCell (cell, new MWRender::ExteriorCellRender (*cell, mEnvironment, mRenderer, mMwRoot, mPhysics)); + loadCell (cell); } } // find current cell CellRenderCollection::iterator iter = mActiveCells.begin(); + cellstore = *active; while (iter!=mActiveCells.end()) { assert (!(iter->first->cell->data.flags & ESM::Cell::Interior)); - if (X==iter->first->cell->data.gridX && - Y==iter->first->cell->data.gridY) + if (X==cellstore->cell->data.gridX && + Y==cellstore->cell->data.gridY) break; ++iter; @@ -157,7 +159,7 @@ namespace MWWorld assert (iter!=mActiveCells.end()); - mCurrentCell = iter->first; + mCurrentCell = cellstore; // adjust player playerCellChange (mWorld->getExterior(X, Y), position, adjustPlayerPos); @@ -169,8 +171,8 @@ namespace MWWorld } //We need the ogre renderer and a scene node. - Scene::Scene (Environment& environment, World *world, OEngine::Render::OgreRenderer& renderer, Ogre::SceneNode *mwRoot, PhysicsSystem *physics) - : mRenderer(renderer), mCurrentCell (0), + Scene::Scene (Environment& environment, World *world, MWRender::RenderingManager& rendering, Ogre::SceneNode *mwRoot, PhysicsSystem *physics) + : mRendering(rendering), mCurrentCell (0), mCellChanged (false), mEnvironment (environment), mWorld(world), mPhysics(physics) { mMwRoot = mwRoot; @@ -178,9 +180,9 @@ namespace MWWorld Scene::~Scene() { - for (CellRenderCollection::iterator iter (mActiveCells.begin()); + /*for (CellRenderCollection::iterator iter (mActiveCells.begin()); iter!=mActiveCells.end(); ++iter) - delete iter->second; + delete iter->second;*/ } bool Scene::hasCellChanged() const @@ -207,7 +209,7 @@ namespace MWWorld std::cout << "cellName:" << cellName << std::endl; Ptr::CellStore *cell = mWorld->getInterior(cellName); - loadCell (cell, new MWRender::InteriorCellRender (*cell, mEnvironment, mRenderer, mMwRoot, mPhysics)); + loadCell (cell); // adjust player mCurrentCell = cell; diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index 6af86a0711..f95c133705 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -52,30 +52,31 @@ namespace MWWorld public: - typedef std::map CellRenderCollection; + typedef std::list CellRenderCollection; private: - OEngine::Render::OgreRenderer& mRenderer; + //OEngine::Render::OgreRenderer& mRenderer; Ogre::SceneNode *mMwRoot; - Ptr::CellStore *mCurrentCell; // the cell, the player is in + Ptr::CellStore* mCurrentCell; // the cell, the player is in CellRenderCollection mActiveCells; bool mCellChanged; Environment& mEnvironment; World *mWorld; PhysicsSystem *mPhysics; + MWRender::RenderingManager& mRendering; void playerCellChange (Ptr::CellStore *cell, const ESM::Position& position, bool adjustPlayerPos = true); public: - Scene (Environment& environment, World *world, OEngine::Render::OgreRenderer& renderer, Ogre::SceneNode *mwRoot, PhysicsSystem *physics); + Scene (Environment& environment, World *world, MWRender::RenderingManager& rendering, Ogre::SceneNode *mwRoot, PhysicsSystem *physics); ~Scene(); void unloadCell (CellRenderCollection::iterator iter); - void loadCell (Ptr::CellStore *cell, MWRender::CellRender *render); + void loadCell (Ptr::CellStore *cell); void changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos); ///< Move from exterior to interior or from interior cell to a different diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index a4e909ffc7..12a6d26fd0 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -130,17 +130,20 @@ namespace MWWorld return Ptr(); } + /* MWRender::CellRender *World::searchRender (Ptr::CellStore *store) { - Scene::CellRenderCollection::const_iterator iter = mWorldScene->getActiveCells().find (store); - - if (iter!=mWorldScene->getActiveCells().end()) - { - return iter->second; - } + 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 { @@ -208,7 +211,7 @@ namespace MWWorld mPhysEngine = physEng; - mWorldScene = new Scene(environment, this, mRendering.getOgreRenderer(), mRendering.getRoot(), mPhysics); + mWorldScene = new Scene(environment, this, mRendering, mRendering.getRoot(), mPhysics); } @@ -308,7 +311,8 @@ namespace MWWorld for (Scene::CellRenderCollection::const_iterator iter (mWorldScene->getActiveCells().begin()); iter!=mWorldScene->getActiveCells().end(); ++iter) { - Ptr ptr = mCells.getPtr (name, *iter->first); + Ptr::CellStore* cellstore = *iter; + Ptr ptr = mCells.getPtr (name, *cellstore); if (!ptr.isEmpty()) return ptr; @@ -333,7 +337,8 @@ namespace MWWorld for (Scene::CellRenderCollection::const_iterator iter (mWorldScene->getActiveCells().begin()); iter!=mWorldScene->getActiveCells().end(); ++iter) { - Ptr ptr = getPtrViaHandle (handle, *iter->first); + Ptr::CellStore* cellstore = *iter; + Ptr ptr = getPtrViaHandle (handle, *cellstore); if (!ptr.isEmpty()) return ptr; @@ -348,13 +353,20 @@ namespace MWWorld { reference.getRefData().enable(); - if (MWRender::CellRender *render = searchRender (reference.getCell())) - { - render->enable (reference.getRefData().getHandle()); + + //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); - } + + } } @@ -364,16 +376,20 @@ namespace MWWorld { reference.getRefData().disable(); - if (MWRender::CellRender *render = searchRender (reference.getCell())) - { - render->disable (reference.getRefData().getHandle()); - - if (mWorldScene->getActiveCells().find (reference.getCell())!=mWorldScene->getActiveCells().end()) + + //render->disable (reference.getRefData().getHandle()); + for (Scene::CellRenderCollection::const_iterator iter (mWorldScene->getActiveCells().begin()); + iter!=mWorldScene->getActiveCells().end(); ++iter) { - Class::get (reference).disable (reference, mEnvironment); - mEnvironment.mSoundManager->stopSound3D (reference); + Ptr::CellStore* cellstore = *iter; + if(reference.getCell() == cellstore){ + Class::get (reference).disable (reference, mEnvironment); + mEnvironment.mSoundManager->stopSound3D (reference); + break; + } } - } + + } } @@ -531,21 +547,26 @@ namespace MWWorld { ptr.getRefData().setCount (0); - if (MWRender::CellRender *render = searchRender (ptr.getCell())) - { - if (mWorldScene->getActiveCells().find (ptr.getCell())!=mWorldScene->getActiveCells().end()) + + for (Scene::CellRenderCollection::const_iterator iter (mWorldScene->getActiveCells().begin()); + iter!=mWorldScene->getActiveCells().end(); ++iter) { - Class::get (ptr).disable (ptr, mEnvironment); - mEnvironment.mSoundManager->stopSound3D (ptr); + Ptr::CellStore* cellstore = *iter; + if(ptr.getCell() == cellstore){ + Class::get (ptr).disable (ptr, mEnvironment); + mEnvironment.mSoundManager->stopSound3D (ptr); - mPhysics->removeObject (ptr.getRefData().getHandle()); + mPhysics->removeObject (ptr.getRefData().getHandle()); - mLocalScripts.remove (ptr); + mLocalScripts.remove (ptr); + break; + } } + - render->deleteObject (ptr.getRefData().getHandle()); - ptr.getRefData().setHandle (""); - } + //Should this go here or inside the for loop? + mRendering.getObjects().deleteObject (ptr.getRefData().getHandle()); + ptr.getRefData().setBaseNode(0); } } diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index ca1759e00d..4a26fd11af 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -88,7 +88,7 @@ namespace MWWorld Ptr getPtrViaHandle (const std::string& handle, Ptr::CellStore& cellStore); - MWRender::CellRender *searchRender (Ptr::CellStore *store); + //MWRender::CellRender *searchRender (Ptr::CellStore *store); int getDaysPerMonth (int month) const;