Notifications
Clear all

[Closed] Offset transform an axis with a matrix

Hi, I’m trying to do a real time transform on some object when I move a Slider
the problem is I have 3 sliders, one for each axis, and every time I construct a new matrix it overrides the old one.
Right now, what I’m doing is basically:
make a rotation matrix.
multiply it by the stored original transformation.

What I need:
make a rotation Matrix in which I take into account the current rotation OFFSET of the 2 axis I’m not modifying but leave the current axis at it’s identity value, then multiply this by the original transform that I have stored somewhere.

I thought this would be possible multiplying the current transform by the inverse of the stored original transform and then multiplying this by the rotation matrix and then multiply the resulting matrix by the stored original transform.

this did not give me the result I wanted, even when I replaced the corresponding axis by it’s identity equivalent.

Anyone has any tips that might help?

19 Replies

do you want to translate the transform in its own coordinates (local) or in world?

I’m doing both.
I’m applying the translation at the end, right now I’m dealing with rotations and all matrices have the 4th row at 0,0,0.
if it’s only local I guess it’s simpler, I just store and reasign after the transformation the 2 axis that i’m not using, but if it is a world transform I don’t know how to do it.
Maybe it’s a matter of transforming the matrices to world space doing the previously mentioned operation and going to local space after that?

since you use a slider does it mean you want to move an object in a ranged area only?

Yeah, from -360 to 360

I tried composing a rotation matrix with the 3 rotation values every time a slider changes, that almost worked but one oxis would get weird, it seems that it would blend the values of the other two into its value.

in the local space everything is simple…
here is how we can do it the world space:

try (destroydialog Transformer) catch()
rollout Transformer "Transformer by denisT" width:200
(
	local originTM = Matrix3 1
	
	group "Position: "
	(
		slider pos_x "X" width:190 range:[-100,100,0]
		slider pos_y "Y" width:190 range:[-100,100,0]
		slider pos_z "Z" width:190 range:[-100,100,0]
	)
	group "Position: "
	(
		slider rot_x "X" width:190 range:[-180,180,0]
		slider rot_y "Y" width:190 range:[-180,180,0]
		slider rot_z "Z" width:190 range:[-180,180,0]
	)
	
	button hold_tm_bt "Hold Transform" width:190 
	button reset_tm_bt "Zero Offset" width:190 
	
	fn transformNode node: = 
	(
		if node == unsupplied do node = selection[1]
		if isvalidnode node do
		(
			rotTM = (eulerangles rot_x.value rot_y.value rot_z.value) as matrix3
			posTM = originTM * (transmatrix [pos_x.value, pos_y.value, pos_z.value])
			tm = originTM * rotTM
			tm.pos = posTM.pos
			
			node.transform = tm
		)
	)
	
	on pos_x changed val do transformNode()
	on pos_y changed val do transformNode()
	on pos_z changed val do transformNode()

	on rot_x changed val do transformNode()
	on rot_y changed val do transformNode()
	on rot_z changed val do transformNode()
		
	on hold_tm_bt pressed do if isvalidnode (node = selection[1]) do
	(
		originTM = node.transform
		rot_x.value = rot_y.value = rot_z.value = pos_x.value = pos_y.value = pos_z.value = 0
	)
	on reset_tm_bt pressed do if isvalidnode (node = selection[1]) do
	(
		rot_x.value = rot_y.value = rot_z.value = pos_x.value = pos_y.value = pos_z.value = 0
		transformNode()
	)
)
createdialog Transformer

with redraw off
(
	delete objects
	d = dummy name:#target pos:(random -[10,10,10] [10,10,10]) dir:(random -[1,1,1] [1,1,1]) isselected:on
)




press “Hold Transform” any time when you want to start a new “transformation” session

That is great!, I was doing something similar with rotateYPRMatrix but this is better.
I didn’t know you could Cast eulerAngles as Matrices, that is really cool!

the problem I’m having now is with local space, I’m getting some kind of gimbal lock

using your example, what I did is invert the order of the space conversion:


tm = rotTM * originTM
tm.pos = posTM.pos
			
node.transform = tm

I tried with controllers but I still get the lock if I want to make an offset.
How would you recomend I aproach it using Matrices?
assuming that Matrices are the way to go.

in local space just needs to change order of matrix multiplication:
from

			posTM = originTM * (transmatrix [pos_x.value, pos_y.value, pos_z.value])
			tm = originTM * rotTM

 

to

			posTM = (transmatrix [pos_x.value, pos_y.value, pos_z.value]) * originTM
			tm =  rotTM * originTM

no… rotation has to be handled differently. but without MAX i can’t write the code that will works right for sure

Page 1 / 2