1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-01 02:45:32 +00:00

Always create a skeleton from a NIF when there's more than one NiNode

This commit is contained in:
Chris Robinson 2013-02-09 17:48:23 -08:00
parent 8d6f017f17
commit f4e587c72c

View file

@ -21,8 +21,6 @@
*/ */
//loadResource->handleNode->handleNiTriShape->createSubMesh
#include "ogre_nif_loader.hpp" #include "ogre_nif_loader.hpp"
#include <algorithm> #include <algorithm>
@ -456,30 +454,28 @@ void loadResource(Ogre::Resource *resource)
bool createSkeleton(const std::string &name, const std::string &group, const Nif::Node *node) bool createSkeleton(const std::string &name, const std::string &group, const Nif::Node *node)
{ {
/* If the root node is a NiTriShape, or is a parent to only NiTriShapes, do
* not create a skeleton. */
if(node->recType == Nif::RC_NiTriShape) if(node->recType == Nif::RC_NiTriShape)
return false; return false;
if(node->boneTrafo != NULL) if(node->recType == Nif::RC_NiNode)
{ {
Ogre::SkeletonManager &skelMgr = Ogre::SkeletonManager::getSingleton(); bool alltrishapes = true;
skelMgr.create(name, group, true, &sLoaders[name]); const Nif::NiNode *ninode = static_cast<const Nif::NiNode*>(node);
return true; const Nif::NodeList &children = ninode->children;
for(size_t i = 0;i < children.length() && alltrishapes;i++)
{
if(!children[i].empty() && children[i]->recType != Nif::RC_NiTriShape)
alltrishapes = false;
}
if(alltrishapes)
return false;
} }
const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(node); Ogre::SkeletonManager &skelMgr = Ogre::SkeletonManager::getSingleton();
if(ninode) skelMgr.create(name, group, true, &sLoaders[name]);
{ return true;
const Nif::NodeList &children = ninode->children;
for(size_t i = 0;i < children.length();i++)
{
if(!children[i].empty())
{
if(createSkeleton(name, group, children[i].getPtr()))
return true;
}
}
}
return false;
} }
}; };
@ -1052,7 +1048,7 @@ public:
e = e->extra; e = e->extra;
} }
if(node->recType == Nif::RC_NiTriShape) if(node->recType == Nif::RC_NiTriShape && !(flags&0x01)) // Not hidden
{ {
const Nif::NiTriShape *shape = dynamic_cast<const Nif::NiTriShape*>(node); const Nif::NiTriShape *shape = dynamic_cast<const Nif::NiTriShape*>(node);
mShapeName = shape->name; mShapeName = shape->name;
@ -1068,11 +1064,8 @@ public:
{ {
NIFMeshLoader *loader = &sLoaders[fullname]; NIFMeshLoader *loader = &sLoaders[fullname];
*loader = *this; *loader = *this;
if(!(flags&0x01)) // Not hidden loader->mShapeIndex = shape->recIndex;
{ loader->mMaterialName = NIFMaterialLoader::getMaterial(shape, fullname, mGroup);
loader->mShapeIndex = shape->recIndex;
loader->mMaterialName = NIFMaterialLoader::getMaterial(shape, fullname, mGroup);
}
mesh = meshMgr.createManual(fullname, mGroup, loader); mesh = meshMgr.createManual(fullname, mGroup, loader);
mesh->setAutoBuildEdgeLists(false); mesh->setAutoBuildEdgeLists(false);
@ -1093,6 +1086,29 @@ public:
} }
} }
} }
void createEmptyMesh(const Nif::Node *node, MeshInfoList &meshes)
{
/* 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
* other meshes are hidden or entities attached to a specific node
* instead of skinned. */
std::string fullname = mName;
Misc::StringUtils::toLower(fullname);
Ogre::MeshManager &meshMgr = Ogre::MeshManager::getSingleton();
Ogre::MeshPtr mesh = meshMgr.getByName(fullname);
if(mesh.isNull())
{
NIFMeshLoader *loader = &sLoaders[fullname];
*loader = *this;
mesh = meshMgr.createManual(fullname, mGroup, loader);
mesh->setAutoBuildEdgeLists(false);
}
meshes.push_back(MeshInfo(mesh->getName(), (node->parent ? node->parent->name : node->name),
node->trafo.pos, node->trafo.rotation, node->trafo.scale));
}
}; };
NIFMeshLoader::LoaderMap NIFMeshLoader::sLoaders; NIFMeshLoader::LoaderMap NIFMeshLoader::sLoaders;
@ -1135,7 +1151,9 @@ MeshInfoList Loader::load(const std::string &name, const std::string &group)
} }
NIFMeshLoader meshldr(name, group); NIFMeshLoader meshldr(name, group);
meshldr.createMeshes(node, meshes); if(hasSkel)
meshldr.createEmptyMesh(node, meshes);
meshldr.createMeshes(node, meshes, 0);
return meshes; return meshes;
} }