1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-26 18:35:20 +00:00

Use the skeleton as defined in the NIF model

The avoids having to duplicate models that get attached to different character
skeletons.
This commit is contained in:
Chris Robinson 2013-01-30 22:37:39 -08:00
parent d6f923f274
commit c6a9ea5007
2 changed files with 32 additions and 29 deletions

View File

@ -754,7 +754,6 @@ class NIFMeshLoader : Ogre::ManualResourceLoader
std::string mName; std::string mName;
std::string mGroup; std::string mGroup;
size_t mShapeIndex; size_t mShapeIndex;
std::string mSkelName;
std::string mMaterialName; std::string mMaterialName;
std::string mShapeName; std::string mShapeName;
@ -782,11 +781,11 @@ class NIFMeshLoader : Ogre::ManualResourceLoader
{ {
// Only set a skeleton when skinning. Unskinned meshes with a skeleton will be // Only set a skeleton when skinning. Unskinned meshes with a skeleton will be
// explicitly attached later. // explicitly attached later.
mesh->setSkeletonName(mSkelName); mesh->setSkeletonName(mName);
// Get the skeleton resource, so vertices can be transformed into the bones' initial state. // Get the skeleton resource, so vertices can be transformed into the bones' initial state.
Ogre::SkeletonManager *skelMgr = Ogre::SkeletonManager::getSingletonPtr(); Ogre::SkeletonManager *skelMgr = Ogre::SkeletonManager::getSingletonPtr();
skel = skelMgr->getByName(mSkelName); skel = skelMgr->getByName(mName);
// Convert vertices and normals to bone space from bind position. It would be // Convert vertices and normals to bone space from bind position. It would be
// better to transform the bones into bind position, but there doesn't seem to // better to transform the bones into bind position, but there doesn't seem to
@ -823,22 +822,26 @@ class NIFMeshLoader : Ogre::ManualResourceLoader
srcVerts = newVerts; srcVerts = newVerts;
srcNorms = newNorms; srcNorms = newNorms;
} }
else if(mSkelName.length() == 0) else
{ {
// No skinning and no skeleton, so just transform the vertices and Ogre::SkeletonManager *skelMgr = Ogre::SkeletonManager::getSingletonPtr();
// normals into position. if(skelMgr->getByName(mName).isNull())
Ogre::Matrix4 mat4 = shape->getWorldTransform();
for(size_t i = 0;i < srcVerts.size();i++)
{ {
Ogre::Vector4 vec4(srcVerts[i].x, srcVerts[i].y, srcVerts[i].z, 1.0f); // No skinning and no skeleton, so just transform the vertices and
vec4 = mat4*vec4; // normals into position.
srcVerts[i] = Ogre::Vector3(&vec4[0]); Ogre::Matrix4 mat4 = shape->getWorldTransform();
} for(size_t i = 0;i < srcVerts.size();i++)
for(size_t i = 0;i < srcNorms.size();i++) {
{ Ogre::Vector4 vec4(srcVerts[i].x, srcVerts[i].y, srcVerts[i].z, 1.0f);
Ogre::Vector4 vec4(srcNorms[i].x, srcNorms[i].y, srcNorms[i].z, 0.0f); vec4 = mat4*vec4;
vec4 = mat4*vec4; srcVerts[i] = Ogre::Vector3(&vec4[0]);
srcNorms[i] = Ogre::Vector3(&vec4[0]); }
for(size_t i = 0;i < srcNorms.size();i++)
{
Ogre::Vector4 vec4(srcNorms[i].x, srcNorms[i].y, srcNorms[i].z, 0.0f);
vec4 = mat4*vec4;
srcNorms[i] = Ogre::Vector3(&vec4[0]);
}
} }
} }
@ -998,8 +1001,8 @@ class NIFMeshLoader : Ogre::ManualResourceLoader
public: public:
NIFMeshLoader() NIFMeshLoader()
{ } { }
NIFMeshLoader(const std::string &name, const std::string &group, const std::string skelName) NIFMeshLoader(const std::string &name, const std::string &group)
: mName(name), mGroup(group), mShapeIndex(~(size_t)0), mSkelName(skelName) : mName(name), mGroup(group), mShapeIndex(~(size_t)0)
{ } { }
virtual void loadResource(Ogre::Resource *resource) virtual void loadResource(Ogre::Resource *resource)
@ -1010,7 +1013,9 @@ public:
Nif::NIFFile::ptr nif = Nif::NIFFile::create(mName); Nif::NIFFile::ptr nif = Nif::NIFFile::create(mName);
if(mShapeIndex >= nif->numRecords()) if(mShapeIndex >= nif->numRecords())
{ {
mesh->setSkeletonName(mSkelName); Ogre::SkeletonManager *skelMgr = Ogre::SkeletonManager::getSingletonPtr();
if(!skelMgr->getByName(mName).isNull())
mesh->setSkeletonName(mName);
return; return;
} }
@ -1061,8 +1066,6 @@ public:
std::string fullname = mName+"@index="+Ogre::StringConverter::toString(shape->recIndex); std::string fullname = mName+"@index="+Ogre::StringConverter::toString(shape->recIndex);
if(mShapeName.length() > 0) if(mShapeName.length() > 0)
fullname += "@shape="+mShapeName; fullname += "@shape="+mShapeName;
if(mSkelName.length() > 0 && mName != mSkelName)
fullname += "@skel="+mSkelName;
Misc::StringUtils::toLower(fullname); Misc::StringUtils::toLower(fullname);
Ogre::MeshPtr mesh = meshMgr.getByName(fullname); Ogre::MeshPtr mesh = meshMgr.getByName(fullname);
@ -1105,13 +1108,13 @@ NIFMeshLoader::LoaderMap NIFMeshLoader::sLoaders;
typedef std::map<std::string,MeshInfoList> MeshInfoMap; typedef std::map<std::string,MeshInfoList> MeshInfoMap;
static MeshInfoMap sMeshInfoMap; static MeshInfoMap sMeshInfoMap;
MeshInfoList Loader::load(const std::string &name, const std::string &skelName, const std::string &group) MeshInfoList Loader::load(const std::string &name, const std::string &group)
{ {
MeshInfoMap::const_iterator meshiter = sMeshInfoMap.find(name+"@skel="+skelName); MeshInfoMap::const_iterator meshiter = sMeshInfoMap.find(name);
if(meshiter != sMeshInfoMap.end()) if(meshiter != sMeshInfoMap.end())
return meshiter->second; return meshiter->second;
MeshInfoList &meshes = sMeshInfoMap[name+"@skel="+skelName]; MeshInfoList &meshes = sMeshInfoMap[name];
Nif::NIFFile::ptr pnif = Nif::NIFFile::create(name); Nif::NIFFile::ptr pnif = Nif::NIFFile::create(name);
Nif::NIFFile &nif = *pnif.get(); Nif::NIFFile &nif = *pnif.get();
if(nif.numRecords() < 1) if(nif.numRecords() < 1)
@ -1139,7 +1142,7 @@ MeshInfoList Loader::load(const std::string &name, const std::string &skelName,
hasSkel = skelldr.createSkeleton(name, group, node); hasSkel = skelldr.createSkeleton(name, group, node);
} }
NIFMeshLoader meshldr(name, group, (hasSkel ? skelName : std::string())); NIFMeshLoader meshldr(name, group);
meshldr.createMeshes(node, meshes); meshldr.createMeshes(node, meshes);
return meshes; return meshes;
@ -1150,7 +1153,7 @@ EntityList Loader::createEntities(Ogre::SceneNode *parentNode, std::string name,
EntityList entitylist; EntityList entitylist;
Misc::StringUtils::toLower(name); Misc::StringUtils::toLower(name);
MeshInfoList meshes = load(name, name, group); MeshInfoList meshes = load(name, group);
if(meshes.size() == 0) if(meshes.size() == 0)
return entitylist; return entitylist;
@ -1199,7 +1202,7 @@ EntityList Loader::createEntities(Ogre::Entity *parent, const std::string &bonen
EntityList entitylist; EntityList entitylist;
Misc::StringUtils::toLower(name); Misc::StringUtils::toLower(name);
MeshInfoList meshes = load(name, parent->getMesh()->getSkeletonName(), group); MeshInfoList meshes = load(name, group);
if(meshes.size() == 0) if(meshes.size() == 0)
return entitylist; return entitylist;

View File

@ -66,7 +66,7 @@ typedef std::vector<MeshInfo> MeshInfoList;
class Loader class Loader
{ {
static MeshInfoList load(const std::string &name, const std::string &skelName, const std::string &group); static MeshInfoList load(const std::string &name, const std::string &group);
public: public:
static EntityList createEntities(Ogre::Entity *parent, const std::string &bonename, static EntityList createEntities(Ogre::Entity *parent, const std::string &bonename,