diff --git a/apps/openmw/mwclass/static.cpp b/apps/openmw/mwclass/static.cpp index 851b4d7bf..cf0be9499 100644 --- a/apps/openmw/mwclass/static.cpp +++ b/apps/openmw/mwclass/static.cpp @@ -19,7 +19,7 @@ namespace MWClass const std::string &model = ref->base->model; if (!model.empty()) { - MWRender::Rendering rendering (cellRender, ref->ref); + MWRender::Rendering rendering (cellRender, ref->ref, true); cellRender.insertMesh ("meshes\\" + model); cellRender.insertObjectPhysics(); ref->mData.setHandle (rendering.end (ref->mData.isEnabled())); diff --git a/apps/openmw/mwrender/cellimp.hpp b/apps/openmw/mwrender/cellimp.hpp index 272bfeeab..664fed64f 100644 --- a/apps/openmw/mwrender/cellimp.hpp +++ b/apps/openmw/mwrender/cellimp.hpp @@ -35,7 +35,7 @@ namespace MWRender virtual ~CellRenderImp() {} /// start inserting a new reference. - virtual void insertBegin (ESM::CellRef &ref) = 0; + virtual void insertBegin (ESM::CellRef &ref, bool static_ = false) = 0; virtual void rotateMesh(Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName[], int elements) = 0; /// insert a mesh related to the most recent insertBegin call. @@ -71,10 +71,10 @@ namespace MWRender public: - Rendering (CellRenderImp& cellRender, ESM::CellRef &ref) + Rendering (CellRenderImp& cellRender, ESM::CellRef &ref, bool static_ = false) : mCellRender (cellRender), mEnd (false) { - mCellRender.insertBegin (ref); + mCellRender.insertBegin (ref, static_); } ~Rendering() diff --git a/apps/openmw/mwrender/exterior.cpp b/apps/openmw/mwrender/exterior.cpp index fe54af84a..1cdc51c98 100644 --- a/apps/openmw/mwrender/exterior.cpp +++ b/apps/openmw/mwrender/exterior.cpp @@ -31,12 +31,24 @@ float ExteriorCellRender::lightQuadraticRadiusMult = 1; bool ExteriorCellRender::lightOutQuadInLin = false; -// start inserting a new reference. +int ExteriorCellRender::uniqueID = 0; -void ExteriorCellRender::insertBegin (ESM::CellRef &ref) +ExteriorCellRender::ExteriorCellRender(ESMS::CellStore &_cell, MWWorld::Environment& environment, + MWScene &_scene) + : mCell(_cell), mEnvironment (environment), mScene(_scene), mBase(NULL), mInsert(NULL), mAmbientMode (0) +{ + uniqueID = uniqueID +1; + sg = mScene.getMgr()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); +} + + + +void ExteriorCellRender::insertBegin (ESM::CellRef &ref, bool static_) { assert (!mInsert); + isStatic = static_; + // Create and place scene node for this object mInsert = mBase->createChildSceneNode(); @@ -59,7 +71,7 @@ void ExteriorCellRender::insertBegin (ESM::CellRef &ref) // Rotates first around z, then y, then x mInsert->setOrientation(xr*yr*zr); - mInsertMesh.clear(); + mInsertMesh.clear(); } @@ -202,11 +214,20 @@ void ExteriorCellRender::insertMesh(const std::string &mesh) assert (mInsert); NIFLoader::load(mesh); - MovableObject *ent = mScene.getMgr()->createEntity(mesh); - mInsert->attachObject(ent); + Entity *ent = mScene.getMgr()->createEntity(mesh); - if (mInsertMesh.empty()) - mInsertMesh = mesh; + if(!isStatic) + { + mInsert->attachObject(ent); + } + else + { + sg->addEntity(ent,mInsert->_getDerivedPosition(),mInsert->_getDerivedOrientation(),mInsert->_getDerivedScale()); + sg->setRegionDimensions(Ogre::Vector3(100000,10000,100000)); + mScene.getMgr()->destroyEntity(ent); + } + if (mInsertMesh.empty()) + mInsertMesh = mesh; } void ExteriorCellRender::insertObjectPhysics() @@ -333,6 +354,8 @@ void ExteriorCellRender::show() configureFog(); insertCell(mCell, mEnvironment); + + sg->build(); } void ExteriorCellRender::hide() @@ -341,15 +364,49 @@ void ExteriorCellRender::hide() mBase->setVisible(false); } +void ExteriorCellRender::destroyAllAttachedMovableObjects(Ogre::SceneNode* i_pSceneNode) +{ + if ( !i_pSceneNode ) + { + assert( false ); + return; + } + + // Destroy all the attached objects + SceneNode::ObjectIterator itObject = i_pSceneNode->getAttachedObjectIterator(); + + while ( itObject.hasMoreElements() ) + { + MovableObject* pObject = static_cast(itObject.getNext()); + i_pSceneNode->getCreator()->destroyMovableObject( pObject ); + } + + // Recurse to child SceneNodes + SceneNode::ChildNodeIterator itChild = i_pSceneNode->getChildIterator(); + + while ( itChild.hasMoreElements() ) + { + SceneNode* pChildNode = static_cast(itChild.getNext()); + destroyAllAttachedMovableObjects( pChildNode ); + } +} + void ExteriorCellRender::destroy() { if(mBase) { + destroyAllAttachedMovableObjects(mBase); mBase->removeAndDestroyAllChildren(); mScene.getMgr()->destroySceneNode(mBase); } - mBase = NULL; + mBase = 0; + + if (sg) + { + mScene.getMgr()->destroyStaticGeometry (sg); + sg = 0; + } } // Switch through lighting modes. diff --git a/apps/openmw/mwrender/exterior.hpp b/apps/openmw/mwrender/exterior.hpp index 93491f263..40d9c60ae 100644 --- a/apps/openmw/mwrender/exterior.hpp +++ b/apps/openmw/mwrender/exterior.hpp @@ -57,13 +57,17 @@ namespace MWRender std::string mInsertMesh; Ogre::SceneNode *mNpcPart; + //the static geometry + Ogre::StaticGeometry *sg; + bool isStatic; + // 0 normal, 1 more bright, 2 max int mAmbientMode; Ogre::ColourValue mAmbientColor; /// start inserting a new reference. - virtual void insertBegin (ESM::CellRef &ref); + virtual void insertBegin (ESM::CellRef &ref, bool static_ = false); /// insert a mesh related to the most recent insertBegin call. virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements); @@ -95,8 +99,7 @@ namespace MWRender public: ExteriorCellRender(ESMS::CellStore &_cell, MWWorld::Environment& environment, - MWScene &_scene) - : mCell(_cell), mEnvironment (environment), mScene(_scene), mBase(NULL), mInsert(NULL), mAmbientMode (0) {} + MWScene &_scene); virtual ~ExteriorCellRender() { destroy(); } @@ -121,6 +124,10 @@ namespace MWRender /// Remove the reference with the given handle permanently from the scene. virtual void deleteObject (const std::string& handle); + + void destroyAllAttachedMovableObjects(Ogre::SceneNode* i_pSceneNode); + + static int uniqueID; }; } diff --git a/apps/openmw/mwrender/interior.cpp b/apps/openmw/mwrender/interior.cpp index dbacaacf9..ad0ecf69d 100644 --- a/apps/openmw/mwrender/interior.cpp +++ b/apps/openmw/mwrender/interior.cpp @@ -35,7 +35,7 @@ bool InteriorCellRender::lightOutQuadInLin = false; // start inserting a new reference. -void InteriorCellRender::insertBegin (ESM::CellRef &ref) +void InteriorCellRender::insertBegin (ESM::CellRef &ref, bool static_) { assert (!insert); diff --git a/apps/openmw/mwrender/interior.hpp b/apps/openmw/mwrender/interior.hpp index 7c4b2aaf1..295eaa475 100644 --- a/apps/openmw/mwrender/interior.hpp +++ b/apps/openmw/mwrender/interior.hpp @@ -63,7 +63,7 @@ namespace MWRender Ogre::ColourValue ambientColor; /// start inserting a new reference. - virtual void insertBegin (ESM::CellRef &ref); + virtual void insertBegin (ESM::CellRef &ref, bool static_ = false); virtual void rotateMesh(Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName[], int elements); virtual void scaleMesh(Ogre::Vector3 axis, std::string sceneNodeName[], int elements); /// insert a mesh related to the most recent insertBegin call. diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 68e3a745d..f1563e621 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -284,7 +284,6 @@ namespace MWWorld removeScripts (iter->first); mEnvironment.mMechanicsManager->dropActors (iter->first); - iter->second->destroy(); mEnvironment.mSoundManager->stopSound (iter->first); delete iter->second; mActiveCells.erase (iter); diff --git a/components/files/multidircollection.hpp b/components/files/multidircollection.hpp index a04c12c22..f9fae7aaa 100644 --- a/components/files/multidircollection.hpp +++ b/components/files/multidircollection.hpp @@ -26,8 +26,8 @@ namespace Files for (std::size_t i=0; idata; - createMaterial(material, d->ambient, d->diffuse, d->specular, d->emissive, - d->glossiness, d->alpha, alphaFlags, alphaTest, texName); + + std::multimap::iterator itr = MaterialMap.find(texName); + std::multimap::iterator lastElement; + lastElement = MaterialMap.upper_bound(texName); + if (itr != MaterialMap.end()) + { + for ( ; itr != lastElement; ++itr) + { + //std::cout << "OK!"; + //MaterialPtr mat = MaterialManager::getSingleton().getByName(itr->second,recourceGroup); + material = itr->second; + //if( mat->getA + } + } + else + { + //std::cout << "new"; + createMaterial(material, d->ambient, d->diffuse, d->specular, d->emissive, + d->glossiness, d->alpha, alphaFlags, alphaTest, texName); + MaterialMap.insert(std::make_pair(texName,material)); + } } else { diff --git a/components/nifogre/ogre_nif_loader.hpp b/components/nifogre/ogre_nif_loader.hpp index 6ab22aa2f..cec9d95d7 100644 --- a/components/nifogre/ogre_nif_loader.hpp +++ b/components/nifogre/ogre_nif_loader.hpp @@ -132,6 +132,7 @@ class NIFLoader : Ogre::ManualResourceLoader int numbers; int stack; + std::multimap MaterialMap; // pointer to the ogre mesh which is currently build Ogre::Mesh *mesh;