diff --git a/code/ColladaHelper.h b/code/ColladaHelper.h index bfcd126fd..22fe1e001 100644 --- a/code/ColladaHelper.h +++ b/code/ColladaHelper.h @@ -371,6 +371,9 @@ struct Controller // accessor URL of the joint names std::string mJointNameSource; + ///< The bind shape matrix, as array of floats. I'm not sure what this matrix actually describes, but it can't be ignored in all cases + float mBindShapeMatrix[16]; + // accessor URL of the joint inverse bind matrices std::string mJointOffsetMatrixSource; diff --git a/code/ColladaLoader.cpp b/code/ColladaLoader.cpp index 49eda4060..16c9f612e 100644 --- a/code/ColladaLoader.cpp +++ b/code/ColladaLoader.cpp @@ -676,6 +676,26 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada:: bone->mWeights = new aiVertexWeight[bone->mNumWeights]; std::copy( dstBones[a].begin(), dstBones[a].end(), bone->mWeights); + // apply bind shape matrix to offset matrix + aiMatrix4x4 bindShapeMatrix; + bindShapeMatrix.a1 = pSrcController->mBindShapeMatrix[0]; + bindShapeMatrix.a2 = pSrcController->mBindShapeMatrix[1]; + bindShapeMatrix.a3 = pSrcController->mBindShapeMatrix[2]; + bindShapeMatrix.a4 = pSrcController->mBindShapeMatrix[3]; + bindShapeMatrix.b1 = pSrcController->mBindShapeMatrix[4]; + bindShapeMatrix.b2 = pSrcController->mBindShapeMatrix[5]; + bindShapeMatrix.b3 = pSrcController->mBindShapeMatrix[6]; + bindShapeMatrix.b4 = pSrcController->mBindShapeMatrix[7]; + bindShapeMatrix.c1 = pSrcController->mBindShapeMatrix[8]; + bindShapeMatrix.c2 = pSrcController->mBindShapeMatrix[9]; + bindShapeMatrix.c3 = pSrcController->mBindShapeMatrix[10]; + bindShapeMatrix.c4 = pSrcController->mBindShapeMatrix[11]; + bindShapeMatrix.d1 = pSrcController->mBindShapeMatrix[12]; + bindShapeMatrix.d2 = pSrcController->mBindShapeMatrix[13]; + bindShapeMatrix.d3 = pSrcController->mBindShapeMatrix[14]; + bindShapeMatrix.d4 = pSrcController->mBindShapeMatrix[15]; + bone->mOffsetMatrix *= bindShapeMatrix; + // HACK: (thom) Some exporters address the bone nodes by SID, others address them by ID or even name. // Therefore I added a little name replacement here: I search for the bone's node by either name, ID or SID, // and replace the bone's name by the node's name so that the user can use the standard @@ -939,7 +959,7 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars for( size_t c = 0; c < e.mValueAccessor->mParams.size(); ++c) { float v = ReadFloat( *e.mValueAccessor, *e.mValueData, pos-1, c); - temp[c] += (v - temp[6]) * factor; + temp[c] += (v - temp[c]) * factor; } } diff --git a/code/ColladaParser.cpp b/code/ColladaParser.cpp index 73c105172..05368dd0e 100644 --- a/code/ColladaParser.cpp +++ b/code/ColladaParser.cpp @@ -479,9 +479,19 @@ void ColladaParser::ReadController( Collada::Controller& pController) } else if( IsElement( "bind_shape_matrix")) { - // content is 16 floats to define some sort of matrix... I'm going to ignore this - // as long as I don't have a clue how to interpret it - SkipElement(); + // content is 16 floats to define a matrix... it seems to be important for some models + const char* content = GetTextContent(); + + // read the 16 floats + for( unsigned int a = 0; a < 16; a++) + { + // read a number + content = fast_atof_move( content, pController.mBindShapeMatrix[a]); + // skip whitespace after it + SkipSpacesAndLineEnd( &content); + } + + TestClosing( "bind_shape_matrix"); } else if( IsElement( "source")) {