Assimp: Collada Animations: Use quaternion problem

Created on 20 Nov 2018  路  2Comments  路  Source: assimp/assimp

1.Keyframes in the DAE model:
quat1-0.033333 :0.043640,0.666785,0.048615,-0.742380
quat2-0.066666 :0.042636,0.664431,0.047763,-0.744605
2.After import via Assimp:
0.033333 : -0.0436404, -0.666785, -0.0486147, 0.742381
0.044444 : 0.621911, -0.374857, 0.552608, 0.409065
0.055555 : 0.66569, 0.290997, 0.600118, -0.334718
0.066666 : -0.0426365, -0.66443, -0.0477633, 0.744603

After I extracted the quaternion in the animation channel, I get the above error.
Adopt version 4.1.0

Bug

Most helpful comment

// 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[channelElement.mTransformIndex].mType == Collada::TF_ROTATE && channelElement.mSubElement == 3 && pos > 0 && pos < channelElement.mTimeAccessor->mCount)
{
const ai_real cur_key_angle = ReadFloat(
channelElement.mValueAccessor, channelElement.mValueData, pos, 0);
const ai_real last_key_angle = ReadFloat(
channelElement.mValueAccessor, channelElement.mValueData, pos - 1, 0);
const ai_real cur_key_time = ReadFloat(
channelElement.mTimeAccessor, channelElement.mTimeData, pos, 0);
const ai_real last_key_time = ReadFloat(
channelElement.mTimeAccessor, channelElement.mTimeData, pos - 1, 0);
const ai_real last_eval_angle = last_key_angle + (cur_key_angle - last_key_angle) * (time - last_key_time) / (cur_key_time - last_key_time);
const ai_real delta = std::abs(cur_key_angle - last_eval_angle);
if (delta >= 180.0) {
const int subSampleCount = static_cast(std::floor(delta / 90.0));
if (cur_key_time != time) {
const ai_real nextSampleTime = time + (cur_key_time - time) / subSampleCount;
nextTime = std::min(nextTime, nextSampleTime);
}
}
}
/

By temporarily annotating the above code, the problem is basically solved. There should be an error in the interpolation in the keyframe of the model.

All 2 comments

// 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[channelElement.mTransformIndex].mType == Collada::TF_ROTATE && channelElement.mSubElement == 3 && pos > 0 && pos < channelElement.mTimeAccessor->mCount)
{
const ai_real cur_key_angle = ReadFloat(
channelElement.mValueAccessor, channelElement.mValueData, pos, 0);
const ai_real last_key_angle = ReadFloat(
channelElement.mValueAccessor, channelElement.mValueData, pos - 1, 0);
const ai_real cur_key_time = ReadFloat(
channelElement.mTimeAccessor, channelElement.mTimeData, pos, 0);
const ai_real last_key_time = ReadFloat(
channelElement.mTimeAccessor, channelElement.mTimeData, pos - 1, 0);
const ai_real last_eval_angle = last_key_angle + (cur_key_angle - last_key_angle) * (time - last_key_time) / (cur_key_time - last_key_time);
const ai_real delta = std::abs(cur_key_angle - last_eval_angle);
if (delta >= 180.0) {
const int subSampleCount = static_cast(std::floor(delta / 90.0));
if (cur_key_time != time) {
const ai_real nextSampleTime = time + (cur_key_time - time) / subSampleCount;
nextTime = std::min(nextTime, nextSampleTime);
}
}
}
/

By temporarily annotating the above code, the problem is basically solved. There should be an error in the interpolation in the keyframe of the model.

Thanks for the report. And many thanks for the hint as well. I will try to find some time to take a look onto your solution.

Was this page helpful?
0 / 5 - 0 ratings