I'm attempting to use a basic physics system to create an arcade flight model. So far I have managed to get the aircraft moving forward, apply gravity, etc. However, after trying to implement torque I noticed some interesting behaviour in the flight model. When turning after a while the controls appear to reverse, sometimes, the controls for the different movements (pitch, roll, yaw) also seem to change. I was hoping that someone may be able to advise me as to what I should check next. I have included my source code in case anyone spots any glaring mistakes! I have listed some of the variables below to show their data types:
Quaternion rotation = Quaternion.Identity;
Quaternion newRotation = Quaternion.Identity;
Vector3 rotationChange = Vector3.Zero;
Vector3 rotVec = Vector3.Zero;
Below is the update logic for the rotational forces:
dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
if (dt > 1.0f / 60.0f)
{
dt = 1.0f / 60.0f;
}
Vector3 newRotationChange = rotationChange + dt * angularAcceleration;
Vector3 newRotVec = rotVec + dt * newRotationChange;
rotationChange = newRotationChange;
rotVec = newRotVec;
Vector3 rotAxis = rotVec;
rotAxis.Normalize();
if (rotVec.Length() < 0.001f)
{
rotVec = Vector3.Zero;
newRotation = Quaternion.CreateFromAxisAngle(forwardVector, 0.0f);
}
else
{
float angle = rotVec.Length();
newRotation = Quaternion.CreateFromAxisAngle(rotAxis, angle);
}
if (rotationChange.Length() < 0.001f)
{
rotationChange = Vector3.Zero;
}
rotation = newRotation;
angularAcceleration = Vector3.Zero;
My method for creating the torque:
///
/// Creates a rotational force for an object
///
/// Point the force is being applied on the object
///
/// Magnitude of the force being applied
/// Direction of the force being applied
public void CreateTorque(Vector3 pointOfAction, float forceAmount, Vector3
forceDir)
{
// Vector from position to pointOfAction
Vector3 r = pointOfAction - position;
// Create the force
Vector3 force = forceDir * forceAmount;
// Create the torque force
torque = Vector3.Cross(r, force);
angularAcceleration += torque;
}
Sorry for the massive code block and thanks in advance for any help you can give.
Answer
Ok so I finally managed to work out what I was doing wrong. The issue was how I was applying the rotation vector to the quaternion. Basically rather than use Quaternion.CreateFromAxisAngle()
I now create a rotation change Quaternion using my angular velocity as the X,Y,Z components and 0 for the scalar. So just for clarity here is my new update code for rotational physics. ( This replaces every line of code after calculating dt
)
Vector3 newAngularVelocity = angularVelocity + dt * angularAcceleration;
Quaternion rotChange =
new Quaternion(angularVelocity.X, angularVelocity.Y, angularVelocity.z, 0);
rotChange = Quaternion.Multiply(rotChange, dampeningFactor) * rotation;
rotation += rotChange * dt;
rotation.Normalize();
angularVelocity = newAngularVelocity;
angularAcceleration = Vector3.Zero;
Hopefully this proves helpful to someone else!
No comments:
Post a Comment