This forum has been permanently closed and archived; you can still access all content but can't post anymore.

Of course, you can still join us in other places!
To get support and talk about RxLaboratory and with the team, come here: https://rainboxlab.org/support/

Need Help modifying the Duik's Connector Code

Rigging, animation, import/export of characters, props and cameras comprehensive tool set for After Effects.
Locked
jetrotal

Need Help modifying the Duik's Connector Code

Post by jetrotal » Sat May 04, 2019 7:02 pm

Image

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;
I added an img attachment file, comparing both original code (left/red) and the code that i wrote (right/green).



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);
MODDED CODE:

Code: Select all

keyF_A = connect(value_A);
keyF_B = connect(value_B);
return linear(time,time_A, time_B, keyF_A, keyF_B);
The thing is that i couldn't think any other way to capture and interpolate the values from both nearest keyframes.


- 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...

jetrotal

Re: Need Help modifying the Duik's Connector Code

Post by jetrotal » Tue May 14, 2019 7:04 pm

I did it! Thanks to Filip Vandueren, from CreativeCow.
https://github.com/jetrotal/Duik.Connec ... poseMOD.js


I had to add

Code: Select all

	ctrlNearK = ctrlFrames.nearestKey(time);

	try{
		ctrlPrevK = ctrlNearK.time&lt;time ? ctrlNearK : ctrlFrames.key(ctrlNearK.index-1);
	}catch(err){
		ctrlPrevK = ctrlNearK.time&lt;time ? ctrlNearK : ctrlFrames.key(ctrlNearK.index);
	
	}try{
		ctrlNextK = ctrlFrames.key(ctrlPrevK.index+1);
	}catch(err){
		ctrlNextK = ctrlFrames.key(ctrlPrevK.index)
	}

and change the last linear(); function to:

Code: Select all

keyF_A = connect(value_A);
keyF_B = connect(value_B);


	if (ctrlPrevK.value<ctrlNextK.value) {
		return linear(ctrlFrames.value, ctrlPrevK.value, ctrlNextK.value, keyF_A, keyF_B);
	} else {
		return linear(ctrlFrames.value, (ctrlNextK.value+0.1), ctrlPrevK.value, keyF_B, keyF_A);
	}

}

My code is a messy hell, with tons of try and catch, but at least it works.
If you guys have any advise to clean it up, would be welcome...

Locked