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:
parent
8d6f017f17
commit
f4e587c72c
1 changed files with 45 additions and 27 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue