• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Chaosenemy

I need help with matrices

20 posts in this topic

Hey guys,

I would greatly appreciate any help you can offer me. I'm writing a big Entity/Sprite/Model/Rendering system and I am having the hardest time understanding how to use matrices properly. I guess my main questions is: how can I use only a single matrix per object to define where it is located, how it is rotated, and how it is scaled? Since matrix multiplication is cumulative, I have come to the conclusion that I have no choice but to store a (Vector3D) position, (Quaternion) rotation, and (Vector3D) scale, and then re-calculate the matrix (for rendering) each frame from these values. This seems.... cumbersome and ugly. Is there some way to simply have a Matrix for each object and modify it directly when I call SetPosition(), RotateX(), etc.? I'm not that great with Matrix manipulation, so maybe this is no-brainer, but I can't seem to find any direct answer to this no matter where I search.

 

Side note: This isn't meant to sound rude at all, but please don't suggest that I use SDL or some matrix library. I get that a lot, but I want to make this myself. I just need some help in the right direction. Believe me, I've tried learning this myself, but I learn by example, so reading books explaining matrices just doesn't make it click for me.

 

Thanks in advance!

1

Share this post


Link to post
Share on other sites

Storing the model-to-world transform as (position, rotation, scale) has advantages (although I would argue that scale should be a single number, or not exist at all). But you can certainly use matrices instead.

 

I am not sure what you are having trouble with, though. To SetPosition, you just modify the "translation vector" part of the affine matrix. To RotateX, you multiply the 3x3 submatrix corresponding to the endomorphism of the vector space (ignore the big words: You probably know perfectly well what 3x3 submatrix I am talking about) by a 3x3 matrix that rotates around the x axis.

 

That probably doesn't help you, but I need to know what you know about how a 4x4 matrix of a special form can be used to encode the transformations you are interested in.

0

Share this post


Link to post
Share on other sites

I also use floats for everything, and in the render function build a matrix from it and render,

maybe you find it ugly, but it seems the way to go.

0

Share this post


Link to post
Share on other sites

Voting mean down means i,m waiting for an explaination.

So please tell me why vote me down ?

Edited by the incredible smoker
-1

Share this post


Link to post
Share on other sites
Because your input had no meaning in the context of the conversation.
You said you use floats.
Vector3D uses floats.
Quaternion uses floats.
Matrix uses floats.

In other words, everyone uses floats.
Your reply is nonsensical at best, detrimental at worst to anyone who understands it to mean he or she should replace a Vector3D with 3 floats. That is absolutely 100% not the way it “seems to go”.

That is absolutely terrible advice.
What sane person would do that?
Vectors provide encapsulation, simplify the code, and make its intent clearer.

With 3 separate floats you have basically a pool of ungrouped floats rather than a clear separation between rotation values, position values, and scale values.

With 3 separate floats you have to do this:
object->addPos( off_x, off_y, off_z );
instead of this:
object->pos() += off;
Vector3D operators make manipulating code easier and faster.

What if one day you want to add SIMD optimizations to vector operations? Good luck if you just use raw floats everywhere.


That is why I down-voted you. And trust me, as rare as it is that I down-vote, you should take it as a serious hint.


L. Spiro Edited by L. Spiro
2

Share this post


Link to post
Share on other sites

floats or vector, i personally have floats, but its about the idea.

I did not tell him he should use floats instead of vector.

 

btw : i am sane.

Edited by the incredible smoker
0

Share this post


Link to post
Share on other sites

I think the core question here is, how to directly modify a matrix, instead of storing an additional data for position, rotation, scale and then rebuilding the matrix

 

For this, i'll point you to what i guess is the canonical resource on matrices: http://www.cs.princeton.edu/~gewang/projects/darth/stuff/quat_faq.html

If you look at the breakdown of the matrix composition, M[3][0] M[3][1] M[3][2] holds the translation vector. So, a function to set the position would simply modify these three bits of the matrix.

 

I hope this addresses the question.

Good luck!

Edited by uglybdavis
1

Share this post


Link to post
Share on other sites

You don't have to recalculate the matrix every frame, only when the position, translation or scale changes.

 

I think that doing operations with only some indexes of the matrix will give you more troubles than solutions, as you say, the transformations are cumulative, so it's not the same to have a rotation of 90° and then a translation, or a rotation of 45° a translation and another rotation of 45°. If you change only some values of a precalculated matrix you'll get something more like the second case when it sounds you want the first case.

0

Share this post


Link to post
Share on other sites

For the most part you will have to build your matrix each frame unless the object is completely static. The order I build matrices is:

scaling

rotation

position

The scaling is not usually going to change. If your object doesn't change its scale, then you could store that matrix as the object's origin matrix.

The rotation (judging from you post) is done with a quaternion and then you build a matrix from that.... Multiply your scaling matrix by this one.

Position is simply:

matrix(3,0) is x

matrix(3,1) is y

and matrix(3,2) is z

It seems like a lot to do, but matrix math is fast.

 

Another note: If you are using a quaternion for rotation, have that quaternion as part of the structure of your object and make it cumulative.

