示例#1
0
        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.
                    Vector3F relativeContactVelocity = vehicle.Chassis.GetVelocityOfWorldPoint(wheel.GroundPosition)
                                                       - wheel.TouchedBody.GetVelocityOfWorldPoint(wheel.GroundPosition);
                    float forwardVelocity = Vector3F.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;
            }
        }
示例#2
0
    // 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);
    }
示例#3
0
        // 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);
        }
示例#4
0
    // 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;
        }
      }
    }
示例#5
0
        // 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;
                }
            }
        }
示例#6
0
    //--------------------------------------------------------------
    #region Creation & Cleanup
    //--------------------------------------------------------------

    public ConstraintVehicleObject(IServiceLocator services)
    {
      Name = "Vehicle";

      _services = services;
      _inputService = services.GetInstance<IInputService>();

      _simulation = services.GetInstance<Simulation>();

      // Load models for rendering.
      var contentManager = services.GetInstance<ContentManager>();
      _vehicleModelNode = contentManager.Load<ModelNode>("Car/Car").Clone();
      _wheelModelNodes = new ModelNode[4];
      _wheelModelNodes[0] = contentManager.Load<ModelNode>("Car/Wheel").Clone();
      _wheelModelNodes[1] = _wheelModelNodes[0].Clone();
      _wheelModelNodes[2] = _wheelModelNodes[0].Clone();
      _wheelModelNodes[3] = _wheelModelNodes[0].Clone();

      // Add wheels under the car model node.
      _vehicleModelNode.Children.Add(_wheelModelNodes[0]);
      _vehicleModelNode.Children.Add(_wheelModelNodes[1]);
      _vehicleModelNode.Children.Add(_wheelModelNodes[2]);
      _vehicleModelNode.Children.Add(_wheelModelNodes[3]);

      // ----- Create the chassis of the car.
      // The Vehicle needs a rigid body that represents the chassis. This can be any shape (e.g.
      // a simple BoxShape). In this example we will build a convex polyhedron from the car model.

      // 1. Extract the vertices from the car model.
      // The car model has ~10,000 vertices. It consists of a MeshNode for the glass
      // parts and a MeshNode "Car" for the chassis.
      var meshNode = _vehicleModelNode.GetDescendants()
                                      .OfType<MeshNode>()
                                      .First(mn => mn.Name == "Car");
      var mesh = MeshHelper.ToTriangleMesh(meshNode.Mesh);
      // Apply the transformation of the mesh node.
      mesh.Transform(meshNode.PoseWorld * Matrix44F.CreateScale(meshNode.ScaleWorld));

      // 2. (Optional) Create simplified convex hull from mesh.
      // We could also skip this step and directly create a convex polyhedron from the mesh using
      //    var chassisShape = new ConvexPolyhedron(mesh.Vertices);
      // However, the convex polyhedron would still have 500-600 vertices. 
      // We can reduce the number of vertices by using the GeometryHelper.
      // Create a convex hull for mesh with max. 64 vertices. Additional, shrink the hull by 4 cm.
      var convexHull = GeometryHelper.CreateConvexHull(mesh.Vertices, 64, -0.04f);

      // 3. Create convex polyhedron shape using the vertices of the convex hull.
      var chassisShape = new ConvexPolyhedron(convexHull.Vertices.Select(v => v.Position));

      // (Note: Building convex hulls and convex polyhedra are time-consuming. To save loading time 
      // we should build the shape in the XNA content pipeline. See other DigitalRune Physics 
      // Samples.)

      // The mass properties of the car. We use a mass of 800 kg.
      var mass = MassFrame.FromShapeAndMass(chassisShape, Vector3F.One, 800, 0.1f, 1);

      // Trick: We artificially modify the center of mass of the rigid body. Lowering the center
      // of mass makes the car more stable against rolling in tight curves. 
      // We could also modify mass.Inertia for other effects.
      var pose = mass.Pose;
      pose.Position.Y -= 0.5f; // Lower the center of mass.
      pose.Position.Z = -0.5f; // The center should be below the driver. 
      // (Note: The car model is not exactly centered.)
      mass.Pose = pose;

      // Material for the chassis.
      var material = new UniformMaterial
      {
        Restitution = 0.1f,
        StaticFriction = 0.2f,
        DynamicFriction = 0.2f
      };

      var chassis = new RigidBody(chassisShape, mass, material)
      {
        Pose = new Pose(new Vector3F(0, 2, 0)),  // Start position
        UserData = "NoDraw",                     // (Remove this line to render the collision model.)
      };

      // ----- Create the vehicle.
      Vehicle = new ConstraintVehicle(_simulation, chassis);

      // Add 4 wheels.
      Vehicle.Wheels.Add(new ConstraintWheel { Offset = new Vector3F(-0.9f, 0.6f, -2.0f), Radius = 0.36f, SuspensionRestLength = 0.55f, MinSuspensionLength = 0.25f, Friction = 2 });  // Front left
      Vehicle.Wheels.Add(new ConstraintWheel { Offset = new Vector3F(0.9f, 0.6f, -2.0f), Radius = 0.36f, SuspensionRestLength = 0.55f, MinSuspensionLength = 0.25f, Friction = 2 });   // Front right
      Vehicle.Wheels.Add(new ConstraintWheel { Offset = new Vector3F(-0.9f, 0.6f, 0.98f), Radius = 0.36f, SuspensionRestLength = 0.55f, MinSuspensionLength = 0.25f, Friction = 1.8f });// Back left
      Vehicle.Wheels.Add(new ConstraintWheel { Offset = new Vector3F(0.9f, 0.6f, 0.98f), Radius = 0.36f, SuspensionRestLength = 0.55f, MinSuspensionLength = 0.25f, Friction = 1.8f }); // Back right

      // Vehicles are disabled per default. This way we can create the vehicle and the simulation
      // objects are only added when needed.
      Vehicle.Enabled = false;

    }
示例#7
0
    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.
          Vector3F relativeContactVelocity = vehicle.Chassis.GetVelocityOfWorldPoint(wheel.GroundPosition)
                                             - wheel.TouchedBody.GetVelocityOfWorldPoint(wheel.GroundPosition);
          float forwardVelocity = Vector3F.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;
      }
    }