Browse Source

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
ulfjorensen 15 năm trước cách đây
mục cha
commit
3e529ac1fc
3 tập tin đã thay đổi với 20 bổ sung4 xóa
  1. 2 1
      code/ColladaHelper.h
  2. 3 3
      code/ColladaLoader.cpp
  3. 15 0
      code/ColladaParser.cpp

+ 2 - 1
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<std::string> 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;
 	}
 };

+ 3 - 3
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

+ 15 - 0
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