Confusion over "local" coordinate transforms in constraints.

Hello, Having recently watched the Blender Cookie Mechanical Rigging Tutorial I decided to try this method to rig a little minifig model I’ve made.

I’ve hit a snag trying to rig the hands though, I’ve parent the hand object to an empty that has the correct orientation to rotate nicely around the z-axis. If I select this object in the 3d View and perform a rotation around local-Z it does exactly what I expect. However, if I add a constraint ( copy rotation, or transform ) to the empty to the helper control object (and set to local space) the rotation I get doesn’t seem to be in this space.

I am new to this, so I’ve likely made a silly mistake, or these words do not mean what I think they mean!

Any guidance you can offer on how to get this working is gratefully received. Thankyou.

Here’s the bust minifig .blend file.

The Hand


The Empty (Wrist)


The Control I want to hook up


As far as I know Local axis has to do with Armatures and Pose space. Armature works within its own space. That way when you reset it, they will go back to where it was placed; there 0, 0, 0. Objects including Empty works in Global space.

I’ve used “localspace” constraints on the legs, head and arms, and they’re working fine, it’s just the hands that are causing me grief.

Thanks for the link, I think I have a good understanding of local/world (and other) spaces in ordinary contexts, and indeed it’s working entirely as I’d expect for the other constraints which are based on local translations.

Alas for the wrist empty the “local” rotation an attached constraint provides is not matching the “local” rotation experienced by the object when I manipulate it in the viewport. Constraining either the empty or the hand itself seem to fail much the same, and I have tried adding in another empty in the hierarchy to separate concerns to no avail.

Does local in the transform constraint mean local to each the source and target object, or just the source object? That sounds weird but if local is referring to one space in both it might explain what I’m seeing.

Does the transform panel only show/use the cumulative rotation, even though it shows the real local translation? How can I see/target the real local rotation?

How do I rig this such that the hand rotation is expressed as a single axis rotation?

I’m finding this confusing. (*) My background is Game Engines, where a local transform is a local transform and no funny business!

The more I dig into this the less sense it makes to me… probably I should just rig it with an armature, I only tried this because I thought it’d be quicker and easier. <sigh>

For what it’s worth I managed to rig this how I wanted in the end.

The main issue was that empties don’t seem to act fully as parent frames for rotation. Weird, but I couldn’t get them to work that way.

If I replaced the empties I was using to set rigging axes with non-rendered cubes I could get it to work. I needed two cubes to do it though, the first cube to set the axis, then a child cube to hold the local rotation. And these had to be rigged together BEFORE being transformed, then moved into place.

I expect I still missing important information here, but I have to say this was is a really non-intuitive way of working.

[EDIT] Actually got the empties working in pairs like the cubes, but they still need to be parented when still with a null rotation. I’d like to know why, if anyone knows…

Well here’s the answer. Pretty well buried, but here it is… Sheesh

From N00b to Pro

Clear Parent Inverse Clarified[edit]
Normally, when a parent relationship is set up, if the parent has already had an object transformation applied, the child does not immediately inherit that. Instead, it only picks up subsequent changes to the parent’s object transformation. What happens is that, at the time the parent relationship is set up, the inverse of the current parent object transformation is calculated and henceforth applied before passing the parent transformation onto the child. This cancels out the initial transformation, leaving the child where it is to start with. This inverse is not recomputed when the parent object is subsequently moved or subject to other object transformations, so the child follows along thereafter.

The “Clear Parent Inverse” function sets this inverse transformation to the identity transformation, so the child picks up the full parent object transformation.

1 Like