From eb4daaf512c37c3ba353784415672a2f4f6bb863 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 8 May 2013 01:03:57 -0700 Subject: [PATCH] Build a skeleton for Nifs that have a matching .kf file --- components/nifogre/skeleton.cpp | 57 +++++++++++++++++++++------------ components/nifogre/skeleton.hpp | 2 ++ 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/components/nifogre/skeleton.cpp b/components/nifogre/skeleton.cpp index 3aec920fc..04bffdeab 100644 --- a/components/nifogre/skeleton.cpp +++ b/components/nifogre/skeleton.cpp @@ -81,7 +81,7 @@ void NIFSkeletonLoader::loadResource(Ogre::Resource *resource) } -Ogre::SkeletonPtr NIFSkeletonLoader::createSkeleton(const std::string &name, const std::string &group, const Nif::Node *node) +bool NIFSkeletonLoader::needSkeleton(const Nif::Node *node) { /* We need to be a little aggressive here, since some NIFs have a crap-ton * of nodes and Ogre only supports 256 bones. We will skip a skeleton if: @@ -89,32 +89,49 @@ Ogre::SkeletonPtr NIFSkeletonLoader::createSkeleton(const std::string &name, con * are no nodes named "AttachLight", and the tree consists of NiNode, * NiTriShape, and RootCollisionNode types only. */ - if(!node->boneTrafo) + if(node->boneTrafo) + return true; + + if(!node->controller.empty() || node->name == "AttachLight") + return true; + + if(node->recType == Nif::RC_NiNode || node->recType == Nif::RC_RootCollisionNode) { - if(node->controller.empty() && node->name != "AttachLight") + const Nif::NiNode *ninode = static_cast(node); + const Nif::NodeList &children = ninode->children; + for(size_t i = 0;i < children.length();i++) { - if(node->recType == Nif::RC_NiTriShape) - return Ogre::SkeletonPtr(); - if(node->recType == Nif::RC_NiNode || node->recType == Nif::RC_RootCollisionNode) + if(!children[i].empty()) { - const Nif::NiNode *ninode = static_cast(node); - const Nif::NodeList &children = ninode->children; - for(size_t i = 0;i < children.length();i++) - { - if(!children[i].empty()) - { - Ogre::SkeletonPtr skel = createSkeleton(name, group, children[i].getPtr()); - if(!skel.isNull()) - return skel; - } - } - return Ogre::SkeletonPtr(); + if(needSkeleton(children[i].getPtr())) + return true; } } + return false; + } + if(node->recType == Nif::RC_NiTriShape) + return false; + + return true; +} + +Ogre::SkeletonPtr NIFSkeletonLoader::createSkeleton(const std::string &name, const std::string &group, const Nif::Node *node) +{ + bool forceskel = false; + std::string::size_type extpos = name.rfind('.'); + if(extpos != std::string::npos && name.compare(extpos, name.size()-extpos, ".nif") == 0) + { + Ogre::ResourceGroupManager &resMgr = Ogre::ResourceGroupManager::getSingleton(); + forceskel = resMgr.resourceExistsInAnyGroup(name.substr(0, extpos)+".kf"); + } + + if(forceskel || needSkeleton(node)) + { + Ogre::SkeletonManager &skelMgr = Ogre::SkeletonManager::getSingleton(); + return skelMgr.create(name, group, true, &sLoaders[name]); } - Ogre::SkeletonManager &skelMgr = Ogre::SkeletonManager::getSingleton(); - return skelMgr.create(name, group, true, &sLoaders[name]); + return Ogre::SkeletonPtr(); } // Looks up an Ogre Bone handle ID from a NIF's record index. Should only be diff --git a/components/nifogre/skeleton.hpp b/components/nifogre/skeleton.hpp index 38cfe14e3..9ec3a0c82 100644 --- a/components/nifogre/skeleton.hpp +++ b/components/nifogre/skeleton.hpp @@ -38,6 +38,8 @@ class NIFSkeletonLoader : public Ogre::ManualResourceLoader void buildBones(Ogre::Skeleton *skel, const Nif::Node *node, Ogre::Bone *parent=NULL); + static bool needSkeleton(const Nif::Node *node); + // Lookup to retrieve an Ogre bone handle for a given Nif record index std::map mNifToOgreHandleMap;