4
$\begingroup$

I would like to have a track- or rotation-constraint on a child of a scaled and rotated parent. Unfortunately both types of constraints seem to overwrite the inherited scale.

In the example gif below the sphere is the child of the rectangular block parent. The lower cube acts as the track target. As you can see, rotating the sphere manually (without constraints) works just as you'd think. It rotates while inheriting the scale and rotation of the parent (almost like a shearing effect).

enter image description here

Once I enable the track constraint the sphere rotates toward the target cube which technically is what I want but it acts like the scale and rotation of the parent rotates with it? All I want is a similar behaviour to rotating the sphere manually.

I don't fully understand why exactly this is the result. Is there a way around this?

Thanks in advance!

$\endgroup$

2 Answers 2

6
$\begingroup$

I don't fully understand why exactly this is the result.

Blender uses matrices to store the orientation of objects. These matrices can be converted into a different space, and can be easily broken down into parts that correspond to rotation, scale, and location. So to Limit Rotation, for example, Blender breaks down the matrix into rotation components, clamps the values, and then re-creates the full matrix from these new rotation components. Matrices are a convenient way to store orientations, and they're necessary whenever you want to convert between two different coordinate systems, as is often necessary in constraints.

But when a matrix is the combination of rotation and inherited, non-uniform scale, it creates shear:

enter image description here

In this case, the rotation and scale get mixed together in the matrix, and they're not cleanly divisible for Blender to decompose the matrix. And creating the inverse of the matrix, to, say, turn an orientation in one space into a different space, becomes very difficult and slow, whereas it's nearly trivial when we have uniform scale.

To actually damped track something, we'd need to convert between spaces like that:

enter image description here

The parented bone has exactly the same rotation as the unparented bone. But it doesn't point in the same direction, not when considered in world space, because of its inherited scale. So to damped track a target, we'd need to find the position of that target, in the local space of the bone damped tracking it. 45 degrees in the world is not 45 degrees in a non-uniformly scaled space.

Is there a way around this?

In this case, there is, but it's not easy.

If we want to apply some particular rotation to sheared bone or object, we can use drivers. These don't act the same way as constraints-- they act before rotation and scale components are converted into a matrix. So if we wanted the same rotation values as some unscaled bone, we could use a driver to copy the rotation:

enter image description here

Unlike a copy rotation constraint, driving the rotation preserves the inherited scale. For purposes of a damped track constraint, that's not good enough-- even with the same rotation values, we're not pointing the +Y axis at the same position. But it's a start.

But we can get the location of a position in some arbitrary space with a copy location constraint on a parented bone, in world->world, and then read the local position of that bone. Rotation and scale get mixed together with shear, but location remains separable.

enter image description here

After applying visual transform, we can see the bone copying the location of the tail of the unsheared bone is storing its coordinates in its own, scaled space.

Let's instead copy the location of our "real" tracking target. We'll first copy its location, world->world, onto a scaled bone. Then, we'll copy that location, local->local, onto an unscaled bone, and track the modified location with an unscaled bone. Finally, we can use drivers to copy that rotation onto the scaled tracker:

enter image description here

The rotation values to track our modified location are exactly the same as the rotation values to track our real location, in the scaled space. We have created an inverse, for location only, so that we can evaluate the local space position of a world space target, and then turned that location into the proper rotation that we need.

I expect that you'll want to download the file:

$\endgroup$
2
  • 1
    $\begingroup$ Wow, thanks Nathan! I was worried this post would fly into the void of obscure questions so I wasn't expecting such an elaborate answer. Thanks for answering so quickly and especially for that example scene, it is incredibly helpful. Thank you so much. Have a good day! $\endgroup$
    – Ninkognito
    Aug 29, 2023 at 16:17
  • $\begingroup$ Agreed this can be a head-spinning area. Nicely explained. Thanks. $\endgroup$
    – Robin Betts
    Aug 29, 2023 at 19:50
4
$\begingroup$

If I read you right, this is the behaviour you don't want:

enter image description here

..and this is the behaviour you do want:

enter image description here

With @Nathan's help, it emerges that a clean fix is to evaluate the 'Track To' rotation entirely in the (scaled) parent's space. That way, the inherited transform is preserved, in the correct orientation:

enter image description here

$\endgroup$
7
  • $\begingroup$ Quick and easy solution. Just one thing: Now if I rotate the parent the track constraint isn't accurate anymore as the sphere will receive the additional rotation from the child of constraint. Unfortunately this means that it doesn't help in my case but maybe another soul will find it useful. Either way thanks for your reply! :) $\endgroup$
    – Ninkognito
    Aug 29, 2023 at 16:40
  • $\begingroup$ The problem is that once you scale it, your track axis is no longer pointing at the target: imgur.com/a/7zrJbwf . You need a different rotation to point at the target in a differently scaled space. $\endgroup$
    – Nathan
    Aug 29, 2023 at 17:10
  • $\begingroup$ Ahhh! @Nathan to the rescue! Yes. This is a duff answer. If it's done at mesh-level, with a parented hook, it works. But I'm reluctant to post that way as an answer until I can work out why. Maybe you can put that into plain words. I'm still trying to work it out. $\endgroup$
    – Robin Betts
    Aug 29, 2023 at 18:29
  • $\begingroup$ @RobinBetts In that file, it's not the hook that matters-- it's the "track-to", which allows a custom space, whereas the damped track does not. So you're measuring the track to in the correct, scaled space. $\endgroup$
    – Nathan
    Aug 29, 2023 at 18:55
  • 1
    $\begingroup$ If you put damped track on top of your track to, one after the other, the damped track won't override anything. Which seems weird, unintuitive to me. That confused me at first and led me down a wrong path :) Maybe the same thing happened to you. $\endgroup$
    – Nathan
    Aug 29, 2023 at 19:40

You must log in to answer this question.

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