From 1624e0fd8a7f9604d6913f270fba6022b83ae669 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 7 Dec 2013 20:12:03 +0100 Subject: [PATCH] Rename ObjectList to ObjectScene. Wrap it in a SharedPtr so we can automate the destruction routine. --- apps/openmw/mwrender/animation.cpp | 114 ++++++++------------ apps/openmw/mwrender/animation.hpp | 10 +- apps/openmw/mwrender/npcanimation.cpp | 40 ++++--- apps/openmw/mwrender/npcanimation.hpp | 4 +- apps/openmw/mwrender/sky.cpp | 19 ++-- apps/openmw/mwrender/sky.hpp | 4 + components/nifogre/ogrenifloader.cpp | 148 +++++++++++++++----------- components/nifogre/ogrenifloader.hpp | 16 ++- 8 files changed, 178 insertions(+), 177 deletions(-) diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index dddbc2c73..42d11aa6d 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -51,28 +51,6 @@ void Animation::EffectAnimationValue::setValue(Ogre::Real) { } - -void Animation::destroyObjectList(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objects) -{ - for(size_t i = 0;i < objects.mLights.size();i++) - { - Ogre::Light *light = objects.mLights[i]; - // If parent is a scene node, it was created specifically for this light. Destroy it now. - if(light->isAttached() && !light->isParentTagPoint()) - sceneMgr->destroySceneNode(light->getParentSceneNode()); - sceneMgr->destroyLight(light); - } - for(size_t i = 0;i < objects.mParticles.size();i++) - sceneMgr->destroyParticleSystem(objects.mParticles[i]); - for(size_t i = 0;i < objects.mEntities.size();i++) - sceneMgr->destroyEntity(objects.mEntities[i]); - objects.mControllers.clear(); - objects.mLights.clear(); - objects.mParticles.clear(); - objects.mEntities.clear(); - objects.mSkelBase = NULL; -} - Animation::Animation(const MWWorld::Ptr &ptr, Ogre::SceneNode *node) : mPtr(ptr) , mCamera(NULL) @@ -90,13 +68,9 @@ Animation::Animation(const MWWorld::Ptr &ptr, Ogre::SceneNode *node) Animation::~Animation() { - for (std::vector::iterator it = mEffects.begin(); it != mEffects.end(); ++it) - destroyObjectList(mInsert->getCreator(), it->mObjects); + mEffects.clear(); mAnimSources.clear(); - - Ogre::SceneManager *sceneMgr = mInsert->getCreator(); - destroyObjectList(sceneMgr, mObjectRoot); } @@ -105,7 +79,7 @@ void Animation::setObjectRoot(const std::string &model, bool baseonly) OgreAssert(mAnimSources.empty(), "Setting object root while animation sources are set!"); mSkelBase = NULL; - destroyObjectList(mInsert->getCreator(), mObjectRoot); + mObjectRoot.setNull(); if(model.empty()) return; @@ -126,11 +100,11 @@ void Animation::setObjectRoot(const std::string &model, bool baseonly) mObjectRoot = (!baseonly ? NifOgre::Loader::createObjects(mInsert, mdlname) : NifOgre::Loader::createObjectBase(mInsert, mdlname)); - if(mObjectRoot.mSkelBase) + if(mObjectRoot->mSkelBase) { - mSkelBase = mObjectRoot.mSkelBase; + mSkelBase = mObjectRoot->mSkelBase; - Ogre::AnimationStateSet *aset = mObjectRoot.mSkelBase->getAllAnimationStates(); + Ogre::AnimationStateSet *aset = mObjectRoot->mSkelBase->getAllAnimationStates(); Ogre::AnimationStateIterator asiter = aset->getAnimationStateIterator(); while(asiter.hasMoreElements()) { @@ -141,7 +115,7 @@ void Animation::setObjectRoot(const std::string &model, bool baseonly) // Set the bones as manually controlled since we're applying the // transformations manually - Ogre::SkeletonInstance *skelinst = mObjectRoot.mSkelBase->getSkeleton(); + Ogre::SkeletonInstance *skelinst = mObjectRoot->mSkelBase->getSkeleton(); Ogre::Skeleton::BoneIterator boneiter = skelinst->getBoneIterator(); while(boneiter.hasMoreElements()) boneiter.getNext()->setManuallyControlled(true); @@ -162,10 +136,10 @@ void Animation::setObjectRoot(const std::string &model, bool baseonly) else mAttachedObjects.clear(); - for(size_t i = 0;i < mObjectRoot.mControllers.size();i++) + for(size_t i = 0;i < mObjectRoot->mControllers.size();i++) { - if(mObjectRoot.mControllers[i].getSource().isNull()) - mObjectRoot.mControllers[i].setSource(mAnimationValuePtr[0]); + if(mObjectRoot->mControllers[i].getSource().isNull()) + mObjectRoot->mControllers[i].setSource(mAnimationValuePtr[0]); } } @@ -233,15 +207,15 @@ public: } }; -void Animation::setRenderProperties(const NifOgre::ObjectList &objlist, Ogre::uint32 visflags, Ogre::uint8 solidqueue, Ogre::uint8 transqueue, Ogre::Real dist, bool enchantedGlow, Ogre::Vector3* glowColor) +void Animation::setRenderProperties(NifOgre::ObjectScenePtr objlist, Ogre::uint32 visflags, Ogre::uint8 solidqueue, Ogre::uint8 transqueue, Ogre::Real dist, bool enchantedGlow, Ogre::Vector3* glowColor) { - std::for_each(objlist.mEntities.begin(), objlist.mEntities.end(), + std::for_each(objlist->mEntities.begin(), objlist->mEntities.end(), VisQueueSet(visflags, solidqueue, transqueue, dist)); - std::for_each(objlist.mParticles.begin(), objlist.mParticles.end(), + std::for_each(objlist->mParticles.begin(), objlist->mParticles.end(), VisQueueSet(visflags, solidqueue, transqueue, dist)); if (enchantedGlow) - std::for_each(objlist.mEntities.begin(), objlist.mEntities.end(), + std::for_each(objlist->mEntities.begin(), objlist->mEntities.end(), AddGlow(glowColor)); } @@ -340,7 +314,7 @@ void Animation::clearAnimSources() } -void Animation::addExtraLight(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objlist, const ESM::Light *light) +void Animation::addExtraLight(Ogre::SceneManager *sceneMgr, NifOgre::ObjectScenePtr objlist, const ESM::Light *light) { const MWWorld::Fallback *fallback = MWBase::Environment::get().getWorld()->getFallback(); @@ -353,8 +327,8 @@ void Animation::addExtraLight(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList if((light->mData.mFlags&ESM::Light::Negative)) color *= -1; - objlist.mLights.push_back(sceneMgr->createLight()); - Ogre::Light *olight = objlist.mLights.back(); + objlist->mLights.push_back(sceneMgr->createLight()); + Ogre::Light *olight = objlist->mLights.back(); olight->setDiffuseColour(color); Ogre::ControllerValueRealPtr src(Ogre::ControllerManager::getSingleton().getFrameTimeSource()); @@ -366,7 +340,7 @@ void Animation::addExtraLight(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList (light->mData.mFlags&ESM::Light::PulseSlow) ? OEngine::Render::LT_PulseSlow : OEngine::Render::LT_Normal )); - objlist.mControllers.push_back(Ogre::Controller(src, dest, func)); + objlist->mControllers.push_back(Ogre::Controller(src, dest, func)); bool interior = !(mPtr.isInCell() && mPtr.getCell()->mCell->isExterior()); bool quadratic = fallback->getFallbackBool("LightAttenuation_OutQuadInLin") ? @@ -392,14 +366,14 @@ void Animation::addExtraLight(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList } // If there's an AttachLight bone, attach the light to that, otherwise put it in the center, - if(objlist.mSkelBase && objlist.mSkelBase->getSkeleton()->hasBone("AttachLight")) - objlist.mSkelBase->attachObjectToBone("AttachLight", olight); + if(objlist->mSkelBase && objlist->mSkelBase->getSkeleton()->hasBone("AttachLight")) + objlist->mSkelBase->attachObjectToBone("AttachLight", olight); else { Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL; - for(size_t i = 0;i < objlist.mEntities.size();i++) + for(size_t i = 0;i < objlist->mEntities.size();i++) { - Ogre::Entity *ent = objlist.mEntities[i]; + Ogre::Entity *ent = objlist->mEntities[i]; bounds.merge(ent->getBoundingBox()); } @@ -942,8 +916,8 @@ Ogre::Vector3 Animation::runAnimation(float duration) ++stateiter; } - for(size_t i = 0;i < mObjectRoot.mControllers.size();i++) - mObjectRoot.mControllers[i].update(); + for(size_t i = 0;i < mObjectRoot->mControllers.size();i++) + mObjectRoot->mControllers[i].update(); // Apply group controllers for(size_t grp = 0;grp < sNumGroups;grp++) @@ -986,7 +960,7 @@ public: void Animation::enableLights(bool enable) { - std::for_each(mObjectRoot.mLights.begin(), mObjectRoot.mLights.end(), ToggleLight(enable)); + std::for_each(mObjectRoot->mLights.begin(), mObjectRoot->mLights.end(), ToggleLight(enable)); } @@ -1005,7 +979,7 @@ public: Ogre::AxisAlignedBox Animation::getWorldBounds() { Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL; - std::for_each(mObjectRoot.mEntities.begin(), mObjectRoot.mEntities.end(), MergeBounds(&bounds)); + std::for_each(mObjectRoot->mEntities.begin(), mObjectRoot->mEntities.end(), MergeBounds(&bounds)); return bounds; } @@ -1055,17 +1029,17 @@ void Animation::addEffect(const std::string &model, int effectId, bool loop, con params.mEffectId = effectId; params.mBoneName = bonename; - for(size_t i = 0;i < params.mObjects.mControllers.size();i++) + for(size_t i = 0;i < params.mObjects->mControllers.size();i++) { - if(params.mObjects.mControllers[i].getSource().isNull()) - params.mObjects.mControllers[i].setSource(Ogre::SharedPtr (new EffectAnimationValue())); + if(params.mObjects->mControllers[i].getSource().isNull()) + params.mObjects->mControllers[i].setSource(Ogre::SharedPtr (new EffectAnimationValue())); } if (!texture.empty()) { - for(size_t i = 0;i < params.mObjects.mParticles.size(); ++i) + for(size_t i = 0;i < params.mObjects->mParticles.size(); ++i) { - Ogre::ParticleSystem* partSys = params.mObjects.mParticles[i]; + Ogre::ParticleSystem* partSys = params.mObjects->mParticles[i]; sh::Factory::getInstance()._ensureMaterial(partSys->getMaterialName(), "Default"); Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().getByName(partSys->getMaterialName()); static int count = 0; @@ -1099,7 +1073,6 @@ void Animation::removeEffect(int effectId) { if (it->mEffectId == effectId) { - destroyObjectList(mInsert->getCreator(), it->mObjects); mEffects.erase(it); return; } @@ -1119,32 +1092,31 @@ void Animation::updateEffects(float duration) { for (std::vector::iterator it = mEffects.begin(); it != mEffects.end(); ) { - NifOgre::ObjectList& objects = it->mObjects; - for(size_t i = 0; i < objects.mControllers.size() ;i++) + NifOgre::ObjectScenePtr objects = it->mObjects; + for(size_t i = 0; i < objects->mControllers.size() ;i++) { - EffectAnimationValue* value = dynamic_cast(objects.mControllers[i].getSource().get()); + EffectAnimationValue* value = dynamic_cast(objects->mControllers[i].getSource().get()); if (value) value->addTime(duration); - objects.mControllers[i].update(); + objects->mControllers[i].update(); } - if (objects.mControllers[0].getSource()->getValue() >= objects.mMaxControllerLength) + if (objects->mControllers[0].getSource()->getValue() >= objects->mMaxControllerLength) { if (it->mLoop) { // Start from the beginning again; carry over the remainder - float remainder = objects.mControllers[0].getSource()->getValue() - objects.mMaxControllerLength; - for(size_t i = 0; i < objects.mControllers.size() ;i++) + float remainder = objects->mControllers[0].getSource()->getValue() - objects->mMaxControllerLength; + for(size_t i = 0; i < objects->mControllers.size() ;i++) { - EffectAnimationValue* value = dynamic_cast(objects.mControllers[i].getSource().get()); + EffectAnimationValue* value = dynamic_cast(objects->mControllers[i].getSource().get()); if (value) value->resetTime(remainder); } } else { - destroyObjectList(mInsert->getCreator(), it->mObjects); it = mEffects.erase(it); continue; } @@ -1214,16 +1186,16 @@ public: bool ObjectAnimation::canBatch() const { - if(!mObjectRoot.mParticles.empty() || !mObjectRoot.mLights.empty() || !mObjectRoot.mControllers.empty()) + if(!mObjectRoot->mParticles.empty() || !mObjectRoot->mLights.empty() || !mObjectRoot->mControllers.empty()) return false; - return std::find_if(mObjectRoot.mEntities.begin(), mObjectRoot.mEntities.end(), - FindEntityTransparency()) == mObjectRoot.mEntities.end(); + return std::find_if(mObjectRoot->mEntities.begin(), mObjectRoot->mEntities.end(), + FindEntityTransparency()) == mObjectRoot->mEntities.end(); } void ObjectAnimation::fillBatch(Ogre::StaticGeometry *sg) { - std::vector::reverse_iterator iter = mObjectRoot.mEntities.rbegin(); - for(;iter != mObjectRoot.mEntities.rend();++iter) + std::vector::reverse_iterator iter = mObjectRoot->mEntities.rbegin(); + for(;iter != mObjectRoot->mEntities.rend();++iter) { Ogre::Node *node = (*iter)->getParentNode(); sg->addEntity(*iter, node->_getDerivedPosition(), node->_getDerivedOrientation(), node->_getDerivedScale()); diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index e28aecbc1..b11b2b0a5 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -112,7 +112,7 @@ protected: struct EffectParams { std::string mModelName; // Just here so we don't add the same effect twice - NifOgre::ObjectList mObjects; + NifOgre::ObjectScenePtr mObjects; int mEffectId; bool mLoop; std::string mBoneName; @@ -125,7 +125,7 @@ protected: Ogre::SceneNode *mInsert; Ogre::Entity *mSkelBase; - NifOgre::ObjectList mObjectRoot; + NifOgre::ObjectScenePtr mObjectRoot; AnimSourceList mAnimSources; Ogre::Node *mAccumRoot; Ogre::Node *mNonAccumRoot; @@ -187,11 +187,9 @@ protected: void addAnimSource(const std::string &model); /** Adds an additional light to the given object list using the specified ESM record. */ - void addExtraLight(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objlist, const ESM::Light *light); + void addExtraLight(Ogre::SceneManager *sceneMgr, NifOgre::ObjectScenePtr objlist, const ESM::Light *light); - static void destroyObjectList(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objects); - - static void setRenderProperties(const NifOgre::ObjectList &objlist, Ogre::uint32 visflags, Ogre::uint8 solidqueue, + static void setRenderProperties(NifOgre::ObjectScenePtr objlist, Ogre::uint32 visflags, Ogre::uint8 solidqueue, Ogre::uint8 transqueue, Ogre::Real dist=0.0f, bool enchantedGlow=false, Ogre::Vector3* glowColor=NULL); diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 4ba49cf55..a57816f34 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -106,10 +106,6 @@ NpcAnimation::~NpcAnimation() { if (!mListenerDisabled) mPtr.getClass().getInventoryStore(mPtr).setListener(NULL, mPtr); - - Ogre::SceneManager *sceneMgr = mInsert->getCreator(); - for(size_t i = 0;i < ESM::PRT_Count;i++) - destroyObjectList(sceneMgr, mObjectParts[i]); } @@ -447,18 +443,18 @@ public: } }; -NifOgre::ObjectList NpcAnimation::insertBoundedPart(const std::string &model, int group, const std::string &bonename, bool enchantedGlow, Ogre::Vector3* glowColor) +NifOgre::ObjectScenePtr NpcAnimation::insertBoundedPart(const std::string &model, int group, const std::string &bonename, bool enchantedGlow, Ogre::Vector3* glowColor) { - NifOgre::ObjectList objects = NifOgre::Loader::createObjects(mSkelBase, bonename, mInsert, model); + NifOgre::ObjectScenePtr objects = NifOgre::Loader::createObjects(mSkelBase, bonename, mInsert, model); setRenderProperties(objects, (mViewMode == VM_FirstPerson) ? RV_FirstPerson : mVisibilityFlags, RQG_Main, RQG_Alpha, 0, enchantedGlow, glowColor); - std::for_each(objects.mEntities.begin(), objects.mEntities.end(), SetObjectGroup(group)); - std::for_each(objects.mParticles.begin(), objects.mParticles.end(), SetObjectGroup(group)); + std::for_each(objects->mEntities.begin(), objects->mEntities.end(), SetObjectGroup(group)); + std::for_each(objects->mParticles.begin(), objects->mParticles.end(), SetObjectGroup(group)); - if(objects.mSkelBase) + if(objects->mSkelBase) { - Ogre::AnimationStateSet *aset = objects.mSkelBase->getAllAnimationStates(); + Ogre::AnimationStateSet *aset = objects->mSkelBase->getAllAnimationStates(); Ogre::AnimationStateIterator asiter = aset->getAnimationStateIterator(); while(asiter.hasMoreElements()) { @@ -466,7 +462,7 @@ NifOgre::ObjectList NpcAnimation::insertBoundedPart(const std::string &model, in state->setEnabled(false); state->setLoop(false); } - Ogre::SkeletonInstance *skelinst = objects.mSkelBase->getSkeleton(); + Ogre::SkeletonInstance *skelinst = objects->mSkelBase->getSkeleton(); Ogre::Skeleton::BoneIterator boneiter = skelinst->getBoneIterator(); while(boneiter.hasMoreElements()) boneiter.getNext()->setManuallyControlled(true); @@ -494,11 +490,13 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed) for(size_t i = 0;i < ESM::PRT_Count;i++) { - std::vector >::iterator ctrl(mObjectParts[i].mControllers.begin()); - for(;ctrl != mObjectParts[i].mControllers.end();ctrl++) + if (mObjectParts[i].isNull()) + continue; + std::vector >::iterator ctrl(mObjectParts[i]->mControllers.begin()); + for(;ctrl != mObjectParts[i]->mControllers.end();ctrl++) ctrl->update(); - Ogre::Entity *ent = mObjectParts[i].mSkelBase; + Ogre::Entity *ent = mObjectParts[i]->mSkelBase; if(!ent) continue; updateSkeletonInstance(baseinst, ent->getSkeleton()); ent->getAllAnimationStates()->_notifyDirty(); @@ -512,7 +510,7 @@ void NpcAnimation::removeIndividualPart(ESM::PartReferenceType type) mPartPriorities[type] = 0; mPartslots[type] = -1; - destroyObjectList(mInsert->getCreator(), mObjectParts[type]); + mObjectParts[type].setNull(); } void NpcAnimation::reserveIndividualPart(ESM::PartReferenceType type, int group, int priority) @@ -544,12 +542,12 @@ bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int g mPartPriorities[type] = priority; mObjectParts[type] = insertBoundedPart(mesh, group, sPartList.at(type), enchantedGlow, glowColor); - if(mObjectParts[type].mSkelBase) + if(mObjectParts[type]->mSkelBase) { - Ogre::SkeletonInstance *skel = mObjectParts[type].mSkelBase->getSkeleton(); - if(mObjectParts[type].mSkelBase->isParentTagPoint()) + Ogre::SkeletonInstance *skel = mObjectParts[type]->mSkelBase->getSkeleton(); + if(mObjectParts[type]->mSkelBase->isParentTagPoint()) { - Ogre::Node *root = mObjectParts[type].mSkelBase->getParentNode(); + Ogre::Node *root = mObjectParts[type]->mSkelBase->getParentNode(); if(skel->hasBone("BoneOffset")) { Ogre::Bone *offset = skel->getBone("BoneOffset"); @@ -571,8 +569,8 @@ bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int g // TODO: // type == ESM::PRT_Weapon should get an animation source based on the current offset // of the weapon attack animation (from its beginning, or start marker?) - std::vector >::iterator ctrl(mObjectParts[type].mControllers.begin()); - for(;ctrl != mObjectParts[type].mControllers.end();ctrl++) + std::vector >::iterator ctrl(mObjectParts[type]->mControllers.begin()); + for(;ctrl != mObjectParts[type]->mControllers.end();ctrl++) { if(ctrl->getSource().isNull()) { diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index 4e252d9d0..962663268 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -46,7 +46,7 @@ private: bool mListenerDisabled; // Bounded Parts - NifOgre::ObjectList mObjectParts[ESM::PRT_Count]; + NifOgre::ObjectScenePtr mObjectParts[ESM::PRT_Count]; const ESM::NPC *mNpc; std::string mHeadModel; @@ -66,7 +66,7 @@ private: void updateNpcBase(); - NifOgre::ObjectList insertBoundedPart(const std::string &model, int group, const std::string &bonename, + NifOgre::ObjectScenePtr insertBoundedPart(const std::string &model, int group, const std::string &bonename, bool enchantedGlow, Ogre::Vector3* glowColor=NULL); void removeIndividualPart(ESM::PartReferenceType type); diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 03e14dc07..39f7ccc85 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -285,10 +285,10 @@ void SkyManager::create() // Stars mAtmosphereNight = mRootNode->createChildSceneNode(); - NifOgre::ObjectList objects = NifOgre::Loader::createObjects(mAtmosphereNight, "meshes\\sky_night_01.nif"); - for(size_t i = 0, matidx = 0;i < objects.mEntities.size();i++) + NifOgre::ObjectScenePtr objects = NifOgre::Loader::createObjects(mAtmosphereNight, "meshes\\sky_night_01.nif"); + for(size_t i = 0, matidx = 0;i < objects->mEntities.size();i++) { - Entity* night1_ent = objects.mEntities[i]; + Entity* night1_ent = objects->mEntities[i]; night1_ent->setRenderQueueGroup(RQG_SkiesEarly+1); night1_ent->setVisibilityFlags(RV_Sky); night1_ent->setCastShadows(false); @@ -307,14 +307,14 @@ void SkyManager::create() night1_ent->getSubEntity(j)->setMaterialName(matName); } } - + mObjects.push_back(objects); // Atmosphere (day) mAtmosphereDay = mRootNode->createChildSceneNode(); objects = NifOgre::Loader::createObjects(mAtmosphereDay, "meshes\\sky_atmosphere.nif"); - for(size_t i = 0;i < objects.mEntities.size();i++) + for(size_t i = 0;i < objects->mEntities.size();i++) { - Entity* atmosphere_ent = objects.mEntities[i]; + Entity* atmosphere_ent = objects->mEntities[i]; atmosphere_ent->setCastShadows(false); atmosphere_ent->setRenderQueueGroup(RQG_SkiesEarly); atmosphere_ent->setVisibilityFlags(RV_Sky); @@ -325,14 +325,14 @@ void SkyManager::create() // Using infinite AAB here to prevent being clipped by the custom near clip plane used for reflections/refractions atmosphere_ent->getMesh()->_setBounds (aabInf); } - + mObjects.push_back(objects); // Clouds SceneNode* clouds_node = mRootNode->createChildSceneNode(); objects = NifOgre::Loader::createObjects(clouds_node, "meshes\\sky_clouds_01.nif"); - for(size_t i = 0;i < objects.mEntities.size();i++) + for(size_t i = 0;i < objects->mEntities.size();i++) { - Entity* clouds_ent = objects.mEntities[i]; + Entity* clouds_ent = objects->mEntities[i]; clouds_ent->setVisibilityFlags(RV_Sky); clouds_ent->setRenderQueueGroup(RQG_SkiesEarly+5); for(unsigned int j = 0;j < clouds_ent->getNumSubEntities();j++) @@ -341,6 +341,7 @@ void SkyManager::create() // Using infinite AAB here to prevent being clipped by the custom near clip plane used for reflections/refractions clouds_ent->getMesh()->_setBounds (aabInf); } + mObjects.push_back(objects); mCreated = true; } diff --git a/apps/openmw/mwrender/sky.hpp b/apps/openmw/mwrender/sky.hpp index 3df8846cd..965907a97 100644 --- a/apps/openmw/mwrender/sky.hpp +++ b/apps/openmw/mwrender/sky.hpp @@ -11,6 +11,8 @@ #include +#include + #include "../mwworld/weather.hpp" @@ -196,6 +198,8 @@ namespace MWRender Ogre::SceneNode* mAtmosphereDay; Ogre::SceneNode* mAtmosphereNight; + std::vector mObjects; + // remember some settings so we don't have to apply them again if they didnt change Ogre::String mClouds; Ogre::String mNextClouds; diff --git a/components/nifogre/ogrenifloader.cpp b/components/nifogre/ogrenifloader.cpp index ec24089b8..44c3042c6 100644 --- a/components/nifogre/ogrenifloader.cpp +++ b/components/nifogre/ogrenifloader.cpp @@ -47,6 +47,28 @@ namespace NifOgre { + +ObjectScene::~ObjectScene() +{ + for(size_t i = 0;i < mLights.size();i++) + { + Ogre::Light *light = mLights[i]; + // If parent is a scene node, it was created specifically for this light. Destroy it now. + if(light->isAttached() && !light->isParentTagPoint()) + mSceneMgr->destroySceneNode(light->getParentSceneNode()); + mSceneMgr->destroyLight(light); + } + for(size_t i = 0;i < mParticles.size();i++) + mSceneMgr->destroyParticleSystem(mParticles[i]); + for(size_t i = 0;i < mEntities.size();i++) + mSceneMgr->destroyEntity(mEntities[i]); + mControllers.clear(); + mLights.clear(); + mParticles.clear(); + mEntities.clear(); + mSkelBase = NULL; +} + // FIXME: Should not be here. class DefaultFunction : public Ogre::ControllerFunction { @@ -504,7 +526,7 @@ class NIFObjectLoader static void createEntity(const std::string &name, const std::string &group, - Ogre::SceneManager *sceneMgr, ObjectList &objectlist, + Ogre::SceneManager *sceneMgr, ObjectScenePtr scene, const Nif::Node *node, int flags, int animflags) { const Nif::NiTriShape *shape = static_cast(node); @@ -521,16 +543,16 @@ class NIFObjectLoader Ogre::Entity *entity = sceneMgr->createEntity(fullname); entity->setVisible(!(flags&Nif::NiNode::Flag_Hidden)); - objectlist.mEntities.push_back(entity); - if(objectlist.mSkelBase) + scene->mEntities.push_back(entity); + if(scene->mSkelBase) { if(entity->hasSkeleton()) - entity->shareSkeletonInstanceWith(objectlist.mSkelBase); + entity->shareSkeletonInstanceWith(scene->mSkelBase); else { int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, shape->recIndex); - Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid); - objectlist.mSkelBase->attachObjectToBone(trgtbone->getName(), entity); + Ogre::Bone *trgtbone = scene->mSkelBase->getSkeleton()->getBone(trgtid); + scene->mSkelBase->attachObjectToBone(trgtbone->getName(), entity); } } @@ -548,10 +570,10 @@ class NIFObjectLoader Ogre::ControllerValueRealPtr dstval(OGRE_NEW UVController::Value(material, uv->data.getPtr())); UVController::Function* function = OGRE_NEW UVController::Function(uv, (animflags&Nif::NiNode::AnimFlag_AutoPlay)); - objectlist.mMaxControllerLength = std::max(function->mStopTime, objectlist.mMaxControllerLength); + scene->mMaxControllerLength = std::max(function->mStopTime, scene->mMaxControllerLength); Ogre::ControllerFunctionRealPtr func(function); - objectlist.mControllers.push_back(Ogre::Controller(srcval, dstval, func)); + scene->mControllers.push_back(Ogre::Controller(srcval, dstval, func)); } else if(ctrl->recType == Nif::RC_NiGeomMorpherController) { @@ -563,10 +585,10 @@ class NIFObjectLoader Ogre::ControllerValueRealPtr dstval(OGRE_NEW GeomMorpherController::Value(entity->getSubEntity(0), geom->data.getPtr())); GeomMorpherController::Function* function = OGRE_NEW GeomMorpherController::Function(geom, (animflags&Nif::NiNode::AnimFlag_AutoPlay)); - objectlist.mMaxControllerLength = std::max(function->mStopTime, objectlist.mMaxControllerLength); + scene->mMaxControllerLength = std::max(function->mStopTime, scene->mMaxControllerLength); Ogre::ControllerFunctionRealPtr func(function); - objectlist.mControllers.push_back(Ogre::Controller(srcval, dstval, func)); + scene->mControllers.push_back(Ogre::Controller(srcval, dstval, func)); } ctrl = ctrl->next; } @@ -647,7 +669,7 @@ class NIFObjectLoader } static void createParticleSystem(const std::string &name, const std::string &group, - Ogre::SceneNode *sceneNode, ObjectList &objectlist, + Ogre::SceneNode *sceneNode, ObjectScenePtr scene, const Nif::Node *partnode, int flags, int partflags) { const Nif::NiAutoNormalParticlesData *particledata = NULL; @@ -696,8 +718,8 @@ class NIFObjectLoader if(!partctrl->emitter.empty()) { int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, partctrl->emitter->recIndex); - Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid); - createParticleEmitterAffectors(partsys, partctrl, trgtbone, objectlist.mSkelBase->getName()); + Ogre::Bone *trgtbone = scene->mSkelBase->getSkeleton()->getBone(trgtid); + createParticleEmitterAffectors(partsys, partctrl, trgtbone, scene->mSkelBase->getName()); } Ogre::ControllerValueRealPtr srcval((partflags&Nif::NiNode::ParticleFlag_AutoPlay) ? @@ -707,20 +729,20 @@ class NIFObjectLoader ParticleSystemController::Function* function = OGRE_NEW ParticleSystemController::Function(partctrl, (partflags&Nif::NiNode::ParticleFlag_AutoPlay)); - objectlist.mMaxControllerLength = std::max(function->mStopTime, objectlist.mMaxControllerLength); + scene->mMaxControllerLength = std::max(function->mStopTime, scene->mMaxControllerLength); Ogre::ControllerFunctionRealPtr func(function); - objectlist.mControllers.push_back(Ogre::Controller(srcval, dstval, func)); + scene->mControllers.push_back(Ogre::Controller(srcval, dstval, func)); } ctrl = ctrl->next; } partsys->setVisible(!(flags&Nif::NiNode::Flag_Hidden)); - objectlist.mParticles.push_back(partsys); + scene->mParticles.push_back(partsys); } - static void createNodeControllers(const std::string &name, Nif::ControllerPtr ctrl, ObjectList &objectlist, int animflags) + static void createNodeControllers(const std::string &name, Nif::ControllerPtr ctrl, ObjectScenePtr scene, int animflags) { do { if(ctrl->recType == Nif::RC_NiVisController) @@ -728,17 +750,17 @@ class NIFObjectLoader const Nif::NiVisController *vis = static_cast(ctrl.getPtr()); int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, ctrl->target->recIndex); - Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid); + Ogre::Bone *trgtbone = scene->mSkelBase->getSkeleton()->getBone(trgtid); Ogre::ControllerValueRealPtr srcval((animflags&Nif::NiNode::AnimFlag_AutoPlay) ? Ogre::ControllerManager::getSingleton().getFrameTimeSource() : Ogre::ControllerValueRealPtr()); Ogre::ControllerValueRealPtr dstval(OGRE_NEW VisController::Value(trgtbone, vis->data.getPtr())); VisController::Function* function = OGRE_NEW VisController::Function(vis, (animflags&Nif::NiNode::AnimFlag_AutoPlay)); - objectlist.mMaxControllerLength = std::max(function->mStopTime, objectlist.mMaxControllerLength); + scene->mMaxControllerLength = std::max(function->mStopTime, scene->mMaxControllerLength); Ogre::ControllerFunctionRealPtr func(function); - objectlist.mControllers.push_back(Ogre::Controller(srcval, dstval, func)); + scene->mControllers.push_back(Ogre::Controller(srcval, dstval, func)); } else if(ctrl->recType == Nif::RC_NiKeyframeController) { @@ -746,16 +768,16 @@ class NIFObjectLoader if(!key->data.empty()) { int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, ctrl->target->recIndex); - Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid); + Ogre::Bone *trgtbone = scene->mSkelBase->getSkeleton()->getBone(trgtid); Ogre::ControllerValueRealPtr srcval((animflags&Nif::NiNode::AnimFlag_AutoPlay) ? Ogre::ControllerManager::getSingleton().getFrameTimeSource() : Ogre::ControllerValueRealPtr()); Ogre::ControllerValueRealPtr dstval(OGRE_NEW KeyframeController::Value(trgtbone, key->data.getPtr())); KeyframeController::Function* function = OGRE_NEW KeyframeController::Function(key, (animflags&Nif::NiNode::AnimFlag_AutoPlay)); - objectlist.mMaxControllerLength = std::max(function->mStopTime, objectlist.mMaxControllerLength); + scene->mMaxControllerLength = std::max(function->mStopTime, scene->mMaxControllerLength); Ogre::ControllerFunctionRealPtr func(function); - objectlist.mControllers.push_back(Ogre::Controller(srcval, dstval, func)); + scene->mControllers.push_back(Ogre::Controller(srcval, dstval, func)); } } ctrl = ctrl->next; @@ -804,7 +826,7 @@ class NIFObjectLoader static void createObjects(const std::string &name, const std::string &group, Ogre::SceneNode *sceneNode, const Nif::Node *node, - ObjectList &objectlist, int flags, int animflags, int partflags) + ObjectScenePtr scene, int flags, int animflags, int partflags) { // Do not create objects for the collision shape (includes all children) if(node->recType == Nif::RC_RootCollisionNode) @@ -830,7 +852,7 @@ class NIFObjectLoader const Nif::NiTextKeyExtraData *tk = static_cast(e.getPtr()); int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, node->recIndex); - extractTextKeys(tk, objectlist.mTextKeys[trgtid]); + extractTextKeys(tk, scene->mTextKeys[trgtid]); } else if(e->recType == Nif::RC_NiStringExtraData) { @@ -849,7 +871,7 @@ class NIFObjectLoader } if(!node->controller.empty() && (node->parent || node->recType != Nif::RC_NiNode)) - createNodeControllers(name, node->controller, objectlist, animflags); + createNodeControllers(name, node->controller, scene, animflags); if(node->recType == Nif::RC_NiCamera) { @@ -858,13 +880,13 @@ class NIFObjectLoader if(node->recType == Nif::RC_NiTriShape && !(flags&0x80000000)) { - createEntity(name, group, sceneNode->getCreator(), objectlist, node, flags, animflags); + createEntity(name, group, sceneNode->getCreator(), scene, node, flags, animflags); } if((node->recType == Nif::RC_NiAutoNormalParticles || node->recType == Nif::RC_NiRotatingParticles) && !(flags&0x40000000)) { - createParticleSystem(name, group, sceneNode, objectlist, node, flags, partflags); + createParticleSystem(name, group, sceneNode, scene, node, flags, partflags); } const Nif::NiNode *ninode = dynamic_cast(node); @@ -874,14 +896,14 @@ class NIFObjectLoader for(size_t i = 0;i < children.length();i++) { if(!children[i].empty()) - createObjects(name, group, sceneNode, children[i].getPtr(), objectlist, flags, animflags, partflags); + createObjects(name, group, sceneNode, children[i].getPtr(), scene, flags, animflags, partflags); } } } static void createSkelBase(const std::string &name, const std::string &group, Ogre::SceneManager *sceneMgr, const Nif::Node *node, - ObjectList &objectlist) + ObjectScenePtr scene) { /* This creates an empty mesh to which a skeleton gets attached. This * is to ensure we have an entity with a skeleton instance, even if all @@ -890,12 +912,12 @@ class NIFObjectLoader if(meshMgr.getByName(name).isNull()) NIFMeshLoader::createMesh(name, name, group, ~(size_t)0); - objectlist.mSkelBase = sceneMgr->createEntity(name); - objectlist.mEntities.push_back(objectlist.mSkelBase); + scene->mSkelBase = sceneMgr->createEntity(name); + scene->mEntities.push_back(scene->mSkelBase); } public: - static void load(Ogre::SceneNode *sceneNode, ObjectList &objectlist, const std::string &name, const std::string &group, int flags=0) + static void load(Ogre::SceneNode *sceneNode, ObjectScenePtr scene, const std::string &name, const std::string &group, int flags=0) { Nif::NIFFile::ptr nif = Nif::NIFFile::create(name); if(nif->numRoots() < 1) @@ -919,9 +941,9 @@ public: !NIFSkeletonLoader::createSkeleton(name, group, node).isNull()) { // Create a base skeleton entity if this NIF needs one - createSkelBase(name, group, sceneNode->getCreator(), node, objectlist); + createSkelBase(name, group, sceneNode->getCreator(), node, scene); } - createObjects(name, group, sceneNode, node, objectlist, flags, 0, 0); + createObjects(name, group, sceneNode, node, scene, flags, 0, 0); } static void loadKf(Ogre::Skeleton *skel, const std::string &name, @@ -984,37 +1006,37 @@ public: }; -ObjectList Loader::createObjects(Ogre::SceneNode *parentNode, std::string name, const std::string &group) +ObjectScenePtr Loader::createObjects(Ogre::SceneNode *parentNode, std::string name, const std::string &group) { - ObjectList objectlist; + ObjectScenePtr scene = ObjectScenePtr (new ObjectScene(parentNode->getCreator()));; Misc::StringUtils::toLower(name); - NIFObjectLoader::load(parentNode, objectlist, name, group); + NIFObjectLoader::load(parentNode, scene, name, group); - for(size_t i = 0;i < objectlist.mEntities.size();i++) + for(size_t i = 0;i < scene->mEntities.size();i++) { - Ogre::Entity *entity = objectlist.mEntities[i]; + Ogre::Entity *entity = scene->mEntities[i]; if(!entity->isAttached()) parentNode->attachObject(entity); } - return objectlist; + return scene; } -ObjectList Loader::createObjects(Ogre::Entity *parent, const std::string &bonename, +ObjectScenePtr Loader::createObjects(Ogre::Entity *parent, const std::string &bonename, Ogre::SceneNode *parentNode, std::string name, const std::string &group) { - ObjectList objectlist; + ObjectScenePtr scene = ObjectScenePtr (new ObjectScene(parentNode->getCreator())); Misc::StringUtils::toLower(name); - NIFObjectLoader::load(parentNode, objectlist, name, group); + NIFObjectLoader::load(parentNode, scene, name, group); bool isskinned = false; - for(size_t i = 0;i < objectlist.mEntities.size();i++) + for(size_t i = 0;i < scene->mEntities.size();i++) { - Ogre::Entity *ent = objectlist.mEntities[i]; - if(objectlist.mSkelBase != ent && ent->hasSkeleton()) + Ogre::Entity *ent = scene->mEntities[i]; + if(scene->mSkelBase != ent && ent->hasSkeleton()) { isskinned = true; break; @@ -1029,12 +1051,12 @@ ObjectList Loader::createObjects(Ogre::Entity *parent, const std::string &bonena { std::string filter = "@shape=tri "+bonename; Misc::StringUtils::toLower(filter); - for(size_t i = 0;i < objectlist.mEntities.size();i++) + for(size_t i = 0;i < scene->mEntities.size();i++) { - Ogre::Entity *entity = objectlist.mEntities[i]; + Ogre::Entity *entity = scene->mEntities[i]; if(entity->hasSkeleton()) { - if(entity == objectlist.mSkelBase || + if(entity == scene->mSkelBase || entity->getMesh()->getName().find(filter) != std::string::npos) parentNode->attachObject(entity); } @@ -1047,9 +1069,9 @@ ObjectList Loader::createObjects(Ogre::Entity *parent, const std::string &bonena } else { - for(size_t i = 0;i < objectlist.mEntities.size();i++) + for(size_t i = 0;i < scene->mEntities.size();i++) { - Ogre::Entity *entity = objectlist.mEntities[i]; + Ogre::Entity *entity = scene->mEntities[i]; if(!entity->isAttached()) { Ogre::TagPoint *tag = parent->attachObjectToBone(bonename, entity); @@ -1058,32 +1080,32 @@ ObjectList Loader::createObjects(Ogre::Entity *parent, const std::string &bonena } } - for(size_t i = 0;i < objectlist.mParticles.size();i++) + for(size_t i = 0;i < scene->mParticles.size();i++) { - Ogre::ParticleSystem *partsys = objectlist.mParticles[i]; + Ogre::ParticleSystem *partsys = scene->mParticles[i]; if(partsys->isAttached()) partsys->detachFromParent(); - Ogre::TagPoint *tag = objectlist.mSkelBase->attachObjectToBone( - objectlist.mSkelBase->getSkeleton()->getRootBone()->getName(), partsys); + Ogre::TagPoint *tag = scene->mSkelBase->attachObjectToBone( + scene->mSkelBase->getSkeleton()->getRootBone()->getName(), partsys); tag->setScale(scale); } - return objectlist; + return scene; } -ObjectList Loader::createObjectBase(Ogre::SceneNode *parentNode, std::string name, const std::string &group) +ObjectScenePtr Loader::createObjectBase(Ogre::SceneNode *parentNode, std::string name, const std::string &group) { - ObjectList objectlist; + ObjectScenePtr scene = ObjectScenePtr (new ObjectScene(parentNode->getCreator())); Misc::StringUtils::toLower(name); - NIFObjectLoader::load(parentNode, objectlist, name, group, 0xC0000000); + NIFObjectLoader::load(parentNode, scene, name, group, 0xC0000000); - if(objectlist.mSkelBase) - parentNode->attachObject(objectlist.mSkelBase); + if(scene->mSkelBase) + parentNode->attachObject(scene->mSkelBase); - return objectlist; + return scene; } diff --git a/components/nifogre/ogrenifloader.hpp b/components/nifogre/ogrenifloader.hpp index de06dd3d5..94d4aa674 100644 --- a/components/nifogre/ogrenifloader.hpp +++ b/components/nifogre/ogrenifloader.hpp @@ -39,12 +39,14 @@ namespace NifOgre typedef std::multimap TextKeyMap; static const char sTextKeyExtraDataID[] = "TextKeyExtraData"; -struct ObjectList { +struct ObjectScene { Ogre::Entity *mSkelBase; std::vector mEntities; std::vector mParticles; std::vector mLights; + Ogre::SceneManager* mSceneMgr; + // The maximum length on any of the controllers. For animations with controllers, but no text keys, consider this the animation length. float mMaxControllerLength; @@ -52,24 +54,28 @@ struct ObjectList { std::vector > mControllers; - ObjectList() : mSkelBase(0), mMaxControllerLength(0) + ObjectScene(Ogre::SceneManager* sceneMgr) : mSkelBase(0), mMaxControllerLength(0), mSceneMgr(sceneMgr) { } + + ~ObjectScene(); }; +typedef Ogre::SharedPtr ObjectScenePtr; + class Loader { public: - static ObjectList createObjects(Ogre::Entity *parent, const std::string &bonename, + static ObjectScenePtr createObjects(Ogre::Entity *parent, const std::string &bonename, Ogre::SceneNode *parentNode, std::string name, const std::string &group="General"); - static ObjectList createObjects(Ogre::SceneNode *parentNode, + static ObjectScenePtr createObjects(Ogre::SceneNode *parentNode, std::string name, const std::string &group="General"); - static ObjectList createObjectBase(Ogre::SceneNode *parentNode, + static ObjectScenePtr createObjectBase(Ogre::SceneNode *parentNode, std::string name, const std::string &group="General");