0

Share this post


Link to post
Share on other sites

Because your input had no meaning in the context of the conversation

Actually, I disagree. Float instead of vector is an odd (and perhaps uninformed) choice, but Smoker's right that people don't usually store this information in matrix form, and that building the matrix anew each frame is par for the course even if it seems inefficient.

Voting mean down means i,m waiting for an explaination.
So please tell me why vote me down ?

You got voted down here because you have a history of making uneducated or just plane wrong statements, and this particular post lacked sufficient detail and clarity for anyone to see it for anything but that. Post carelessly often enough and people will rightly stop giving you the benefit of the doubt.
2

Share this post


Link to post
Share on other sites

The others have hinted at this, but I think it needs to be made more clear. A 4x4 matrix can be interpreted as an array of 4 vectors: Right axis, Up axis, Forward axis, and Position. At least, if you use left handed coordinates and row-major matrices like DirectX. Normally we only use x/y/z of each vector, so the last component of each row is 0. Or you can write a 4x3 matrix class.

 

The Right, Up and Forward axes represent both the orientation and the scale, so it's not really practical to "set" those values if they're all mixed up with eachother.

 

Also, it's really only practical to "set" one rotation at a time... e.g. generating a standard Y rotation matrix. But you can apply rotations incrementally, which is the real reason to use a quaternion or matrix instead of euler angles in the first place.

 

So, you can't do exactly what you're wanting, but you can store your orientation and position as a matrix and use incremental rotations, and apply the scale separately. And depending on the game, you may only need a single float for the scale, rather than separate x/y/z scaling.

 

Another thing you can do is use a combination of matrix and one or two euler angles for the orientation. For example, a matrix plus a yaw angle, and by convention never do any yaw rotation in the matrix part. That could be useful in a game like mario kart, where you want the cars to tilt according to the terrain, and the player only has left/right controls (yaw angle), so you only need one that's convenient to read and modify. Set the matrix's up axis to the ground normal, cross product that with the natural forward (0,0,1) to get the right axis, and cross the up and right axes to get the new forward axis. Then generate a yaw matrix from your facing direction and multiply by that, and the car will rotate around the tilted up axis in a similar way to using incremental rotations, while keeping the convenient readability and set-ability of an euler angle for what the player controls apply to.

0

Share this post


Link to post
Share on other sites


You don't have to recalculate the matrix every frame, only when the position, translation or scale changes.
As a side note, I saw what the Ogre developers were doing a few months ago, they were tuning their codebase to be more cache friendly. They had some structure going to compute the matrices that were modified since the last frame.

 

IIRC, they found out that by disabling the "if(dirty) compute" paths and recomputing everything always, performance improved in quite a few cases by just plain hitting less branches even if the total matrix computations were more.

0

Share this post


Link to post
Share on other sites

I know you don't want to USE a library, but what is wrong about LEARNING from a library?

 

Grab a copy of GLM and have a look at the way they handle matrix math.

 

The guys who wrote it spent a lot of time and energy optimising their code for various architectures so you can learn a lot from how they approach the problem.

 

Have a look on their support forums and you can get a lot more information as well.

 

Personally I won't use it because of a couple of issues ( and a certain level of arrogance by the developers which annoyed the hell out of me) but I'm not too proud to admit that they did a lot of good stuff here.

 

In my experience the amount of time you spend on matrix math in a game frame on mobile devices is trivial compared to the amount of time pushing polygons.  

Edited by Stainless
1

Share this post


Link to post
Share on other sites

Not meaning to hijack the thread, but I suspect using matrices would help me too.

 

I have a camera class, it has this simple function to apply it.

//Some weird shit going on here
//Old comment but kept for lols
void Camera::ApplyICam()
{
  glRotatef(-m_rotation.m_xValue*180/PI, 1.0, 0.0, 0.0);
  glRotatef(-m_rotation.m_yValue*180/PI, 0.0, 1.0, 0.0);
  glRotatef(-m_rotation.m_zValue*180/PI, 0.0, 0.0, 1.0);

  glTranslatef(-m_position.m_xValue, 
               -m_position.m_yValue, 
               -m_position.m_zValue);
}

 

 

My object class also stores position and rotation as two 3 dimensional vectors. Using this system I can move my camera and view my objects just fine, the problem comes when I want to rotate the object.

 

Doing a simple initial rotation is easy, I simply set my m_rotate in object, my question is how to rotate my object after this initial rotation. Say we have an aircraft and I want the plane to bank left aka roll anticlockwise along it's central axis by say 15 degrees. I am unsure how to calculate this rotation given that the plane is no longer aligned along one of our axis, it has its own arbitrary axis. Simply put I cannot figure out how I need to alter my initial rotation.

 

Here is part of my code showing the order of transformations

  glLoadIdentity();
  cam->ApplyICam();
  obj->AddRotation(0.0, 0.025, 0.0);
  obj->ApplyTransformations();
  obj->GetMesh()->DrawMesh();
  cam->ApplyICam();

