View Full Version : matrix transformation & the align tool...

01 January 2009, 04:00 AM
i'm having an issue emulating the behavior of the align tool in script. here's the problem (i've attached a 2009 max file to illustrate)...

i have two objects ($Rotator_01 & $Rotator_02) rotated at arbitrary angles. i have another object ($Pointer) parented to $Rotator1 and aligned with it. i want to realign this child object to the rotation of $Rotator_02. this part is simple (& probably could be simpler than how i have it below)...

aTm = $Pointer.transform

aTm.row1 = $Rotator_02.transform.row1
aTm.row2 = $Rotator_02.transform.row2
aTm.row3 = $Rotator_02.transform.row3

$Pointer.transform = atm

the next step is the sticky part ...
i want to then be able to script the same result as using the align tool to align $Pointer 's orientation to $Rotator_01 on the Z axis only (z checkbox checked). while this doesn't really look like it's being rotated on the z-axis, it does produce the result i need. using the tool is perfect, but for the life of me, i can't figure out how i would do this in script. i'm hoping there's some matrix manipulation voodoo that can do it.

01 January 2009, 02:33 PM
I didn't test it much so let me know if this works for you.

origAngles=$sphere01.transform.rotation as eulerAngles
targetAngles=$box01.transform.rotation as eulerAngles

in coordsys (transMatrix $sphere01.transform.pos) $sphere01.rotation=eulerAngles origAngles.x origAngles.y targetAngles.z

01 January 2009, 05:22 PM
thanks paul, but unfortunately that doesn't get the result i'm looking for. i've attached an updated max file to illustrate the desired final alignment. it appears to me that after $Pointer is aligned to $Rotator_02's orientation, i want to $Pointer to adopt $Rotator_01's Y rotation but in relation to $Rotator_02's local coordsys - does that make sense?

i hope the max file can illustrate it better than i can describe it.



01 January 2009, 11:53 PM
based off the max file in your second post I dont really know what you're trying to do, but based off your first post where you're trying to emulate the align tool in a single axis I have a solution:
fn getVectorsAngle v1 v2 =
acos (dot (normalize v1) (normalize v2))
fn getNormalVector v1 v2 =
normalize (cross v1 v2)
fn rotateMatrix tm q =
x = tm.row1 * q
y = tm.row2 * q
z = tm.row3 * q
matrix3 x y z tm.pos

a = $Pointer
b = $Rotator_02

za = a.transform.row3
zb = b.transform.row3

ang = getVectorsAngle za zb
norm = getNormalVector za zb
q = quat -ang norm -- not sure why the angle has to be negative, but it works...

a.transform = rotateMatrix a.transform q

)By looking at the result of the align tool, I determined that for a single axis alignment the entire matrix is being rotated, rather than 'aligned'. The rotation axis is found by the normal to the plane defined by the 2 Z axis vectors (cross product). The rotation angle is found by simply finding the angle between the 2 z axis vectors.

Now I spent a fair while trying to figure out a way to rotate the matrix by using the inbuilt functions like preRotate etc but I couldn't find a solution that worked so I ended up just creating my own function that rotates each axis 'by hand' by multiplying them individually by the quaternion. I used THIS POST ( in the Geometric calculations thread, for reference.

I have attached an updated max file with some comments (as text objects) and other objects in there for visual aid. Run the above code and it should align as the align tool does. Hopefully its what you're after

EDIT: Ok it seems i was wrong. I tried it on the x and y axis and it didnt work. I double checked the result of the z axis and it was close but not exactly what the align tool does.

01 January 2009, 04:13 AM
thanks a bunch gravey - looking at the file you posted you definitely put some thought & time into the response & i really appreciate it.

but, unfortunately it still doesn't get the expected result (adopting $Rotator_02's orientation & then re-aligning to Rotator_01's local z orientation only - la using the align tool by hand). i did ham up the expectation in my second post, so the best description i still the first one.

i need to move on, but i would still love to see if this challenge could be solved. i'll hammer away at it in my spare (?) time, but if anyone has an epiphany please post it!

thx again.

01 January 2009, 03:13 PM
What about using a simple lookat controller instead of a script controller

1. create a point helper and align it and parent it to $Rotator_01.
2. move it on it's local Z axis above $Rotator_01.
3. make $Pointer's rotation controller a lookat constraint.
4. use it's Z axis to look at the point helper.
5. using axis align make $Rotator_02 the upnode and use the same axis to align them.

Hope this helps you..

CGTalk Moderation
01 January 2009, 03:13 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.