- 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
pull/1/head
ulfjorensen 2009-06-02 20:03:08 +00:00
parent a241829149
commit fe58fa6603
2 changed files with 65 additions and 21 deletions

View File

@ -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 // 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 // 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 // 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]; dstMesh->mNormals = new aiVector3D[numVertices];
std::copy( pSrcMesh->mNormals.begin() + pStartVertex, pSrcMesh->mNormals.begin() + std::copy( pSrcMesh->mNormals.begin() + pStartVertex, pSrcMesh->mNormals.begin() +
@ -531,7 +531,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
} }
// tangents, if given. // tangents, if given.
if( pSrcMesh->mTangents.size() == pSrcMesh->mPositions.size()) if( pSrcMesh->mTangents.size() >= pStartVertex + numVertices)
{ {
dstMesh->mTangents = new aiVector3D[numVertices]; dstMesh->mTangents = new aiVector3D[numVertices];
std::copy( pSrcMesh->mTangents.begin() + pStartVertex, pSrcMesh->mTangents.begin() + std::copy( pSrcMesh->mTangents.begin() + pStartVertex, pSrcMesh->mTangents.begin() +
@ -539,7 +539,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
} }
// bitangents, if given. // bitangents, if given.
if( pSrcMesh->mBitangents.size() == pSrcMesh->mPositions.size()) if( pSrcMesh->mBitangents.size() >= pStartVertex + numVertices)
{ {
dstMesh->mBitangents = new aiVector3D[numVertices]; dstMesh->mBitangents = new aiVector3D[numVertices];
std::copy( pSrcMesh->mBitangents.begin() + pStartVertex, pSrcMesh->mBitangents.begin() + 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 // 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++) 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]; dstMesh->mTextureCoords[real] = new aiVector3D[numVertices];
for( size_t b = 0; b < numVertices; ++b) 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 // 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++) 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]; dstMesh->mColors[real] = new aiColor4D[numVertices];
std::copy( pSrcMesh->mColors[a].begin() + pStartVertex, pSrcMesh->mColors[a].begin() + pStartVertex + numVertices,dstMesh->mColors[real]); std::copy( pSrcMesh->mColors[a].begin() + pStartVertex, pSrcMesh->mColors[a].begin() + pStartVertex + numVertices,dstMesh->mColors[real]);

View File

@ -1474,7 +1474,7 @@ void ColladaParser::ReadSource()
{ {
if( mReader->getNodeType() == irr::io::EXN_ELEMENT) 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(); ReadDataArray();
} }
@ -1515,7 +1515,7 @@ void ColladaParser::ReadSource()
void ColladaParser::ReadDataArray() void ColladaParser::ReadDataArray()
{ {
std::string elmName = mReader->getNodeName(); std::string elmName = mReader->getNodeName();
bool isStringArray = (elmName == "IDREF_array"); bool isStringArray = (elmName == "IDREF_array" || elmName == "Name_array");
// read attributes // read attributes
int indexID = GetAttribute( "id"); int indexID = GetAttribute( "id");
@ -1975,6 +1975,7 @@ void ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector<InputChannel>& pPer
} }
} }
// if I ever get my hands on that guy who invented this steaming pile of indirection... // if I ever get my hands on that guy who invented this steaming pile of indirection...
TestClosing( "p"); TestClosing( "p");
} }
@ -2009,39 +2010,71 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si
else else
DefaultLogger::get()->error("Collada: just one vertex position stream supported"); DefaultLogger::get()->error("Collada: just one vertex position stream supported");
break; break;
case IT_Normal: // ignore all normal streams except 0 - there can be only one normal 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) if( pInput.mIndex == 0)
pMesh->mNormals.push_back( aiVector3D( obj[0], obj[1], obj[2])); pMesh->mNormals.push_back( aiVector3D( obj[0], obj[1], obj[2]));
else else
DefaultLogger::get()->error("Collada: just one vertex normal stream supported"); DefaultLogger::get()->error("Collada: just one vertex normal stream supported");
break; break;
case IT_Tangent: // ignore all tangent streams except 0 - there can be only one tangent 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) if( pInput.mIndex == 0)
pMesh->mTangents.push_back( aiVector3D( obj[0], obj[1], obj[2])); pMesh->mTangents.push_back( aiVector3D( obj[0], obj[1], obj[2]));
else else
DefaultLogger::get()->error("Collada: just one vertex tangent stream supported"); DefaultLogger::get()->error("Collada: just one vertex tangent stream supported");
break; break;
case IT_Bitangent: // ignore all bitangent streams except 0 - there can be only one bitangent 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) if( pInput.mIndex == 0)
pMesh->mBitangents.push_back( aiVector3D( obj[0], obj[1], obj[2])); pMesh->mBitangents.push_back( aiVector3D( obj[0], obj[1], obj[2]));
else else
DefaultLogger::get()->error("Collada: just one vertex bitangent stream supported"); DefaultLogger::get()->error("Collada: just one vertex bitangent stream supported");
break; break;
case IT_Texcoord: // up to 4 texture coord sets are fine, ignore the others case IT_Texcoord:
if( pInput.mIndex < AI_MAX_NUMBER_OF_TEXTURECOORDS) { // 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])); 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 */ if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) /* hack ... consider cleaner solution */
pMesh->mNumUVComponents[pInput.mIndex]=3; pMesh->mNumUVComponents[pInput.mIndex]=3;
} } else
else {
DefaultLogger::get()->error("Collada: too many texture coordinate sets. Skipping."); DefaultLogger::get()->error("Collada: too many texture coordinate sets. Skipping.");
}
break; 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) 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])); 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."); DefaultLogger::get()->error("Collada: too many vertex color sets. Skipping.");
}
break; break;
} }
} }
@ -2525,9 +2558,20 @@ aiMatrix4x4 ColladaParser::CalculateResultTransform( const std::vector<Transform
switch( tf.mType) switch( tf.mType)
{ {
case TF_LOOKAT: case TF_LOOKAT:
// TODO: (thom) {
assert( false); aiVector3D pos( tf.f[0], tf.f[1], tf.f[2]);
aiVector3D dstPos( tf.f[3], tf.f[4], tf.f[5]);
aiVector3D up = aiVector3D( tf.f[6], tf.f[7], tf.f[8]).Normalize();
aiVector3D dir = aiVector3D( dstPos - pos).Normalize();
aiVector3D right = (dir ^ up).Normalize();
res *= aiMatrix4x4(
right.x, up.x, -dir.x, pos.x,
right.y, up.y, -dir.y, pos.y,
right.z, up.z, -dir.z, pos.z,
0, 0, 0, 1);
break; break;
}
case TF_ROTATE: case TF_ROTATE:
{ {
aiMatrix4x4 rot; aiMatrix4x4 rot;