Help with calculation to steer ship in 3d space

Posted by Aaron Anodide on Game Development See other posts from Game Development or by Aaron Anodide
Published on 2012-11-01T05:15:42Z Indexed on 2012/11/01 5:17 UTC
Read the original article Hit count: 237

Filed under:
|

I'm a beginner using XNA to try and make a 3D Asteroids game.

I'm really close to having my space ship drive around as if it had thrusters for pitch and yaw.

The problem is I can't quite figure out how to translate the rotations, for instance, when I pitch forward 45 degrees and then start to turn - in this case there should be rotation being applied to all three directions to get the "diagonal yaw" - right? I thought I had it right with the calculations below, but they cause a partly pitched forward ship to wobble instead of turn.... :(

Here's current (almost working) calculations for the Rotation acceleration:

        float accel = .75f;

        // Thrust +Y / Forward
        if (currentKeyboardState.IsKeyDown(Keys.I))
        {
            this.ship.AccelerationY += (float)Math.Cos(this.ship.RotationZ) * accel;
            this.ship.AccelerationX += (float)Math.Sin(this.ship.RotationZ) * -accel;
            this.ship.AccelerationZ += (float)Math.Sin(this.ship.RotationX) * accel;
        }

        // Rotation +Z / Yaw
        if (currentKeyboardState.IsKeyDown(Keys.J))
        {
            this.ship.RotationAccelerationZ += (float)Math.Cos(this.ship.RotationX) * accel;
            this.ship.RotationAccelerationY += (float)Math.Sin(this.ship.RotationX) * accel;
            this.ship.RotationAccelerationX += (float)Math.Sin(this.ship.RotationY) * accel;
        }

        // Rotation -Z / Yaw
        if (currentKeyboardState.IsKeyDown(Keys.K))
        {
            this.ship.RotationAccelerationZ += (float)Math.Cos(this.ship.RotationX) * -accel;
            this.ship.RotationAccelerationY += (float)Math.Sin(this.ship.RotationX) * -accel;
            this.ship.RotationAccelerationX += (float)Math.Sin(this.ship.RotationY) * -accel;
        }

        // Rotation +X / Pitch
        if (currentKeyboardState.IsKeyDown(Keys.F))
        {
            this.ship.RotationAccelerationX += accel;
        }

        // Rotation -X / Pitch
        if (currentKeyboardState.IsKeyDown(Keys.D))
        {
            this.ship.RotationAccelerationX -= accel;
        }

I'm combining that with drawing code that does a rotation to the model:

public void Draw(Matrix world, Matrix view, Matrix projection, TimeSpan elsapsedTime)
{
    float seconds = (float)elsapsedTime.TotalSeconds;

    // update velocity based on acceleration
    this.VelocityX += this.AccelerationX * seconds;
    this.VelocityY += this.AccelerationY * seconds;
    this.VelocityZ += this.AccelerationZ * seconds;

    // update position based on velocity
    this.PositionX += this.VelocityX * seconds;
    this.PositionY += this.VelocityY * seconds;
    this.PositionZ += this.VelocityZ * seconds;

    // update rotational velocity based on rotational acceleration
    this.RotationVelocityX += this.RotationAccelerationX * seconds;
    this.RotationVelocityY += this.RotationAccelerationY * seconds;
    this.RotationVelocityZ += this.RotationAccelerationZ * seconds;

    // update rotation based on rotational velocity
    this.RotationX += this.RotationVelocityX * seconds;
    this.RotationY += this.RotationVelocityY * seconds;
    this.RotationZ += this.RotationVelocityZ * seconds;

    Matrix translation = Matrix.CreateTranslation(PositionX, PositionY, PositionZ);

    Matrix rotation = Matrix.CreateRotationX(RotationX) * Matrix.CreateRotationY(RotationY) * Matrix.CreateRotationZ(RotationZ);

    model.Root.Transform = rotation * translation * world;

    model.CopyAbsoluteBoneTransformsTo(boneTransforms);

    foreach (ModelMesh mesh in model.Meshes)
    {
        foreach (BasicEffect effect in mesh.Effects)
        {
            effect.World = boneTransforms[mesh.ParentBone.Index];

            effect.View = view;

            effect.Projection = projection;

            effect.EnableDefaultLighting();
        }

        mesh.Draw();
    }
}

© Game Development or respective owner

Related posts about xna-4.0

Related posts about rotation