/// <summary> /// Applies the Steering Force to the current Velocity and Speed values /// </summary> /// <param name="gameTime"></param> /// <remarks>Override this method to modify how the computed Steering Force is applied</remarks> public virtual void ApplySteeringForce(GameTime gameTime) { Vector3 newAcceleration = _steeringForce / Mass; if (gameTime.ElapsedGameTime.TotalSeconds > 0) { float smoothRate = MathHelper.Clamp(9 * (float)gameTime.ElapsedGameTime.TotalSeconds, 0.15f, 0.4f); MathExtensions.BlendIntoAccumulator(smoothRate, newAcceleration, ref _acceleration); } Velocity += _acceleration * (float)gameTime.ElapsedGameTime.TotalSeconds; if (MaxSpeed > 0) { Velocity = Vector3Extensions.Truncate(Velocity, MaxSpeed); } if (MinSpeed > 0) { Velocity = Vector3Extensions.Extend(Velocity, MinSpeed); } if (Velocity.LengthSquared() > 0.000000001f) { if (SmoothRotation) { Velocity = AdjustVelocityForSmoothRotation(gameTime); } VelocityForward = Vector3.Normalize(Velocity); VelocityRight = Vector3.Normalize(Vector3.Cross(VelocityForward, VelocityUp)); VelocityUp = Vector3.Normalize(Vector3.Cross(VelocityRight, VelocityForward)); if (UsesBanking) { // the length of this global-upward-pointing vector controls the vehicle's // tendency to right itself as it is rolled over from turning acceleration var globalUp = new Vector3(0, 0.25f, 0); Vector3 accelerationUp = _acceleration * 0.05f; Vector3 bankUp = accelerationUp + globalUp; bankUp.Z = 0f; float smoothRate = (float)gameTime.ElapsedGameTime.TotalSeconds * 3; Vector3 tempUp = VelocityUp; MathExtensions.BlendIntoAccumulator(smoothRate, bankUp, ref tempUp); VelocityUp = Vector3.Normalize(tempUp); VelocityRight = Vector3.Normalize(Vector3.Cross(VelocityForward, VelocityUp)); } } Speed = Velocity.Length(); }