Пример #1
0
    // Creates a test scene with a lot of randomly placed objects.
    internal static void CreateScene(ServiceContainer services, ContentManager content, DeferredGraphicsScreen graphicsScreen)
    {
      var gameObjectService = services.GetInstance<IGameObjectService>();
      var graphicsService = services.GetInstance<IGraphicsService>();

      gameObjectService.Objects.Add(new DynamicSkyObject(services, true, false, true)
      {
        EnableAmbientLight = false, // Disable ambient light of sky to make shadows more visible.
        EnableCloudShadows = false
      });

      gameObjectService.Objects.Add(new GroundObject(services));
      gameObjectService.Objects.Add(new DynamicObject(services, 1));
      gameObjectService.Objects.Add(new DynamicObject(services, 2));
      gameObjectService.Objects.Add(new DynamicObject(services, 3));
      gameObjectService.Objects.Add(new DynamicObject(services, 5));
      gameObjectService.Objects.Add(new DynamicObject(services, 6));
      gameObjectService.Objects.Add(new DynamicObject(services, 7));
      gameObjectService.Objects.Add(new ObjectCreatorObject(services));
      gameObjectService.Objects.Add(new LavaBallsObject(services));

      var random = new Random();

      // Spheres
      var sphereMesh = SampleHelper.CreateMesh(content, graphicsService, new SphereShape(1));
      for (int i = 0; i < 100; i++)
      {
        Vector3F position = new Vector3F(random.NextFloat(-100, 100), random.NextFloat(0, 3), random.NextFloat(-100, 100));
        float scale = random.NextFloat(0.5f, 3f);
        var meshNode = new MeshNode(sphereMesh)
        {
          PoseLocal = new Pose(position),
          ScaleLocal = new Vector3F(scale),
          IsStatic = true,
        };
        graphicsScreen.Scene.Children.Add(meshNode);
      }

      // Boxes
      var boxMesh = SampleHelper.CreateMesh(content, graphicsService, new BoxShape(1, 1, 1));
      for (int i = 0; i < 100; i++)
      {
        Vector3F position = new Vector3F(random.NextFloat(-100, 100), random.NextFloat(0, 3), random.NextFloat(-100, 100));
        QuaternionF orientation = random.NextQuaternionF();
        Vector3F scale = random.NextVector3F(0.1f, 4f);
        var meshNode = new MeshNode(boxMesh)
        {
          PoseLocal = new Pose(position, orientation),
          ScaleLocal = scale,
          IsStatic = true,
        };
        graphicsScreen.Scene.Children.Add(meshNode);
      }

      // Height field with smooth hills.
      var numberOfSamplesX = 20;
      var numberOfSamplesZ = 20;
      var samples = new float[numberOfSamplesX * numberOfSamplesZ];
      for (int z = 0; z < numberOfSamplesZ; z++)
      {
        for (int x = 0; x < numberOfSamplesX; x++)
        {
          if (x == 0 || z == 0 || x == 19 || z == 19)
          {
            // Set this boundary elements to a low height, so that the height field is connected
            // to the ground.
            samples[z * numberOfSamplesX + x] = -1;
          }
          else
          {
            // A sine/cosine function that creates some interesting waves.
            samples[z * numberOfSamplesX + x] = 1 + (float)(Math.Cos(z / 2f) * Math.Sin(x / 2f) * 1);
          }
        }
      }
      var heightField = new HeightField(0, 0, 20, 20, samples, numberOfSamplesX, numberOfSamplesZ);
      var heightFieldMesh = SampleHelper.CreateMesh(content, graphicsService, heightField);
      var heightFieldMeshNode = new MeshNode(heightFieldMesh)
      {
        PoseLocal = new Pose(new Vector3F(20, 0, -20)),
        ScaleLocal = new Vector3F(1, 2, 1),
        IsStatic = true,
      };
      graphicsScreen.Scene.Children.Add(heightFieldMeshNode);

      // Dudes.
      for (int i = 0; i < 10; i++)
      {
        Vector3F position = new Vector3F(random.NextFloat(-20, 20), 0, random.NextFloat(-20, 20));
        Matrix33F orientation = Matrix33F.CreateRotationY(random.NextFloat(0, ConstantsF.TwoPi));
        gameObjectService.Objects.Add(new DudeObject(services) { Pose = new Pose(position, orientation) });
      }

      // Palm trees.
      for (int i = 0; i < 100; i++)
      {
        Vector3F position = new Vector3F(random.NextFloat(-80, 80), 0, random.NextFloat(-100, 100));
        Matrix33F orientation = Matrix33F.CreateRotationY(random.NextFloat(0, ConstantsF.TwoPi));
        float scale = random.NextFloat(0.5f, 1.2f);
        gameObjectService.Objects.Add(new StaticObject(services, "PalmTree/palm_tree", scale, new Pose(position, orientation)));
      }

      // Rocks
      for (int i = 0; i < 100; i++)
      {
        Vector3F position = new Vector3F(random.NextFloat(-80, 80), 1, random.NextFloat(-100, 100));
        QuaternionF orientation = RandomHelper.Random.NextQuaternionF();
        float scale = random.NextFloat(0.5f, 1.2f);
        gameObjectService.Objects.Add(new StaticObject(services, "Rock/rock_05", scale, new Pose(position, orientation)));
      }

      // Grass
      for (int i = 0; i < 100; i++)
      {
        Vector3F position = new Vector3F(random.NextFloat(-20, 20), 0, random.NextFloat(-20, 20));
        Matrix33F orientation = Matrix33F.CreateRotationY(random.NextFloat(0, ConstantsF.TwoPi));
        float scale = random.NextFloat(0.5f, 1.2f);
        gameObjectService.Objects.Add(new StaticObject(services, "Grass/Grass", scale, new Pose(position, orientation)));
      }

      // More plants
      for (int i = 0; i < 100; i++)
      {
        Vector3F position = new Vector3F(random.NextFloat(-20, 20), 0, random.NextFloat(-20, 20));
        Matrix33F orientation = Matrix33F.CreateRotationY(random.NextFloat(0, ConstantsF.TwoPi));
        float scale = random.NextFloat(0.5f, 1.2f);
        gameObjectService.Objects.Add(new StaticObject(services, "Parviflora/Parviflora", scale, new Pose(position, orientation)));
      }

      // "Skyscrapers"
      for (int i = 0; i < 20; i++)
      {
        Vector3F position = new Vector3F(random.NextFloat(90, 100), 0, random.NextFloat(-100, 100));
        Matrix33F orientation = Matrix33F.CreateRotationY(random.NextFloat(0, ConstantsF.TwoPi));
        Vector3F scale = new Vector3F(random.NextFloat(6, 20), random.NextFloat(10, 100), random.NextFloat(6, 20));
        var meshNode = new MeshNode(boxMesh)
        {
          PoseLocal = new Pose(position, orientation),
          ScaleLocal = scale,
          IsStatic = true,
          UserFlags = 1, // Mark the distant huge objects. Used in render callbacks in the CompositeShadowSample.
        };
        graphicsScreen.Scene.Children.Add(meshNode);
      }

      // "Hills"
      for (int i = 0; i < 20; i++)
      {
        Vector3F position = new Vector3F(random.NextFloat(-90, -100), 0, random.NextFloat(-100, 100));
        Vector3F scale = new Vector3F(random.NextFloat(10, 20), random.NextFloat(10, 30), random.NextFloat(10, 20));
        var meshNode = new MeshNode(sphereMesh)
        {
          PoseLocal = new Pose(position),
          ScaleLocal = scale,
          IsStatic = true,
          UserFlags = 1, // Mark the distant huge objects. Used in render callbacks in the CompositeShadowSample.
        };
        graphicsScreen.Scene.Children.Add(meshNode);
      }
    }
