Beispiel #1
0
    //--------------------------------------------------------------
    #region Creation & Cleanup
    //--------------------------------------------------------------

    public VehicleObject(IServiceLocator services)
    {
      _services = services;
      Name = "Vehicle";

      _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 Vehicle(_simulation, chassis);

      // Add 4 wheels.
      Vehicle.Wheels.Add(new Wheel { 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 Wheel { 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 Wheel { 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 Wheel { 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;

    }
 //--------------------------------------------------------------
 /// <summary>
 /// Initializes a new instance of the <see cref="VehicleForceEffect"/> class.
 /// </summary>
 /// <param name="vehicle">The vehicle.</param>
 internal VehicleForceEffect(Vehicle vehicle)
 {
     Debug.Assert(vehicle != null);
       Vehicle = vehicle;
 }