Loch's picture

A Hybrid Rotation Rule

Let me preface this by saying I am new to 3D graphics and my brain is crammed with matrix/quaternion and various math functions trying to figure this out. Along the way I came across Tao, which lead me here. I've read the documentation PDF, done a few searches, read some forum posts, tried a few things in a simple app.. and now my head has exploded. I now request help. :)

I want to create a little 3D space in one of my apps that takes user input to rotate a cube. Seems easy enough. However, the rules for rotation aren't (to me).

1. The Z-Axis rotation needs to be relative to the environment.
2. The X- and Y-Axis rotations need to be relative to the cube itself.

I have an additional requirement to allow the user to spin the cube with their mouse (I'll get ArcBall going for this, I think) and update the user's input fields with the correct rotational values for that new orientation.

So.. pseudocode time!

void ScrewyRotation() {
    float rotX = (float)txtBoxX.Text;
    float rotY = (float)txtBoxY.Text;
    float rotZ = (float)txtBoxZ.Text;
    Vector3 finalVector = math.to.determine.desired.rotation.somehow(rotX,rotY,rotZ);
}
void UpdateRotationFieldsBecauseUserPlayedWithTheirMouse(){
   float cubeX = determine.the.X.rotation.relative.to.the.objects.natural.Z.axis;
   float cubeY = determine.the.Y.rotation.relative.to.the.objects.natural.Z.axis;
   float cubeZ = determine.the.Z.rotation.relative.to.the.environment;
   txtBoxX.Text = cubeX.ToString();
   txtBoxY.Text = cubeY.ToString();
   txtBoxZ.Text = cubeZ.ToString();
}

My gut tells me that I'd need to maybe do the rotation twice.. once on the world-Z and then once on the object-X-Y.

To get from mouse back to text, I have a feeling that I have to somehow figure out the math required to rotate the object's X and Y back to zero and then figure out what it's Z is at that point.

If anyone has a clue what I'm talking about and wouldn't mind giving me a quick rundown on how to do this, it would go a long way towards restoring my sanity.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
nythrix's picture

I have never done this but I'll give it a go.

This pseudocode should be pretty much self-explanatory. X and Y axes are transformed to give their local counterparts. Z is not. With these three update the total transformation matrix.

// during initialization
Matrix4 transform = Matrix4.Identity;
// somewhere in the drawing/update/whatever loop
Matrix4 rotXMat = Matrix4.CreateFromAxisAngle(transform * new Vector3(1, 0, 0), rotX);
Matrix4 rotYMat = Matrix4.CreateFromAxisAngle(transform * new Vector3(0, 1, 0), rotY);
Matrix4 rotZMat = Matrix4.CreateFromAxisAngle(new Vector3(0, 0, 1), rotZ);
// update the total transformation matix
transform = rotXMat * rotYMat * rotZMat * transform;
// use transform for drawing
GL.LoadMatrix(transform);

Note that I give no guarantee for this. It's just something that popped inside my head. I'm particularly unsure about the order of operands in the last equation. So you could try fiddling with that.

Instead of rotation matrices you could also go for quaternions. Should work the same.