convert right-hand rotation to left-hand rotation

Started by
12 comments, last by Buckeye 14 years, 1 month ago
I've found an example or two via google searches but it's in complicated math notation. It goes right over my head. Can anyone explain how to do the conversion?
Advertisement
Quote:I've found an example or two via google searches but it's in complicated math notation. It goes right over my head.

Can anyone explain how to do the conversion?
Can you post links to one or more of the references you found?

Changing the handedness of a rotation isn't really a well-defined operation (not as I understand it at least). In some contexts, it might simply mean negating the angle of rotation. In other contexts it might mean negating the angle of rotation and flipping the axis of rotation across one of the cardinal planes. In any case, the operation is dependent on context (a rotation, taken by itself, does not have an inherent handedness, so asking how to change the handedness without providing any context isn't particularly meaningful).

Can you describe the exact problem you're trying to solve?
Quote:Original post by jyk
...so asking how to change the handedness without providing any context isn't particularly meaningful).

Can you describe the exact problem you're trying to solve?
My apologies. For me this is such new territory to the point I don't even know how to properly ask the question.

I wrote a joint animation class that uses the joint animation data from MilkShape. MilkShape's data is all right-hand. Since my engine uses DirectX, it needs to be converted to left-hand.

Converting mesh data from right-hand to left-hand is no problem. We're good there. Since I finished my joint animation class, I discovered that I need to convert the key-frame rotations from right-hand to left-hand.

From what I've read, my understanding is that I need to use a matrix along with flipping and rearranging the data (-X,Z,Y) to accomplish this. I've implemented -X,Z,Y with the rotation values and that alone almost seems to work but not entirely.

So my problem is I don't fully understand what needs to be done to do the conversion.
What's the result look like??? <=== this would help greatly!
-------------------------------------All my life all I ever wanted to be was, Gangsta!
Quote:Since my engine uses DirectX, it needs to be converted to left-hand.
For what it's worth, that's not actually true; you can use a right-handed coordinate system with DirectX/D3D if that works better for your application.
Quote:From what I've read, my understanding is that I need to use a matrix along with flipping and rearranging the data (-X,Z,Y) to accomplish this. I've implemented -X,Z,Y with the rotation values and that alone almost seems to work but not entirely.
Are the rotations/orientations that you're wanting to convert in Euler-angle form?
Quote:Original post by jyk
Are the rotations/orientations that you're wanting to convert in Euler-angle form?
yes. In another forum, it was suggested that I convert the euler angles to quaternion, do the conversion and then convert it back to euler.

euler->quaternion

tmp_quaternion = quaternion
quaternion.x = -tmp_quaternion.x
quaternion.y = tmp_quaternion.z
quaternion.z = tmp_quaternion.y

quaternion->euler

I found some code and was able to do the above. Problem was, going through all that was no different then just taking the euler angles and doing the same thing with them. I had a feeling I would get the same thing back.

There must be something else I need to do.
Don't know if this information will help or not. It may give you some hints. So, for what it's worth..

As an ongoing project, I've managed to import SMD (ValveSource) animation files (RH) created in XSI, and export them to animation x-files (LH). Note, however: it results in a mirror reflection of the XSI animation but the rotations and skinweighting result in a non-FUBAR animation. I.e., if I animate the left side of the mesh in XSI, it displays as a right side animation in DX. For the time being, it's better than nothing.

[ I'm still working on a full RH-to-LH conversion but, so far, am unsuccessful ]

By examination of the imported mesh vertices, the mesh is oriented with up = +Z. I export that to DX with a mesh transformation of identity. I make no further changes to any imported coordinates or rotations and it renders and animates because the frame (bone) transforms, as imported, are oriented up = +Z also. If I use the mesh transform as imported, things are FUBAR. My rendering world is up = +Y, so I set my mesh world matrix during rendering to orient it appropriately.

So, first thing to do is ensure that the mesh orientation matches the bone/joint orientation.

I don't know what MilkShape exports but there are several parameters and matrices that may need to be generated.

You may have to play with the tex coords for each vertex. You might try something like exportTV = 1.0f - importTV. That, of course, depends entirely on how the texture is mapped to the mesh in MilkShape.

The skinweights in DirectX have an offset matrix. That offset matrix is what "moves" the mesh vertices to the weighted bone/joint space. In my import data, that offset matrix for each joint is local and not global. That is, to calculate the offset matrix for each bone iteratively:

offsetTmp = localOffset * parent localOffset * parent's parent localOffset..

skinweight offset = inverse(offsetTmp)

I export the animation matrices to DX for the joints "as-is." They are also local, but, during the DX animation, I combine the frame transforms before calculating the final transforms for rendering.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

In general, if you have a transformation T relative to one coordinate frame F1 and you want it relative to another coordinate frame F2 then you have to do the following:
1. Transform the vector/point relative to the coordinate frame F2 to the coordinate frame F1. Let M be this transformation.
2. Transform the vector in the coordinate frame F1. The transformation is T.
3. Transform back the resulting vector to the original coordinate frame F2. This is M-1. If M is an orthogonal (as in your case) you simply need the transpose.
The transformation is therefore vMTM-1 using the convention of DirectX to use row vectors.

EDIT: Consider for example the frames F1 = {X, Y, Z} and F2 = {-X, Z, Y} and the rotation around the last axis in F1 of an angle θ. If you have a vector v = (v1, v2, v3) relative to F2, the transformation is:
M = [-1 0 0; 0 0 1; 0 1 0]
T = [cos(θ) -sin(θ) 0; sin(θ) cos(θ) 0; 0 0 1]
M-1 = M-1 = M
Therefore the rotation is:
MTM = [cos(θ) 0 sin(θ); 0 1 0; -sin(θ) 0 cos(θ)]



[Edited by - apatriarca on February 12, 2010 11:08:19 AM]
Apology to howie_007 for hijacking the thread for a moment.

apatriarca:

Two questions-

1. The transformation needed in this case is, given a vector v and a rotation r about an axis in F1, to transform v and r to F2. Is it correct to assume that v' = vMT, and r' = MT?

2. Would you explain (generalize) the derivation of T?

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

The transformation T is your function (transformation) in the original frame F1. So in your example the transformation T is your axis angle rotation. You just need to convert it to matrix form and perform the basis change. v is just a generic vector (the ones you are going to transform at runtime).

The idea is that you have a function(transformation) T that takes as input vectors/points in F1 and ouputs vectors/points in F1 transformed. But your engine wants vectors/points in F2 and ouputs in F2 space. So you perform the basis change in your function so it accepts vectors/points in F2 and ouputs them in F2 too. That process is the one explained by apatriarca, known as change of basis in linear algebra.

In the change of basis process what you need to calculate is M and it's inverse. When talking about a right-handed to left-handed conversion is as simple as a reflection transform and it's inverse.

This topic is closed to new replies.

Advertisement