6DOF, and my game

Started by
30 comments, last by medevilenemy 16 years, 10 months ago
Again, I apologize for doing such a bad job of explaining my question. I have these vectors, what I'm trying to do is pull out specific orientation related angles from them (whatever works, preferably roll, pitch, yaw if they would work), specific velocities of motion (i assume that is what upmove and forwardmove are, but that makes me wonder why there isnt a sidemove) and if possible a specific location in the global coordinate system (basically, pull the displacement out of the matrix, and apply it to the global system to get a global coordinate position). I just don't how to properly access vectors in C++. I know the mathematics of vectors, but how do I apply that to a data object?
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.
Advertisement
That totally depends on the implementation of the vector class, as in standard
C++ there is no such class; thus, everybody solves this problem in his own way,
although each and every one of it still represents a vector...

So, either you provide more info (on the scene org class you use, the vector class
and the matrix class and how their interface looks like) or (preferably) you go
looking for it yourself; if you know the math, as you claim, it shouldn't be too
hard to identify which method does what and delivers what.

Either way, I would strongly suggest you to do some basic research in scene
management on your own and start writing your own class which serves the basic
needs before you go and use other people's (probably more advanced) classes,
as you need to have done it yourself at least once to be able to grasp what's
going on.
Start with a quadtree structure maybe, it should provide you with a reasonable
understanding on how scene management works, what data you will come across
and what this data represents; quadtrees are easy enough to go for a start since
they are basically two-dimensional - the 3d equivalent would be octrees, which
work the same way, but might be a but too complicated to follow for a start.

And, by the way, the names of the vectors in that class are fair enough
self-explanatory; all it takes is a little bit of reading and it jumps off your
head what the meaning of all those vectors is; and, btw, you claim you know vector
math and linear algebra, so why don't you know trigonometry - or why is it that
you seem unable to calculate angles from vector components?
I do know how... I just don't know how to access the various parts of the vector object... I'll go digging around in the class, and hopefully I'll find a function to return the magnitude and direction. I don't know if its there, but I hope so.
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.
Quote:Original post by medevilenemy
These are the variables in the "OpenglObject" class which store the relevant dataL

Vector3 m_pos;
Vector3 m_side;
Vector3 m_up;
Vector3 m_forward;
Vector3 m_upMove;
Vector3 m_forwardMove;

Basically, I have to figure out which vector stores what values, and then write a couple little general functions to extract it (which shouldn't be too hard... although I don't have experience working with C++ vector classes -- although I do know the trig/vector math)

Thanks for all the help, everyone.


I'm going to take a stab here...

Imagine a person standing still just blankly staring forward...

m_pos = the bottom-most point and directly between the feet (the bottom of the bounding-box)
m_side = the right-most point (maybe left instead) and sits roughly around the person's elbow (the right/left side of the bounding-box)
m_up = i'm sure you see where i am going with this... the top of the head (the top of the bounding-box)
m_forward = somewhere around the belly-button (the front of the bounding-box... this could be because the bounding-box isn't a 2D square stretched to a 3D rectangle, but rather a 2D rectangle stretched to a 3D rectangle and therefore you can't just rely on the m_side value to determine the front and back dimensions as well)
m_upMove = the velocity per frame towards the m_up vector
m_forwardMove = the velocity towards the m_forward vector

Now most people of normal thinking probably would have (like myself) had rotation values for the different axis etc, but if what i have said for the different vector vars is correct then i would have to say it appears that instead of simple bounding-box and rotation values this instead has the ALREADY rotated information... so to discover what the rotation values applied were you will need to reverse-rotate (i think i just made that up) back to the original forward-facing position you (and me) would have expected to have started with and not what appears to be here.

If that doesn't make sense to you then think of it this way... imagine yourself facing forward and you have golf-balls stuck to your body in the positions i mentioned earlier. now randomly walk around and look at something, and add a little forward lean, and side lean. The golf-balls now roughly represent what it seems you have in the vector variables you are trying to figure-out.

I'm guessing there is no m_sideMove because whatever the thing is that these variable represent doesn't have a "strafe" movement and only goes wherever it's facing and with a possible vertical "jump" or "fall" etc.

I'm probably speaking rubbish and would be interested in what the data actually does represent if i am wrong.
Well, its one of jyk's utility classes, not mine, so all I can tell you is that I am using it to handle the motion of Spacecraft/other spatial objects in a 3D Space based pseudo rpg type thing I'm working on (I really don't have a better name than that for it right now, sorry). You are probably right about the vectors, but one thing seems odd about that... if they represent motion in a single direction, it doesn't make sense for them to be vectors... since vectors represent a combination of a magnitude and and angle, not just a magnitude. In any case, I will have to figure it out before I can implement any collision detection or the AI.

Thanks for the feedback, though... It may prove useful once this all gets settled.
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.
Since I wrote the aforementioned OpenGLObject class, I'll go ahead and chime in with some clarification.

The class supports movement along each of the three axes (forward/backward, up/down, and strafe). The reason there are separate 'move' vectors for forward and up is that the class supports three different types of object/camera motion. The three modes are:

1. FPS. Similar to a character in a first-person shooter. Forward/backward motion is always in the ground plane, and up/down motion is always along the world up axis. Given that the character can (presumably) pitch the view up and down, the forward and up orientation vectors may be different than the forward and up movement vectors, hence the separate 'move' vectors for these axes.

2. FPS spectator. Similar to FPS, except that forward motion is along the view vector rather than being constrained to the ground plane (allowing you to 'fly'). In this case the forward move vector corresponds to the forward orientation vector, but the up move vector is still the world up vector (which may or may not correspond to the orientation up vector).

3. 6DOF. Motion is always along the local axes, so the 'move' vectors always correspond to the 'orientation' vectors.

The reason there is no 'side move' vector is that the strafe move vector always corresponds to the side orientation vector, regardless of mode.

Since the OP is using 6DOF mode, the move vectors can effectively be ignored (since they are the same as the corresponding orientation vectors).

Although an Euler-angle triple is a common representation (and due to its intuitiveness and prevalence in tutorials and certain types of games might be considered by some to be the 'normal' representation for orientation), the three orthonormal vectors used by the OpenGLObject class is actually much more straightforward and useful (at least for the 6DOF case). These vectors can easily be converted to matrix or quaternion form if needed (in fact, the class includes functions for conversion to matrix form).

@The OP: I'm not completely clear on the nature of the problem you're trying to solve, but whatever it is, the three basis vectors (plus the position, depending on the nature of the computation) almost certainly provide all the information you need. This representation is the 'absolute orientation' you're looking for (provided it isn't a node down a branch of a scene graph).

For AI, I think the most useful pieces of info would be the position of the enemy in local space (derived by transforming said position by the inverse of the transform matrix, which, by the way, can be queried directly from the OpenGLObject class), and perhaps the relative orientation of the enemy (computable using a little vector and/or matrix math). To provide more details than that, we'd probably have to know more about how you intend to use this information.
Ah yeah, thats exactly what I'm trying to do. Basically, the AI needs to be able to tell whether or not its guns (which are separate objects ships carry) is lined up with an enemy ship or object so it can fire at it... and everything (especially projectiles) need to know where they are in global space so they can determine whether or not they are within the bounding box for an object.

I figured all the required information is stored within the object already, I just don't quite know how to pull it out. The reason I was asking about angular measurements is because that is way I can best understand orientation, but if I can somehow write a function to handle it another way that works too. The biggest thing is pulling out the global coordinate location (that is, global in the sense of the main coordinate system where everything is), and orientation data in such a way that I can compare with corresponding data from other objects and determine collisions/line of sight/etc.

Thanks Again!
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.
<bump>

also, @jyk: I just noticed some odd behavior with the rotations using the openglobject code (probably my fault). for some reason, when rolled 90 degrees, pitch becomes yaw.

I am including the relevent code below

class PShip{    private:        void UpdateFromPitchYaw();        void Orthonormalize();        float DegToRad(float angle);        float RadToDeg(float angle);        Vector3 m_pos;        Vector3 m_side;        Vector3 m_up;        Vector3 m_forward;        Vector3 m_upMove;        Vector3 m_forwardMove;        float m_pitch;        float m_yaw;        float acceleration;        float maxvelocity;        float damage; // Damage Dealt Per Bullet        int throttle; // keep between -100 and 100        int energy; // keep between 0 and 100        int weaponheat; // keep between 0 and 100        float currenthp;        float maxhp;        float currentshields;        float maxshields;        bool engineson;        bool shieldson;        bool weaponson;    public:        void Init(float hpc, float hpt, float shieldsc, float shieldst, float dmg);        void Draw(); // Draws the ship model with the appropriate texture at the appropriate angles        Vector3 GetPos() const;        Vector3 GetSide() const;        Vector3 GetUp() const;        Vector3 GetForward() const;        Vector3 GetUpMove() const;        Vector3 GetForwardMove() const;        void SetPos(const Vector3& pos);        void SetMode(int mode);        void Identity();        void ApplyYaw(float angle);        void ApplyPitch(float angle);        void ApplyRoll(float angle);        void MoveAlongSideAxis(float t);        void MoveAlongUpAxis(float t);        void MoveAlongForwardAxis(float t);        void LookAt(const Vector3& pos, const Vector3& target, const Vector3& up);        void SetOpenGLModelMatrix();        void SetOpenGLViewMatrix();        void MultOpenGLModelMatrix();        void MultOpenGLViewMatrix();        void GetModelMatrix(float m[16]) const;        void GetViewMatrix(float m[16]) const;        void Move(            bool yawLeft,     bool yawRight,            bool pitchDown,   bool pitchUp,            bool rollRight,   bool rollLeft,            bool moveLeft,    bool moveRight,            bool moveUp,      bool moveDown,            bool moveForward, bool moveBack,            float yawSpeed,   float pitchSpeed, float rollSpeed,            float sideSpeed,  float upSpeed,    float forwardSpeed,            float dt);        void ChangeThrottle(int percent); // Changes the value of throttle by percent        void TakeDamage(float amount); // Applies damage to the ship        float GetDamage(void); // Returns the current value of the variable 'Damage'        float GetCurrenthp(void);        float GetMaxhp(void);        float GetCurrentShields(void);        float GetMaxShields(void);        int GetThrottle(void);        int GetEnergy(void);        int GetHeat(void);        void Increasehp(void);        void IncreaseShields(void);        bool IsDead(); // Returns true if the ship is dead or false if it is not} pShip;void PShip::Init(float hpc, float hpt, float shieldsc, float shieldst, float dmg){    Identity();    m_upMove = m_up;    m_forwardMove = m_forward;    acceleration = 0.01;    acceleration = 0;    maxvelocity = 0;    throttle = 0;    energy = 100;    weaponheat = 0;    damage = dmg;    currenthp = hpc;    maxhp = hpt;    currentshields = shieldsc;    maxshields = shieldst;    engineson = true;    shieldson = true;    weaponson = true;}void PShip::Draw(){    glMatrixMode(GL_MODELVIEW);    glEnable(GL_LIGHT1);    //DrawObj(models[0], 0, 0, 0, -2.0); // Draw Ship Model    glColor4d(1.0, 0.0, 0.0, 1.0);    /*glBegin(GL_QUADS);        glVertex3d(-1, 1, zz);        glVertex3d(1, 1, zz);        glVertex3d(1, -1, zz);        glVertex3d(-1,-1, zz);    glEnd();*/    glPushMatrix();    MultOpenGLModelMatrix();    starfield.Draw();    glPopMatrix();    glDisable(GL_LIGHT1);}// INSERT FUNCTIONS HEREVector3 PShip::GetPos() const {return m_pos;}Vector3 PShip::GetSide() const {return m_side;}Vector3 PShip::GetUp() const {return m_up;}Vector3 PShip::GetForward() const {return m_forward;}Vector3 PShip::GetUpMove() const {return m_upMove;}Vector3 PShip::GetForwardMove() const {return m_forwardMove;}void PShip::SetPos(const Vector3& pos) {m_pos = pos;}void PShip::Identity(){    m_pos.set(0.0f, 0.0f, 0.0f);    m_side.set(1.0f, 0.0f, 0.0f);    m_up.set(0.0f, 1.0f, 0.0f);    m_forward.set(0.0f, 0.0f, 1.0f);    m_upMove = m_up;    m_forwardMove = m_forward;    m_pitch = 0.0f;    m_yaw = 0.0f;}void PShip::ApplyYaw(float angle){    // Rotate side and forward about up    float s = sinf(DegToRad(angle));    float c = cosf(DegToRad(angle));    Vector3 forward = c * m_forward + s * m_side;    Vector3 side = c * m_side - s * m_forward;    m_side = side;    m_forward = forward;    m_upMove = m_up;    m_forwardMove = m_forward;    Orthonormalize();}void PShip::ApplyPitch(float angle){    // Rotate up and forward about side    float s = sinf(DegToRad(angle));    float c = cosf(DegToRad(angle));    Vector3 up = c * m_up + s * m_forward;    Vector3 forward = c * m_forward - s * m_up;    m_up = up;    m_forward = forward;    m_upMove = m_up;    m_forwardMove = m_forward;    Orthonormalize();}void PShip::ApplyRoll(float angle){    // Rotate side and up about forward    float s = sinf(DegToRad(angle));    float c = cosf(DegToRad(angle));    Vector3 side = c * m_side + s * m_up;    Vector3 up = c * m_up - s * m_side;    m_side = side;    m_up = up;    m_upMove = m_up;    m_forwardMove = m_forward;    Orthonormalize();}void PShip::MoveAlongSideAxis(float t){    m_pos += m_side * t;}void PShip::MoveAlongUpAxis(float t){    m_pos += m_upMove * t;}void PShip::MoveAlongForwardAxis(float t){    m_pos += m_forwardMove * t;}void PShip::LookAt(const Vector3& pos, const Vector3& target, const Vector3& up){    m_forward = target - pos;    m_forward.normalize();    m_side = up.cross(m_forward);    m_side.normalize();    m_up = m_forward.cross(m_side);    m_pos = pos;}void PShip::SetOpenGLModelMatrix(){    float m[16];    GetModelMatrix(m);    glLoadMatrixf(m);}void PShip::SetOpenGLViewMatrix(){    float m[16];    GetViewMatrix(m);    glLoadMatrixf(m);}void PShip::MultOpenGLModelMatrix(){    float m[16];    GetModelMatrix(m);    glMultMatrixf(m);}void PShip::MultOpenGLViewMatrix(){    float m[16];    GetViewMatrix(m);    glMultMatrixf(m);}void PShip::GetModelMatrix(float m[16]) const{    m[0] =  m_side[0];    m[1] =  m_side[1];    m[2] =  m_side[2];    m[3] =  0.0f;    m[4] =  m_up[0];    m[5] =  m_up[1];    m[6] =  m_up[2];    m[7] =  0.0f;    m[8] =  m_forward[0];    m[9] =  m_forward[1];    m[10] = m_forward[2];    m[11] = 0.0f;    m[12] = m_pos[0];    m[13] = m_pos[1];    m[14] = m_pos[2];    m[15] = 1.0f;}void PShip::GetViewMatrix(float m[16]) const{    m[0] =  -m_side[0];    m[1] =   m_up[0];    m[2] =  -m_forward[0];    m[3] =   0.0f;    m[4] =  -m_side[1];    m[5] =   m_up[1];    m[6] =  -m_forward[1];    m[7] =   0.0f;    m[8] =  -m_side[2];    m[9] =   m_up[2];    m[10] = -m_forward[2];    m[11] =  0.0f;    m[12] =  m_pos.dot(m_side);    m[13] = -m_pos.dot(m_up);    m[14] =  m_pos.dot(m_forward);    m[15] =  1.0f;}void PShip::UpdateFromPitchYaw(){    float sp = sinf(DegToRad(m_pitch));    float cp = cosf(DegToRad(m_pitch));    float sy = sinf(DegToRad(m_yaw));    float cy = cosf(DegToRad(m_yaw));    m_side.set(cy, 0.0f, -sy);    m_forward.set(sy * cp, -sp, cy * cp);    m_up = m_forward.cross(m_side);    m_upMove.set(0.0f, 1.0f, 0.0f);    m_forwardMove = m_forward;}void PShip::Orthonormalize(){    m_forward.normalize();    m_side = m_up.cross(m_forward);    m_side.normalize();    m_up = m_forward.cross(m_side);}void PShip::Move(    bool yawLeft,     bool yawRight,    bool pitchDown,   bool pitchUp,    bool rollRight,   bool rollLeft,    bool moveLeft,    bool moveRight,    bool moveUp,      bool moveDown,    bool moveForward, bool moveBack,    float yawSpeed,   float pitchSpeed, float rollSpeed,    float sideSpeed,  float upSpeed,    float forwardSpeed,    float dt){    if (yawLeft)        ApplyYaw(yawSpeed * dt);    if (yawRight)        ApplyYaw(-yawSpeed * dt);    if (pitchDown)        ApplyPitch(pitchSpeed * dt);    if (pitchUp)        ApplyPitch(-pitchSpeed * dt);    if (rollRight)        ApplyRoll(rollSpeed * dt);    if (rollLeft)        ApplyRoll(-rollSpeed * dt);    if (moveLeft)        MoveAlongSideAxis(sideSpeed * dt);    if (moveRight)        MoveAlongSideAxis(-sideSpeed * dt);    if (moveUp)        MoveAlongUpAxis(upSpeed * dt);    if (moveDown)        MoveAlongUpAxis(-upSpeed * dt);    if (moveForward)        MoveAlongForwardAxis(forwardSpeed * dt);    if (moveBack)        MoveAlongForwardAxis(-forwardSpeed * dt);}float PShip::DegToRad(float angle){    const float DEG_TO_RAD = (atanf(1.0f) * 4.0f) / 180.0f;    return angle * DEG_TO_RAD;}// --------------------------------------------------------------------------------------float PShip::RadToDeg(float angle){    const float DEG_TO_RAD = 180.0f / (atanf(1.0f) * 4.0f);    return angle * DEG_TO_RAD;}void PShip::ChangeThrottle(int percent){    throttle+=percent;    if(throttle > 100)        throttle = 100;    if(throttle < -100)        throttle = -100;}void PShip::TakeDamage(float amount){    if(shieldson && currentshields > 0 && currenthp >= 0)    {        currentshields -= amount;        if(currentshields < 0)        {            currenthp += currentshields; //Transfer overflow to hull            currentshields = 0;        }    }    else if(!shieldson || currentshields == 0)    {        currenthp -= amount;    }}float PShip::GetCurrenthp(void){    return currenthp;}float PShip::GetMaxhp(void){    return maxhp;}float PShip::GetCurrentShields(void){    return currentshields;}float PShip::GetMaxShields(void){    return maxshields;}int PShip::GetThrottle(void){    return throttle;}int PShip::GetEnergy(void){    return energy;}int PShip::GetHeat(void){    return weaponheat;}


and here is where the main scene is rendered

void MainScreen(void){    DrawOverlay(); // ----- THIS DRAWS THE HUD    glEnable(GL_LIGHTING);    gluPerspective(45,1024/768,0.01,1000);    pShip.Draw(); // --- Doesnt actually draw a ship on the screen, rather it is where the rotations are updated    starfield.Draw();    glDisable(GL_LIGHTING);}


[Edited by - medevilenemy on June 8, 2007 2:32:10 PM]
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.
I'm pretty sure the oddness I mentioned in my last post is being caused by applying the rotation code from the openglobject class for the camera... I know... dumb mistake.
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.
ok, after hunting through my code, I'm pretty sure the oddness can be settled if I put in a proper 6dof camera (which I have to find). While I'm at that it may be a good idea to replace the openglobject class with something simpler, or at least simplify it (while adding a way to extract angular x,y, and z rotations and an actual xyz coordinate set for position). Does anyone know of any freely usable classes or whatnot to do this?

Any help is greatly appreciated, I'd like to finally be able to move on to other things like weapons and ships (which shouldn't be a problem if I can just get rotation and such working properly [wink]).
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.

This topic is closed to new replies.

Advertisement