Xelnath написалLooking at the code, isnt this just a bug where because 1 ->2 -> 1 means 1 qualifies as being 'first' its not getting added to the list as 'last' as well - or worse is being mixed from the original mix at full alpha when it shouldnt be?
No, if the animations are A -> B -> A, the entry for each A is a different TrackEntry instance.
Xelnath написалaren't both of these sections going 'backwards' up the linked list, when one you want one to be going backward and one to be going forward?
No, timelinesFirst
adds the last linked list item first using call stack recursion. timelinesLast
adds the first linked list item first, which doesn't need recursion.
Xelnath написалA->B, and a key is only set in 'b', TimelinesLast won't be set for a value that was keyed in B, but not A, because the first thing it does is skip to the previous entry...
Not sure what you mean by skipping the previous entry. The code doesn't bother computing timelinesLast
for track entries below the lowest track with a mixingFrom
entry.
I believe the timeslinesFirst
and timelinesLast
calculations are correct. If there is a bug, it's elsewhere. Otherwise the logic to solve the dipping is flawed.
BinaryCats написалResults in when Pickup is nolonger playing (i.e. currentTrackEntry.animation.name != "pickup") the skeleton, for one frame, snaps to setupPose, then continues playing idle.
I doubt this is related to this thread. Your Skeleton Viewer unit test idea is interesting. It's on my (not so) short list.
Xelnath написалfreeze the mix % between the current Timeline and the Bind Pose until the new Track reaches 100%
I'm not sure why or how this would solve the problem.
BinaryCats написалWhat's the status of this issue? And or the experimental code?
Many other things needed attending so I had to stop working on this for a few days. You can try the experimental code, here it is updated to the current master
branch:
http://n4te.com/x/1128-aAAq.txt
It works, there is no dipping, but interrupting a mix can have snapping. You could avoid that by disabling multiple mixingFrom
entries. To do that, find this code:
if (from != null) {
if (interrupt) queue.interrupt(from);
current.mixingFrom = from;
current.mixTime = 0;
from.timelinesRotation.clear(); // Reset rotation for mixing out, in case entry was mixed in.
// If not completely mixed in, set mixAlpha so mixing out happens from current mix to zero.
if (from.mixingFrom != null && from.mixDuration > 0) current.mixAlpha *= Math.min(from.mixTime / from.mixDuration, 1);
}
And replace it with:
if (from != null) {
if (interrupt) queue.interrupt(from);
if (from.mixingFrom != null) {
if (from.mixDuration > 0) {
current.mixAlpha = Math.min(from.mixTime / from.mixDuration, 1);
if (from.mixTime / from.mixDuration < 0.5f) {
TrackEntry mixingFrom = from.mixingFrom;
mixingFrom.mixingFrom = from;
from.mixingFrom = null;
from = mixingFrom;
}
}
from.mixTime = from.mixDuration - 0.0001f; // One frame to mix out the old animation.
}
current.mixingFrom = from;
current.mixTime = 0;
from.timelinesRotation.clear(); // Reset rotation for mixing out, in case entry was mixed in.
}
This is how the old AnimationState worked, it chooses the closer of the 2 animations being mixed and discards the one that is further away. This means when interrupting a mix you'll get a snap, but it won't be nearly as bad as without this patch.