• Advertisement
Sign in to follow this  

Building my own Matrix class...

This topic is 3628 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm currently working my way into 3D land. I'm busy with OpenGL and I'm up to the point where I want to do some actual things in 3D space, other than showing a bunch of cubes. But, do I actually need my own matrix class for this? For instance, if I want to have an object rotate/orbit another object, using a matrix rotation would be cool. 2nd question: When translating an object using a matrix, I need a 1x4 matrix(or, that's what we used in college a while back), but for rotation I need a 3x3 matrix. How the hell do I solve that issue, or am I missing something here? Toolmaker

Share this post


Link to post
Share on other sites
Advertisement
Quote:
But, do I actually need my own matrix class for this? For instance, if I want to have an object rotate/orbit another object, using a matrix rotation would be cool.
For all practical purposes, you'll need a separate math library if you want to write non-trivial simulations using OpenGL. What you described - making one object orbit around another - can be done using OpenGL alone, but when you get into areas such as collision detection, visibility determination, AI, and so on, things will be easier if you have a math library available.

As for the math library itself, you can write your own, or use any of the many math libraries already available online.
Quote:
2nd question: When translating an object using a matrix, I need a 1x4 matrix(or, that's what we used in college a while back), but for rotation I need a 3x3 matrix. How the hell do I solve that issue, or am I missing something here?
Graphics APIs generally work with 4x4 homogeneous matrices. In the case of translation, the translation vector typically goes in the 4th row or column (as a homogeneous 4-d vector with a w value of 1); in the case of rotation, the 3x3 orthonormal rotation matrix is stored in the upper-left 3x3 portion of the 4x4 matrix.

This material will probably become more clear the farther you get into '3D land' :)

Share this post


Link to post
Share on other sites
You only NEED your own matrix class if you NEED the transformation information for your object.
GLRotate/GLTranslate will graphically put your object where you want, but you can't get the transformed position back from OpenGL.
This is where your matrix comes in, because it takes the place of all the GLRotates/Translate calls and replaced them all with one
matrix call, then you do your movement/rotation to that matrix.

What you really need is a 4x4 Matrix. [At,Left,Up,Pos] or [At,Up,Left,Pos] depending on what you choose as your global "up".
The rotation is imbeded in the upperleft 3x3 part of the matrix, and your translation is the last column.

:'(. I wasn't quite fast enough.

Share this post


Link to post
Share on other sites
Quote:
Original post by Toolmaker
I'm currently working my way into 3D land. I'm busy with OpenGL and I'm up to the point where I want to do some actual things in 3D space, other than showing a bunch of cubes.

But, do I actually need my own matrix class for this? For instance, if I want to have an object rotate/orbit another object, using a matrix rotation would be cool.



This depends on what you want to achieve. For most stuff, you simply need to load a 4x4 matrix and pass it to OpenGL using the glMultMatrix() functions. As always, google is your friend with this stuff.

you will need a separate matrix and vector maths library if you want to do things such as mouse picking (without the Z buffer - a method I don't use for various reasons, i will explain if you like) and ray casting. If you are only interested in graphics, you can get away with using the OpenGL matrix system. If you have a physics engine in your games, it will come with a maths library, which you may wish to use.

Quote:


2nd question: When translating an object using a matrix, I need a 1x4 matrix(or, that's what we used in college a while back), but for rotation I need a 3x3 matrix. How the hell do I solve that issue, or am I missing something here?

Toolmaker



[xr] [xr] [xr] [xp]

[yr] [yr] [yr] [yp]

[zr] [zr] [zr] [zp]

[0.0][0.0][0.0][1.0]

Here, xr yr and zr represent the 3 rows of the rotation matrix. The translation matrix (vector) is down the right side. The bottom row is unused, its job is to ensure the matrix is orthogonal. Notice that the bottom right cell contains 1. This is the remains of the "identity" matrix.

Although a rotation matrix (at least, the kind I know of) in 3d space is 3x3, a forth column and row are used to allow you to multiply the matrix by a 1x4 matrix (a 3d vector). We add a forth column and row to keep everything orthogonal.

A matrix of this kind can be used to store *both* euler angle rotations, and 3d translations. The vector is stored in the right hand column, and to keep the matrix orthogonal, it must also have a bottom row. And, since this matrix is now 4x4, a 3d vector must be 1x4 to allow multiplication of the two.

Many kinds of transformations in 3d space can be stored in a 4x4 matrix, for example scaling an object by 2.5:

[2.5] [0] [0] [0]

[0] [2.5] [0] [0]

[0] [0] [2.5] [0]

[0] [0] [0] [1.0]


Or moving it up and left:

[1.0] [0.0] [0.0] [1.0]

[0.0] [1.0] [0.0] [1.0]

[0.0] [0.0] [1.0] [0.0]

[0.0] [0.0] [00.] [1.0]


Or both at the same time:

[2.5] [0.0] [0.0] [1.0]

[0.0] [2.5] [0.0] [1.0]

[0.0] [0.0] [2.5] [0.0]

[0.0] [0.0] [00.] [1.0]



Currently I am using NewtonGD as the physics library in my game project, and my matrix / vector classes are in fact wrappers to the one included with Newton. If, for example, I wish to change to PhysX at some time in the future, I can change the contents of the library. As a fallback I have the library I wrote myself when I was learning this stuff, but it isn't nearly as fast.

Here is a console dump of a matrix, representing a cube falling through space and hitting a ground object, and coming to a rest:


1,0,0,0,
0,1,0,0,
0,0,1,0,
0,9.99932,0,1,

1,0,0,0,
0,1,0,0,
0,0,1,0,
0,9.97562,0,1,

1,0,0,0,
0,1,0,0,
0,0,1,0,
0,9.97562,0,1,

1,0,0,0,
0,1,0,0,
0,0,1,0,
0,9.97562,0,1,

1,0,0,0,
0,1,0,0,
0,0,1,0,
0,9.97562,0,1,

1,0,0,0,
0,1,0,0,
0,0,1,0,
0,9.97562,0,1,

1,0,0,0,
0,1,0,0,
0,0,1,0,
0,9.96955,0,1,

1,0,0,0,
0,1,0,0,
0,0,1,0,
0,9.96955,0,1,

//...a bit later on
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,6.60085,0,1,

1,0,0,0,
0,1,0,0,
0,0,1,0,
0,6.53718,0,1,

1,0,0,0,
0,1,0,0,
0,0,1,0,
0,6.53718,0,1,

1,0,0,0,
0,1,0,0,
0,0,1,0,
0,6.47296,0,1,

1,0,0,0,
0,1,0,0,
0,0,1,0,
0,6.47296,0,1,

1,0,0,0,
0,1,0,0,
0,0,1,0,
0,6.40819,0,1,





Note that the matrix is sideways, down to the way c++ stores 2d arrays compared with, er, just about everything else.

<disclaimer>
I expect that I have made a few mistakes, since I didn't learn this stuff in school, but rather I asked questions here, or looked in books / tutorials. There is no warranty on my statements, which may cause loss of sleep, loss of hair, or acute cases of spontaneous human conbustion, and nothing will be my fault.
</disclaimer>

Share this post


Link to post
Share on other sites
Quote:
Original post by Toolmaker
But, do I actually need my own matrix class for this? For instance, if I want to have an object rotate/orbit another object, using a matrix rotation would be cool.


As already said, you don't need a matrix class library, but using it can be very useful when you want to transform vertices without having opengl doing it (for example, they are not using for visualization, but are simplified mesh for collision detection and so on) or perform other operations (inverting a transformation for example).
As for building your own or using existing ones: there are good ones out there, but unless you already have a deep understanding of matrices and vectors I suggest to build your own because this way you are forced to face many issues:
-using 3x3 or 4x4 homogeneous matrices?
-using column major or row major (memory layout)?
-using column vector or row vector?
-Which operations are available for matrices and vector? How are implemented cross and dot products? Ho do I get the inverted of a matrix?

All those design decisions require you to learn a lot of things, but when you will then deal with external libraries or documentation (papers and so on) you will be more preapared. In addition, there are differences in how DX and OGL handle matrices, you will discover that and this may be helpful when you see DX code and want to translate it to OGL code.

Quote:

2nd question: When translating an object using a matrix, I need a 1x4 matrix(or, that's what we used in college a while back), but for rotation I need a 3x3 matrix. How the hell do I solve that issue, or am I missing something here?

Toolmaker


As already said, homogeneous matrices (and vectors) resolve this issue. For example, for my raytracer I use 4 components vectors (x,y,z,w) and 4x4 matrices. In the book "Physically based rendering" they use 3 components vectors: they have two different implementations, for direction vectors and for points (well they have also normals, but this is another story).
My 4 vector can be used both for directions and points, but in the first case you need to set the w component to 0 (to prevent the translation to have effects) and in the second case to 1.

Share this post


Link to post
Share on other sites
Interesting... While I already have a basic matrix class(ie, a class that can store all the data and do operations on it), this changes what I need to implement a bit.

Are there any good and understandable reads on this out there? Wikipedia is way to technical for me to follow(And probably not the best way to learn about this anyway).

Toolmaker

Share this post


Link to post
Share on other sites
Quote:
Original post by Toolmaker
Interesting... While I already have a basic matrix class(ie, a class that can store all the data and do operations on it), this changes what I need to implement a bit.

Please keep in mind that matrices are only 1 possibility of dealing with transformations. They have the advantage of being able to represent all affine transformations at once, but you get this not for free. E.g. animation and simulation methods may work better with other representations (e.g. the often stressed rotation interpolation). Or the storage consumption of matrices may be too heavy (e.g. homogeneous vertex position vectors in VAs/VBOs, or using 16 values instead of 3 for translations) what also may have an impact on runtime efficiency. This is especially true if dealing with decomposed transformations where the parts are animated separately, like e.g. the OP's orbiting animation. IMHO a matrix is a tool in the mathematical toolbox, but just one of several. But that doesn't unburden you to have a matrix class at hand, of course.

Share this post


Link to post
Share on other sites
You could certainly find informations about the linear algebra involved:
a free linear algebra book
mathworld
just to name a couple.

Other useful resources are the OGL and DX documentations, that show how the matrices are built for the different transformations.

I've found google codesearch very useful to discover how others handled this.

There are many Open Source renderer out there. I personally gave a look to the source of the pbrt raytracer and the yafray renderer. Also blender could be interesting. You may very well give a look to Ogre3d or similar engines, as well as a few geometric libraries on sourceforge.

Other than that, pieces of informations can be found here and there: here on gamedev past topics and the tutorials all around the net. I wasn't able to find one single resource for everything.

Hope this helps.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement