1
$\begingroup$

I've seen a few implementations of a geometry nodes "lookat" setup, where your object is facing an empty. The easiest setup being like this: example

However when both object (source object and lookat target) are moving around, there are always moments where the rotation is suddenly mixed up.

Does anyone know how to add an up-vector or some kind of pole target (like in IK-rigging) or is this a limitation of the geometry nodes itself / do we need to revert to python scripting / matrix manipulations for this?

$\endgroup$

1 Answer 1

2
$\begingroup$

First, GN is probably not the best way to do this specific problem. An armature modifier (or object constraints, if you don't care about deformation vs transformation) is going to be faster and easier.

However, it is possible in GN. I don't think Align Euler to Vector is going to work, because that only aligns object space basis vectors, and for what you want, we need serial rotations-- rotations that align already modified vectors to vectors, not basis vectors.

A track-to is basically two different rotations. We first rotate in (object) Z to the target, as best we can; we then rotate in X to the target, at which point we reach the target.

We'll start with rotating in object Z to point at the target, so that we can then node group and re-use for our rotation in X:

enter image description here

Our constant -YVec is the vector we want to point at the target. We get the vector to our target and discard the Z component, since we can't rotate that way. We get the arccos of the normalized dot product to get the angle, and we rotate about cross product of our vectors (which creates a vector perpendicular to both vectors) to figure out our axis. We rotate our individual vertices and write our new position.

We also perform this same rotation on the vector that represents our tracking vector, the -Y vector, so that we can use this as our new tracking vector for the next rotation. Let's group it up and add another copy:

enter image description here

Now we can use our new vector-to-align as the input for a new copy. We're not discarding any target XYZ components on this, making it equivalent to a damped track/swing, but because we've already rotated in Z to the target, that's the same thing as a locked track, same as rotation in only X.

Okay, so what about a pole angle? A pole angle is similar, in that it is two sequential rotations: first we track the target, then we rotate about our modified tracking axis to a new target. This is actually a little more complicated-- we could use some tricks before to do our earlier locked track, by just discarding vector components, that we can't do once we're no longer measuring object basis vectors:

enter image description here

So for our inputs, we have the relative location of two empties, we have a track-to vector, and we also have a pole vector-- the vector that should point to our pole. We've slightly edited our node group so that in addition to outputting our modified track-to vector, it also outputs a modified extra vector-- in this case, our modified pole vector.

We need to measure the angle between our pole target and our modified pole vector, but the vec to pole target isn't necessarily going to be in the new XZ plane in which we want to rotate, so to get the target vector into the proper plane, we do a pair of cross-products.

We can use the arcos of the dot product of normalized vectors to get the angle between them (note that cross-products are not necessarily normalized vectors!) This angle isn't directional however, so we need to look at which direction our rotation axis is pointing to decide whether to rotate by arccos(dot) or by negative arcos(dot). I'm using a mixRGB as a simple switch here. Finally, we'll rotate about our modified tracking vector as an axis.

Of course, you'll want to

I wouldn't be surprised if there were some optimizations to be found here. This is merely me working out the problem, testing it, fixing bugs as I go.

$\endgroup$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .