diff --git a/code/ColladaExporter.cpp b/code/ColladaExporter.cpp
index cf9968795..330981f00 100644
--- a/code/ColladaExporter.cpp
+++ b/code/ColladaExporter.cpp
@@ -1224,43 +1224,13 @@ void ColladaExporter::WriteSceneLibrary()
mOutput << startstr << "" << endstr;
PushTag();
+ // start write armature at the root node
+ for( size_t a = 0; a < mScene->mRootNode->mNumChildren; ++a )
+ WriteNode( mScene, mScene->mRootNode->mChildren[a], true);
+
// start recursive write at the root node
for( size_t a = 0; a < mScene->mRootNode->mNumChildren; ++a )
- WriteNode( mScene, mScene->mRootNode->mChildren[a]);
-
- for( size_t a = 0; a < mScene->mNumMeshes; ++a )
- {
- const aiMesh* mesh = mScene->mMeshes[a];
- const std::string idstr = GetMeshId( a);
- const std::string idstrEscaped = XMLEscape(idstr);
-
- if ( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
- continue;
-
- if ( mesh->mNumBones == 0 )
- continue;
-
- const std::string mesh_name_escaped = XMLEscape(mesh->mName.C_Str());
- mOutput << startstr
- << ""
- << endstr;
- PushTag();
-
- mOutput << startstr
- << ""
- << endstr;
- PushTag();
-
- mOutput << startstr << "#skeleton_root" << endstr;
-
- PopTag();
- mOutput << startstr << "" << endstr;
-
- PopTag();
- mOutput << startstr << "" << endstr;
- }
+ WriteNode( mScene, mScene->mRootNode->mChildren[a], false);
PopTag();
mOutput << startstr << "" << endstr;
@@ -1285,7 +1255,7 @@ aiBone* findBone( const aiScene* scene, const char * name) {
// ------------------------------------------------------------------------------------------------
// Recursively writes the given node
-void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
+void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode, bool need_output_joint)
{
// the node must have a name
if (pNode->mName.length == 0)
@@ -1309,13 +1279,20 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
is_skeleton_root = true;
}
+ if(need_output_joint ^ is_joint)
+ return;
+
const std::string node_name_escaped = XMLEscape(pNode->mName.data);
mOutput << startstr
<< "" << endstr;
PushTag();
@@ -1323,7 +1300,7 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
// write transformation - we can directly put the matrix there
// TODO: (thom) decompose into scale - rot - quad to allow addressing it by animations afterwards
const aiMatrix4x4& mat = pNode->mTransformation;
- mOutput << startstr << "";
+ mOutput << startstr << "";
mOutput << mat.a1 << " " << mat.a2 << " " << mat.a3 << " " << mat.a4 << " ";
mOutput << mat.b1 << " " << mat.b2 << " " << mat.b3 << " " << mat.b4 << " ";
mOutput << mat.c1 << " " << mat.c2 << " " << mat.c3 << " " << mat.c4 << " ";
@@ -1351,38 +1328,55 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
for( size_t a = 0; a < pNode->mNumMeshes; ++a )
{
const aiMesh* mesh = mScene->mMeshes[pNode->mMeshes[a]];
- // do not instanciate mesh if empty. I wonder how this could happen
- if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
- continue;
- mOutput << startstr << "mMeshes[a])) << "\">" << endstr;
- PushTag();
- mOutput << startstr << "" << endstr;
- PushTag();
- mOutput << startstr << "" << endstr;
- PushTag();
- mOutput << startstr << "mMaterialIndex].name) << "\">" << endstr;
- PushTag();
- for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
- {
- if( mesh->HasTextureCoords( static_cast(a) ) )
- // semantic as in
- // input_semantic as in
- // input_set as in
- mOutput << startstr << "" << endstr;
- }
- PopTag();
- mOutput << startstr << "" << endstr;
- PopTag();
- mOutput << startstr << "" << endstr;
- PopTag();
- mOutput << startstr << "" << endstr;
- PopTag();
- mOutput << startstr << "" << endstr;
+ // do not instanciate mesh if empty. I wonder how this could happen
+ if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
+ continue;
+
+ if( mesh->mNumBones == 0 )
+ {
+ mOutput << startstr << "mMeshes[a])) << "\">" << endstr;
+ PushTag();
+ }
+ else
+ {
+ mOutput << startstr
+ << "mMeshes[a])) << "-skin\">"
+ << endstr;
+ PushTag();
+
+ mOutput << startstr << "#skeleton_root" << endstr;
+ }
+ mOutput << startstr << "" << endstr;
+ PushTag();
+ mOutput << startstr << "" << endstr;
+ PushTag();
+ mOutput << startstr << "mMaterialIndex].name) << "\">" << endstr;
+ PushTag();
+ for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
+ {
+ if( mesh->HasTextureCoords( static_cast(a) ) )
+ // semantic as in
+ // input_semantic as in
+ // input_set as in
+ mOutput << startstr << "" << endstr;
+ }
+ PopTag();
+ mOutput << startstr << "" << endstr;
+ PopTag();
+ mOutput << startstr << "" << endstr;
+ PopTag();
+ mOutput << startstr << "" << endstr;
+
+ PopTag();
+ if( mesh->mNumBones == 0)
+ mOutput << startstr << "" << endstr;
+ else
+ mOutput << startstr << "" << endstr;
}
// recurse into subnodes
for( size_t a = 0; a < pNode->mNumChildren; ++a )
- WriteNode( pScene, pNode->mChildren[a]);
+ WriteNode( pScene, pNode->mChildren[a], need_output_joint);
PopTag();
mOutput << startstr << "" << endstr;
diff --git a/code/ColladaExporter.h b/code/ColladaExporter.h
index 695b00bfd..b3c08f8c4 100644
--- a/code/ColladaExporter.h
+++ b/code/ColladaExporter.h
@@ -122,7 +122,7 @@ protected:
void WriteSceneLibrary();
/// Recursively writes the given node
- void WriteNode( const aiScene* scene, aiNode* pNode);
+ void WriteNode( const aiScene* scene, aiNode* pNode, bool need_output_joint);
/// Enters a new xml element, which increases the indentation
void PushTag() { startstr.append( " "); }
diff --git a/code/MMDImporter.cpp b/code/MMDImporter.cpp
index b57fe55db..80e966ca6 100644
--- a/code/MMDImporter.cpp
+++ b/code/MMDImporter.cpp
@@ -324,7 +324,8 @@ aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
auto pBone = new aiBone;
const auto &pmxBone = pModel->bones[ii];
pBone->mName = pmxBone.bone_name;
- pBone->mOffsetMatrix = aiMatrix4x4();
+ aiVector3D pos(pmxBone.position[0], -pmxBone.position[1], -pmxBone.position[2]);
+ aiMatrix4x4::Translation(pos, pBone->mOffsetMatrix);
auto it = bone_vertex_map.find(ii);
if (it != bone_vertex_map.end()) {
pBone->mNumWeights = it->second.size();