Пример #2
0
    // Creates a lot of random objects.
    private void CreateRandomObjects()
    {
      var random = new Random();

      var isFirstHeightField = true;

      int currentShape = 0;
      int numberOfObjects = 0;
      while (true)
      {
        numberOfObjects++;
        if (numberOfObjects > ObjectsPerType)
        {
          currentShape++;
          numberOfObjects = 0;
        }

        Shape shape;
        switch (currentShape)
        {
          case 0:
            // Box
            shape = new BoxShape(ObjectSize, ObjectSize * 2, ObjectSize * 3);
            break;
          case 1:
            // Capsule
            shape = new CapsuleShape(0.3f * ObjectSize, 2 * ObjectSize);
            break;
          case 2:
            // Cone
            shape = new ConeShape(1 * ObjectSize, 2 * ObjectSize);
            break;
          case 3:
            // Cylinder
            shape = new CylinderShape(0.4f * ObjectSize, 2 * ObjectSize);
            break;
          case 4:
            // Sphere
            shape = new SphereShape(ObjectSize);
            break;
          case 5:
            // Convex hull of several points.
            ConvexHullOfPoints hull = new ConvexHullOfPoints();
            hull.Points.Add(new Vector3F(-1 * ObjectSize, -2 * ObjectSize, -1 * ObjectSize));
            hull.Points.Add(new Vector3F(2 * ObjectSize, -1 * ObjectSize, -0.5f * ObjectSize));
            hull.Points.Add(new Vector3F(1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize));
            hull.Points.Add(new Vector3F(-1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize));
            hull.Points.Add(new Vector3F(-1 * ObjectSize, 0.7f * ObjectSize, -0.6f * ObjectSize));
            shape = hull;
            break;
          case 6:
            // A composite shape: two boxes that form a "T" shape.
            var composite = new CompositeShape();
            composite.Children.Add(
              new GeometricObject(
                new BoxShape(ObjectSize, 3 * ObjectSize, ObjectSize),
                new Pose(new Vector3F(0, 0, 0))));
            composite.Children.Add(
              new GeometricObject(
                new BoxShape(2 * ObjectSize, ObjectSize, ObjectSize),
                new Pose(new Vector3F(0, 2 * ObjectSize, 0))));
            shape = composite;
            break;
          case 7:
            shape = new CircleShape(ObjectSize);
            break;
          case 8:
            {
              var compBvh = new CompositeShape();
              compBvh.Children.Add(new GeometricObject(new BoxShape(0.5f, 1, 0.5f), new Pose(new Vector3F(0, 0.5f, 0), Matrix33F.Identity)));
              compBvh.Children.Add(new GeometricObject(new BoxShape(0.8f, 0.5f, 0.5f), new Pose(new Vector3F(0.5f, 0.7f, 0), Matrix33F.CreateRotationZ(-MathHelper.ToRadians(15)))));
              compBvh.Children.Add(new GeometricObject(new SphereShape(0.3f), new Pose(new Vector3F(0, 1.15f, 0), Matrix33F.Identity)));
              compBvh.Children.Add(new GeometricObject(new CapsuleShape(0.2f, 1), new Pose(new Vector3F(0.6f, 1.15f, 0), Matrix33F.CreateRotationX(0.3f))));
              compBvh.Partition = new AabbTree<int>();
              shape = compBvh;
              break;
            }
          case 9:
            CompositeShape comp = new CompositeShape();
            comp.Children.Add(new GeometricObject(new BoxShape(0.5f * ObjectSize, 1 * ObjectSize, 0.5f * ObjectSize), new Pose(new Vector3F(0, 0.5f * ObjectSize, 0), QuaternionF.Identity)));
            comp.Children.Add(new GeometricObject(new BoxShape(0.8f * ObjectSize, 0.5f * ObjectSize, 0.5f * ObjectSize), new Pose(new Vector3F(0.3f * ObjectSize, 0.7f * ObjectSize, 0), QuaternionF.CreateRotationZ(-MathHelper.ToRadians(45)))));
            comp.Children.Add(new GeometricObject(new SphereShape(0.3f * ObjectSize), new Pose(new Vector3F(0, 1.15f * ObjectSize, 0), QuaternionF.Identity)));
            shape = comp;
            break;
          case 10:
            shape = new ConvexHullOfPoints(new[]
            {
              new Vector3F(-1 * ObjectSize, -2 * ObjectSize, -1 * ObjectSize),
              new Vector3F(2 * ObjectSize, -1 * ObjectSize, -0.5f * ObjectSize),
              new Vector3F(1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize),
              new Vector3F(-1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize),
              new Vector3F(-1 * ObjectSize, 0.7f * ObjectSize, -0.6f * ObjectSize)
            });
            break;
          case 11:
            ConvexHullOfShapes shapeHull = new ConvexHullOfShapes();
            shapeHull.Children.Add(new GeometricObject(new SphereShape(0.3f * ObjectSize), new Pose(new Vector3F(0, 2 * ObjectSize, 0), Matrix33F.Identity)));
            shapeHull.Children.Add(new GeometricObject(new BoxShape(1 * ObjectSize, 2 * ObjectSize, 3 * ObjectSize), Pose.Identity));
            shape = shapeHull;
            break;
          case 12:
            shape = Shape.Empty;
            break;
          case 13:
            var numberOfSamplesX = 10;
            var numberOfSamplesZ = 10;
            var samples = new float[numberOfSamplesX * numberOfSamplesZ];
            for (int z = 0; z < numberOfSamplesZ; z++)
              for (int x = 0; x < numberOfSamplesX; x++)
                samples[z * numberOfSamplesX + x] = (float)(Math.Cos(z / 3f) * Math.Sin(x / 2f) * BoxSize / 6);
            HeightField heightField = new HeightField(0, 0, 2 * BoxSize, 2 * BoxSize, samples, numberOfSamplesX, numberOfSamplesZ);
            shape = heightField;
            break;
          //case 14:
          //shape = new LineShape(new Vector3F(0.1f, 0.2f, 0.3f), new Vector3F(0.1f, 0.2f, -0.3f).Normalized);
          //break;            
          case 15:
            shape = new LineSegmentShape(
              new Vector3F(0.1f, 0.2f, 0.3f), new Vector3F(0.1f, 0.2f, 0.3f) + 3 * ObjectSize * new Vector3F(0.1f, 0.2f, -0.3f));
            break;
          case 16:
            shape = new MinkowskiDifferenceShape
            {
              ObjectA = new GeometricObject(new SphereShape(0.1f * ObjectSize)),
              ObjectB = new GeometricObject(new BoxShape(1 * ObjectSize, 2 * ObjectSize, 3 * ObjectSize))
            };
            break;
          case 17:
            shape = new MinkowskiSumShape
            {
              ObjectA = new GeometricObject(new SphereShape(0.1f * ObjectSize)),
              ObjectB = new GeometricObject(new BoxShape(1 * ObjectSize, 2 * ObjectSize, 3 * ObjectSize)),
            };
            break;
          case 18:
            shape = new OrthographicViewVolume(0, ObjectSize, 0, ObjectSize, ObjectSize / 2, ObjectSize * 2);
            break;
          case 19:
            shape = new PerspectiveViewVolume(MathHelper.ToRadians(60f), 16f / 10, ObjectSize / 2, ObjectSize * 3);
            break;
          case 20:
            shape = new PointShape(0.1f, 0.3f, 0.2f);
            break;
          case 21:
            shape = new RayShape(new Vector3F(0.2f, 0, -0.12f), new Vector3F(1, 2, 3).Normalized, ObjectSize * 2);
            break;
          case 22:
            shape = new RayShape(new Vector3F(0.2f, 0, -0.12f), new Vector3F(1, 2, 3).Normalized, ObjectSize * 2)
            {
              StopsAtFirstHit = true
            };
            break;
          case 23:
            shape = new RectangleShape(ObjectSize, ObjectSize * 2);
            break;
          case 24:
            shape = new TransformedShape(
              new GeometricObject(
                new BoxShape(1 * ObjectSize, 2 * ObjectSize, 3 * ObjectSize),
                new Pose(new Vector3F(0.1f, 1, -0.2f))));
            break;
          case 25:
            shape = new TriangleShape(
              new Vector3F(ObjectSize, 0, 0), new Vector3F(0, ObjectSize, 0), new Vector3F(ObjectSize, ObjectSize, ObjectSize));
            break;
          //case 26:
          //  {
          //    // Create a composite object from which we get the mesh.
          //    CompositeShape compBvh = new CompositeShape();
          //    compBvh.Children.Add(new GeometricObject(new BoxShape(0.5f, 1, 0.5f), new Pose(new Vector3F(0, 0.5f, 0), Matrix33F.Identity)));
          //    compBvh.Children.Add(
          //      new GeometricObject(
          //        new BoxShape(0.8f, 0.5f, 0.5f),
          //        new Pose(new Vector3F(0.5f, 0.7f, 0), Matrix33F.CreateRotationZ(-(float)MathHelper.ToRadians(15)))));
          //    compBvh.Children.Add(new GeometricObject(new SphereShape(0.3f), new Pose(new Vector3F(0, 1.15f, 0), Matrix33F.Identity)));
          //    compBvh.Children.Add(
          //      new GeometricObject(new CapsuleShape(0.2f, 1), new Pose(new Vector3F(0.6f, 1.15f, 0), Matrix33F.CreateRotationX(0.3f))));

          //    TriangleMeshShape meshBvhShape = new TriangleMeshShape { Mesh = compBvh.GetMesh(0.01f, 3) };
          //    meshBvhShape.Partition = new AabbTree<int>();
          //    shape = meshBvhShape;
          //    break;
          //  }
          //case 27:
          //  {
          //    // Create a composite object from which we get the mesh.
          //    CompositeShape compBvh = new CompositeShape();
          //    compBvh.Children.Add(new GeometricObject(new BoxShape(0.5f, 1, 0.5f), new Pose(new Vector3F(0, 0.5f, 0), QuaternionF.Identity)));
          //    compBvh.Children.Add(
          //      new GeometricObject(
          //        new BoxShape(0.8f, 0.5f, 0.5f),
          //        new Pose(new Vector3F(0.5f, 0.7f, 0), QuaternionF.CreateRotationZ(-(float)MathHelper.ToRadians(15)))));
          //    compBvh.Children.Add(new GeometricObject(new SphereShape(0.3f), new Pose(new Vector3F(0, 1.15f, 0), QuaternionF.Identity)));
          //    compBvh.Children.Add(
          //      new GeometricObject(new CapsuleShape(0.2f, 1), new Pose(new Vector3F(0.6f, 1.15f, 0), QuaternionF.CreateRotationX(0.3f))));

          //    TriangleMeshShape meshBvhShape = new TriangleMeshShape { Mesh = compBvh.GetMesh(0.01f, 3) };
          //    meshBvhShape.Partition = new AabbTree<int>();
          //    shape = meshBvhShape;
          //    break;
          //  }
          case 28:
            shape = new ConvexPolyhedron(new[]
            {
              new Vector3F(-1 * ObjectSize, -2 * ObjectSize, -1 * ObjectSize),
              new Vector3F(2 * ObjectSize, -1 * ObjectSize, -0.5f * ObjectSize),
              new Vector3F(1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize),
              new Vector3F(-1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize),
              new Vector3F(-1 * ObjectSize, 0.7f * ObjectSize, -0.6f * ObjectSize)
            });
            break;
          case 29:
            return;
          default:
            currentShape++;
            continue;
        }

        // Create an object with the random shape, pose, color and velocity.
        Pose randomPose = new Pose(
          random.NextVector3F(-BoxSize + ObjectSize * 2, BoxSize - ObjectSize * 2),
          random.NextQuaternionF());
        var newObject = new MovingGeometricObject
        {
          Pose = randomPose,
          Shape = shape,
          LinearVelocity = random.NextQuaternionF().Rotate(new Vector3F(MaxLinearVelocity, 0, 0)),
          AngularVelocity = random.NextQuaternionF().Rotate(Vector3F.Forward)
                            * RandomHelper.Random.NextFloat(0, MaxAngularVelocity),
        };

        if (RandomHelper.Random.NextBool())
          newObject.LinearVelocity = Vector3F.Zero;
        if (RandomHelper.Random.NextBool())
          newObject.AngularVelocity = Vector3F.Zero;

        if (shape is LineShape || shape is HeightField)
        {
          // Do not move lines or the height field.
          newObject.LinearVelocity = Vector3F.Zero;
          newObject.AngularVelocity = Vector3F.Zero;
        }

        // Create only 1 heightField!
        if (shape is HeightField)
        {
          if (isFirstHeightField)
          {
            isFirstHeightField = true;
            newObject.Pose = new Pose(new Vector3F(-BoxSize, -BoxSize, -BoxSize));
          }
          else
          {
            currentShape++;
            numberOfObjects = 0;
            continue;
          }
        }

        // Add collision object to collision domain.
        _domain.CollisionObjects.Add(new CollisionObject(newObject));

        //co.Type = CollisionObjectType.Trigger;
        //co.Name = "Object" + shape.GetType().Name + "_" + i;
      }
    }
