瀏覽代碼

Sub-sample axis-angle channels if the delta between two consecutive key-frame angles is >= 180 degrees. Fixes #458.

Alexander Gessler 10 年之前
父節點
當前提交
ff4e1d9446
共有 1 個文件被更改,包括 20 次插入0 次删除
  1. 20 0
      code/ColladaLoader.cpp

+ 20 - 0
code/ColladaLoader.cpp

@@ -1143,6 +1143,26 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
 						}
 						++pos;
 					}
+
+					// https://github.com/assimp/assimp/issues/458
+					// Sub-sample axis-angle channels if the delta between two consecutive
+					// key-frame angles is >= 180 degrees.
+					if (transforms[e.mTransformIndex].mType == Collada::TF_ROTATE && e.mSubElement == 3 && pos > 0 && pos < e.mTimeAccessor->mCount) {
+						float cur_key_angle  = ReadFloat( *e.mValueAccessor, *e.mValueData, pos, 0);
+						float last_key_angle = ReadFloat( *e.mValueAccessor, *e.mValueData, pos - 1, 0);
+						float cur_key_time  = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos, 0);
+						float last_key_time = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos - 1, 0);
+
+						float last_eval_angle = last_key_angle + (cur_key_angle - last_key_angle) * (time - last_key_time) / (cur_key_time - last_key_time);
+						float delta = std::fabs(cur_key_angle-last_eval_angle);
+						if (delta >= 180.0f) {
+							int subSampleCount = static_cast<int>(std::floorf(delta / 90.0f));
+							if (cur_key_time != time) {
+								float nextSampleTime = time  + (cur_key_time - time) / subSampleCount;
+								nextTime = std::min( nextTime, nextSampleTime);
+							}
+						}
+					}
 				}
 
 				// no more keys on any channel after the current time -> we're done