My first matrix

I’ve tried to create a matrix class that is useful and that i can understand (as I can’t quite grasp anyone else’s classes).

My matrix class is only designed to be used by opengl commands so I probably won’t need to know a lot to make it work.

I’ve done a lot of groundwork before posting and have read a lot of matrix articles. I’m stuck on one point though.

So far I have a camera and an object matrix. The way I understand this is that the object matrix represents a local coordinate system. It’s translation moves the local coordinate system around in world space. (Mhen multiplied).

I rotate my object around the Z axis(roll) by 45deg then rotate around the Y axis 45 deg(yaw) then tell it to move down the Z axis X units. This seems to squish the object at the object remains on the z plane.

Here are some code samples to show what I’m doing:

inline void CMatrix::Yaw(const float a_Degrees)
{
float Radians = Degrees2Radians(a_Degrees);
float c = Cos(Radians);
float s = Sin(Radians);

m[0] = c;
m[2] = -s;
m[8] = s;
m[10] = c;
}
and

inline void CMatrix::Forward(const float a_Units)
{
m[12] = m[8] * a_Units + m[12];
m[13] = m[9] * a_Units + m[13];
m[14] = m[10] * a_Units + m[14];
m[15] = m[11] * a_Units + m[15];
}

inline void CMatrix::Roll(const float a_Degrees)
{
float Radians = Degrees2Radians(a_Degrees);
float c = Cos(Radians);
float s = Sin(Radians);

m[0] = c;
m[1] = s;
m[4] = -s;
m[5] = c;
}

and this is how I’d like to use my matrix:

glMatrixMode(GL_MODELVIEW);
CMatrix Camera = -Viewer;
glLoadMatrixf(Camera);

glPushMatrix();
glMultMatrixf(Object1);
glColor3f(0,0,1);
glRotatef(180,0,1,0); //Glut cone is back to front
glutWireCone(0.5,1,10,6);
glPopMatrix();

Can anyone see where I’m going wrong?

I also have another problem with that code while it’s up, I can’t seem to work out how to rotate multiple times. How do I take the rotation I have, then ‘add’ another rotation to it. I assume I’ll need to renormalise at some point. Do I renormalise all the 9 elements together or each vector seperatly?

