Organizing matrices

Started by
8 comments, last by Zakwayda 14 years, 12 months ago
Hi I am working on a basic 3D-object class but I haven't found any information on how one usually organize the matrices. Should I use one matrix and just translate/rotate this matrix in the rotate() and translate()-functions of the objects? E.g.:

private SMatrix4x4 matrix;


// Object-functions rotateX() 
public void rotateX(float theta) {
    SMatrix4x4 rotation = new SMatrix4x4();
    rotation.setRotation(theta, 0.0f, 0.0f);
    
    matrix = SMatrix4x4.mul(rotation, matrix);
}
Or should I have one translation-matrix and one rotation-matrix and multiply these together in the e.g. getTransformedMatrix-function in my class? Thanks for any replies :)
Advertisement
You can do it however you want - just do whatever you think will work best given the context. One caveat: if you're going to be applying incremental rotations (which you appear to be doing in your example), be sure to normalize the results occasionally to prevent drift.

As for what representation to use, here are a few options:

- A single 4x4, 3x4, or 4x3 matrix
- A 3x3 matrix and a translation vector
- A quaternion and a translation vector
- A set of Euler angles and a translation vector (often not the best choice)

There are other options as well, but the above are all fairly common choices.
Ok, guess I'll try and implement a vector position + quaternion aproach then.

Tried a little but got few issues. It seems like the object is rotate just a few degrees CW now. When I do object.rotateY(360.0f) it will rotate allright, but I don't see why the object is rotated at the start (the rotation quaternion is set to ((0.0, 0.0, 0.0) 1.0)).

Also the rotation seems to be counter clockwise?


Here is the (pseudo)code.

private SVector position;private SQuaternion rotation;...public void rotateY(float theta) {    theta = MathUtil.degreesToRads(theta);    SQuaternion rotY = fromAxisAngle(new SVector(0.0f, 1.0f, 0.0f), theta);    rotY.normalize();    rotation = rotY * rotation;}...// This is fead to the glPushMatrix()public SMatrix4x4 getMatrix() {    SMatrix4x4 matrix = rotation.toMatrix();    matrix.setTranslation(position);    return matrix;}



If the quaternion is identity, the object should not be rotated relative to its default orientation. Are you sure your toMatrix() function is correct?

Also, you don't need to normalize rotY after building the rotation (it will already be unit length, within numerical limits).

Finally, can I ask what math library you're using? In particular, I'm curious what the 'S' prefix indicates.
I'll double-check the toMatrix-function and see if there are any errors there.

I am using my own math library (as a part of my little java 3D-engine project :P).

I use the S-prefix because I named the project "Skuld" :)
using quaternions like youre doing there is gonna result in slower code (from a quick glance Ild say that would be at least twice as slow)
Mkae it easy on yourslef stick to matrices

Ild just use 4x4 matrices first off + then see later if u wanna save some memory
Quote:using quaternions like youre doing there is gonna result in slower code (from a quick glance Ild say that would be at least twice as slow)
I'm curious as to why you say that. The question of which is 'faster' or 'slower' (quaternions or matrices) is highly context-dependent, so I don't think we can really make that evaluation based on the bits of code the OP has posted.

Also, even the posted code doesn't look to me like it would suffer too much from the use of quaternions. The function rotateY() is actually likely to be slightly more efficient than the equivalent matrix version would be (not that it's likely to matter). You pay for this of course when it comes time to convert the quaternion to matrix form, but whether this comes out as a win or a loss depends, again, on the context.

I agree that sticking with matrices could be a better choice, but not necessarily for performance-related reasons. (And I'm still curious as where the 'twice as slow' estimation comes from - maybe I'm missing something?)
I don't see how it can be twice at slow. There are not that much more operations involved in my quaternion-based code than my matrix-implementation.

I guess I'll stick with quaternions anyway, mainly because I need to learn how to use them (especially for interpolation and skelleton animation).

The main reason I am making a game engine is to learn anyway :)

Getting a specified axis of the rotation is just making a an axis-vector and transforming it by the rotation quaternion? Seems like this worked for me (but again I am on thin ice now so I don't want to use any code that works out of luck :P):

SQuaternion rotation;...// Rotating the object around its own yAxis:public void rotateY(float theta) {    theta = MathUtil.degreesToRads(theta);    SVector yAxis = new SVector(0.0f, 1.0f, 0.0f);    yAxis.transformQuat(rotation);    SQuaternion yRot = fromAxisAngle(yAxis, theta);    rotation = yRot * rotation;}// Translate the object using its zAxispublic void translateZAxis(float dz) {    SVector zAxis = new SVector(0.0f, 0.0f, 1.0f);    zAxis.transformQuat(rotation);    zAxis.mul(dz);    translate(zAxis);}


There are getXAxis/getYAxis/getZAxis-functions in my quaternion-class. I just showed it here to see if it is was right.
Found out why the model was rotate just a little: I was rendering the wrong keyframe :P

Anyway, the code seems to work now (and my rotation-functions are only 2 slim lines).

Is there any effective ways to implements a lookAt-functions with the rotation-quaternioen. E.g. rotating an object around the yAxis so it faces an object/point, and rotating the camera to look at an object (without moving it).
Quote:Getting a specified axis of the rotation is just making a an axis-vector and transforming it by the rotation quaternion?
Yes, you can do it that way. You can also convert the quaternion to a matrix and grab all three axes at once (they will be the rows or columns of the matrix).
Quote:
SQuaternion rotation;...// Rotating the object around its own yAxis:public void rotateY(float theta) {    theta = MathUtil.degreesToRads(theta);    SVector yAxis = new SVector(0.0f, 1.0f, 0.0f);    yAxis.transformQuat(rotation);    SQuaternion yRot = fromAxisAngle(yAxis, theta);    rotation = yRot * rotation;}


There are getXAxis/getYAxis/getZAxis-functions in my quaternion-class. I just showed it here to see if it is was right.
That should work, but you can actually achieve the same results by simply changing the multiplication order, e.g.:
public void rotateY(float theta) {    theta = MathUtil.degreesToRads(theta);    SQuaternion yRot = fromAxisAngle(0.0f, 1.0f, 0.0f, theta);    rotation *= yRot;}
Quote:Is there any effective ways to implements a lookAt-functions with the rotation-quaternioen. E.g. rotating an object around the yAxis so it faces an object/point, and rotating the camera to look at an object (without moving it).
There are certainly ways to rotate an object towards a target using quaternions, but for actually building a 'look-at' rotation, the easiest thing to do is to use the standard algorithm to generate a look-at matrix, and then convert the matrix to a quaternion.

This topic is closed to new replies.

Advertisement