Asmodeus

09-27-2015, 07:13 AM

Hello everyone , finally i had some time to work and enchance my skeletal animation, and i was thinking of how to implement an interpolation between two different animations to guarantee a smooth transition. Here is my idea of how it should work, haven't implemented anything yet just some thoughts.

Let's take two animations walk and attack. Here i think its worth mentioning that my animations' matrices are pre-cached and pre-calculated , and just loaded runtime based on something like this.

RunningTime += elapsedTime;

double TimeInTicks = RunningTime * TICKS_PER_SECOND;

double AnimationTime = fmod(TimeInTicks, (double)(size - 1));

index = (int)AnimationTime;

Where index gives me the current animation matrix that i have to load into the shader. And it works smooth and nice , it's time dependant so its equally fast on different systems.

Now if i decide to load a new animation in the shader, new matrices are being loaded in and the transition (expectedly) is not that smooth.

Here is what i was thinking.

- Use Animation 1

- Before swapping to animation 2 lerp(Anim1,Anim2)

Where Lerp will linearly interpolate the last N matrices of Anim1 and the first N animation matrices from Anim2. GLM has a nice function for that , its something like:

T = mix(T1,T2,mix_factor).

Where mix_factor can start from 0.0f and grow 1.0f . Meaning having more of the T2 mixed in at the end and less at the start.

- Upload those N lerp-ed matrices in the shader for vertex skinning

- Continue with Anim2 (from start - 0 ? or offset Anim2 matrices before uploading with N ?)

Simple Process schema

Play Anim1 -> Interpolate last N matrices from A1 with first N matrices from A2 -> Play Anim2

Let's take two animations walk and attack. Here i think its worth mentioning that my animations' matrices are pre-cached and pre-calculated , and just loaded runtime based on something like this.

RunningTime += elapsedTime;

double TimeInTicks = RunningTime * TICKS_PER_SECOND;

double AnimationTime = fmod(TimeInTicks, (double)(size - 1));

index = (int)AnimationTime;

Where index gives me the current animation matrix that i have to load into the shader. And it works smooth and nice , it's time dependant so its equally fast on different systems.

Now if i decide to load a new animation in the shader, new matrices are being loaded in and the transition (expectedly) is not that smooth.

Here is what i was thinking.

- Use Animation 1

- Before swapping to animation 2 lerp(Anim1,Anim2)

Where Lerp will linearly interpolate the last N matrices of Anim1 and the first N animation matrices from Anim2. GLM has a nice function for that , its something like:

T = mix(T1,T2,mix_factor).

Where mix_factor can start from 0.0f and grow 1.0f . Meaning having more of the T2 mixed in at the end and less at the start.

- Upload those N lerp-ed matrices in the shader for vertex skinning

- Continue with Anim2 (from start - 0 ? or offset Anim2 matrices before uploading with N ?)

Simple Process schema

Play Anim1 -> Interpolate last N matrices from A1 with first N matrices from A2 -> Play Anim2