Many, many thanks. (I really need to work this out.

Chris

[This message has been edited by gimp (edited 02-26-2001).]

My best estimation is that you are not using correct translation matrixes. I don’t understand where you got the whole:

inline void CMatrix::Forward(const float a_Units)
{
m[12] = m[8] * a_Units + m[12];
m[13] = m[9] * a_Units + m[13];
m[14] = m[10] * a_Units + m[14];
m[15] = m[11] * a_Units + m[15];
}

function from… all the translation matrixes I have seen are in the form:

1 0 0 0;
0 1 0 0;
0 0 1 0;
x y z 1;

so if you m[8]-m[11] are anything but 0’s or 1’s, you have some odd sort of matrix. Your code looks good as far as theory goes. If you want multiply translation/rotations/ect to affect you camera, you simply need to multiply your camera matrix by each in order.

Please note: that camera motion is inverse of percieved motion, meaning you need to translate/rotate it like a normal object, then invert it before passing it to glLoadMatrixf to get correct motion.

GL (goodluck)

Yeah, why are you using m[15]? Do a search on multmatrix on this board, and you will find a ~90 thread message that has all this stuff in it. Your modifying the wrong elements is your first problem. For rotations, after you have your rotation matrix made, you could use that again, or just rebuild one again. It depends what you want done.

Elixer, should we just run a faked discussion here?

LOL

It is too bad we can’t “flag” certain messages that are helpfull to lots of people. Maybe the board operator can make a “FAQ” section, and then move all the helpfull messages to that area?

I’m sorry I only partialy get what your talking about… Are you suggesting keeping this thread running so you don’t see it appear again by a different person in a few days?

I have missed the point when it comes to m15, I have no idea as to what it’s for. I think the 4th member of a vector normally has something to do with scaling… No idea with matricies.

I DID have a look for the 90 post thread, though the search engine doesn’t show how many posts each topic has, does anyone know a word that would be in there other than ‘matrix’ ?

I’ve also been reading as much as I can relating to this subject though books I have like “3D Game Engine Design”,“Real time rendering”,“OpenGL(Red Book)”,“3D Graphics Programming” + a few other books all seem to jump from basics to advanced. I know how to invert(transpose?) a matrix but not move a local coordinate system.

My forward example was trying to simplfy my case, obviously a local transform can be handled just as easily(in fact Forward should probably reimplement a generic local transform)

A faq would be great that covers in detail the structure of a matrix, I’ve seen nothing on the net that does this. (Yes, I also have hexapods matrix & Quat faq)

I’d really love to learn this stuff, My curiosity has been awakened to all this cool math stuff I’ve been getting in to recently to the point where I’m thinking about finaly going to uni(after 10+ years since HS).

The reason I’m asking about this is I’m building a scene graph and want each object to store it’s matrix so I can transform them quickly (ie a turret on a tank is easily positioned relative to the tank). I’d also like to be able to jump my camera between objects so at some point I’ll probably need to learn how to apply projective transforms, but one step at a time huh?

I have found many Matrix Class example but non have a member function that does transform that are affected by local rotations. Am I missing something?

Many thanks

Chris

Can someone help me find that 90 post thread?

Do search multmatrix. I find there.

try this for the old thread
http://www.opengl.org/discussion_boards/ubb/Forum2/HTML/002537.html

As far as:

inline void CMatrix::Forward(const float a_Units)
{
m[12] = m[8] * a_Units + m[12];
m[13] = m[9] * a_Units + m[13];
m[14] = m[10] * a_Units + m[14];
m[15] = m[11] * a_Units + m[15];
}

It makes perfect sense to me… why doesn’t it make sense to anyone else? He’s moving the center (local origin) of the matrix (12,13,14 but 15 I’m not so sure) in the direction of the “front” vector (8,9,10 and again I’m not sure about 11) multiplied by a certain distance. If he wanted to do the same only move it in the “up” direction, he’d do the same except instead of 8,9, and 10, he’d use 4,5, and 6. What’s so wrong with that? I realize it may not be what most people do and is a bit unusual but it should work.

Punchey did you by any chance read the ~90 msgs. thread?

Yes, have you? I made several posts in it. Why do you ask?

Sorry Punchey, didn’t mean to sound so harsh, i was just wondering if you wanted to restart the thread
btw i agree with your statemnt above it should work like that…

[This message has been edited by DaViper (edited 03-02-2001).]

Sorry. Yeah, I don’t think that part is the problem because that should translate an object “forward” just fine. I think we might should not “restart” the ~90 post thread as such but rather consolodate all this info into a FAQ of sorts. Because it’s VERY confusing to follow all the posts in that thread, IMHO. Alot of going back and forth. So I think people would probably get more confused than anything. In fact, that’s what one of my posts to that thread was about. There was alot of bickering about the layout of the matrix. And some people just can’t understand why others (less-mathematically minded people) might be confused by representing a matrix by writing it out like you would in a math book and then arguing about how OpenGL represents it. They don’t understand how some people might read their representations a column at a time or a row at a time yielding different results. So, I suggest that whenever we’re reffering to actual OpenGL use of matrices (not purely mathematical discussions) that we use actual array indeces or something more absolute that cannot be mistaken.

Ok, I’ve read the ~90 posts, most of it was a waste of time, a small number came close to what I was after but never hit exactly what I was looking for (unless I’m mistaken). I’ve spent the last week downloading every simple looking matrix class I can find to find one that work that I can disect to see how it works.

What I found :
-Most libraries don’t include rotate ranslate functions as its ‘based on implementation’
-Those that do have working copies require other files that arn’t supplied
-Some seem incomprehensible as they support order of M*N matricies and are generally written as templates
-Other like David Eberly’s are hard to get going without including half his core library then still don’t supply the functions I’m looking for.
-Nate Miller had a simple class but when rotating objects them moving them I get squashed object’s… H hasn’t replied to my mail in 4 days.
-glvelocity had 3 classes, none of which I can get working…

Following is a hunk of code that I’m trying to get working as a basic test, once that works I can start picking the code apart to find out how it works (my usual method of learning)

#include “Matrix.h”
#include <GL/glut.h>

CMatrix Object1;
CMatrix Object2;

void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
glEnable(GL_DEPTH_TEST);

//Pull camera back
Object2.Identity();
Object2.Transform(0,0,6);

//Start object at origin
Object1.Identity();
Object1.RotateY(45);
Object1.Transform(0,0,-2);
Object1.RotateZ(45);
Object1.Transform(0,0,-2);

}

void display(void)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);

