I'm a beginner using XNA to try and make a 3D Asteroids game.
Update: I'm having a slightly hard time describing this so I made a little animation to show what I'm talking about: http://www.youtube.com/watch?v=4TyGQX_iRI4&feature=youtu.be
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.... :(
So my quesiton is: how do you calculate the X, Y, and Z rotations for an object in terms of pitch and yaw?
In this picture the first is the starting position, the second is after pitch is applied, and the third is after both pitch and yaw are applied. I'm trying to figure out how to get the fourth picture to be the result of consecutive pitch and yaw operations (yaw being applied to already pitched ship).
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();
}
}