It is Known that Duik's Connector cycles through every keyframe that is connected to a controller. It works like using Time Remap on a Property.
I Thought that would be useful if we had an "Absolute" animation mode. That interpolates only the values between the two nearest keyframes from a controller, ignoring all the other keyframes that the connected propriety has. The example above explains a little better what am i trying to do.
That said, i started tinkering the Connector's code and found a way to do this "Absolute" animation with it:
Here's what i wrote:
Code: Select all
//Duik.connector "absolute animation" mod
var ctrlLayer =thisComp.layer("C | Slider 2");
var ctrlValue = ctrlLayer.effect("Slider")(18);
var ctrlEffect = ctrlLayer.effect("Value Connector");
var useVelocity = ctrlEffect(1).value == 2;
if (useVelocity) ctrlValue = ctrlValue.velocity;
else ctrlValue = ctrlValue.value;
var tHasKeys = ctrlLayer.transform.xPosition.numKeys > 1;
function connect(keyF){
var ctrlMin = ctrlEffect(2).value; //0
var ctrlMax = ctrlEffect(3).value; //100
var result = value;
if (numKeys >= 2 && ctrlEffect.enabled)
{
var t = 0;
var beginTime = key(1).time;
var endTime = key(numKeys).time;
if (ctrlMin > ctrlMax)
{
t = linear(keyF, ctrlMin, ctrlMax, endTime, beginTime);
// t = linear(time, 0, 100, 0.5, 0.0); ????????
}
else
{
t = linear(keyF, ctrlMin, ctrlMax, beginTime, endTime);
}
result = valueAtTime(t);
}
var driver = Math.floor(result);
//
return driver;
}
sliderController = ctrlLayer.transform.xPosition;
poses = [];
temp = 1;
while ( temp <= thisComp.marker.numKeys ) {
poses.push ( this.value );
i = temp++ ;
}
function getValues(){
var obj_A = sliderController
var ID_A = obj_A.nearestKey(time).index;
var value_A;
var time_A;
var keyF_A;
var keyF_B;
if (obj_A.nearestKey(time).time <= time ){
value_A = obj_A.key(ID_A).value;
time_A = obj_A.key(ID_A).time;
} else {
try{
obj_A.key(ID_A-1).value;
value_A = obj_A.key(ID_A-1).value;
time_A = obj_A.key(ID_A-1).time;
}catch(err){
value_A = obj_A.key(ID_A).value;
time_A = obj_A.key(ID_A).time;
}
}
var obj_B = sliderController
var ID_B = obj_B.nearestKey(time).index;
var value_B;
var time_B;
if (obj_B.nearestKey(time).time >= time ){
value_B = obj_B.key(ID_B).value;
time_B = obj_B.key(ID_B).time;
} else {
try{
obj_B.key(ID_B+1).value;
value_B = obj_B.key(ID_B+1).value;
time_B = obj_B.key(ID_B+1).time;
}catch(err){
value_B = obj_B.key(ID_B).value;
time_B = obj_B.key(ID_B).time;
}
}
keyF_A = connect(value_A);
keyF_B = connect(value_B);
return linear(time,time_A, time_B, keyF_A, keyF_B);
// time value can't read the easing from the slider keyframes, I must discover a way to mimic the ctrlEffect + UseVelocity shenanigans from the original code.
}
if(tHasKeys) getValues() else key(1).value;
The code kinda works as intended.
I only have three issues with it:
- I can't translate the connector's speed and easing from the connector to the to the connected properties.
Somehow the original code can do it, i believe it's because of how the linear that determines the current value was built
OG CODE:
Code: Select all
t = linear(ctrlValue, ctrlMin, ctrlMax, endTime, beginTime);
result = valueAtTime(t);
Code: Select all
keyF_A = connect(value_A);
keyF_B = connect(value_B);
return linear(time,time_A, time_B, keyF_A, keyF_B);
- It Can't work natively with shape layers.
The OG code can because it is written based on the valueAtTime() function.
To avoid cycling through every frame i had base myself on the .value property instead. This is not a big deal to me, since i can work with points follow nulls or something similar.
- The code has tons of ugly and unnecessaries sintaxes.
Well, i'm not a programmer. I can't read very cleary what i'm doing with my code.
I know some of the issues listed above could be solved if i wrote the code more likely to how the original was written, but I burned out all my knowledge about expressions trying to figure out the solutions i wrote.
I can't argue about the last two issues, the easing issue could already make the code 100% usable.
With it done, we could have a powerfull LipSync/Facial expressions Rig that can jump straight to desired poses on an animation.
Thanks in advance and sorry if i did not made clear what i'm trying to do. English is not my native language...