Meaning of inWeight and outWeight in Keyframe, or recalculate tangents from sampling
I'm writing an editor plugin to mirror automatically some animations. It works, but I cannot generate the correct tangents, and I suspect it is for I don't understand the tangent weight meaning. Here the long story:
I have a function GetValueAtTime(EditorCurveBinding binding, float time) that sample the animation and get the corresponding binded value. It works, because the flipped animation respond perfectly on the keyframes.
Now I want to calculate the tangents and weights between two keyframes, oldKey and newKey. To do this I simply sample the model in two different equally spaced intermediate points and define the 4 points I'll use for the interpolation:
var intermediateTime1 = 1 / 3f * (2 * oldKey.time + newKey.time);
var intermediateTime2 = 1 / 3f * ( oldKey.time + 2 * newKey.time);
var intermediateValue1 = GetValueAtTime(binding, intermediateTime1);
var intermediateValue2 = GetValueAtTime(binding, intermediateTime2);
var p1 = new Vector2(oldKey.time, oldKey.value);
var p2 = new Vector2(intermediateTime1, intermediateValue1);
var p3 = new Vector2(intermediateTime2, intermediateValue2);
var p4 = new Vector2(newKey.time, newKey.value);
The next thing I do is to calculate the coefficients of the corresponding hermite polynomial c1 t^3 + c2 t^2 + c3 * t^1 + c4, supposing it is the correct interpolation unity do between keyframes:
//var c1 = - 9/2f * p1 + 27/2f * p2 - 27/2f * p3 + 9 / 2f * p4;
var c2 = 9 * p1 - 45/2f * p2 + 18 * p3 - 9 / 2f * p4;
var c3 = -11/2f * p1 + 9 * p2 - 9/2f * p3 + p4;
//var c4 = p1;
I don't need c1 and c4 so I commented out their calculation. t is a parameter that goes from 0 to one.
Now I need to calculate the tangents, and knowing that each point of the curve can be defined as (2p1 - 2p4 + p1' + p4') t^3 + (-3p1 + 3p2 - 2p1' - p4') t^2 + p1' t + p1, where p1' and p4' are the componentwise derivatives of the respective points, I can calculate the respective tangents and slopes:
var t1 = c3;
var t2 = -3 * p1 + 3 * p2 - 2 * t1 - c2;
var slope1 = t1.y / t1.x;
var slope2 = t2.y / t2.x;
oldKey.outTangent = slope1;
newKey.inTangent = slope2;
By now it seems almost correct, the elements seems to start to move in the right direction and the animation don't seems too weird, but in the hermite polynomial the interpolation between the points does not depend just on the tangents but even on the strenght the tangents have, strenght that I lose in the division I make to obtain the slope. Trying the animation, in fact, I don't have the same values of the original animation when I'm not in the keyframes. The mirrored animation is not so distant from the original one but does not perfectly match.
I experimented a lot with the inWeight and outWeight parameters of the Keyframe, trying to understand what they reresent, but I was not able to figure out it. I even tryed to read the Unity sources to figure out the exact algorithm it uses, but I didn't find the implementation in it, maybe the evaluation is in a part of the sources Unity Technologies didn't publish. So my answers are: are my thoughts correct untill this point? And what exactly represents inWeight and outWeight in the curve interpolation?
Your answer
Follow this Question
Related Questions
Elastic Interpolation of Quaternion 0 Answers
What exactly does Mathf.InverseLerp() do? 4 Answers
Finding a tangent vector from a given point and circle 1 Answer
Logarithmic Interpolation 1 Answer
Unity Recorder error v2020.2.7f1 0 Answers