Пример #3
0
    public override void Update(GameTime gameTime)
    {
      Random random = new Random(1234567);

      // The debug renderer stores all draw commands. In this sample we recreate 
      // the draw jobs each frame. --> Clear draw jobs of last frame.
      _debugRenderer.Clear();

      // The DebugRenderer can draw stuff "in" the scene (enabled z test) or "over" 
      // the scene (disabled z test). 

      // Draw some points and line "in" and "over" the scene.
      for (int i = 0; i < 10; i++)
      {
        var position = new Vector3F(-6, 0, -3) + random.NextVector3F(-0.5f, 0.5f);
        _debugRenderer.DrawPoint(position, Color.Green, false);
      }

      for (int i = 0; i < 10; i++)
      {
        var position = new Vector3F(-4, 0, -3) + random.NextVector3F(-0.5f, 0.5f);
        _debugRenderer.DrawPoint(position, Color.Yellow, true);
      }

      for (int i = 0; i < 10; i++)
      {
        var start = new Vector3F(-2, 0, -3) + random.NextVector3F(-0.5f, 0.5f);
        var end = new Vector3F(-2, 0, -3) + random.NextVector3F(-0.5f, 0.5f);
        _debugRenderer.DrawLine(start, end, Color.Green, false);
      }

      for (int i = 0; i < 10; i++)
      {
        var start = new Vector3F(0, 0, -3) + random.NextVector3F(-0.5f, 0.5f);
        var end = new Vector3F(0, 0, -3) + random.NextVector3F(-0.5f, 0.5f);
        _debugRenderer.DrawLine(start, end, Color.Yellow, true);
      }

      // Text without a specified position is drawn at a default position.
      _debugRenderer.DefaultTextPosition = new Vector2F(10, 100);
      _debugRenderer.DrawText("White objects are positioned in screen space.");
      _debugRenderer.DrawText("Yellow objects are positioned in world space. Depth test disabled.");
      _debugRenderer.DrawText("Other objects are positioned in world space. Depth test enabled.");

      // Text can also be drawn in world space coordinates or in screen space coordinates.
      _debugRenderer.DrawText("WorldSpacePosition (0, 0, 0)", new Vector3F(0, 0, 0), Color.Green, false);
      _debugRenderer.DrawText("WorldSpacePosition (0, 0, -1)", new Vector3F(0, 0, -1), Color.Yellow, true);
      _debugRenderer.DrawText("ScreenPosition (600, 40)", new Vector2F(600, 40), Color.White);
      _debugRenderer.DrawText("ScreenPosition (640, 360)", new Vector2F(640, 360), Color.White);

      // It is often useful to copy textures to the screen for debugging.
      _debugRenderer.DrawTexture(NoiseHelper.GetGrainTexture(GraphicsService, 128), new Rectangle(1000, 10, 128, 128));

      // Axes can be drawn to display poses (positions and orientations).
      _debugRenderer.DrawAxes(new Pose(new Vector3F(0, 0, 0)), 1, true);

      // Axis-aligned bounding boxes (AABB)
      _debugRenderer.DrawAabb(new Aabb(new Vector3F(-0.5f), new Vector3F(0.5f)), new Pose(new Vector3F(2, 0, -3)), Color.Green, false);
      _debugRenderer.DrawAabb(new Aabb(new Vector3F(-0.5f), new Vector3F(0.5f)), new Pose(new Vector3F(4, 0, -3)), Color.Yellow, true);

      // Box shapes
      var orientation = random.NextQuaternionF();
      _debugRenderer.DrawBox(1, 1, 1, new Pose(new Vector3F(-6, 0, -5), orientation), new Color(255, 0, 0, 100), false, false);
      _debugRenderer.DrawBox(1, 1, 1, new Pose(new Vector3F(-6, 0, -5), orientation), Color.Green, true, false);
      _debugRenderer.DrawBox(1, 1, 1, new Pose(new Vector3F(-4, 0, -5), orientation), Color.Yellow, true, true);

      // View volumes (frustums)
      var viewVolume = new PerspectiveViewVolume(1, 2, 0.1f, 1f);
      _debugRenderer.DrawViewVolume(viewVolume, new Pose(new Vector3F(-2, 0, -5), orientation), new Color(0, 255, 0, 100), false, false);
      _debugRenderer.DrawViewVolume(viewVolume, new Pose(new Vector3F(-2, 0, -5), orientation), Color.Green, true, false);
      _debugRenderer.DrawViewVolume(viewVolume, new Pose(new Vector3F(0, 0, -5), orientation), Color.Yellow, true, true);

      // Spheres
      _debugRenderer.DrawSphere(0.5f, new Pose(new Vector3F(2, 0, -5), orientation), new Color(0, 0, 255, 100), false, false);
      _debugRenderer.DrawSphere(0.5f, new Pose(new Vector3F(2, 0, -5), orientation), Color.Green, true, false);
      _debugRenderer.DrawSphere(0.5f, new Pose(new Vector3F(4, 0, -5), orientation), Color.Yellow, true, true);

      // Capsules
      _debugRenderer.DrawCapsule(0.3f, 1, new Pose(new Vector3F(-6, 0, -7), orientation), new Color(255, 255, 0, 100), false, false);
      _debugRenderer.DrawCapsule(0.3f, 1, new Pose(new Vector3F(-6, 0, -7), orientation), Color.Green, true, false);
      _debugRenderer.DrawCapsule(0.3f, 1, new Pose(new Vector3F(-4, 0, -7), orientation), Color.Yellow, true, true);

      // Cylinders
      _debugRenderer.DrawCylinder(0.3f, 1, new Pose(new Vector3F(-2, 0, -7), orientation), new Color(255, 0, 255, 100), false, false);
      _debugRenderer.DrawCylinder(0.3f, 1, new Pose(new Vector3F(-2, 0, -7), orientation), Color.Green, true, false);
      _debugRenderer.DrawCylinder(0.3f, 1, new Pose(new Vector3F(0, 0, -7), orientation), Color.Yellow, true, true);

      // Cones
      _debugRenderer.DrawCone(0.3f, 1, new Pose(new Vector3F(2, 0, -7), orientation), new Color(0, 255, 255, 100), false, false);
      _debugRenderer.DrawCone(0.3f, 1, new Pose(new Vector3F(2, 0, -7), orientation), Color.Green, true, false);
      _debugRenderer.DrawCone(0.3f, 1, new Pose(new Vector3F(4, 0, -7), orientation), Color.Yellow, true, true);

      // The debug renderer can draw any IGeometricObjects, like SceneNodes, RigidBodies, etc.
      _debugRenderer.DrawObject(_geometricObject, Color.Brown, false, false);
      _debugRenderer.DrawObject(_geometricObject, Color.Yellow, true, true);

      // The debug renderer can also an XNA model (without materials).
      _debugRenderer.DrawModel(_xnaModel, new Pose(new Vector3F(0, 2, -2), orientation), new Vector3F(1, 2, 1), new Color(128, 255, 64, 100), false, false);
      _debugRenderer.DrawModel(_xnaModel, new Pose(new Vector3F(0, 2, -2), orientation), new Vector3F(1, 2, 1), Color.LightCyan, true, false);

      // Draw a DigitalRune model.
      _debugRenderer.DrawModel(_modelNode, Color.Peru, true, false);

      // Draw the bounding shapes of the meshes in this model.
      foreach (var node in _modelNode.GetSubtree())
        _debugRenderer.DrawObject(node, Color.PeachPuff, true, false);
    }
