From fe58fa66036814f07ce5683c0e0af17a645c28d3 Mon Sep 17 00:00:00 2001 From: ulfjorensen Date: Tue, 2 Jun 2009 20:03:08 +0000 Subject: [PATCH] - Bugfix: Collada loader now loads meshes with mixed textured / non-textured parts correctly. At least I hope so, the example files load fine now. - Bugfix: implemented Collada Look-At transformation type. Untested due to lack of testing material git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@428 67173fc5-114c-0410-ac8e-9d2fd5bffc1f --- code/ColladaLoader.cpp | 10 +++--- code/ColladaParser.cpp | 76 +++++++++++++++++++++++++++++++++--------- 2 files changed, 65 insertions(+), 21 deletions(-) diff --git a/code/ColladaLoader.cpp b/code/ColladaLoader.cpp index 5531113fd..11ddeab7f 100644 --- a/code/ColladaLoader.cpp +++ b/code/ColladaLoader.cpp @@ -523,7 +523,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada:: // normals, if given. HACK: (thom) Due to the fucking Collada spec we never // know if we have the same number of normals as there are positions. So we // also ignore any vertex attribute if it has a different count - if( pSrcMesh->mNormals.size() == pSrcMesh->mPositions.size()) + if( pSrcMesh->mNormals.size() >= pStartVertex + numVertices) { dstMesh->mNormals = new aiVector3D[numVertices]; std::copy( pSrcMesh->mNormals.begin() + pStartVertex, pSrcMesh->mNormals.begin() + @@ -531,7 +531,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada:: } // tangents, if given. - if( pSrcMesh->mTangents.size() == pSrcMesh->mPositions.size()) + if( pSrcMesh->mTangents.size() >= pStartVertex + numVertices) { dstMesh->mTangents = new aiVector3D[numVertices]; std::copy( pSrcMesh->mTangents.begin() + pStartVertex, pSrcMesh->mTangents.begin() + @@ -539,7 +539,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada:: } // bitangents, if given. - if( pSrcMesh->mBitangents.size() == pSrcMesh->mPositions.size()) + if( pSrcMesh->mBitangents.size() >= pStartVertex + numVertices) { dstMesh->mBitangents = new aiVector3D[numVertices]; std::copy( pSrcMesh->mBitangents.begin() + pStartVertex, pSrcMesh->mBitangents.begin() + @@ -550,7 +550,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada:: // empty slots are not allowed, need to pack and adjust UV indexes accordingly for( size_t a = 0, real = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) { - if( pSrcMesh->mTexCoords[a].size() == pSrcMesh->mPositions.size()) + if( pSrcMesh->mTexCoords[a].size() >= pStartVertex + numVertices) { dstMesh->mTextureCoords[real] = new aiVector3D[numVertices]; for( size_t b = 0; b < numVertices; ++b) @@ -564,7 +564,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada:: // same for vertex colors, as many as we have. again the same packing to avoid empty slots for( size_t a = 0, real = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) { - if( pSrcMesh->mColors[a].size() == pSrcMesh->mPositions.size()) + if( pSrcMesh->mColors[a].size() >= pStartVertex + numVertices) { dstMesh->mColors[real] = new aiColor4D[numVertices]; std::copy( pSrcMesh->mColors[a].begin() + pStartVertex, pSrcMesh->mColors[a].begin() + pStartVertex + numVertices,dstMesh->mColors[real]); diff --git a/code/ColladaParser.cpp b/code/ColladaParser.cpp index 5b4321dd1..31bbcf564 100644 --- a/code/ColladaParser.cpp +++ b/code/ColladaParser.cpp @@ -1474,7 +1474,7 @@ void ColladaParser::ReadSource() { if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if( IsElement( "float_array") || IsElement( "IDREF_array")) + if( IsElement( "float_array") || IsElement( "IDREF_array") || IsElement( "Name_array")) { ReadDataArray(); } @@ -1515,7 +1515,7 @@ void ColladaParser::ReadSource() void ColladaParser::ReadDataArray() { std::string elmName = mReader->getNodeName(); - bool isStringArray = (elmName == "IDREF_array"); + bool isStringArray = (elmName == "IDREF_array" || elmName == "Name_array"); // read attributes int indexID = GetAttribute( "id"); @@ -1975,6 +1975,7 @@ void ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector& pPer } } + // if I ever get my hands on that guy who invented this steaming pile of indirection... TestClosing( "p"); } @@ -2009,39 +2010,71 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si else DefaultLogger::get()->error("Collada: just one vertex position stream supported"); break; - case IT_Normal: // ignore all normal streams except 0 - there can be only one normal - if( pInput.mIndex == 0) + case IT_Normal: + // pad to current vertex count if necessary + if( pMesh->mNormals.size() < pMesh->mPositions.size()-1) + pMesh->mNormals.insert( pMesh->mNormals.end(), pMesh->mPositions.size() - pMesh->mNormals.size() - 1, aiVector3D( 0, 1, 0)); + + // ignore all normal streams except 0 - there can be only one normal + if( pInput.mIndex == 0) pMesh->mNormals.push_back( aiVector3D( obj[0], obj[1], obj[2])); else DefaultLogger::get()->error("Collada: just one vertex normal stream supported"); break; - case IT_Tangent: // ignore all tangent streams except 0 - there can be only one tangent - if( pInput.mIndex == 0) + case IT_Tangent: + // pad to current vertex count if necessary + if( pMesh->mTangents.size() < pMesh->mPositions.size()-1) + pMesh->mTangents.insert( pMesh->mTangents.end(), pMesh->mPositions.size() - pMesh->mTangents.size() - 1, aiVector3D( 1, 0, 0)); + + // ignore all tangent streams except 0 - there can be only one tangent + if( pInput.mIndex == 0) pMesh->mTangents.push_back( aiVector3D( obj[0], obj[1], obj[2])); else DefaultLogger::get()->error("Collada: just one vertex tangent stream supported"); break; - case IT_Bitangent: // ignore all bitangent streams except 0 - there can be only one bitangent - if( pInput.mIndex == 0) + case IT_Bitangent: + // pad to current vertex count if necessary + if( pMesh->mBitangents.size() < pMesh->mPositions.size()-1) + pMesh->mBitangents.insert( pMesh->mBitangents.end(), pMesh->mPositions.size() - pMesh->mBitangents.size() - 1, aiVector3D( 0, 0, 1)); + + // ignore all bitangent streams except 0 - there can be only one bitangent + if( pInput.mIndex == 0) pMesh->mBitangents.push_back( aiVector3D( obj[0], obj[1], obj[2])); else DefaultLogger::get()->error("Collada: just one vertex bitangent stream supported"); break; - case IT_Texcoord: // up to 4 texture coord sets are fine, ignore the others - if( pInput.mIndex < AI_MAX_NUMBER_OF_TEXTURECOORDS) { + case IT_Texcoord: + // up to 4 texture coord sets are fine, ignore the others + if( pInput.mIndex < AI_MAX_NUMBER_OF_TEXTURECOORDS) + { + // pad to current vertex count if necessary + if( pMesh->mTexCoords[pInput.mIndex].size() < pMesh->mPositions.size()-1) + pMesh->mTexCoords[pInput.mIndex].insert( pMesh->mTexCoords[pInput.mIndex].end(), + pMesh->mPositions.size() - pMesh->mTexCoords[pInput.mIndex].size() - 1, aiVector3D( 0, 0, 0)); pMesh->mTexCoords[pInput.mIndex].push_back( aiVector3D( obj[0], obj[1], obj[2])); if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) /* hack ... consider cleaner solution */ pMesh->mNumUVComponents[pInput.mIndex]=3; - } - else + } else + { DefaultLogger::get()->error("Collada: too many texture coordinate sets. Skipping."); + } break; - case IT_Color: // up to 4 color sets are fine, ignore the others + case IT_Color: + // up to 4 color sets are fine, ignore the others if( pInput.mIndex < AI_MAX_NUMBER_OF_COLOR_SETS) + { + // pad to current vertex count if necessary + if( pMesh->mColors[pInput.mIndex].size() < pMesh->mPositions.size()-1) + pMesh->mColors[pInput.mIndex].insert( pMesh->mColors[pInput.mIndex].end(), + pMesh->mPositions.size() - pMesh->mColors[pInput.mIndex].size() - 1, aiColor4D( 0, 0, 0, 1)); + pMesh->mColors[pInput.mIndex].push_back( aiColor4D( obj[0], obj[1], obj[2], obj[3])); - else + } else + { DefaultLogger::get()->error("Collada: too many vertex color sets. Skipping."); + } + break; } } @@ -2525,9 +2558,20 @@ aiMatrix4x4 ColladaParser::CalculateResultTransform( const std::vector