Copy link to clipboard
Copied
Hi!
I'd like a 3D Null to get the orientation of 3D a layer. (without parenting, it would be too easy )
I've tried a lot of solutions, through orientation, rotations, both combined... some results are close, but never perfect.
If I'm right, orientation is computed before rotations...
I think the simplest way would be with auto-orientation, or the lookAt() expression on orientation, wich gives me correct X and Y orientations, and then get an expression on zRotation to get a "full" orientation.
But what would it be?
How can I get the Z orientation in layer space?
Any idea will be appreciated!
François
Try this oreientation expression:
L = thisComp.layer("other layer");
u = fromWorldVec(L.toWorldVec([1,0,0]));
v = fromWorldVec(L.toWorldVec([0,1,0]));
w = normalize(fromWorldVec(L.toWorldVec([0,0,1])));
sinb = clamp(w[0],-1,1);
b = Math.asin(sinb);
cosb = Math.cos(b);
if (Math.abs(cosb) > .0005){
c = -Math.atan2(v[0],u[0]);
a = -Math.atan2(w[1],w[2]);
}else{
a = (sinb < 0 ? -1 : 1)*Math.atan2(u[1],v[1]);
c = 0;
}
[radiansToDegrees(a),radiansToDegrees(b),radiansToDegrees(c)]
Dan
Copy link to clipboard
Copied
No, when you normalise the vectors in the getRotation function you should get rid of the scaling and you're not using the distorted vectors anymore. This would be equivalent to dividing the vector by the value of the scale, basically, but I'd expect the result to be more accurate with the normalize function.
I'll need to give it another try later but since I'm only changing the direction of the vector in the new expressions I don't see why it wouldn't work with non-uniform scaling now if it worked before.
Edit: i just gave it a try with crazy scales and the parent and "parented" layers always sticked like glue. If you're still having an issue you can send me a project.
Copy link to clipboard
Copied
So, I must have done something wrong
Here is a project:
https://www.dropbox.com/s/tdfz118ymxidayn/Orientation.aep
Thanx in advance!
Copy link to clipboard
Copied
arrgh ... you're right, I guess once again I didn't try the right combination of scales/rotations for the parent's parent.
I think that issue is with the scale calculation loop: when you parent a layer to another one, the scales of each layers are applied to the rotated axes of each layer. But we don't take that into account in the loop: we just multiply the values of the scale and apply them in the last layer's basis, as if each parent and grandparent had the exact same orientation. Does this make sense?
That's why I was calculating the scale using 1/toWorldVec( /* X, Y or Z vector */ ) , I remember now.
So back to the same issue with the negative scales, I'm beginning to wonder if I haven't overlooked something simple and I'm not making things more complicate dthan they are! If not, the simplest solution I see right now would be to put expressions in the parents' scale and rotation expressions to force the scale to positive values, and if a negative value is entered rotate the layer by 180º around the next axis.
I guess you should go back to your X/Y workaround for now ...
Copy link to clipboard
Copied
I agree... If we try to compensate, there will always be a new issue showing up, cos the toWorldVec function returns something from a layer, not from a value.
If we were in Scripting World, (or even in the SDK), we could create a "fake" layer, modify it and then call toWorldVec... Or at least try!
But the After Effects API encounters this kind of issues too: if you give a layer a parent, scale the parent and rotate it (specially in 3D), then un-parent it, your layer won't match old-parent's orientation (nor scale)...
May be one day!
Cheers,
François
Copy link to clipboard
Copied
10 years later, still a life saver!
Copy link to clipboard
Copied
This thread has helped me a lot but I'm stuck on something. I'm trying to set up expressions for an animation of an office chair. I have a 3D null called "null - direction" which controls the path of the chair, and it is set to auto-orient along the path. But I wanted the wheels to have a slight delay so that when the chair turns a corner the wheels take a little bit of extra time to rotate into that orientation.
In order to do this I made a null called "null - getOrientation" and I used the expressions in this thread to get the orientation of the chair, and then I used another null called "null - delay" to delay the orientation by half a second. The orientation of the wheels is pick-whipped to the orientation of "null - delay"
It all seems to work ok at the first corner but when we get to the second corner the chair is turning clockwise but "null - getOrientation" and "null - delay" start turning anticlockwise and we end up with wheels not oriented to the path. I'm attaching a video which I hope shows what I mean. On further investigation it seems to be occurring when the value of sinb reaches the top or bottom of the sine wave curve ie. at 1 or -1.