Issue 1639: Smd mesh vertex bone assignment
bone.mOffsetMatrix not set when bone.iParent == -1pull/2249/head
parent
9100ca8664
commit
2761681022
|
@ -169,11 +169,11 @@ void SMDImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
|
|||
|
||||
// now fix invalid time values and make sure the animation starts at frame 0
|
||||
FixTimeValues();
|
||||
|
||||
// compute absolute bone transformation matrices
|
||||
// ComputeAbsoluteBoneTransformations();
|
||||
}
|
||||
|
||||
// build output nodes (bones are added as empty dummy nodes)
|
||||
CreateOutputNodes();
|
||||
|
||||
if (!(pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE))
|
||||
{
|
||||
// create output meshes
|
||||
|
@ -181,10 +181,13 @@ void SMDImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
|
|||
|
||||
// build an output material list
|
||||
CreateOutputMaterials();
|
||||
}
|
||||
|
||||
// build output nodes (bones are added as empty dummy nodes)
|
||||
CreateOutputNodes();
|
||||
// use root node that renders all meshes
|
||||
pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
|
||||
pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
|
||||
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i)
|
||||
pScene->mRootNode->mMeshes[i] = i;
|
||||
}
|
||||
|
||||
// build the output animation
|
||||
CreateOutputAnimations(pFile, pIOHandler);
|
||||
|
@ -397,7 +400,7 @@ void SMDImporter::CreateOutputMeshes()
|
|||
for (unsigned int iBone = 0; iBone < asBones.size();++iBone)
|
||||
if (!aaiBones[iBone].empty())++iNum;
|
||||
|
||||
if (false && iNum)
|
||||
if (iNum)
|
||||
{
|
||||
pcMesh->mNumBones = iNum;
|
||||
pcMesh->mBones = new aiBone*[pcMesh->mNumBones];
|
||||
|
@ -456,7 +459,14 @@ void SMDImporter::AddBoneChildren(aiNode* pcNode, uint32_t iParent)
|
|||
pc->mName.Set(bone.mName);
|
||||
|
||||
// store the local transformation matrix of the bind pose
|
||||
pc->mTransformation = bone.sAnim.asKeys[bone.sAnim.iFirstTimeKey].matrix;
|
||||
if (bone.sAnim.asKeys.size())
|
||||
pc->mTransformation = bone.sAnim.asKeys[0].matrix;
|
||||
|
||||
if (bone.iParent == -1)
|
||||
bone.mOffsetMatrix = pc->mTransformation;
|
||||
else
|
||||
bone.mOffsetMatrix = asBones[bone.iParent].mOffsetMatrix * pc->mTransformation;
|
||||
|
||||
pc->mParent = pcNode;
|
||||
|
||||
// add children to this node, too
|
||||
|
@ -469,17 +479,11 @@ void SMDImporter::AddBoneChildren(aiNode* pcNode, uint32_t iParent)
|
|||
void SMDImporter::CreateOutputNodes()
|
||||
{
|
||||
pScene->mRootNode = new aiNode();
|
||||
if (!(pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE))
|
||||
{
|
||||
// create one root node that renders all meshes
|
||||
pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
|
||||
pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
|
||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
||||
pScene->mRootNode->mMeshes[i] = i;
|
||||
}
|
||||
|
||||
// now add all bones as dummy sub nodes to the graph
|
||||
AddBoneChildren(pScene->mRootNode,(uint32_t)-1);
|
||||
for (auto &bone : asBones)
|
||||
bone.mOffsetMatrix.Inverse();
|
||||
|
||||
// if we have only one bone we can even remove the root node
|
||||
if (pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE &&
|
||||
|
@ -624,67 +628,6 @@ void SMDImporter::GetAnimationFileList(const std::string &pFile, IOSystem* pIOHa
|
|||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SMDImporter::ComputeAbsoluteBoneTransformations()
|
||||
{
|
||||
// For each bone: determine the key with the lowest time value
|
||||
// theoretically the SMD format should have all keyframes
|
||||
// in order. However, I've seen a file where this wasn't true.
|
||||
for (unsigned int i = 0; i < asBones.size();++i)
|
||||
{
|
||||
SMD::Bone& bone = asBones[i];
|
||||
|
||||
uint32_t iIndex = 0;
|
||||
double dMin = 10e10;
|
||||
for (unsigned int i = 0; i < bone.sAnim.asKeys.size();++i)
|
||||
{
|
||||
double d = std::min(bone.sAnim.asKeys[i].dTime,dMin);
|
||||
if (d < dMin)
|
||||
{
|
||||
dMin = d;
|
||||
iIndex = i;
|
||||
}
|
||||
}
|
||||
bone.sAnim.iFirstTimeKey = iIndex;
|
||||
}
|
||||
|
||||
unsigned int iParent = 0;
|
||||
while (iParent < asBones.size())
|
||||
{
|
||||
for (unsigned int iBone = 0; iBone < asBones.size();++iBone)
|
||||
{
|
||||
SMD::Bone& bone = asBones[iBone];
|
||||
|
||||
if (iParent == bone.iParent)
|
||||
{
|
||||
SMD::Bone& parentBone = asBones[iParent];
|
||||
|
||||
|
||||
uint32_t iIndex = bone.sAnim.iFirstTimeKey;
|
||||
const aiMatrix4x4& mat = bone.sAnim.asKeys[iIndex].matrix;
|
||||
aiMatrix4x4& matOut = bone.sAnim.asKeys[iIndex].matrixAbsolute;
|
||||
|
||||
// The same for the parent bone ...
|
||||
iIndex = parentBone.sAnim.iFirstTimeKey;
|
||||
const aiMatrix4x4& mat2 = parentBone.sAnim.asKeys[iIndex].matrixAbsolute;
|
||||
|
||||
// Compute the absolute transformation matrix
|
||||
matOut = mat * mat2;
|
||||
}
|
||||
}
|
||||
++iParent;
|
||||
}
|
||||
|
||||
// Store the inverse of the absolute transformation matrix
|
||||
// of the first key as bone offset matrix
|
||||
for (iParent = 0; iParent < asBones.size();++iParent)
|
||||
{
|
||||
SMD::Bone& bone = asBones[iParent];
|
||||
bone.mOffsetMatrix = bone.sAnim.asKeys[bone.sAnim.iFirstTimeKey].matrixAbsolute;
|
||||
bone.mOffsetMatrix.Inverse();
|
||||
}
|
||||
}
|
||||
\
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// create output materials
|
||||
void SMDImporter::CreateOutputMaterials()
|
||||
|
|
|
@ -290,13 +290,6 @@ protected:
|
|||
*/
|
||||
unsigned int GetTextureIndex(const std::string& filename);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Computes absolute bone transformations
|
||||
* All output transformations are in worldspace.
|
||||
*/
|
||||
void ComputeAbsoluteBoneTransformations();
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Parse a line in the skeleton section
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue