🔒 Locked
Movement
Advertisement
Original Post
Hello, this is my first post and I've run out of many options here. I've spent the past year, nearly daily for 12+ hours a day in front of a computer and most of it programming a game idea. Untill recently, i wanted to make a new kinda game that I havent done before that involves 3D motion. When I used motion in 2D, I used the simple: x = Math.cos(deg) * speed + x; y = Math.sin(deg) * speed + y; But for 3D I cant find the right lines of math to accomplish the similar tasks. Thus far I've come across these two kinds: //Code 1: x1 = z*Math.sin(Math.toRadians(yaw)) + x*Math.cos(Math.toRadians(yaw)); y1 = y; z1 = z*Math.cos(Math.toRadians(yaw)) - x*Math.sin(Math.toRadians(yaw)); x2 = x1; y2 = y1*Math.cos(Math.toRadians(pitch)) - z1*Math.sin(Math.toRadians(pitch)); z2 = y1*Math.sin(Math.toRadians(pitch)) + z1*Math.cos(Math.toRadians(pitch)); x3 = y2*Math.sin(Math.toRadians(roll)) + x2*Math.cos(Math.toRadians(roll)); y3 = y2*Math.cos(Math.toRadians(roll)) - x2*Math.sin(Math.toRadians(roll)); z3 = z2; //Code 2: y = Math.cos(angleAroundXAxis)*radius; z = Math.sin(angleAroundXAxis)*radius; x = Math.cos(angleAroundYAxis)*radius; z = Math.sin(angleAroundYAxis)*radius; x = Math.cos(angleAroundZAxis)*radius; y = Math.sin(angleAroundZAxis)*radius; I could use the help desprately. I'm rereading 3D trig books and looking at a dozen sites for something that could help. The kind of movement im looking for is that of a plane in the air, if it rolls, and ends up upside down, it'll pull down when the player tries to pitch up, etc. If anyone can help, your savin my sanity :P
First, back up a little.
In 2D, your code can be written in "vector form" like this:
In the realm of 3D, it is simpler and more convenient to use vectors and matrices. You should look into linear algebra.
In 2D, your code can be written in "vector form" like this:
P' = speed * D + P where D is a "direction vector" and computed like this: D<sub>X</sub> = cos( angle ) D<sub>Y</sub> = sin( angle ) Now, the nice thing is that in 3D, you use the same equation, but with x, y, and z, instead of just x and y. The unfortunate thing about 3D is that simple trigonometry no longer works, so the components of D are no longer simply sine and cosine of an angle.In the realm of 3D, it is simpler and more convenient to use vectors and matrices. You should look into linear algebra.
Ah thank you for the reply. was reading trig, might of been looking in the wrong area. :) If theres anymore help you can give, like how to use vectors for 3D motion, i'd be appericative. :)
If the above posts are not enough here's my camera class:
implementation:
header:
There are some things you might not need, just take what's useful.
implementation:
#include <math.h> #include "mldCamera.h"#include "mldfpscount.h"#include <string>#include "convert.h"using namespace std;const float piover180 = 0.0174532925f;MldCamera::MldCamera(void){ priviresusjos = -(piover180 * 22); zpos = 30;}void MldCamera::ComputeCamMt(float speed, int MaxZ, int MaxX) // Camera matrix computation;{ SpeedFctr = speed; XLimit = MaxX; ZLimit = MaxZ; D3DXMatrixIdentity(&IdentityMt); D3DXMatrixTranslation(&TranslateMatrix,xpos,ypos,zpos); //asign to Translate matrix mofific in x,y,z pos sceneroty = (360 * piover180)- yrot; D3DXMatrixRotationX(&RotateX, priviresusjos); D3DXMatrixRotationY(&RotateY, sceneroty); //_________________________// Compute Rotation XY Matrix and then Camera Matrix D3DXMatrixMultiply(&RotateXY, &RotateY, &RotateX); D3DXMatrixMultiply(&CamMt,&TranslateMatrix, &RotateXY); //Apply Rotation Matrix over Transl Matrix;}void MldCamera::CMoveHorFow(void){ xpos -= (float)sin(heading*piover180) * 1.0f * SpeedFctr; zpos -= (float)cos(heading*piover180) * 1.0f * SpeedFctr; LimitMove();}void MldCamera::CMoveHorBack(void){ xpos += (float)sin(heading*piover180) * 1.0f* SpeedFctr; zpos += (float)cos(heading*piover180) * 1.0f* SpeedFctr; LimitMove();}void MldCamera::CStrafeL(void){ xpos += (float)sin((heading+ 90)*piover180) * 1.0f* SpeedFctr; zpos += (float)cos((heading+ 90)*piover180) * 1.0f* SpeedFctr; LimitMove();}void MldCamera::CStrafeR(void){ xpos -= (float)sin((heading+ 90)*piover180) * 1.0f* SpeedFctr; zpos -= (float)cos((heading+ 90)*piover180) * 1.0f* SpeedFctr; LimitMove();}void MldCamera::LimitMove(void){ if(xpos > XLimit) { xpos = XLimit; } if(xpos < (-XLimit)) { xpos = (- XLimit); } if(zpos > ZLimit) { zpos = ZLimit; } if(zpos < (-ZLimit)) { zpos = (- ZLimit); }}void MldCamera::CLookUp(void){ if (priviresusjos < 1.5882) priviresusjos += 0.01 * SpeedFctr ;}void MldCamera::CLookDown(void){ if (priviresusjos > -1.5882) priviresusjos -= 0.01 * SpeedFctr;}void MldCamera::CLookTurnL(void){ heading -= 4.0f * SpeedFctr; yrot = (heading * piover180); if (heading> 360) heading = 1; }void MldCamera::CLookTurnR(void){ heading += 4.0f * SpeedFctr; yrot = (heading * piover180); if (heading> 360) heading = 1;} void MldCamera::setHeight(float Height){ypos = Height;}void MldCamera::setPosX(float Xpos){xpos = Xpos;}void MldCamera::setPosZ(float Zpos){zpos = Zpos;}int MldCamera::getPosX(){return xpos;}int MldCamera::getPosZ(){return zpos; }int MldCamera::getPosY(){return ypos;}string MldCamera::Serialize(){string CameraPX = "[cmX]"+ ItoS(getPosX()) +"[/cmX]";string CameraPY = "[cmY]"+ ItoS(getPosY()) +"[/cmY]";string CameraPZ = "[cmZ]"+ ItoS(getPosZ()) +"[/cmZ]";string CameraHeading = "[cmH]" + FtoS(heading) + "[/cmH]";string CameraYRot = "[cmR]" + FtoS(yrot) + "[/cmR]";string CameraData = CameraPX + CameraPY + CameraPZ + CameraHeading + CameraYRot;return CameraData;}void MldCamera::Unserialize(string & FileContent){ FileFlags CameraPX; ExtractPositions(FileContent,"[cmX]", "[/cmX]", CameraPX); FileFlags CameraPY; ExtractPositions(FileContent,"[cmY]", "[/cmY]", CameraPY); FileFlags CameraPZ; ExtractPositions(FileContent,"[cmZ]", "[/cmZ]", CameraPZ); FileFlags CameraHeading; ExtractPositions(FileContent,"[cmH]", "[/cmH]", CameraHeading); FileFlags CameraYRot; ExtractPositions(FileContent,"[cmR]", "[/cmR]", CameraYRot); for(int z = 0; z < CameraPX.Start.size(); z++) { xpos = StoF(CameraPX.DataString[z]); ypos = StoF(CameraPY.DataString[z]); zpos = StoF(CameraPZ.DataString[z]); heading = StoF(CameraHeading.DataString[z]); yrot = StoF(CameraYRot.DataString[z]); } }header:
#ifndef MLDCAMERA_H#define MLDCAMERA_H#include <d3dx9.h> #include <math.h> //#include "Common.h"//#include "CameraInDLL.h"#include <string>class MldCamera{private: D3DXMATRIX TranslateMatrix; D3DXMATRIX IdentityMt,RotateX, RotateY; float priviresusjos; float xpos; float ypos; float zpos; int XLimit; int ZLimit; float SpeedFctr; void LimitMove(void);public: float yrot, sceneroty; float heading, headingAng; MldCamera(void); // constructor D3DXMATRIX CamMt; D3DXMATRIX RotateXY; void CMoveHorFow(void); void CMoveHorBack(void); void CStrafeL(void); void CStrafeR(void); void CLookTurnL(void); void CLookTurnR(void); void CLookUp(void); void CLookDown(void); void setHeight(float); void setPosX(float); void setPosZ(float); int getPosX(); int getPosZ(); int getPosY(); std::string Serialize(void); void Unserialize(std::string & Data); void ComputeCamMt(float , int, int ); };#endifThere are some things you might not need, just take what's useful.
wow those two posts look promising :D i'll have to rewrite to JOGL but hopefully it'll be worth it ;) thanks you two for your help :) much appericated
And as usual my advice to stay as far away from Euler Angles as possible, unless you're planning to write a simple ground based shooter. When you render your object, you need to tell the API it's orientation. You do this, by passing a 4x4 transformation matrix (very obvious in D3D) or a bunch of rotate/translate calls (not so obvious in OpenGL).
So, instead of storing three pretty inadequate and annoying angles and getting a head ache from figuring out where your object is facing, it is a lot less painful (not to mention more efficient) to store this matrix. Rotation means building a rotation matrix and multiplying with it, translation.. begs for a shortcut. Somewhat more attractive than storing angles and creating a matrix from them every single frame, even if nothing has changed.
And if matrices scare you: as long as you don't use scaling, this ominous "transformation matrix" is nothing but 4 vectors. right, up, forward and position. This also avoids the recurring "how do I make my object face in a certain direction"-question, as instead of some more trig induced head ache you already know where to plug in the direction you want. So, especially when you're already using D3D with it's handy matrix classes anyway, there is no excuse for Euler Angles to store orientations. (I assume JOGL has a matrix library flying around somewhere, so this should be easy to port.. else you can always abuse OGL to do the matrix math for you).
[Edited by - Trienco on April 15, 2006 2:41:30 AM]
So, instead of storing three pretty inadequate and annoying angles and getting a head ache from figuring out where your object is facing, it is a lot less painful (not to mention more efficient) to store this matrix. Rotation means building a rotation matrix and multiplying with it, translation.. begs for a shortcut. Somewhat more attractive than storing angles and creating a matrix from them every single frame, even if nothing has changed.
And if matrices scare you: as long as you don't use scaling, this ominous "transformation matrix" is nothing but 4 vectors. right, up, forward and position. This also avoids the recurring "how do I make my object face in a certain direction"-question, as instead of some more trig induced head ache you already know where to plug in the direction you want. So, especially when you're already using D3D with it's handy matrix classes anyway, there is no excuse for Euler Angles to store orientations. (I assume JOGL has a matrix library flying around somewhere, so this should be easy to port.. else you can always abuse OGL to do the matrix math for you).
class Object {private: D3DXMATRIX Transform; public: Object(float x=0, float y=0, float z=0) { D3DXMatrixIdentity(&Transform); Transform(3,0)=x; Transform(3,1)=y; Transform(3,2)=z; } void move(float x, float y, float z, bool global=false, float distance=1) { if (global) { //usually won't need that part float dx=x*Transform(0,0) + y*Transform(1,0) + z*Transform(2,0); float dy=x*Transform(0,1) + y*Transform(1,1) + z*Transform(2,1); float dz=x*Transform(0,2) + y*Transform(1,2) + z*Transform(2,2); Transform(3,0) += dx * distance; Transform(3,1) += dy * distance; Transform(3,2) += dz * distance; } else { Transform(3,0) += x * distance; Transform(3,1) += y * distance; Transform(3,2) += z * distance; } } void rotate(float rad, float x, float y, float z, bool global=false) { D3DXMATRIX rot; D3DXVECTOR3 axe(x, y, z); D3DXMatrixRotationAxis(&rot, &axe, rad); if (global) D3DXMatrixMultiply(&Transform, &Transform, &rot); else D3DXMatrixMultiply(&Transform, &rot, &Transform); }};[Edited by - Trienco on April 15, 2006 2:41:30 AM]
I would use matrices but i run into the mental block of trying to pull x y z values from them. I probably have the concept all wrong but thats basically another hurdle of mine. Thanks for the reply tho, gonna try putting it into jogl and see what happens.
lol these replys help but i still need to find a way to jus have the values of the position as XYZ also. if i cant do that, then the rotations are pointless to me.
Ship components:
XYZ values
Pitch
Yaw
Roll
thats all i have to work with.
Ship components:
XYZ values
Pitch
Yaw
Roll
thats all i have to work with.
Quote:Just curious, why are you locked into using Euler angles? They're certainly not necessary for any technical reason, so I'm assuming you're using an API or third-party engine that requires their use?
Original post by MythProgrammer
lol these replys help but i still need to find a way to jus have the values of the position as XYZ also. if i cant do that, then the rotations are pointless to me.
Ship components:
XYZ values
Pitch
Yaw
Roll
thats all i have to work with.
actually... no... its just the only things I understand. if I knew how to get XYZ coordinates in 3D space from matrices, then I could use them, but I dont so I'm confined to Cos and Sin combinations using pitch roll and yaw. see... im self taught in this stuff, i have a weak foundation in 3d knowledge, vectors are relatively new to me even tho ive used them in a different form. i dont program games how others might like to program theirs :/ so for now I'm trying to adapt this new dimension with what i know.
lol imagine having 40 books on 3D programming and physics
10-15 books on physics. talking of vectors, addition, subtraction, never fully explaining how to get xyz coordiantes from it
20 books on programming, games in particular. briefly covering movement and moving directly into rendering, never telling how a matrix works or how to get pieces from a matrix.
the rest misc books about game designs, not even covering it
my knowledge is thin :P
lol imagine having 40 books on 3D programming and physics
10-15 books on physics. talking of vectors, addition, subtraction, never fully explaining how to get xyz coordiantes from it
20 books on programming, games in particular. briefly covering movement and moving directly into rendering, never telling how a matrix works or how to get pieces from a matrix.
the rest misc books about game designs, not even covering it
my knowledge is thin :P
Quote:Ah, I understand.
Original post by MythProgrammer
actually... no... its just the only things I understand. if I knew how to get XYZ coordinates in 3D space from matrices, then I could use them, but I dont so I'm confined to Cos and Sin combinations using pitch roll and yaw. see... im self taught in this stuff, i have a weak foundation in 3d knowledge, vectors are relatively new to me even tho ive used them in a different form. i dont program games how others might like to program theirs :/ so for now I'm trying to adapt this new dimension with what i know.
You may have already answered this, but I can't remember: what kind of motion are you after? For example:
1. First-person-shooter type motion, where you basically only yaw and pitch
2. Flight-sim, where you can yaw, pitch and roll, but always relative to a fixed up vector
3. 6DOF, like in a space game, where you can turn, rotate, and orient yourself in any direction
The first two you can do with Euler angles only; the latter will require vectors or matrices (or quaternions, but I wouldn't worry about those at the moment). Don't be put off by the vector and matrix math - you'll need to learn it eventually if you want to program games, and now's probably as good a time to start as any :-)
For what it's worth, the code sample I linked to includes everything you need for 6DOF motion in an OpenGL environment, and could easily be adapted for DirectX. Some of the other samples posted to this thread probably offer this as well.
One last piece of advice: don't let yourself get stuck with Euler angles just because they're 'easy' to understand. Although they're useful in some cases, overall they're very limiting and basically a pain to work with. If you have any interest in 6DOF motion, physics simulation, terrain following, or anything else that requires arbitrary rotations, you should really move on from Euler angles at the earliest opportunity.
Quote:
Original post by Grain
You can pass matrices just as easily in OpenGL. There’s no need for rotate/translate calls.
I know, but D3D is pretty much forcing the matrices on you, so you can hardly ignore them. With OpenGL it seems many consider rotate/translate as semi-magical functions with no idea WHAT they actually do, because it's mostly hiding them from you, except for changing between projection and modelview every once in a while. The only explanation I have for so many "how do I have to rotate my object to make it face this way"-questions.
Quote:
Original post by MythProgrammer
lol imagine having 40 books on 3D programming and physics
10-15 books on physics. talking of vectors, addition, subtraction, never fully explaining how to get xyz coordiantes from it
I take it you're simply exaggerating there, but if you really don't know how to get xyz from a vector then all these books about 3D and physics should be pushed to the far end of the shelf and be replaced with books about basic math and linear algebra. Else what you're doing is trying to read Shakespeare without speaking English in the first place.
Quote:
20 books on programming, games in particular. briefly covering movement and moving directly into rendering, never telling how a matrix works or how to get pieces from a matrix.
Because most of them assume that the reader learned that at school (though I guess not all cover matrices). Sometimes they give a short idea of where rotation, scaling and translation fit in, but usually it's expected that you either know how to multiply matrices or read up on it yourself. Basic math, just like the language the book is written in and the programming language used in the book should already be familiar or you definitely skipped an important step.
the motion i was lookin for all 3 on the list :P but can do 1 already, lol, looks like i gotta learn quaternions or how to use matrices if I want to be able to do that. and number of books not exagurated :P PDF files on my computer. I'll read the linear alg books i have in my folder, see if it sheds any light on the subject. Thanks for your help guys :) appericate the support this forum offers.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement