diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 3890899b0..0009c575b 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -23,19 +23,19 @@ namespace MWClass assert (ref->base != NULL); const std::string &model = ref->base->model; - + + MWRender::Objects& objects = renderingInterface.getObjects(); + objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); + if (!model.empty()) - { - MWRender::Objects& objects = renderingInterface.getObjects(); - objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); objects.insertMesh(ptr, "meshes\\" + model); - const int color = ref->base->data.color; - const float r = ((color >> 0) & 0xFF) / 255.0f; - const float g = ((color >> 8) & 0xFF) / 255.0f; - const float b = ((color >> 16) & 0xFF) / 255.0f; - const float radius = float (ref->base->data.radius); - objects.insertLight (ptr, r, g, b, radius); - } + + const int color = ref->base->data.color; + const float r = ((color >> 0) & 0xFF) / 255.0f; + const float g = ((color >> 8) & 0xFF) / 255.0f; + const float b = ((color >> 16) & 0xFF) / 255.0f; + const float radius = float (ref->base->data.radius); + objects.insertLight (ptr, r, g, b, radius); } void Light::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const @@ -43,13 +43,12 @@ namespace MWClass ESMS::LiveCellRef *ref = ptr.get(); - - const std::string &model = ref->base->model; assert (ref->base != NULL); + const std::string &model = ref->base->model; + if(!model.empty()){ physics.insertObjectPhysics(ptr, "meshes\\" + model); } - } void Light::enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const diff --git a/apps/openmw/mwclass/static.cpp b/apps/openmw/mwclass/static.cpp index 946da311d..24d36dc1e 100644 --- a/apps/openmw/mwclass/static.cpp +++ b/apps/openmw/mwclass/static.cpp @@ -15,11 +15,11 @@ namespace MWClass assert (ref->base != NULL); const std::string &model = ref->base->model; - + if (!model.empty()) { MWRender::Objects& objects = renderingInterface.getObjects(); - objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); + objects.insertBegin(ptr, ptr.getRefData().isEnabled(), true); objects.insertMesh(ptr, "meshes\\" + model); } } @@ -29,13 +29,12 @@ namespace MWClass ESMS::LiveCellRef *ref = ptr.get(); - - const std::string &model = ref->base->model; assert (ref->base != NULL); + const std::string &model = ref->base->model; + if(!model.empty()){ physics.insertObjectPhysics(ptr, "meshes\\" + model); } - } std::string Static::getName (const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwrender/objects.cpp b/apps/openmw/mwrender/objects.cpp index 1e3b4dda0..4e2a3caab 100644 --- a/apps/openmw/mwrender/objects.cpp +++ b/apps/openmw/mwrender/objects.cpp @@ -1,11 +1,11 @@ #include "objects.hpp" + #include + #include -using namespace Ogre; using namespace MWRender; - bool Objects::lightConst = false; float Objects::lightConstValue = 0.0f; @@ -23,10 +23,24 @@ bool Objects::lightOutQuadInLin = false; int Objects::uniqueID = 0; -void Objects::setMwRoot(Ogre::SceneNode* root){ +void Objects::clearSceneNode (Ogre::SceneNode *node) +{ + /// \todo This should probably be moved into OpenEngine at some point. + for (int i=node->numAttachedObjects()-1; i>=0; --i) + { + Ogre::MovableObject *object = node->getAttachedObject (i); + node->detachObject (object); + mRenderer.getScene()->destroyMovableObject (object); + } +} + +void Objects::setMwRoot(Ogre::SceneNode* root) +{ mMwRoot = root; } -void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_){ + +void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_) +{ Ogre::SceneNode* root = mMwRoot; Ogre::SceneNode* cellnode; if(mCellSceneNodes.find(ptr.getCell()) == mCellSceneNodes.end()) @@ -49,90 +63,91 @@ void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_){ f = ptr.getCellRef().pos.rot; // Rotate around X axis - Quaternion xr(Radian(-f[0]), Vector3::UNIT_X); + Ogre::Quaternion xr(Ogre::Radian(-f[0]), Ogre::Vector3::UNIT_X); // Rotate around Y axis - Quaternion yr(Radian(-f[1]), Vector3::UNIT_Y); + Ogre::Quaternion yr(Ogre::Radian(-f[1]), Ogre::Vector3::UNIT_Y); // Rotate around Z axis - Quaternion zr(Radian(-f[2]), Vector3::UNIT_Z); + Ogre::Quaternion zr(Ogre::Radian(-f[2]), Ogre::Vector3::UNIT_Z); - // Rotates first around z, then y, then x + // Rotates first around z, then y, then x insert->setOrientation(xr*yr*zr); + if (!enabled) insert->setVisible (false); ptr.getRefData().setBaseNode(insert); - isStatic = static_; - - + mIsStatic = static_; } -void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh){ + +void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) +{ Ogre::SceneNode* insert = ptr.getRefData().getBaseNode(); assert(insert); NifOgre::NIFLoader::load(mesh); - Entity *ent = mRend.getScene()->createEntity(mesh); + Ogre::Entity *ent = mRenderer.getScene()->createEntity(mesh); - if(!isStatic) + if(!mIsStatic) { insert->attachObject(ent); } else { Ogre::StaticGeometry* sg = 0; - if(mSG.find(ptr.getCell()) == mSG.end()) + if(mStaticGeometry.find(ptr.getCell()) == mStaticGeometry.end()) { uniqueID = uniqueID +1; - sg = mRend.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); + sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); //Create the scenenode and put it in the map - mSG[ptr.getCell()] = sg; + mStaticGeometry[ptr.getCell()] = sg; } else { - sg = mSG[ptr.getCell()]; + sg = mStaticGeometry[ptr.getCell()]; } sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale()); sg->setRegionDimensions(Ogre::Vector3(100000,10000,100000)); - - mRend.getScene()->destroyEntity(ent); + mRenderer.getScene()->destroyEntity(ent); } - - } -void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, float radius){ - Ogre::SceneNode* insert = mRend.getScene()->getSceneNode(ptr.getRefData().getHandle()); + +void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, float radius) +{ + Ogre::SceneNode* insert = mRenderer.getScene()->getSceneNode(ptr.getRefData().getHandle()); assert(insert); - Ogre::Light *light = mRend.getScene()->createLight(); + Ogre::Light *light = mRenderer.getScene()->createLight(); light->setDiffuseColour (r, g, b); float cval=0.0f, lval=0.0f, qval=0.0f; if(lightConst) cval = lightConstValue; - if(!lightOutQuadInLin) - { - if(lightLinear) - radius *= lightLinearRadiusMult; - if(lightQuadratic) - radius *= lightQuadraticRadiusMult; - if(lightLinear) - lval = lightLinearValue / pow(radius, lightLinearMethod); - if(lightQuadratic) - qval = lightQuadraticValue / pow(radius, lightQuadraticMethod); - } - else - { - // FIXME: - // Do quadratic or linear, depending if we're in an exterior or interior - // cell, respectively. Ignore lightLinear and lightQuadratic. - } + if(!lightOutQuadInLin) + { + if(lightLinear) + radius *= lightLinearRadiusMult; + if(lightQuadratic) + radius *= lightQuadraticRadiusMult; - light->setAttenuation(10*radius, cval, lval, qval); + if(lightLinear) + lval = lightLinearValue / pow(radius, lightLinearMethod); + if(lightQuadratic) + qval = lightQuadraticValue / pow(radius, lightQuadraticMethod); + } + else + { + // FIXME: + // Do quadratic or linear, depending if we're in an exterior or interior + // cell, respectively. Ignore lightLinear and lightQuadratic. + } - insert->attachObject(light); + light->setAttenuation(10*radius, cval, lval, qval); + + insert->attachObject(light); } bool Objects::deleteObject (const MWWorld::Ptr& ptr) @@ -145,8 +160,9 @@ bool Objects::deleteObject (const MWWorld::Ptr& ptr) mCellSceneNodes.begin()); iter!=mCellSceneNodes.end(); ++iter) if (iter->second==parent) { + clearSceneNode (base); base->removeAndDestroyAllChildren(); - mRend.getScene()->destroySceneNode (base); + mRenderer.getScene()->destroySceneNode (base); ptr.getRefData().setBaseNode (0); return true; } @@ -157,29 +173,35 @@ bool Objects::deleteObject (const MWWorld::Ptr& ptr) return true; } -void Objects::removeCell(MWWorld::Ptr::CellStore* store){ +void Objects::removeCell(MWWorld::Ptr::CellStore* store) +{ if(mCellSceneNodes.find(store) != mCellSceneNodes.end()) { Ogre::SceneNode* base = mCellSceneNodes[store]; + + for (int i=0; inumChildren(); ++i) + clearSceneNode (static_cast (base->getChild (i))); + base->removeAndDestroyAllChildren(); mCellSceneNodes.erase(store); - mRend.getScene()->destroySceneNode(base); + mRenderer.getScene()->destroySceneNode(base); base = 0; } - - if(mSG.find(store) != mSG.end()) + if(mStaticGeometry.find(store) != mStaticGeometry.end()) { - Ogre::StaticGeometry* sg = mSG[store]; - mSG.erase(store); - mRend.getScene()->destroyStaticGeometry (sg); + Ogre::StaticGeometry* sg = mStaticGeometry[store]; + mStaticGeometry.erase(store); + mRenderer.getScene()->destroyStaticGeometry (sg); sg = 0; } } -void Objects::buildStaticGeometry(ESMS::CellStore& cell){ - if(mSG.find(&cell) != mSG.end()) + +void Objects::buildStaticGeometry(ESMS::CellStore& cell) +{ + if(mStaticGeometry.find(&cell) != mStaticGeometry.end()) { - Ogre::StaticGeometry* sg = mSG[&cell]; + Ogre::StaticGeometry* sg = mStaticGeometry[&cell]; sg->build(); } } diff --git a/apps/openmw/mwrender/objects.hpp b/apps/openmw/mwrender/objects.hpp index 6cd465fdd..d58455b9f 100644 --- a/apps/openmw/mwrender/objects.hpp +++ b/apps/openmw/mwrender/objects.hpp @@ -1,20 +1,21 @@ #ifndef _GAME_RENDER_OBJECTS_H #define _GAME_RENDER_OBJECTS_H -#include "components/esm_store/cell_store.hpp" +#include + +#include #include "../mwworld/refdata.hpp" #include "../mwworld/ptr.hpp" -#include namespace MWRender{ class Objects{ - OEngine::Render::OgreRenderer &mRend; + OEngine::Render::OgreRenderer &mRenderer; std::map mCellSceneNodes; - std::map mSG; + std::map mStaticGeometry; Ogre::SceneNode* mMwRoot; - bool isStatic; + bool mIsStatic; static int uniqueID; static bool lightConst; static float lightConstValue; @@ -30,8 +31,12 @@ class Objects{ static float lightQuadraticRadiusMult; static bool lightOutQuadInLin; + + void clearSceneNode (Ogre::SceneNode *node); + ///< Remove all movable objects from \a node. + public: - Objects(OEngine::Render::OgreRenderer& _rend): mRend(_rend){} + Objects(OEngine::Render::OgreRenderer& renderer): mRenderer (renderer){} ~Objects(){} void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_); void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh);