3D Directional Movement

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

Recommended Posts

In some of my 2D games, I had to find the X and Y velocities with sin/cos based on the angle of the object. This allowed it to travel in the direction that it was facing. I need to do this same thing in 3D. I'm using OpenGL if that makes any difference, but I would guess that this is API independent. Every other time I've done 3D, it was using another library higher than OpenGL and it seemed to take care of this for you. I don't think OpenGL does this for you. Do I just need to use another trig function along with sin/cos?

Share on other sites
I believe you might want to start using matrices. What you have done in your previous 2D games was create a 2D matrix, and plugged in the sin/cos values to get the direction your object was facing. You would do the same thing here, but with a 3x3 matrix for orientation (direction) and a 4x4 matrix for all your other math needs (the 3x3 matrix is actually part of the 4x4 matrix).

There are a ton of resources on this topic ranging from the common use of matrices in 3D applications, to some crazy stuff involving quaternions, etc. Take it slow and learn the basics first.

Take a look at this website:
http://www.morrowland.com/apron/tutorials/gl/gl_matrix.php
http://www.cprogramming.com/tutorial/3d/rotationMatrices.html

Also, I should mention that in order to get your objects to appear in space, 3 things must happen. It must have an Orientation in space, it must have a position (Translation) and if applicable, a scaling factor. Each of those things can be represented by a matrix, which are then multiplied together to form a world matrix for that object.

[World] = [Orientation] * [Translation] * [Scaling];

There are many libraries out there that have all of this implemented that you can just plug into your application.

One I looked into:
http://sourceforge.net/projects/vmmlib

Share on other sites
It depends on what you want, and how you define your orientation.

In most 3D games, you just want to move in the x/z plane anyway, so it's really no different than top-down 2D movement. This is where euler angles are actually useful. At least yaw. Set your x/z velocity from the yaw sin/cos, and let gravity take care of y.

If you need "real" 3D movement like a spaceship or something, then you'll probably want to use a matrix or quaternion as your current orientation. Then to get the forward vector, all you have to do is multiply your natural forward (usually (0,0,1)) by the matrix.

Share on other sites
vmmlib seems like a good way to start, so I think I'll use that.

I'm still not really sure what to do with it though. I'm not asking someone to write it all for me, but I just need some help understanding what I would actually do with the matrices in order to calculate the movement direction. Thanks!

Share on other sites
Simply put, there are two things you should know. Vectors and Matrices. A Vector is a data type that holds 3 values: X, Y, Z (Sometimes a 4th value is added, called W). Those three values are the distances away from the origin (0, 0, 0) on the X, Y, and Z axes. It essentially gives you a direction. A Matrix is made up of 4 of them. In the case of the orientation matrix, those vectors represent the local Up, Left, and Forward direction of that object. To calculate how it would look like, you cal look up rotation Matrix on wikipedia.

I believe there are helper functions that help you calculate a rotation matrix just by specifying its pitch, yaw, and roll. You would feed this matrix into OpenGL or whatever you use to give the object its orientation. So what you can do in this case is take the Forward vector of the matrix, multiply it by some speed value, and apply it to the translation to get movement. Easy, right?

I say, get started, poke around some code. We are always here to help.

Share on other sites
Okay, bad news. For some reason, my project did not copy correctly or something when I was transferring it from where I was working on it today. I can't keep working on it until tomorrow when I can go back and get it.

In the mean time, I have some more questions.

I've been looking up how OpenGL works with matrices. It looks to me like in order to do what you are saying I need to do, I will be using glLoadMatrix and glMultMatrix because those seem to be the only OpenGL matrix functions that allow you to insert an entire matrix into OpenGL as opposed to glTranslate and glRotate which just modify the one that is currently set as the one to modify.

Is this correct? And it seems that I can just store and edit matrices as arrays since they seem to be pretty much the same thing right?

Share on other sites
For the most part, you are correct. There are other ways of manipulating matrices. For example, some higher end engines write their own Math routines instead of having OpenGL do it. Im sure there are dozens of libraries out there that easily works with OpenGL to manipulate matrices, I don't really know of any off hand (I write my own math).

If you think about it, a Matrix is just an array of 16 floats/doubles.

