private static NewtonTire CreateTire(TireID tireID, TransformNode tireTrans, GeometryNode carNode, float gravity) { NewtonTire tire = new NewtonTire(); Material tireMat = new Material(); tireMat.Diffuse = Color.Orange.ToVector4(); tireMat.Specular = Color.White.ToVector4(); tireMat.SpecularPower = 10; float tireRadius = 1.4f; GeometryNode tireNode = new GeometryNode("Race Car " + tireID + " Tire"); tireNode.Model = new Cylinder(tireRadius, tireRadius, 0.9f, 20); tireNode.Material = tireMat; carNode.AddChild(tireTrans); tireTrans.AddChild(tireNode); tire.Mass = 5.0f; tire.Width = 0.3f * 1.25f; tire.Radius = tireRadius; switch (tireID) { case TireID.FrontLeft: tire.TireOffsetMatrix = Matrix.CreateTranslation(new Vector3(-5.9f, 0, -3.0f)); break; case TireID.FrontRight: tire.TireOffsetMatrix = Matrix.CreateTranslation(new Vector3(-5.9f, 0, 3.0f)); break; case TireID.RearLeft: tire.TireOffsetMatrix = Matrix.CreateTranslation(new Vector3(5.0f, 0, -3.0f)); break; case TireID.RearRight: tire.TireOffsetMatrix = Matrix.CreateTranslation(new Vector3(5.0f, 0, 3.0f)); break; } // the tire will spin around the lateral axis of the same tire space tire.Pin = Vector3.UnitZ; tire.SuspensionLength = RaceCar.SUSPENSION_LENGTH; float x = RaceCar.SUSPENSION_LENGTH; tire.SuspensionSpring = (200.0f * (float)Math.Abs(gravity)) / x; //tireSuspesionSpring = (100.0f * dAbs (GRAVITY)) / x; float w = (float)Math.Sqrt(tire.SuspensionSpring); // a critically damped suspension act too jumpy for a race car tire.SuspensionShock = 1.0f * w; // make it a little super critical y damped //tireSuspesionShock = 2.0f * w; tire.CollisionID = 0x100; return(tire); }
public RaceCar(Object container, NewtonPhysics engine) : base(container) { this.engine = engine; //Crea los cuatro nodos de transformacion para las 4 Ruedas tireTransNode = new TransformNode[4]; for (int i = 0; i < 4; i++) { tireTransNode[i] = new TransformNode(); } // set the mass of the race car - Propiedad heredada mass = VEHICLE_MASS; // lower the center of the mass for a race car centerOfMass = -Vector3.UnitY * 1.5f; // sets up the callback function when body moves in the simulation transformCallback = delegate(IntPtr body, float[] matrix) { Matrix mat = MatrixHelper.FloatsToMatrix(matrix); // set the transformation of the vehicle body PhysicsWorldTransform = mat; Matrix invMat = Matrix.Invert(mat); float[] tireMatrix = new float[16]; NewtonTire tire = null; float sign = 0; float angle = 0; float brakePosition = 0; // set the global matrix for each tire for (IntPtr tyreId = Newton.NewtonVehicleGetFirstTireID(joint); tyreId != IntPtr.Zero; tyreId = Newton.NewtonVehicleGetNextTireID(joint, tyreId)) { int tireID = (int)GetTireID(tyreId); tire = tires[tireID]; Newton.NewtonVehicleGetTireMatrix(joint, tyreId, tireMatrix); // calculate the local matrix Matrix tireMat = MatrixHelper.GetRotationMatrix( MatrixHelper.FloatsToMatrix(tireMatrix) * invMat) * tire.TireOffsetMatrix; tire.TireMatrix = tireMat; tireTransNode[tireID].WorldTransformation = Matrix.CreateRotationX(MathHelper.PiOver2) * tireMat; // calcualte the parametric brake position brakePosition = tireMat.Translation.Y - tire.TireRefHeight; tire.BrakeMatrix = Matrix.CreateTranslation(0, tire.BrakeRefPosition.Y + brakePosition, 0); // set suspensionMatrix sign = (tire.BrakeRefPosition.Z > 0) ? 1 : -1; angle = (float)Math.Atan2(sign * brakePosition, Math.Abs(tire.BrakeRefPosition.Z)); Matrix rotationMatrix = new Matrix( 1, 0, 0, 0, 0, (float)Math.Cos(angle), (float)Math.Sin(angle), 0, 0, -(float)Math.Sin(angle), (float)Math.Cos(angle), 0, 0, 0, 0, 1); tire.AxelMatrix = rotationMatrix * tire.AxelMatrix; tire.SuspensionTopMatrix = rotationMatrix * tire.SuspensionTopMatrix; tire.SuspensionBottomMatrix = rotationMatrix * tire.SuspensionBottomMatrix; } }; forceCallback = delegate(IntPtr body) { float Ixx = 0, Iyy = 0, Izz = 0, tmpMass = 0; Newton.NewtonBodyGetMassMatrix(body, ref tmpMass, ref Ixx, ref Iyy, ref Izz); tmpMass *= (1.0f + (float)Math.Abs(GetSpeed()) / 20.0f); float[] force = Vector3Helper.ToFloats(engine.GravityDirection * engine.Gravity * tmpMass); Newton.NewtonBodySetForce(body, force); }; tireUpdate = delegate(IntPtr vehicleJoint) { NewtonTire tire = null; for (IntPtr tyreId = Newton.NewtonVehicleGetFirstTireID(vehicleJoint); tyreId != IntPtr.Zero; tyreId = Newton.NewtonVehicleGetNextTireID(vehicleJoint, tyreId)) { tire = tires[(int)GetTireID(tyreId)]; // If the tire is a front tire if ((tire == tires[(int)TireID.FrontLeft]) || (tire == tires[(int)TireID.FrontRight])) { float currSteerAngle = Newton.NewtonVehicleGetTireSteerAngle(vehicleJoint, tyreId); Newton.NewtonVehicleSetTireSteerAngle(vehicleJoint, tyreId, currSteerAngle + (tire.Steer - currSteerAngle) * 0.035f); } else // if the tire is a rear tire { Newton.NewtonVehicleSetTireTorque(vehicleJoint, tyreId, tire.Torque); if (tire.Brakes > 0) { // ask Newton for the precise acceleration needed to stop the tire float brakeAcceleration = Newton.NewtonVehicleTireCalculateMaxBrakeAcceleration(vehicleJoint, tyreId); // tell Newton you want this tire stoped but only if the torque need it is less than // the brakes pad can withstand (assume max brake pad torque is 500 newton * meter) Newton.NewtonVehicleTireSetBrakeAcceleration(vehicleJoint, tyreId, brakeAcceleration, 10000.0f); // set some side slip as function of the linear speed float speed = Newton.NewtonVehicleGetTireLongitudinalSpeed(vehicleJoint, tyreId); Newton.NewtonVehicleSetTireMaxSideSleepSpeed(vehicleJoint, tyreId, speed * 0.1f); } } } }; bodyLeaveCallback = delegate(IntPtr body) { Respawn(body); }; }
private static NewtonTire CreateTire(TireID tireID, TransformNode tireTrans, GeometryNode carNode, float gravity) { NewtonTire tire = new NewtonTire(); Material tireMat = new Material(); tireMat.Diffuse = Color.Orange.ToVector4(); tireMat.Specular = Color.White.ToVector4(); tireMat.SpecularPower = 10; float tireRadius = 0.7f; GeometryNode tireNode = new GeometryNode("Race Car " + tireID + " Tire"); tireNode.Model = new Cylinder(tireRadius, tireRadius, 0.3f, 20); tireNode.Material = tireMat; carNode.AddChild(tireTrans); tireTrans.AddChild(tireNode); tire.Mass = 5.0f; tire.Width = 0.3f * 1.25f; tire.Radius = tireRadius; switch (tireID) { case TireID.FrontLeft: tire.TireOffsetMatrix = Matrix.CreateTranslation(new Vector3(-1.5f, 0, -1f)); break; case TireID.FrontRight: tire.TireOffsetMatrix = Matrix.CreateTranslation(new Vector3(-1.5f, 0, 1f)); break; case TireID.RearLeft: tire.TireOffsetMatrix = Matrix.CreateTranslation(new Vector3(1.5f, 0, -1f)); break; case TireID.RearRight: tire.TireOffsetMatrix = Matrix.CreateTranslation(new Vector3(1.5f, 0, 1f)); break; } // the tire will spin around the lateral axis of the same tire space tire.Pin = Vector3.UnitZ; tire.SuspensionLength = RaceCar.SUSPENSION_LENGTH; // calculate the spring and damper contact for the subquestion // // from the equation of a simple spring the force is given by // a = k * x // where k is a spring constant and x is the displacement and a is the spring acceleration. // we desire that a rest length the acceleration generated by the spring equal that of the gravity // several gravity forces // m * gravity = k * SUSPENSION_LENGTH * 0.5f, float x = RaceCar.SUSPENSION_LENGTH; tire.SuspensionSpring = (200.0f * (float)Math.Abs(gravity)) / x; //tireSuspesionSpring = (100.0f * dAbs (GRAVITY)) / x; // from the equation of a simple spring / damper system // the system resonate at a frequency // w^2 = ks // // and the damping attenuation is given by // d = ks / 2.0f // where: // if d = w = 2 * pi * f -> the system is critically damped // if d > w < 2 * pi * f -> the system is super critically damped // if d < w < 2 * pi * f -> the system is under damped damped // for a vehicle we usually want a suspension that is about 10% super critically damped float w = (float)Math.Sqrt(tire.SuspensionSpring); // a critically damped suspension act too jumpy for a race car tire.SuspensionShock = 1.0f * w; // make it a little super critical y damped //tireSuspesionShock = 2.0f * w; tire.CollisionID = 0x100; return(tire); }