Attachment offsets and converting coordinate systems

I am working on a tool to export the item attachment data for our game.
I am doing this in max script with transform matrix 3 objects.

Essentially , I need to:

1.) get the item’s’ offset position and rotation from its parent bone
2.)convert the results form Max’s Z up right handed coordinates to the engine’s y-up left handed coords.

I was able to find a z-up to y-up matrix in an old CG Talkthread but I am not sure about the right to left hand thing.

so far I have


--caluculate the offset
zUpOffset=obj.transform*(inverse bone.transform)

--convert the matix form z up to y up
z2yUpMatrix=matrix3[1,0,0][0,0,1][0,-1,0][0,0,0]
yUpOffset=zUpOffset*z2yUpMatrix


--get Pos and Rot values out of xForm

offsetPos=offsetXform.translationpart
offsetRot=offsetXform.rotationpart as Eulerangles

xPos=offsetPos.x 
yPos=offsetPos.z 
zPos=offsetPos.y
	
xRot=offsetRot.x
yRot=offsetRot.y
zRot=offsetRot.z


the results are not working however.
I suspect it’s the missing Right hand to Left hand bit, but I’m not certain.

at StackOverflow I found this:

If your matrix looks like this:
{ rx, ry, rz, 0 }
{ ux, uy, uz, 0 }
{ lx, ly, lz, 0 }
{ px, py, pz, 1 }
To change it from left to right or right to left, flip it like this:

{ rx, rz, ry, 0 }
{ lx, lz, ly, 0 }
{ ux, uz, uy, 0 }
{ px, pz, py, 1 }

so I gatherthat converting matrices form Right handed to Left involves swapping the y and z values.
Then there’s this

This Matrix changes the Y and Z components of a Vector

Matrix mToggle_YZ = new Matrix(
{1, 0, 0, 0}
{0, 0, 1, 0}
{0, 1, 0, 0}
{0, 0, 0, 1})

but that’s a 4x4 matrix and Max scripts Matrix3 objects are 3x4
I am guessing the “missing column” in max is the homogenous coordinate unused for object transforms
If my guess is correct then :


right2left=matrix3[1,0,0][0,0,1][0,1,0][0,0,0]

but I really am out of my depth…and it doesn’t work either

a much discussed question

a 4x3 is a the same as a 4x4 where the right hand column is is 0 0 0 1 ( this assumes no shear). A left to right transformation is not just as swap, it’s also a negative scale (as you can see if you look at the example in the thread above)

a b c
d e f
g h i
k l m

=

a b c 0
d e f 0
g h i 0
k l m 1

thanks theodox…that thread linked to Dubber’s Blog post which presented a simple solution to finding the needed matrix in Max.

namely, creating a point helper and rotating it to reflect the new coordinate system,
then using the helpers transform to multiply the object’s transform into game space.

But!

While I can rotate a point helper to get y-up ,the x axis also needs flipped to get from Z-up(right hand) to Y-up (left hand)
I can only achieve the x axis orientation this way by -100 x scale, which Is not desired.

We’ve always had to detach those props and put their parent at the origin for exporting. Not a very slick solution.

if you think about it, there’s no combination of moves and rotations you could do to your left hand to make it become your right hand (or vice versa) - there’s going to be a (painful) negative scale in there somewhere.

The standard wimp out is to group the entire hierarchy to an identity transform and then apply the transformation to that - everything down the hierarchy will be right (except potentially for things like inverted normals).

ugh, I have spent more time than I expected trying to resolve this.

I have a system that gives correct offsets for position and rotation, but only when the parent bone pivot and the attached object pivot have similar orientations.

unfortunately the Y axis of the left and right hand bones are flipped (an artifact of Max’s bone mirroring )
so the solution won’t work for both hands

I need a method for comparing 2 pivots and seeing if they are oriented simlarly…

I’m at a point now where the numbers are right , but +/- is flipped for one hand. any ideas?

Are you transforming geometry, hierarchy or both?

Just transforming geometry I belive…

problem was solved but strangely, to me. The basic algorithm that seems to work in our case (for left and right hand cases) is:


		offsetXform=obj.transform*(inverse theBone.transform)
		
		offsetPos=offsetXform.translationpart
		offsetRot=offsetXform.rotationpart as Eulerangles
		
		xPos=roundFloat offsetPos.x 
		yPos=roundFloat offsetPos.y 
		zPos=roundFloat ( offsetPos.z )*-1--this is the odd part
			
		xRot=(roundFloat offsetRot.x)-90 --this offset is use on all game assets for reasons known only to our programmer
		yRot=roundFloat offsetRot.y 
		zRot=roundFloat offsetRot.z 

Now that I think of it, Maybe what is really happening is this:
the -90 X rotation introduced by the engine programmer was a hack to change from Z up to Y up,
whose shortcomings only became apparent in the attachment system.
I can sort of see that rotating X 90 degrees and inverting Z might look like Z-up to Y-up.