Пример #4
0
    // Creates a lot of random objects.
    private void CreateRandomObjects()
    {
      var random = new Random(12345);

      for (int i = 0; i < NumberOfObjects; i++)
      {
        // Randomly choose a shape.
        Shape randomShape;
        switch (random.Next(0, 7))
        {
          case 0:
            // Box
            randomShape = new BoxShape(ObjectSize, ObjectSize * 2, ObjectSize * 3);
            break;
          case 1:
            // Capsule
            randomShape = new CapsuleShape(0.3f * ObjectSize, 2 * ObjectSize);
            break;
          case 2:
            // Cone
            randomShape = new ConeShape(1 * ObjectSize, 2 * ObjectSize);
            break;
          case 3:
            // Cylinder
            randomShape = new CylinderShape(0.4f * ObjectSize, 2 * ObjectSize);
            break;
          case 4:
            // Sphere
            randomShape = new SphereShape(ObjectSize);
            break;
          case 5:
            // Convex hull of several points.
            ConvexHullOfPoints hull = new ConvexHullOfPoints();
            hull.Points.Add(new Vector3F(-1 * ObjectSize, -2 * ObjectSize, -1 * ObjectSize));
            hull.Points.Add(new Vector3F(2 * ObjectSize, -1 * ObjectSize, -0.5f * ObjectSize));
            hull.Points.Add(new Vector3F(1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize));
            hull.Points.Add(new Vector3F(-1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize));
            hull.Points.Add(new Vector3F(-1 * ObjectSize, 0.7f * ObjectSize, -0.6f * ObjectSize));
            randomShape = hull;
            break;
          case 6:
            // A composite shape: two boxes that form a "T" shape.
            var composite = new CompositeShape();
            composite.Children.Add(
              new GeometricObject(
                new BoxShape(ObjectSize, 3 * ObjectSize, ObjectSize),
                new Pose(new Vector3F(0, 0, 0))));
            composite.Children.Add(
              new GeometricObject(
                new BoxShape(2 * ObjectSize, ObjectSize, ObjectSize),
                new Pose(new Vector3F(0, 2 * ObjectSize, 0))));
            randomShape = composite;
            break;
          default:
#if WINDOWS
            Trace.Fail("Ups, we shouldn't land here :-(");
#endif
            randomShape = new SphereShape();
            break;
        }

        // Create an object with the random shape, pose, color and velocity.
        Pose randomPose = new Pose(
          random.NextVector3F(-BoxSize + ObjectSize * 2, BoxSize - ObjectSize * 2),
          random.NextQuaternionF());

        var newObject = new MovingGeometricObject
        {
          Pose = randomPose,
          Shape = randomShape,
          LinearVelocity = random.NextQuaternionF().Rotate(new Vector3F(MaxLinearVelocity, 0, 0)),
          AngularVelocity = random.NextQuaternionF().Rotate(Vector3F.Forward)
                            * RandomHelper.Random.NextFloat(0, MaxAngularVelocity),
        };

        // Add collision object to collision domain.
        _domain.CollisionObjects.Add(new CollisionObject(newObject));

        // We will collect a few statistics for debugging.
        Profiler.SetFormat("NumObjects", 1, "The total number of objects.");
        Profiler.SetFormat("NumObjectPairs", 1, "The number of objects pairs, which have to be checked.");
        Profiler.SetFormat("BroadPhasePairs", 1, "The number of overlaps reported by the broad phase.");
        Profiler.SetFormat("ContactSetCount", 1, "The number of actual collisions.");
      }
    }
