Ship movement

I’ve posted this in the maths section too but I thought I might have more luck posting it here.

Basically, I’m working on a game in which the player flies a ship around over a landscape. I have x,y and z coords stored for the ship, aswell as x,y and z rotations which are carried out via glRotatef each frame.

My problem is that I can’t get the ship to steer properly. I have the up arrow key decreasing the z-coord of the ship (making it move forwards) and “z” and “x” keys to rotate the ship ACW and CW respectively. In my draw loop for the ship, if I rotate then translate to the x,y and z coords, the ship is rotated around the main origin making it appear to move sideways when it gets further away from the origin. If I switch rotate and translate around, it draws the rotatated ship at it’s coordinates, but the ship still moves on the universal axes (i.e. it carries on moving forwards relative to the origin and so appears to just rotate on the spot as it moves, the rotation having no effect on it’s direction).

Here’s a screen of it so far:

http://www.arkangel-software.co.uk/Assets/Images/Ship3.jpg

I’m really stuck with this so any help would be greatly appreciated =)

Thanks,
Steve

Here is something I did a few years ago, read the start of this, the concepts apply to your problem even if it’s a scene graph oriented presentation.

http://www.sgi.com/products/software/performer/brew/aqua.html

hi, imho you should use gluLookAt() instead of glRotatef and glTranslatef, theres a tutorial on how to make a good camera class at www.morrowland.com

Thanks for the help guys, still can’t get it to work tho =( I’ve written a camera class already using the principles from that tutorial. I changed my model class so that it is transformed in the same way but it’s still rotating around the world origin even with gllookat =(

this is my main loop:

  • Load identity
  • Set camera to be behind ship
  • Orientate the camera using glLookAt
  • pushmatrix, draw model, popmatrix, repeat
  • take user input for next frame

in my model class i have the same functionality and data structures as the camera class, and the rotate/move functions are called in the main loop as above. I’ve been on all day with this and I really appreciate any help.

Thanks again

Nothing in your loop even mentions ship motion simulation.

You say you set up the camera behind the ship but how do you determine where the ship is?

glulookat is not the issue, the issue is ship dynamics and orientation, especially if the view is tethered outside the ship looking at it with a glulookat.

See my tutorial, and note the distinction between ship positional update, and positioning the camera relative to the ship.

Assuming that the vertical axis is y and the ship is moving in the x-z plane, then what you need to do is to calculate the new heading based on your steering command. This will involve using sines and cosines. So if you rotated your ship by theta ccw, then the movement in the x and z will be given as

xstep=-sin(theta)(longitudinal movement step of ship)
zstep=cos(theta)
(longitudinal movement step of ship)

You will need to store the position of the ship continuously and add the xstep, zstep to the current position everytime you go through your loop.

sorry, I was just trying to keep the loop simple. Like i said, the ship has the same data structures as the camera class (i.e. it has an up vector, a position and a direction/heading vector. so far, when the player presses the “up” arrown key the user input part of my loop calls the move function of the ship, which looks something like this…

// Moves the model forwards or backwards
void model::moveModel(float speed)
{
vector3D vVector = mDir - mPos; // Set up view vector

// Moves model (pos speed = forwards, neg speed = backwards)
mPos.x  = mPos.x  + vVector.x * speed;
mPos.z  = mPos.z  + vVector.z * speed;
mDir.x = mDir.x + vVector.x * speed;
mDir.z = mDir.z + vVector.z * speed;

}

mPos is the position of the ship and mDir is its direction. thanks again for the help guys.

so the tutorial abour the camera class didnt help you?

Yeah I read the tutorial, cheers, but I still can’t seem to get it to work. Like i say, I already have a camera class which works on those principles. The model class works the same way too, but again no luck =(

Sorry, I should also mention that my camera class works fine. It does everythnig its supposed to. It’s just the model movement/rotation which is the problem.

mmm could you post an executable? so we could what is happening

Here’s how I move in my game its a FPS with jetpack’s so it should be similar to what you’d need for a ship:

As a note: I’m programming in C under Linux

G_PLAYER is a typedef struct containing the player’s current X,Y,Z and some other info.
PLAYER->ANGLE is the vertical heading of the player.
PLAYER->ROTATION is the horizontal heading of the player.
The PLAYER_FLYING bitmask simply determines if the player is flying (i.e. Jetpack fired up)

RADDEG is just a #define (0.017453292) I figured out to get degrees instead of radians from sin & cos - Probably not the best way to do it.

My coding might not be all perfect but it works flawlessly - I’m able to control full 3D flight with this.
I have 3 other routines as well: travel backwards, strafe left or right they’re not much differnt from this.

void lod_gplayer_travel_forwards(G_PLAYER *PLAYER, GLdouble distance)
{
GLdouble temp;

    if ((PLAYER->DOING & PLAYER_FLYING) == PLAYER_FLYING) temp = (GLdouble)cos((double)(PLAYER->ANGLE * RADDEG));
    else temp = 1;
                                                                                                                        
    PLAYER->X -= (distance * (temp * (GLdouble)sin( (double)(PLAYER->ROTATION * RADDEG))));
    PLAYER->Z += (distance * (temp * (GLdouble)cos( (double)(PLAYER->ROTATION * RADDEG))));
    if ((PLAYER->DOING & PLAYER_FLYING) == PLAYER_FLYING)
            PLAYER->Y -= (distance * (GLdouble)sin((double)(PLAYER->ANGLE * RADDEG)));

}

Hope this helps

Thanks for the help redarrow, I’ll give it a go. I think I might have tried it already but I’m probably doing something wrong. I’ve uploaded the executable as it is at the minute (in a very bad way I must warn you, the camera’s even moving in the oppisite direction of the ship) along with the main source and the source for the ship and the camera.

http://arkangel-software.co.uk/Downloads/Demos/ship_game_problems.zip

Thanks again for all the help =)

Still can’t get this thing to work =(

Hi, you have to change some minus signs in your code, i couldnt check your code, but while using the exe, if you give the ship a 180 degrees turn then it will move correctly front and back

Thanks for the advice Zukko but I managed to fix that. The problem is still the rotation tho. the ship is moving around the world origin, not it’s own local origin. This means that as it moves away from the world origin it apprears to strafe rather than rotate. What I really want it to do it to rotate on it’s local origin and for it to move forwards relative to itself, not the world coordinates (i.e. to not move sideways etc. after rotation)

i couldnt get to compile your code, im missing some includes, will check the code later

Yeah, I only uploaded the code with problems. There’s a load of other files like enumerations, matrix class and other stuff which I thought was irrelevant. I can upload the whole lot if it’ll help.

Righty, I’ve uploaded the whole project…

http://arkangel-software.co.uk/Downloads/Demos/ship_game - rotation problem.zip

The camera doesn’t follow this ship in this version. I thought it best to get a better view of what’s happening. The up/down arrows make it go forwards/backwards and the left/right arrows rotate it (about the world origin unfortunately) =( if you press ‘C’ you can toggle between the two available cameras, and ‘M’ changes to camera mode so you can move the camera around with the arrow keys for a better angle if you need it. Any help appreciated hugely! I’m seriously stuck with this one. Thanks again in advance =)

sorry, that link should be all one line grrr