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
pull/1/head
ulfjorensen 2010-02-26 15:17:19 +00:00
parent b536a22e4e
commit 3e529ac1fc
3 changed files with 20 additions and 4 deletions

View File

@ -271,6 +271,7 @@ struct Data
struct Accessor struct Accessor
{ {
size_t mCount; // in number of objects 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 mOffset; // in number of values
size_t mStride; // Stride in number of values size_t mStride; // Stride in number of values
std::vector<std::string> mParams; // names of the data streams in the accessors. Empty string tells to ignore. std::vector<std::string> mParams; // names of the data streams in the accessors. Empty string tells to ignore.
@ -281,7 +282,7 @@ struct Accessor
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; mSubOffset[0] = mSubOffset[1] = mSubOffset[2] = mSubOffset[3] = 0;
} }
}; };

View File

@ -947,7 +947,7 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
// read values from there // read values from there
float temp[16]; 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); temp[c] = ReadFloat( *e.mValueAccessor, *e.mValueData, pos, c);
// if not exactly at the key time, interpolate with previous value set // 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 preTime = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos-1, 0);
float factor = (time - postTime) / (preTime - postTime); 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); float v = ReadFloat( *e.mValueAccessor, *e.mValueData, pos-1, c);
temp[c] += (v - temp[c]) * factor; temp[c] += (v - temp[c]) * factor;
@ -964,7 +964,7 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
} }
// Apply values to current transformation // 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 // Calculate resulting transformation

View File

@ -1677,6 +1677,7 @@ void ColladaParser::ReadAccessor( const std::string& pID)
acc.mOffset = offset; acc.mOffset = offset;
acc.mStride = stride; acc.mStride = stride;
acc.mSource = source+1; // ignore the leading '#' acc.mSource = source+1; // ignore the leading '#'
acc.mSize = 0; // gets incremented with every param
// and read the components // and read the components
while( mReader->read()) 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)); // 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); acc.mParams.push_back( name);
// skip remaining stuff of this element, if any // skip remaining stuff of this element, if any