Пример #5
0
        public void RandomizedMassSceneUpdate()
        {
            const int NumberOfSceneNodes = 6;
              const int NumberOfSteps = 10000;
              const float Saturation = 0.7f;  // Percent of scene nodes which should be in the scene.

              var random = new Random(1234567);
              var scene = new Scene();

              int numberOfNodesInScene = 0;

              var nodes = new TestSceneNode[NumberOfSceneNodes];

              // Create random nodes.
              for (int i = 0; i < NumberOfSceneNodes; i++)
              {
            var node = new TestSceneNode();
            nodes[i] = node;

            var position = random.NextVector3F(-1000, 1000);
            var orientation = random.NextQuaternionF();
            node.PoseLocal = new Pose(position, orientation);

            float p = random.NextFloat(0, 1);
            if (p < 0.1f)
              node.Shape = Shape.Empty;
            else if (p < 0.2f)
              node.Shape = Shape.Infinite;
            //else if (p < 0.21f)
            //{
            //  node.Shape = new BoxShape(float.PositiveInfinity, 1, 1);

            //  // Remove orientation - otherwise we get infinite AABB.
            //  node.PoseLocal = new Pose(node.PoseLocal.Position);

            //  var aabb = node.Aabb;
            //  var isValid = node.Aabb.Extent.IsNaN;
            //}
            else
              node.Shape = new SphereShape(random.NextFloat(0, 10));
              }

              for (int updateIndex = 0; updateIndex < NumberOfSteps; updateIndex++)
              {
            for (int i = 0; i < NumberOfSceneNodes; i++)
            {
              var node = nodes[i];

              // Add
              if (node.Parent == null)
              {
            if (random.NextFloat(0, 1) < 0.1f) // 10 percent change to add.
            {
              numberOfNodesInScene++;
              scene.Children.Add(node);
            }
              }

              // Remove
              if (node.Parent != null && ((float)numberOfNodesInScene) / (float)NumberOfSceneNodes > Saturation)
              {
            if (random.NextFloat(0, 1) < 0.1f) // 10 percent change to remove.
            {
              numberOfNodesInScene--;
              node.Parent.Children.Remove(node);
            }
              }

              // Move
              //if (node.IsInScene)
              {
            if (random.NextFloat(0, 1) < 0.5f) // 50% change to move
            {
              var pose = node.PoseWorld;
              pose.Position += random.NextVector3F(0, 10);
              node.PoseWorld = pose;
            }
            if (random.NextFloat(0, 1) < 0.1f) // 50% change to scale
            {
              node.ScaleLocal = random.NextVector3F(0.5f, 1.5f);
            }
              }
            }

            scene.Update(TimeSpan.FromSeconds(0.016666666f));
              }
        }