//Camera
glMatrixMode(GL_MODELVIEW);
matrix Camera;
Camera = !Object2;
glLoadMatrixf(&(Camera[0]));

//Objects
glPushMatrix();
glMultMatrixf(Object1.m_mat);
glColor3f(0,0,1);
glRotatef(180,0,1,0); //Glut cone is back to front
glutWireCone(0.5,1,10,6);
glPopMatrix();

glutSwapBuffers();
}

void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void keyboard (unsigned char key, int x, int y)
{
switch (key)
{
case 27:
exit(0);
break;
default:
break;
}
}

int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);

glutMainLoop();
return 0;
}

As you can see it’s just a simple little glut app to show what the transforms do. My own class which has evolved a little since the original question seems to fail when doing anything but a single rotation. Once I rotate twice in different directions the glutCone starts getting distorted.

As an example is anyone able to provide a simple matrix class that would work something along these lines? If need be I can post my matrix class for you all to pick apart if thats easier (or just the bits that are related to the problem

Many thanks, I’m getting quite desperate

Chris
(I can’t side step this problem my scenegraph depends on me storing transforms. In the meanwhile I bought a few schaum’s books on trig and linear algebra, but it’s slow going learning all that for such a specific problem)

I’m not sure i understand why you want to create your own matrix manipulation class and not just use the opengl transformation glTranslate and glRotate…

[This message has been edited by DaViper (edited 03-05-2001).]

Well I was wondering that but for instance I have an app that returns a transformation/rotation/scale matrix and I use matrix mult as I assumed that opengl would be more efficient at doing this rather than me extract the necessary rotations etc and then use glrotate etc?

gav

well Red Book says under OpenGL Performance Tips

Use specific matrix calls such as glRotate*(), glTranslate*(), and glScale*(), rather than composing your own rotation, translation, and scale matrices and calling glMultMatrix().

First of all your method “Transform” actually translates right? Translation moves the origin, transformation multiplies by a transformation matrix and includes both translation and rotation (it might include scaling and shearing as well, but that is generally bad for various reasons). Try using the gl commands for translation and rotation and see if the problem persists (remember that you’re supposed to invert the camera transform though). If it goes away you can blame your matrix code.

Do this:
struct {
VECTOR right;
float t1;
VECTOR up;
float t2;
VECTOR dir;
float t3;
VECTOR pos;
float t4;}

Now, VECTOR has 3 elements, x,y,z or v[0],v[1],v[2] whatever you pick is fine.
Now, to do transforms, you modify the pos vector. To do rotations, you modify the other vectors. The t1-t4 are basically there for fillers, and are 99.9% of the time not used.
So take the 3x3 matrix (made up of right,up, and dir) and do rotations on that. I don’t have time right now, but you should be able to figure out how, or if you want, post you matrix class, and when I get back, I can have a look.

Note, you can also union that struct to m[16], so you can also access the same elements via array calls if you want.

Oh also, the glvelocity matrix code does work, I have used it. What is it not doing for you? Also remember that if you are using a “camera”, everything it sees is a ~mirror image of what is happening.

I was under the impression that the majority of professional coders did it this way. (ie retain the matrix , do the rotations themselveves then just plugged the value in when they neded to transform an object.

Yes that used to say translate, this hunk of code has been hacked to peices, the last matrix class I tried called ‘translate’ ‘transform’ and as I was only testing I decided to just use their code to see if it worked.

Camera = !Object2;

In this line I was taking the inverse of the matrix. I have no problem understanding this peice of code. This is set to ! to denote inverse by the last matrix class I tried to get working. (I can’t remeber but it might have been a glvelocity class (nick carpens from my bad memory.

I could just use a 3*4 array to represent the three rotations + position but except for the 4 redundant members isn’t that exactly the same? A matrix vs individual rot rans I mean. Loading the matrix or calling multmatrix make the client code much easier to understand.

Why havent I just used individual rotations? Well I was, and when I rotated a few times I realised that all three local axis will need to be recalculated(well 2 out of 3) for each rotation, and to me this kind of seem just what a matrix does.

To me doing the individual ones is the same thing but just not calling it a matrix.

Second, I wanted to be able to easily move my camera to an objects matrix(ie take control of another vehicle). Copying the matrix to the camera seems very easy…

I had the same problem with my old CMovement class, turn up to the left and move forward 5 units…

Many thanks to all

Chris

PS : I’ll take another shot at the matrix class on glvelocity tonight and return the code that doesn’t work for me.