# Posts tagged ‘Transform Spaces’

I’ve been looking into double quaternions and the belt-trick. The trick also known as the ‘waiter trick’ allows  a rotation with respect to axis order, to rotate from -360 to 360 – full 720 degrees of twist. This alone wont work in a rig and  needs additional support for the identity matrix and a feasable way to produce (t) the tracking value along the surface of the hypersphere,  between each frame (frenet).

Possible ways to achieve the (t) value of the Dirac algorithm is to use a simple slider from a range of 0 – 2Pi. This is a simple solution but takes away controllability to the animator – essentially we need to derive the value from the controls themselves.

Ive been looking into fourier waves and the sawtooth wave, its amplitude and frequency can both be accurately achieved with the phase offset being directly linked to the (t) of the belt trick.

Passing the output of the belt-trick is a simple process of converting the quat to eulerangles. But deriving the t value is a lot more tricker, due mainly to the hemispherical problem of quaternions. A quaternion [v,w] is a vector and a twist on the surface of two 4d hemispheres,  where abouts a transform travels across the hemispheres is Slerp.

What can happen is that if the vector crosses the equator of the hemispheres a 180 degree flip can happen – this is entirely correct but tricky to send to a fn as it keeps flipping. If we take the transform of two objects ‘a’ and ‘b’ with us storing the transform of ‘a’ relatively to ‘b’ as a script_function we can get the constantly updating angle of the transform.

But once we hit 180 degree’s it’ll flip and the transform will reverse – one way to fix this is to reset the transform space when we pass 180. Essentially resetting the rotation of of the transform: 0 -180, 0-180 – a sawtooth wave. A problem with this is rotating backwards.

We need a way of dialing up the transform space rotation, up and down and then feed this in the quat fn.

An animatable pivot is essentially a transformed objects space about which the object rotates and moves in. This transform space can have two purposes and two relatively different affects: either your object rotates/moves about an arbitary ‘pivot’ or this ‘pivot’ transforms your object -They sound the same but are different in the results they acheive.

With the first system you take into account the actual objects transform to acheive its new transform; your only keying the actual object. With the second your transforming the target ‘pivot’ object essentially pinning your object about it. Why do you need a system to handle both?

Well,  in local relativity (in terms of a heirachy or closed system) the first system is key in transforming controls about a character: the ankle about the toe for instance or the chest about the hip for bending down. The second system is in world relativity, by transforming an object about the transform of another we can essentially make it a fake parent – glue it to a surface for example.

A good example of both systems in action is a skateboard move, the foot needs to be glue to the board (transforming space) but may itself need to transform about something, the edge of the board for example. Ontop of this the board itself may need to transform about the hands, to be grabbed for example.

This is why a system like this exists as another layer over the base rig, much like a pose tool is. Key generation should only be on the necessary controls and not on extraneous sliders (even if your using sliders to key them)  etc unless there part of the base rig. When working in transform spaces is vitual that keys  get put onto the actual objects.

So as I was mentioning on CGTalk, the rule I think to animating in transform spaces is that you dont generate automated keys. Or force keys to be generated in realtime – as basically you’d be generating keys for the target object everytime you moved pretty much  anything else. So I think i’ll build a set of tools, animators can constrain and transform controls in any space when they want. The benefit of this is that there generating the keys, id have to build either functionality to work with the f-curve or maybe a ‘pseudo’ f-curve transform space when there using it.. else its just gunna be a transform type-in. As to this system it would work above the rig as a whole, that makes a lot more sence – basically our bodies/skeleton is setup and then ontop of this world interaction happens; we lean on things, rest etc etc.. transforms that happen ontop of how were built.

Anyway so i think ive locked down my rig, amazingly – (probably havent though) but the generality is there:

1. Torso Control – controls upper body
2. Hip Control – independant .Custom built (from the ground up) spline IK system, using either deboor, cardinal, Nurbs  bspline or piecewise curves. Control of length, stretching compression, dynamic realtime if needed, automatic twist and bias control to fix pops.
3. Chest Control – independant, drives head positionally
4. Head Control – independant, drives neck when translated
5. Clavicals – independant, drive arms positionally only
6. Arms – IK/FK, independant orientationally. Ik with pole vectors.
7. Hands, fk digits control, digit curling at second joint. Simple pose storing
8. Legs – ik/fk pole vectors
9. Feet – ankle, ball of foot and toe control
10. transform space toolbox, ability to transform any control about any other control/object on the fly per shot. Possible custom controls built – but always making ‘real’ keys on actual controls.
11. Twist on arms, control for bias position at shoulder and wrist. Additional skin tweeners at shoulder/elbow/wrist driven by positional space targets.

So, It’s been a very long hard day and now after a long bath and let my mind slow to a crawl I can add some more to this blog. Transforms affect everything in rigging, there the staple food for a TD and to know them as they say, is to love them.

What is a transform? well essentially a rotation about an axis (the origin) and an offset from the origin (its position). Rotations dont really exist, they’re just how an objects orientation is defined via an axis. Scale is defined by the lengths of these axis, all in one would be universal. On there own would be non-uniform. Sheering is cause by the axis’ not being orthogonalized or perpendicular to each other.

Every object in max and most other 3d packages has a transform space, this is the space the object inhabits. For example for us our transform space is Earth, with the Sun being the Earths. When an object gets created in max, it exists in root or world space, it has no parent and so both its local and world space’s are the same.

When an about gets transformed ‘into’ anothers space, be it from matrix transformations, controllers or simple parenting it gets a relative local space, but still has a world space.  For example if have ‘A’ at [10,0,0] and ‘B’ at [20,0,0] with B parented to A, B has both a local value and a world. Its local value would be [10,0,0] because now its relative to A, and it has a world space value of [30,0,0]. If I put B back to [10,0,0] it would be [0,0,0] in local space, but [10,0,0]  in world.

Transform spaces are crucial in controlling objects especially if they have no parent, or cant have a parent. One way to make an object relative to another is to transform it. In max we have two systems, a left handed system to the user and an internal right-handed system. What happens behind the scenes is every position/rotation/scale you do is transform into the right space system. So all you need to do is force transform an objects space from its current one to a targets space:

(object.transform * inverse target.transform) –  this simple function will get the transform of any object relative to a targets space. Now if you want to transform with the target you have to multiple by it, for example.

Tm = (a.transform * inverse b.transform)

a.transform = (Tm*b.transform)

They can be achieved, but currently its underwraps.
Clip 1 Clip 2