Share on other sites
Okay, so I'm still thinking things through here since I can't actually write anything (well, I could I guess, but I don't have all the code I already had).

So, it seems like I need to somehow multiply the translation matrix by the rotation matrix of an object and that will cause it to move in the direction the object is facing. That's sort of what I've understood from this. Tell me if I'm way off though.

My question about that is, wouldn't OpenGL be doing that for me already? If I call glRotatef and rotate an object and then call glTranslatef, wouldn't OpenGL be multiplying that together?

EDIT: Oh wait, looking back on the posts I see that you were talking about an orientation matrix. This is separate from a rotation matrix? If that is so, I would actually multiply the translation matrix by the _orientation_ matrix? That would make more sense.

Share on other sites
I think it's more like the orientation is the logical concept, and can be represented by a rotation matrix, quaternion, euler angles, etc.

OpenGL probably won't do what you want. I'm assuming you want to move forward from your current position each frame (like driving a car or something), but your orientation can change every frame. When doing transforms with OpenGL, you generally just set it, render, and never read the result back, so you don't get that cumulative effect.

But if you're not using euler angles for your orientation (in which case you could use the easy method I mentioned before), then as RealMarkP pointed out, the third row (or maybe column) or a rotation matrix is actually the forward vector itself, so you can just pick that out directly and add it to your position.

Share on other sites
Okay, so I've started writing a matrix class to handle a world transformation matrix. It is composed of:

(all 4x4 arrays)
a translation matrix
a scaling matrix
a rotation X matrix
a rotation Y matrix
and a
a rotation Z matrix

These are all based on info from this site:

http://www.morrowland.com/apron/tutorials/gl/gl_matrix.php

So, as I understand it, in order to calculate the world matrix I do something like:

world = rotationx * rotationy * rotationz * translation * scaling

I'm not sure if I'm right about the whole rotation part. Is this how I calculate the world matrix?

Then, the second problem is that of the directional movement this is all about. I don't think that the above takes care of that right?

Let's say I have a move method in the matrix class. In order to find the directional movement do I just do something like:

movement = rotationx * rotationy * rotationz * translation

Is it something like that?

Thanks for all this help by the way!

Share on other sites

http://www.gamedev.net/reference/articles/article417.asp

The formula for finding the object's matrix is:

object = object * translation * rotx * roty * rotz

I don't understand how this works though. What if no rotations are applied and the rotation matrices are all:

1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1

and the translation matrix is:

1 0 0 X
0 1 0 Y
0 0 1 Z
0 0 0 1

If you multiply these together, the X, Y, and Z are going to be multiplied by zero, resulting in zero. This is part of the reason that I don't understand how multiplying these matrices give you a world matrix result.

Share on other sites

I figured out that matrix multiplication is not what I thought it was. I thought it was just like matrix1[x][y] * matrix2[x][y] but it's really adding the products of the columns or something. Anyway, that part is fixed and it seems to be working for the most part.

Now I've run into another problem. What I was doing was doing gluPerspective and then calling glLoadMatrix to load up the custom matrix, but that overwrites the work done by gluPerspective.

I'm not really sure what to do about this because I don't want to do all my own perspective calculations as well. Until now, I didn't realize that the camera perspective stuff was even stored in that same GL_PROJECTION matrix.

So, what can I do about loading up the custom transformation matrix but also using gluPerspective to easily setup a perspective?

Share on other sites
Alright, I know I've posted a lot, but I'm very close.

Now, it almost works. The rotation, translation and scaling works just fine, but now I'm on to my original problem of calculating the forward motion. I found the information about it on this site:

http://www.fastgraph.com/makegames/3drotation/

So, to review, I have three rotation matrices for X, Y, and Z as described in the above link.

I can't find anything that says how I calculate the full rotation matrix using these, but I just assumed I should multiply the matrices together.

So, I did that and then used the resulting matrix to move forward as described in that link.

void tf::matrix::move(tf::vector vct){    float temp[4][4];    setidentity(temp);    multmatrix(temp, _rot_x);    multmatrix(temp, _rot_y);    multmatrix(temp, _rot_z);    _trans[0][3] += vct.get_x() * temp[0][2];    _trans[1][3] += vct.get_y() * temp[1][2];    _trans[2][3] += vct.get_z() * temp[2][2];}

But for some reason, you always move straight ahead on the Z axis no matter which way you are facing. The vector that I pass in is 1,1,1.

I don't see any difference between this and what is described in the article. Anyone see anything? (One thing that is different is that the translation values for the matrix that OpenGL uses is in a different spot in the matrix)

Share on other sites

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

Create an account

Register a new account

• Forum Statistics

• Total Topics
628658
• Total Posts
2984071

• 10
• 9
• 9
• 10
• 21