示例#1
0
    // OnLoad() is called when the GameObject is added to the IGameObjectService.
    protected override void OnLoad()
    {
      var contentManager = _services.GetInstance<ContentManager>();
      
      // A rusty barrel with multiple levels of detail (LODs).
      _rigidBody = new RigidBody(new CylinderShape(0.35f, 1));
      _modelNode0 = contentManager.Load<ModelNode>("Barrel/Barrel").Clone();
      SampleHelper.EnablePerPixelLighting(_modelNode0);

      // Mark the LOD nodes with UserFlags = 1.
      _modelNode0.GetDescendants()
                 .OfType<LodGroupNode>()
                 .SelectMany(lodGroupNode => lodGroupNode.Levels)
                 .Select(level => level.Node)
                 .ForEach(node =>
                          {
                            node.UserFlags = 1;
                          });

      // Add a second model where each LOD has a different color.
      _modelNode1 = contentManager.Load<ModelNode>("Barrel/Barrel_Colored").Clone();
      SampleHelper.EnablePerPixelLighting(_modelNode1);

      // Mark the LOD nodes with UserFlags = 2.
      _modelNode1.GetDescendants()
                 .OfType<LodGroupNode>()
                 .SelectMany(lodGroupNode => lodGroupNode.Levels)
                 .Select(level => level.Node)
                 .ForEach(node =>
                         {
                           node.UserFlags = 2;
                         });


      // Set a random pose.
      var randomPosition = new Vector3F(
        RandomHelper.Random.NextFloat(-10, 10),
        RandomHelper.Random.NextFloat(2, 5),
        RandomHelper.Random.NextFloat(-10, 0));
      _rigidBody.Pose = new Pose(randomPosition, RandomHelper.Random.NextQuaternionF());
      _modelNode0.PoseWorld = _rigidBody.Pose;
      _modelNode1.PoseWorld = _rigidBody.Pose;

      // Add rigid body to physics simulation and models to scene.
      var simulation = _services.GetInstance<Simulation>();
      simulation.RigidBodies.Add(_rigidBody);

      var scene = _services.GetInstance<IScene>();
      scene.Children.Add(_modelNode0);
      scene.Children.Add(_modelNode1);
    }
示例#2
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;

    }
示例#3
0
    private void SetRandomColorAndAlpha(ModelNode model)
    {
      var randomColor3F = RandomHelper.Random.NextVector3F(0, 4);

      // Desaturate random color to avoid eye cancer. ;-)
      float luminance = Vector3F.Dot(randomColor3F, GraphicsHelper.LuminanceWeights);
      var randomColor = (Vector3)InterpolationHelper.Lerp(new Vector3F(luminance), randomColor3F, 0.5f);

      var randomAlpha = MathHelper.Clamp(RandomHelper.Random.NextFloat(0, 5), 0, 1);

      // Change the values of all effect parameters "InstanceColor" and "InstanceAlpha":
      foreach (MeshNode meshNode in model.GetDescendants().OfType<MeshNode>())
      {
        foreach (MaterialInstance materialInstance in meshNode.MaterialInstances)
        {
          foreach (EffectBinding effectBinding in materialInstance.EffectBindings)
          {
            if (effectBinding.ParameterBindings.Contains("InstanceColor"))
              effectBinding.Set("InstanceColor", randomColor);
            if (effectBinding.ParameterBindings.Contains("InstanceAlpha"))
              effectBinding.Set("InstanceAlpha", randomAlpha);
          }
        }
      }
    }