Community
3ds Max Programming
Welcome to Autodesk’s 3ds Max Forums. Share your knowledge, ask questions, and explore popular 3ds Max SDK, Maxscript and Python topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Mirror an object by rotation

9 REPLIES 9
Reply
Message 1 of 10
Radush
882 Views, 9 Replies

Mirror an object by rotation

Friends, I have a script that perfectly mirrors the position of the left leg to the right (in this case, these are not bones, but regular points). Does anyone know what a command would look like that would do the same thing, only with rotation? Don't forget that all objects are in a hierarchy. I would appreciate any help, Thank you.

 

Original script:

(
-- Define the left and right objects directly
leftObj = $'CThigh_Controller_L'
rightObj = $'CThigh_Controller_R'
 
-- Mirror the position
mirroredPos = [leftObj.pos.x * -1, leftObj.pos.y, leftObj.pos.z]
rightObj.pos = mirroredPos
)
9 REPLIES 9
Message 2 of 10
denisT.MaxDoctor
in reply to: Radush

Your question is unclear, which is why no one has answered it yet. Mirroring or symmetry always needs an axis or plane to be defined, showing where the mirror happens. In MAX, rotations use quaternions, which are like matrices. Their symmetry is usually controlled by scaling.

Please check your question and add more details so we can understand what you need.

Message 3 of 10
Radush
in reply to: denisT.MaxDoctor

I’ve attached two example images below. In the first one, the joints of my character’s left-hand finger are stretched, and to mirror these changes on the right-hand finger, I use the code I mentioned earlier. There are no issues with this task. In the second image, besides the finger being stretched, it is also bent, and this is where the problem arises when trying to mirror this pose onto the right hand. The code above doesn’t account for the rotation, it only works with the position

Message 4 of 10
Radush
in reply to: Radush

Does anyone know the answer?

Message 5 of 10
leeminardi
in reply to: Radush

Edit 10/1/2024:  I found an error in my code and have removed my comment.

Edit 10/2/2024:  I'm not very experienced with Maxscripts but perhaps the following can help you with mirroring the action of one object based on the position and rotation of another.

In the scene below a transform script is used to position and rotate the "lefthand" object based on the  position and rotation of the "righthand" object relative to the YZ plane of a dummy object.  The two objects are linked to the dummy.

leeminardi_0-1727876636507.png

 

 

lee.minardi
Message 6 of 10
Radush
in reply to: leeminardi

Dear friend,

You’ve done an incredibly interesting and complex job. The result is amazing, and I thank you for it! It’s truly an unusual solution that I’m sure will come in handy in the future. However, at the moment, my task is a bit different and, in my opinion, much simpler. I think there might have been a misunderstanding. My task is simply to copy the rotation of the left finger and mirror it onto the right one. There’s a similar option in Biped, where you can copy the position of the right hand and paste it onto the left. Nevertheless, you’ve done an impressive job, and I’ll definitely use your solution in the future. Thank you!

Message 7 of 10
denisT.MaxDoctor
in reply to: Radush

OK... let's start from the basics.
Here is how to mirror transform in an absolute (world) coordinate system:

 

 

 

 

 

fn getMirrorTM axis = 
(
	MIRROR_TM_X = matrix3 [-1,0,0] [0, 1,0] [0,0, 1] [0,0,0]
	MIRROR_TM_Y	= matrix3 [ 1,0,0] [0,-1,0] [0,0, 1] [0,0,0]
	MIRROR_TM_Z	= matrix3 [ 1,0,0] [0, 1,0] [0,0,-1] [0,0,0]

	xtm = case axis of 
	(
		#x: MIRROR_TM_X
		#y: MIRROR_TM_Y
		#z: MIRROR_TM_Z
   default: matrix3 1
	)
)

fn mirrorTransform mat axis:#x = 
(
	mat *= getMirrorTM axis
)

delete objects

