[cpp] Fixed AnimationState not respecting MixBlend.first for rotate timelines. See #1274.

This commit is contained in:
badlogic 2019-02-12 14:24:24 +01:00
parent 2843950e18
commit c0277ff12b

View File

@ -642,34 +642,39 @@ void AnimationState::applyRotateTimeline(RotateTimeline *rotateTimeline, Skeleto
Bone *bone = skeleton._bones[rotateTimeline->_boneIndex]; Bone *bone = skeleton._bones[rotateTimeline->_boneIndex];
Vector<float>& frames = rotateTimeline->_frames; Vector<float>& frames = rotateTimeline->_frames;
float r1, r2;
if (time < frames[0]) { if (time < frames[0]) {
if (blend == MixBlend_Setup) { switch (blend) {
bone->_rotation = bone->_data._rotation; case MixBlend_Setup:
bone->_rotation = bone->_data._rotation;
default:
return;
case MixBlend_First:
r1 = bone->_rotation;
r2 = bone->_data._rotation;
} }
return;
}
float r2;
if (time >= frames[frames.size() - RotateTimeline::ENTRIES]) {
// Time is after last frame.
r2 = bone->_data._rotation + frames[frames.size() + RotateTimeline::PREV_ROTATION];
} else { } else {
// Interpolate between the previous frame and the current frame. r1 = blend == MixBlend_Setup ? bone->_data._rotation : bone->_rotation;
int frame = Animation::binarySearch(frames, time, RotateTimeline::ENTRIES); if (time >= frames[frames.size() - RotateTimeline::ENTRIES]) {
float prevRotation = frames[frame + RotateTimeline::PREV_ROTATION]; // Time is after last frame.
float frameTime = frames[frame]; r2 = bone->_data._rotation + frames[frames.size() + RotateTimeline::PREV_ROTATION];
float percent = rotateTimeline->getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + } else {
RotateTimeline::PREV_TIME] - // Interpolate between the previous frame and the current frame.
frameTime)); int frame = Animation::binarySearch(frames, time, RotateTimeline::ENTRIES);
float prevRotation = frames[frame + RotateTimeline::PREV_ROTATION];
float frameTime = frames[frame];
float percent = rotateTimeline->getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame +
RotateTimeline::PREV_TIME] -
frameTime));
r2 = frames[frame + RotateTimeline::ROTATION] - prevRotation; r2 = frames[frame + RotateTimeline::ROTATION] - prevRotation;
r2 -= (16384 - (int) (16384.499999999996 - r2 / 360)) * 360; r2 -= (16384 - (int) (16384.499999999996 - r2 / 360)) * 360;
r2 = prevRotation + r2 * percent + bone->_data._rotation; r2 = prevRotation + r2 * percent + bone->_data._rotation;
r2 -= (16384 - (int) (16384.499999999996 - r2 / 360)) * 360; r2 -= (16384 - (int) (16384.499999999996 - r2 / 360)) * 360;
}
} }
// Mix between rotations using the direction of the shortest route on the first frame while detecting crosses. // Mix between rotations using the direction of the shortest route on the first frame while detecting crosses.
float r1 = blend == MixBlend_Setup ? bone->_data._rotation : bone->_rotation;
float total, diff = r2 - r1; float total, diff = r2 - r1;
diff -= (16384 - (int) (16384.499999999996 - diff / 360)) * 360; diff -= (16384 - (int) (16384.499999999996 - diff / 360)) * 360;
if (diff == 0) { if (diff == 0) {