private static void UpdateWheelVelocity(float deltaTime, ConstraintVehicle vehicle, ConstraintWheel wheel) { if (wheel.Tag == 1) { wheel.Tag = 0; if (Numeric.IsZero(wheel.BrakeForce)) { // We set the angular velocity, so that the wheel matches the moving underground. Vector3 relativeContactVelocity = vehicle.Chassis.GetVelocityOfWorldPoint(wheel.GroundPosition) - wheel.TouchedBody.GetVelocityOfWorldPoint(wheel.GroundPosition); float forwardVelocity = Vector3.Dot(relativeContactVelocity, wheel.GroundForward); wheel.AngularVelocity = forwardVelocity / wheel.Radius; wheel.RotationAngle += wheel.AngularVelocity * deltaTime; } else { // Braking wheels do not rotate. wheel.AngularVelocity = 0; } } else { // To keep it simple: The wheel continues spinning in the same direction. // Damp angular velocity and update rotation angle. wheel.AngularVelocity *= 0.99f; wheel.RotationAngle += wheel.AngularVelocity * deltaTime; } }
// Creates or gets the ConstraintVehicleHandler instance and adds a vehicle. internal static void Add(ConstraintVehicle vehicle) { var simulation = vehicle.Simulation; var handler = GetHandler(simulation); if (handler == null) { // The first vehicle: Add a new instance of this class to the simulation. handler = new ConstraintVehicleHandler(); simulation.ForceEffects.Add(handler); simulation.SubTimeStepFinished += handler.OnSubTimeStepFinished; } handler._vehicles.Add(vehicle); }
// Removes a vehicle. When the last vehicle is removed, the ConstraintVehicleHandler // instance is removed too. internal static void Remove(ConstraintVehicle vehicle) { Simulation simulation = vehicle.Simulation; ConstraintVehicleHandler handler = GetHandler(simulation); if (handler != null) { handler._vehicles.Remove(vehicle); // The last vehicle was removed. if (handler._vehicles.Count == 0) { simulation.ForceEffects.Remove(handler); simulation.SubTimeStepFinished -= handler.OnSubTimeStepFinished; } } }