From 3e529ac1fc208bf2113ee901a31ed748a1d2a062 Mon Sep 17 00:00:00 2001 From: ulfjorensen Date: Fri, 26 Feb 2010 15:17:19 +0000 Subject: [PATCH] Bugfix: Collada animation parser now handles multi-value data types correctly. Or at least I hope so. git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@555 67173fc5-114c-0410-ac8e-9d2fd5bffc1f --- code/ColladaHelper.h | 3 ++- code/ColladaLoader.cpp | 6 +++--- code/ColladaParser.cpp | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/code/ColladaHelper.h b/code/ColladaHelper.h index 22fe1e001..a12f73d64 100644 --- a/code/ColladaHelper.h +++ b/code/ColladaHelper.h @@ -271,6 +271,7 @@ struct Data struct Accessor { size_t mCount; // in number of objects + size_t mSize; // size of an object, in elements (floats or strings, mostly 1) size_t mOffset; // in number of values size_t mStride; // Stride in number of values std::vector mParams; // names of the data streams in the accessors. Empty string tells to ignore. @@ -281,7 +282,7 @@ struct Accessor Accessor() { - mCount = 0; mOffset = 0; mStride = 0; mData = NULL; + mCount = 0; mSize = 0; mOffset = 0; mStride = 0; mData = NULL; mSubOffset[0] = mSubOffset[1] = mSubOffset[2] = mSubOffset[3] = 0; } }; diff --git a/code/ColladaLoader.cpp b/code/ColladaLoader.cpp index 16c9f612e..c0112479b 100644 --- a/code/ColladaLoader.cpp +++ b/code/ColladaLoader.cpp @@ -947,7 +947,7 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars // read values from there float temp[16]; - for( size_t c = 0; c < e.mValueAccessor->mParams.size(); ++c) + for( size_t c = 0; c < e.mValueAccessor->mSize; ++c) temp[c] = ReadFloat( *e.mValueAccessor, *e.mValueData, pos, c); // if not exactly at the key time, interpolate with previous value set @@ -956,7 +956,7 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars float preTime = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos-1, 0); float factor = (time - postTime) / (preTime - postTime); - for( size_t c = 0; c < e.mValueAccessor->mParams.size(); ++c) + for( size_t c = 0; c < e.mValueAccessor->mSize; ++c) { float v = ReadFloat( *e.mValueAccessor, *e.mValueData, pos-1, c); temp[c] += (v - temp[c]) * factor; @@ -964,7 +964,7 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars } // Apply values to current transformation - std::copy( temp, temp + e.mValueAccessor->mParams.size(), transforms[e.mTransformIndex].f + e.mSubElement); + std::copy( temp, temp + e.mValueAccessor->mSize, transforms[e.mTransformIndex].f + e.mSubElement); } // Calculate resulting transformation diff --git a/code/ColladaParser.cpp b/code/ColladaParser.cpp index 05368dd0e..6c0c94de8 100644 --- a/code/ColladaParser.cpp +++ b/code/ColladaParser.cpp @@ -1677,6 +1677,7 @@ void ColladaParser::ReadAccessor( const std::string& pID) acc.mOffset = offset; acc.mStride = stride; acc.mSource = source+1; // ignore the leading '#' + acc.mSize = 0; // gets incremented with every param // and read the components while( mReader->read()) @@ -1719,6 +1720,20 @@ void ColladaParser::ReadAccessor( const std::string& pID) // DefaultLogger::get()->warn( boost::str( boost::format( "Unknown accessor parameter \"%s\". Ignoring data channel.") % name)); } + // read data type + int attrType = TestAttribute( "type"); + if( attrType) + { + // for the moment we only distinguish between a 4x4 matrix and anything else. + // TODO: (thom) I don't have a spec here at work. Check if there are other multi-value types + // which should be tested for here. + std::string type = mReader->getAttributeValue( attrType); + if( type == "float4x4") + acc.mSize += 16; + else + acc.mSize += 1; + } + acc.mParams.push_back( name); // skip remaining stuff of this element, if any