t0 = teapot rotation:(eulerangles -30 -10 -150) pos:[-60,10,10] wirecolor:green
t1 = copy t0 transform:(mirrorTransform t0.transform axis:#x) wirecolor:blue

 

 

 

 

 


 

Message 8 of 10

the next is to mirror in a specified coordinate system:

fn getMirrorTM axis coords:(matrix3 1) = 
(
	MIRROR_TM_X = matrix3 [-1,0,0] [0, 1,0] [0,0, 1] [0,0,0]
	MIRROR_TM_Y	= matrix3 [ 1,0,0] [0,-1,0] [0,0, 1] [0,0,0]
	MIRROR_TM_Z	= matrix3 [ 1,0,0] [0, 1,0] [0,0,-1] [0,0,0]

	xtm = case axis of 
	(
		#x: MIRROR_TM_X
		#y: MIRROR_TM_Y
		#z: MIRROR_TM_Z
   default: matrix3 1
	)
	xformmat xtm (inverse coords)
)

fn mirrorTransform mat axis:#x coords:(matrix3 1) = 
(
	mat *= (getMirrorTM axis coords:coords)
)

delete objects

t0 = teapot rotation:(eulerangles -30 -10 -150) pos:[-60,10,10] wirecolor:green

coords = point rotation:(eulerangles 0 45 0) pos:[-10,0,60] axistripod:on cross:on wirecolor:orange 

t1 = copy t0 transform:(mirrorTransform t0.transform axis:#x coords:coords.transform) wirecolor:blue
Message 9 of 10

What is next? 
... mirror in the parent space
... mirror scale-rotation-part only
... mirror and reset scale

But I'm not sure if I should open a Matrix Algebra class on this forum.

Message 10 of 10
Radush
in reply to: denisT.MaxDoctor

Denis, thanks to you the problem has been solved. Thank you! And here is the solution itself with my objects in the scene:

 

-- Mirror image of left to right rotation:
leftController = $CClavicle_Controller_L
rightController = $CClavicle_Controller_R
 
-- Function to get mirror matrix
fn getMirrorTM axis = 
(
MIRROR_TM_X = matrix3 [-1,0,0] [0, 1,0] [0,0, 1] [0,0,0]
MIRROR_TM_Y = matrix3 [ 1,0,0] [0,-1,0] [0,0, 1] [0,0,0]
MIRROR_TM_Z = matrix3 [ 1,0,0] [0, 1,0] [0,0,-1] [0,0,0]
 
case axis of 
(
#x: MIRROR_TM_X
#y: MIRROR_TM_Y
#z: MIRROR_TM_Z
default: matrix3 1
)
)
 
-- Function to mirror the transform
fn mirrorTransform mat axis:#x = 
(
return mat * getMirrorTM axis
)
 
-- Get the current transform of the left controller
leftTM = leftController.transform
 
-- Mirror it along the X axis
mirroredTM = mirrorTransform leftTM axis:#x
 
-- Apply the mirrored transform to the right controller
rightController.transform = mirroredTM
 
--------------------------------------------
-- Mirror image of right to left rotation:
rightController = $CClavicle_Controller_R
leftController = $CClavicle_Controller_L
 
-- Function to get mirror matrix
fn getMirrorTM axis = 
(
MIRROR_TM_X = matrix3 [-1,0,0] [0, 1,0] [0,0, 1] [0,0,0]
MIRROR_TM_Y = matrix3 [ 1,0,0] [0,-1,0] [0,0, 1] [0,0,0]
MIRROR_TM_Z = matrix3 [ 1,0,0] [0, 1,0] [0,0,-1] [0,0,0]
 
case axis of 
(
#x: MIRROR_TM_X
#y: MIRROR_TM_Y
#z: MIRROR_TM_Z
default: matrix3 1
)
)
 
-- Function to mirror the transform
fn mirrorTransform mat axis:#x = 
(
return mat * getMirrorTM axis
)
 
-- Get the current transform of the right controller
rightTM = rightController.transform
 
-- Mirror it along the X axis
mirroredTM = mirrorTransform rightTM axis:#x
 
-- Apply the mirrored transform to the left controller
leftController.transform = mirroredTM
 

This works in the global coordinate system. Unfortunately, I did not understand the local system, but it is not a big deal since my rig is attached to Biped, I get local coordinates by activating the Biped editing mode:

 

-- Figure Mode
$Bip001.controller.figureMode = true
-- Deactivate Figure Mode for Biped
$Bip001.controller.figureMode = false

 

Again, a huge THANK YOU!!!

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report