Notifications
Clear all

[Closed] Mirroring rotations across an axis

I am trying to write something to mirror animation from a right arm to a left arm, or a character jump left to jump right. Sometimes the arms are dissimilar in orientation. I mainly need to know how to mirror a rotation across an axis, and I can do the rest. On paper you would take the quat of one, extract it’s Z axis, multiply, negate it, then square it… But in max I am unsure. I am kind of a Euler guy myself. And as usual, is there a much easier way to do this?

If you want a laugh, I actually already did it once by getting the start and end point of a bone on one side of the axis, then using that and z dir to create another on the other side of the axis, then orienting the joint to that and then delete the new bone, it worked, but in a loop, max seemed to get ahead of itself. I had to break it up into many loops and toss in some sleeps; it was very messy.

9 Replies
 PEN

Well the way that you tried would be quite acurate.

Have a look at Maxine on the Max8 samples disc. I Have a function built into the custom attribute def that mirrors the matrix values.

Unfortunately I don’t have the Max8 sample disc. (haven’t upgraded)

I actually have it working. But here’s the kicker, because I am mirroring the orientations at each key over time, I lose the controller data. Some are linear some are tweened differently… It is just a headache.

Hey pen which folder is maxine in on the samples disc? Whats the file called I cann’t find it…

thanks

Hi Ken,

C:\Program Files\Autodesk\3dsMax8\scenes\Samples\Scenes\Characters\Complete\maxine.max

It’s in the samples.

Chris

I don’t know if you tried this, but if you’re using Euler XYZ controllers, you can get and assign the x, y, and z values directly. That’s how I mirror limb poses on my own rigs. Here’s an example of what I mean:

-- create a box
b1 = box length:10 width:10 height:40
-- make sure it has an euler xyz rotation controller
b1.rotation.controller = euler_xyz()
-- rotate it by assigning the Y controller value directly
b1.rotation.controller[2].value = 40
-- make a new box by copying the current one
b2 = copy b1
-- move it to see it better
b2.pos = [-40,0,0]
-- set it's Y rotation as the mirror opposite of box 1 by simply inverting the it's rotation controller's Y value
-- this would work for any of the three axes
b2.rotation.controller[2].value = -b1.rotation.controller[2].value

Mirroring to arms with unlike orientations was a problem. But now that I got it working fine, the biggest setback is that mirroring, I lose all the controller info… so now I try to set the controllers to TCB early on then read out the TCB info and apply it from one arm to the other afterwards… but it’s not really working. It looks like I need to scrap this and look into copying controllers and working with their curve data. I was just doing this in my spare time, but now I would really like to get it working.

I’ve got half a method using the Transform Matrix which is really simple to use for this problem. Plus it means that you can set the rotations and positions directly.

 Fn MirrorTM Obj1 Obj2 MObj MAxis OAxis =
(
T = Obj2.Transform * inverse MObj.Transform --- the offset transform Matrix
Case MAxis of --- Mirror T in one axis of MObj 
(
#x:( for i = 1 to 4 do T[i] = [ -T[i].x , T[i].y , T[i].z ] )
#y:( for i = 1 to 4 do T[i] = [ T[i].x , -T[i].y , T[i].z ] )
#z:( for i = 1 to 4 do T[i] = [ T[i].x , T[i].y , -T[i].z ] )
)
case OAxis of --- But the axis has been flipped ...so flip it back.
(
#x:( T[1] = - T[1] )
#y:( T[2] = - T[2] )
#z:( T[3] = - T[3] )
)
 
TM = T * MObj.Transform 
--Obj1.Transform = TM --- would be ok, but will set a scale key with animate on so...
Obj1.rotation = Conjugate TM.rotation
Obj1.pos = TM.pos
)
[size=2]

[/size]
[size=2]Ie To set $Box01 to Mirror $box02 in the x axis of $RootBone , preserving the x axis of $box01 [/size]do…

MirrorTM $box01 $box02 $RootBone #x #x

[size=2]The only problem is that the handedness of the transform matrixs gets flipped (you can see this if you look at the local axis of an object when you click the mirror button in Max). At the moment I’ve set up the function so that, by hand, you can pick an axis to reverse back again. But I sure there must be a way of doing this automatically… I’m away from the office at the moment so I haven’t had a chance to look at Maxine… Maybe PEN has the solution.[/size]

 PEN

Multiply the matrix with a scale matrix to flip the handedness back to right handed.

The basic idea is to convert the matrix to the space of the mirror plane, mirror it across it so that you have a scaled matrix, then mirror the scaled matrix in it’s own space back again.