From ec6ef9f145fa36354dff24a08de5d6a7db4814a0 Mon Sep 17 00:00:00 2001 From: ulfjorensen Date: Fri, 19 Nov 2010 14:06:32 +0000 Subject: [PATCH] Added a workaround to the Collada parser to handle certain XML tags which irrxml doesn't handle well. Corrected formatting on the way. git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@842 67173fc5-114c-0410-ac8e-9d2fd5bffc1f --- code/ColladaLoader.cpp | 80 +++++++++++++++++++++--------------------- code/ColladaParser.cpp | 7 +++- 2 files changed, 46 insertions(+), 41 deletions(-) diff --git a/code/ColladaLoader.cpp b/code/ColladaLoader.cpp index d27cc5b16..f22a9295f 100644 --- a/code/ColladaLoader.cpp +++ b/code/ColladaLoader.cpp @@ -644,14 +644,14 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada:: float weight = ReadFloat( weightsAcc, weights, vertexIndex, 0); - // one day I gonna kill that XSI Collada exporter - if( weight > 0.0f) - { - aiVertexWeight w; - w.mVertexId = a - pStartVertex; - w.mWeight = weight; - dstBones[jointIndex].push_back( w); - } + // one day I gonna kill that XSI Collada exporter + if( weight > 0.0f) + { + aiVertexWeight w; + w.mVertexId = a - pStartVertex; + w.mWeight = weight; + dstBones[jointIndex].push_back( w); + } } } @@ -690,41 +690,41 @@ 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; + // 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 - // find-by-name method to associate nodes with bones. - const Collada::Node* bnode = FindNode( pParser.mRootNode, bone->mName.data); - if( !bnode) - bnode = FindNodeBySID( pParser.mRootNode, bone->mName.data); + // 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 + // find-by-name method to associate nodes with bones. + const Collada::Node* bnode = FindNode( pParser.mRootNode, bone->mName.data); + if( !bnode) + bnode = FindNodeBySID( pParser.mRootNode, bone->mName.data); - // assign the name that we would have assigned for the source node - if( bnode) - bone->mName.Set( FindNameForNode( bnode)); - else - DefaultLogger::get()->warn( boost::str( boost::format( "ColladaLoader::CreateMesh(): could not find corresponding node for joint \"%s\".") % bone->mName.data)); + // assign the name that we would have assigned for the source node + if( bnode) + bone->mName.Set( FindNameForNode( bnode)); + else + DefaultLogger::get()->warn( boost::str( boost::format( "ColladaLoader::CreateMesh(): could not find corresponding node for joint \"%s\".") % bone->mName.data)); - // and insert bone + // and insert bone dstMesh->mBones[boneCount++] = bone; } } diff --git a/code/ColladaParser.cpp b/code/ColladaParser.cpp index aced44841..1eaab595e 100644 --- a/code/ColladaParser.cpp +++ b/code/ColladaParser.cpp @@ -2633,7 +2633,11 @@ void ColladaParser::TestOpening( const char* pName) // Tests for the closing tag of the given element, throws an exception if not found void ColladaParser::TestClosing( const char* pName) { - // read closing tag + // check if we're already on the closing tag and return right away + if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END && strcmp( mReader->getNodeName(), pName) == 0) + return; + + // if not, read some more if( !mReader->read()) ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of \"%s\" element.") % pName)); // whitespace in front is ok, just read again if found @@ -2641,6 +2645,7 @@ void ColladaParser::TestClosing( const char* pName) if( !mReader->read()) ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of \"%s\" element.") % pName)); + // but this has the be the closing tag, or we're lost if( mReader->getNodeType() != irr::io::EXN_ELEMENT_END || strcmp( mReader->getNodeName(), pName) != 0) ThrowException( boost::str( boost::format( "Expected end of \"%s\" element.") % pName)); }