From 3dedac5cb14623911a43de2027c8f86077586e8d Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 17 Jul 2012 13:40:03 -0700 Subject: [PATCH] Create mesh entities for objects when loading the NIF --- apps/openmw/mwrender/objects.cpp | 23 +++++++-------- components/nifogre/ogre_nif_loader.cpp | 39 ++++++++++++++++++++++++++ components/nifogre/ogre_nif_loader.hpp | 12 ++++++++ 3 files changed, 61 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwrender/objects.cpp b/apps/openmw/mwrender/objects.cpp index 2ff9de9a4a..bc1a4a521c 100644 --- a/apps/openmw/mwrender/objects.cpp +++ b/apps/openmw/mwrender/objects.cpp @@ -93,13 +93,10 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) assert(insert); Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL; - NifOgre::MeshPairList meshes = NifOgre::NIFLoader::load(mesh); - std::vector entities(meshes.size()); - for(size_t i = 0;i < meshes.size();i++) + NifOgre::EntityList entities = NifOgre::NIFLoader::createEntities(insert, mesh); + for(size_t i = 0;i < entities.mEntities.size();i++) { - entities[i] = mRenderer.getScene()->createEntity(meshes[i].first->getName()); - - const Ogre::AxisAlignedBox &tmp = entities[i]->getBoundingBox(); + const Ogre::AxisAlignedBox &tmp = entities.mEntities[i]->getBoundingBox(); bounds.merge(Ogre::AxisAlignedBox(insert->_getDerivedPosition() + tmp.getMinimum(), insert->_getDerivedPosition() + tmp.getMaximum()) ); @@ -119,9 +116,9 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) mBounds[ptr.getCell()].merge(bounds); bool transparent = false; - for(size_t i = 0;i < entities.size();i++) + for(size_t i = 0;i < entities.mEntities.size();i++) { - Ogre::Entity *ent = entities[i]; + Ogre::Entity *ent = entities.mEntities[i]; for (unsigned int i=0; igetNumSubEntities(); ++i) { Ogre::MaterialPtr mat = ent->getSubEntity(i)->getMaterial(); @@ -143,10 +140,9 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") || transparent) { - for(size_t i = 0;i < entities.size();i++) + for(size_t i = 0;i < entities.mEntities.size();i++) { - Ogre::Entity *ent = entities[i]; - insert->attachObject(ent); + Ogre::Entity *ent = entities.mEntities[i]; ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc); @@ -197,9 +193,10 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) sg->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); - for(size_t i = 0;i < entities.size();i++) + for(size_t i = 0;i < entities.mEntities.size();i++) { - Ogre::Entity *ent = entities[i]; + Ogre::Entity *ent = entities.mEntities[i]; + insert->detachObject(ent); sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale()); mRenderer.getScene()->destroyEntity(ent); diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index fef7054f73..c90083619d 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -871,6 +872,44 @@ MeshPairList NIFLoader::load(const std::string &name, Ogre::SkeletonPtr *skel, c return meshes; } +EntityList NIFLoader::createEntities(Ogre::SceneNode *parent, const std::string &name, const std::string &group) +{ + EntityList entitylist; + + MeshPairList meshes = load(name, NULL, group); + if(meshes.size() == 0) + return entitylist; + + Ogre::SceneManager *sceneMgr = parent->getCreator(); + for(size_t i = 0;i < meshes.size();i++) + { + entitylist.mEntities.push_back(sceneMgr->createEntity(meshes[i].first->getName())); + Ogre::Entity *entity = entitylist.mEntities.back(); + if(!entitylist.mSkelBase && entity->hasSkeleton()) + entitylist.mSkelBase = entity; + } + + if(entitylist.mSkelBase) + { + parent->attachObject(entitylist.mSkelBase); + for(size_t i = 0;i < entitylist.mEntities.size();i++) + { + Ogre::Entity *entity = entitylist.mEntities[i]; + if(entity != entitylist.mSkelBase && entity->hasSkeleton()) + entity->shareSkeletonInstanceWith(entitylist.mSkelBase); + else if(entity != entitylist.mSkelBase) + entitylist.mSkelBase->attachObjectToBone(meshes[i].second, entity); + } + } + else + { + for(size_t i = 0;i < entitylist.mEntities.size();i++) + parent->attachObject(entitylist.mEntities[i]); + } + + return entitylist; +} + /* More code currently not in use, from the old D source. This was used in the first attempt at loading NIF meshes, where each submesh diff --git a/components/nifogre/ogre_nif_loader.hpp b/components/nifogre/ogre_nif_loader.hpp index 4e9ffc31e3..bd6f99b2f1 100644 --- a/components/nifogre/ogre_nif_loader.hpp +++ b/components/nifogre/ogre_nif_loader.hpp @@ -58,6 +58,14 @@ namespace Nif namespace NifOgre { +struct EntityList { + std::vector mEntities; + Ogre::Entity *mSkelBase; + + EntityList() : mSkelBase(0) + { } +}; + /** This holds a list of meshes along with the names of their parent nodes */ typedef std::vector< std::pair > MeshPairList; @@ -81,6 +89,10 @@ public: static MeshPairList load(const std::string &name, Ogre::SkeletonPtr *skel=NULL, const std::string &group="General"); + + static EntityList createEntities(Ogre::SceneNode *parent, + const std::string &name, + const std::string &group="General"); }; }