This code correctly draws my object in position, spinning around the y axis by 0.025 per frame. What I want to know is how to make my object bank as described above, no matter how it happens to be rotated at the time.

 

I am sorry for the poor description, I have always had a hard time visualizing these rotations 

Edited by foxcode
0

Share this post


Link to post
Share on other sites

Not meaning to hijack the thread, but I suspect using matrices would help me too.

 

I have a camera class, it has this simple function to apply it.

//Some weird shit going on here
//Old comment but kept for lols
void Camera::ApplyICam()
{
  glRotatef(-m_rotation.m_xValue*180/PI, 1.0, 0.0, 0.0);
  glRotatef(-m_rotation.m_yValue*180/PI, 0.0, 1.0, 0.0);
  glRotatef(-m_rotation.m_zValue*180/PI, 0.0, 0.0, 1.0);

  glTranslatef(-m_position.m_xValue, 
               -m_position.m_yValue, 
               -m_position.m_zValue);
}

 

 

My object class also stores position and rotation as two 3 dimensional vectors. Using this system I can move my camera and view my objects just fine, the problem comes when I want to rotate the object.

 

Doing a simple initial rotation is easy, I simply set my m_rotate in object, my question is how to rotate my object after this initial rotation. Say we have an aircraft and I want the plane to bank left aka roll anticlockwise along it's central axis by say 15 degrees. I am unsure how to calculate this rotation given that the plane is no longer aligned along one of our axis, it has its own arbitrary axis. Simply put I cannot figure out how I need to alter my initial rotation.

 

Here is part of my code showing the order of transformations

  glLoadIdentity();
  cam->ApplyICam();
  obj->AddRotation(0.0, 0.025, 0.0);
  obj->ApplyTransformations();
  obj->GetMesh()->DrawMesh();
  cam->ApplyICam();

This code correctly draws my object in position, spinning around the y axis by 0.025 per frame. What I want to know is how to make my object bank as described above, no matter how it happens to be rotated at the time.

 

I am sorry for the poor description, I have always had a hard time visualizing these rotations 

This is where you get into "incremental rotations". Store the aircraft's orientation as a matrix (or quaternion), and when the player wants to turn, generate a pitch, yaw or roll matrix with the small angle delta (your 0.025 value) and multiply the orientation by it. So for example a yaw rotation will rotate around the plane's current up axis, modifying the X and Z axes in the process. Then next time you want to do a pitch rotation, it will be around the modified X axis..It doesn't really matter what order you do them in if the player wants to rotate around multiple axes at the same time, since the change is so small each frame.

 

It can be more tricky at first, working with the orientation as a matrix/quaternion rather than angles, but it's actually easier once you get the hang of it. For example, if you want to move the plane forward, just multiply a vector (0,0,speed) by the orientation, and add it to the position.

 

And don't forget to re-normalize/orthogonalize the orientation periodically to correct any numerical accuracy problems that accumulate.

1

Share this post


Link to post
Share on other sites

The beautiful thing about matrices and quaternions is that the "rotation" is done the same way:

quat:

D3DXQuaternionRotationYawPitchRoll(&qt,y,p,r);

m_objQuat*=qt;//this is the new quaternion

D3DXMatrixQuaternion(&m_orientation,&m_objQuat);//this converts the object's quaternion into an orientation matrix that can be used with rendering

 

******OR********

 

matrix:

D3DXMatrixRotationYawPitchRoll(&mat,y,p,r);

m_orientation*=mat;//this is the new orientation matrix which can be used for rendering

 

 

Take note: the orientation matrix does NOT have translation. This means that it is at the origin, so to render the object using the orientation matrix, you will have to have a "complete" matrix with scaling, rotation, and location.

0

Share this post


Link to post
Share on other sites

You got voted down here because you have a history of making uneducated or just plane wrong statements,

In other words, "You got voted down because we're used to vote you down." lmao

Edited by TheChubu
0

Share this post


Link to post
Share on other sites

I know this isn't game specific, and may not be what you're looking for (if it's not, please cheerfully ignore it cool.png ).

 

If you want to really understand matrices, first you need to understand linear algebra (which emcompasses a lot more than matrices, contrary to what many introductory texts might have you believe). This is an absolutely awesome introduction to the subject. I have no idea why it isn't still in print, especially as it was a Dover publication. When I was an undergrad in Rutgers I convinced one of my professors to use it as the textbook for his course when he told me he was looking for one (I probably saved each of his students about $40). As he put it, the textbook they were using was 'bass ackwards', teaching matrix theory first and vector spaces second.

 

The nice things about the book: it doesn't start with matrices but it does get to them - so you don't confuse vector spaces with matrices. Answers to all the exercises and questions (even the true/false ones) are painstakingly detailed in the book so you understand why the answer is what it is. Yes, it's math, but if you're going to work with these things, you may as well understand what the hell you're doing. I can't imagine more knowledge hurting you blink.png

 

From Amazon it's all 3rd party sellers, so "new" is stupidly expensive. Used-Very Good though is about $12 shipped, which is a bit less than it cost originally, IIRC.

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0