Пример #6
0
        public void RandomizedMassSceneUpdate2()
        {
            const int NumberOfSceneNodes = 10;
              const int NumberOfSteps = 10000;
              const float WorldSize = 1000;

              var random = new Random(123457);
              var scene = new Scene();
              scene.EnableMultithreading = false;

              var nodes = new TestSceneNode[NumberOfSceneNodes];

              // Create random nodes.
              for (int i = 0; i < NumberOfSceneNodes; i++)
              {
            var node = new TestSceneNode();
            nodes[i] = node;

            var position = random.NextVector3F(0, WorldSize);
            var orientation = random.NextQuaternionF();
            node.PoseLocal = new Pose(position, orientation);

            float p = random.NextFloat(0, 100);
            if (p < 0.1f)
              node.Shape = Shape.Empty;
            else if (p < 0.2f)
              node.Shape = Shape.Infinite;
            else if (p < 0.6f)
              node.Shape = new BoxShape(random.NextVector3F(0, WorldSize));
            else
              node.Shape = new SphereShape(random.NextFloat(0, WorldSize));
              }

              var projection = new PerspectiveProjection();
              projection.SetFieldOfView(0.8f, 1, WorldSize / 10000, WorldSize);
              var camera = new Camera(projection);
              var cameraNode = new CameraNode(camera);

              for (int updateIndex = 0; updateIndex < NumberOfSteps; updateIndex++)
              {
            int actionsPerFrame = random.NextInteger(0, 100);
            for (int i = 0; i < actionsPerFrame; i++)
            {
              var node = nodes[random.Next(0, NumberOfSceneNodes)];

              const int numberOfActions = 100;
              int action = random.Next(0, numberOfActions);

              //scene.Validate();

              if (action == 0)
              {
            // Add
            if (node.Parent == null)
            {
              scene.Children.Add(node);
              //scene.Validate();
            }
              }
              else if (action == 1)
              {
            // Remove
            if (node.Parent != null)
            {
              node.Parent.Children.Remove(node);
              //scene.Validate();
            }
              }
              else if (action == 2)
              {
            // Move
            var pose = node.PoseWorld;
            pose.Position = random.NextVector3F(0, WorldSize);
            node.PoseWorld = pose;
            //scene.Validate();
              }
              else if (action == 3)
              {
            // Very small Move
            var pose = node.PoseWorld;
            const float maxDistance = WorldSize / 10000;
            pose.Position += random.NextVector3F(-maxDistance, maxDistance);
            node.PoseWorld = pose;
            //scene.Validate();
              }
              else if (action == 4)
              {
            // Small Move
            var pose = node.PoseWorld;
            const float maxDistance = WorldSize / 100;
            pose.Position += random.NextVector3F(-maxDistance, maxDistance);
            node.PoseWorld = pose;
            //scene.Validate();
              }
              else if (action == 5)
              {
            // Scale
            node.ScaleLocal = random.NextVector3F(0.0f, 10f);
            //scene.Validate();
              }
              else if (action == 6)
              {
            // Rotate
            node.PoseWorld = new Pose(node.PoseWorld.Position, random.NextQuaternionF());
            //scene.Validate();
              }
              else if (action == 7)
              {
            // Query
            var query = scene.Query<CameraFrustumQuery>(cameraNode, null);
            //Debug.WriteLine("Camera queried nodes: " + query.SceneNodes.Count);
            //scene.Validate();
              }
              else if (action == 8)
              {
            // Move camera.
            cameraNode.PoseWorld = new Pose(random.NextVector3F(0, WorldSize), random.NextQuaternionF());
            //scene.Validate();
              }
              else if (action == 9)
              {
            // Change shape.
            int type = random.NextInteger(0, 5);
            if (type == 0)
              node.Shape = new BoxShape(random.NextVector3F(0, WorldSize));
            else if (type == 1)
              node.Shape = new SphereShape(random.NextFloat(0, WorldSize));
            else if (type == 2)
              node.Shape = new BoxShape(new Vector3F(Single.MaxValue));
            else if (type == 3)
              node.Shape = new BoxShape(new Vector3F(0));
            else if (type == 4)
              node.Shape = Shape.Empty;
            //scene.Validate();
              }
              else if (action == 10)
              {
            // Add to random parent.
            if (node.Parent == null)
            {
              var randomParent = nodes[random.NextInteger(0, NumberOfSceneNodes - 1)];

              // Avoid loops:
              bool isLoop = node.GetSubtree().Contains(randomParent);
              if (!isLoop)
              {
                if (randomParent.Children == null)
                  randomParent.Children = new SceneNodeCollection();

                randomParent.Children.Add(node);
              }
            }
              }
              else if (action == 11)
              {
            if (node.Parent != null && node.Parent != scene)
              node.Parent.Children.Remove(node);
              }
              else if (action == 13)
              {
            if (random.NextInteger(0, 100) < 5)
            scene.Children.Clear();
              }
              else if (action == 14)
              {
            if (random.NextInteger(0, 100) < 5)
              scene.Children = new SceneNodeCollection();
              }
            }

            //Debug.WriteLine("Number of nodes in scene: " + scene.GetDescendants().Count());

            //scene.Validate();
            scene.Update(TimeSpan.FromSeconds(0.016666666f));
            //scene.Validate();
              }
        }
Пример #7
0
        public void CompressEmptySrtKeyFrameAnimation2()
        {
            var random = new Random(12345);

              // Animation with 1 keyframe, which is not Identity.
              var srtKeyFrameAnimation = new SrtKeyFrameAnimation();
              var time = TimeSpan.FromTicks(100000);
              var value = new SrtTransform(random.NextVector3F(-2, 2), random.NextQuaternionF(), random.NextVector3F(-10, 10));
              srtKeyFrameAnimation.KeyFrames.Add(new KeyFrame<SrtTransform>(time, value));

              var srtAnimation = AnimationHelper.Compress(srtKeyFrameAnimation, 2, 360, 10);

              Assert.IsNotNull(srtAnimation);
              Assert.AreEqual(srtKeyFrameAnimation.GetTotalDuration(), srtAnimation.GetTotalDuration());

              var defaultSource = SrtTransform.Identity;
              var defaultTarget = SrtTransform.Identity;
              var result = new SrtTransform();
              srtAnimation.GetValue(time, ref defaultSource, ref defaultTarget, ref result);
              Assert.AreEqual(srtKeyFrameAnimation.KeyFrames[0].Value, result);
        }