public void Clone()
        {
            Pose poseA = new Pose(new Vector3(1, 2, 3));
              PointShape pointA = new PointShape(3, 4, 5);
              GeometricObject geometryA = new GeometricObject(pointA, poseA);

              Pose poseB = new Pose(new Vector3(1, 2, 3));
              PointShape pointB = new PointShape(3, 4, 5);
              GeometricObject geometryB = new GeometricObject(pointB, poseB);

              MinkowskiSumShape minkowskiSumShape = new MinkowskiSumShape(geometryA, geometryB);
              MinkowskiSumShape clone = minkowskiSumShape.Clone() as MinkowskiSumShape;
              Assert.IsNotNull(clone);
              Assert.IsNotNull(clone.ObjectA);
              Assert.IsNotNull(clone.ObjectB);
              Assert.AreNotSame(geometryA, clone.ObjectA);
              Assert.AreNotSame(geometryB, clone.ObjectB);
              Assert.IsTrue(clone.ObjectA is GeometricObject);
              Assert.IsTrue(clone.ObjectB is GeometricObject);
              Assert.AreEqual(poseA, clone.ObjectA.Pose);
              Assert.AreEqual(poseB, clone.ObjectB.Pose);
              Assert.IsNotNull(clone.ObjectA.Shape);
              Assert.IsNotNull(clone.ObjectB.Shape);
              Assert.AreNotSame(pointA, clone.ObjectA.Shape);
              Assert.AreNotSame(pointB, clone.ObjectB.Shape);
              Assert.IsTrue(clone.ObjectA.Shape is PointShape);
              Assert.IsTrue(clone.ObjectB.Shape is PointShape);
              Assert.AreEqual(pointA.Position, ((PointShape)clone.ObjectA.Shape).Position);
              Assert.AreEqual(pointB.Position, ((PointShape)clone.ObjectB.Shape).Position);
              Assert.AreEqual(minkowskiSumShape.GetAabb(Pose.Identity).Minimum, clone.GetAabb(Pose.Identity).Minimum);
              Assert.AreEqual(minkowskiSumShape.GetAabb(Pose.Identity).Maximum, clone.GetAabb(Pose.Identity).Maximum);
        }
        public void SerializationBinary()
        {
            Pose poseA = new Pose(new Vector3(1, 2, 3));
              PointShape pointA = new PointShape(3, 4, 5);
              GeometricObject geometryA = new GeometricObject(pointA, poseA);

              Pose poseB = new Pose(new Vector3(11, 22, 33));
              PointShape pointB = new PointShape(33, 44, 55);
              GeometricObject geometryB = new GeometricObject(pointB, poseB);

              var a = new MinkowskiSumShape(geometryA, geometryB);

              // Serialize object.
              var stream = new MemoryStream();
              var formatter = new BinaryFormatter();
              formatter.Serialize(stream, a);

              // Deserialize object.
              stream.Position = 0;
              var deserializer = new BinaryFormatter();
              var b = (MinkowskiSumShape)deserializer.Deserialize(stream);

              Assert.AreEqual(a.ObjectA.Pose, b.ObjectA.Pose);
              Assert.AreEqual(a.ObjectB.Pose, b.ObjectB.Pose);
              Assert.AreEqual(((PointShape)a.ObjectA.Shape).Position, ((PointShape)b.ObjectA.Shape).Position);
              Assert.AreEqual(((PointShape)a.ObjectB.Shape).Position, ((PointShape)b.ObjectB.Shape).Position);
        }
Exemple #3
0
        public void GetShapeVolumeArgumentOutOfRangeException2()
        {
            var s = new SphereShape(1);
            var c = new MinkowskiSumShape(new GeometricObject(s), new GeometricObject(new PointShape()));

            c.GetVolume(0.01f, -1);
        }
Exemple #4
0
        public void Clone()
        {
            Pose poseA = new Pose(new Vector3F(1, 2, 3));
              PointShape pointA = new PointShape(3, 4, 5);
              GeometricObject geometryA = new GeometricObject(pointA, poseA);

              Pose poseB = new Pose(new Vector3F(1, 2, 3));
              PointShape pointB = new PointShape(3, 4, 5);
              GeometricObject geometryB = new GeometricObject(pointB, poseB);

              MinkowskiSumShape minkowskiSumShape = new MinkowskiSumShape(geometryA, geometryB);
              MinkowskiSumShape clone = minkowskiSumShape.Clone() as MinkowskiSumShape;
              Assert.IsNotNull(clone);
              Assert.IsNotNull(clone.ObjectA);
              Assert.IsNotNull(clone.ObjectB);
              Assert.AreNotSame(geometryA, clone.ObjectA);
              Assert.AreNotSame(geometryB, clone.ObjectB);
              Assert.IsTrue(clone.ObjectA is GeometricObject);
              Assert.IsTrue(clone.ObjectB is GeometricObject);
              Assert.AreEqual(poseA, clone.ObjectA.Pose);
              Assert.AreEqual(poseB, clone.ObjectB.Pose);
              Assert.IsNotNull(clone.ObjectA.Shape);
              Assert.IsNotNull(clone.ObjectB.Shape);
              Assert.AreNotSame(pointA, clone.ObjectA.Shape);
              Assert.AreNotSame(pointB, clone.ObjectB.Shape);
              Assert.IsTrue(clone.ObjectA.Shape is PointShape);
              Assert.IsTrue(clone.ObjectB.Shape is PointShape);
              Assert.AreEqual(pointA.Position, ((PointShape)clone.ObjectA.Shape).Position);
              Assert.AreEqual(pointB.Position, ((PointShape)clone.ObjectB.Shape).Position);
              Assert.AreEqual(minkowskiSumShape.GetAabb(Pose.Identity).Minimum, clone.GetAabb(Pose.Identity).Minimum);
              Assert.AreEqual(minkowskiSumShape.GetAabb(Pose.Identity).Maximum, clone.GetAabb(Pose.Identity).Maximum);
        }
Exemple #5
0
        public void ApproximateVolume()
        {
            var s = new SphereShape(1);
            var c = new MinkowskiSumShape(new GeometricObject(s), new GeometricObject(new PointShape()));
            var v = c.GetVolume(0.001f,
                                0); // !!!

            // v is AABB volume.
            Assert.AreEqual(2 * 2 * 2, v);
        }
        // OnLoad() is called when the GameObject is added to the IGameObjectService.
        protected override void OnLoad()
        {
            var graphicsService   = _services.GetInstance <IGraphicsService>();
            var gameObjectService = _services.GetInstance <IGameObjectService>();
            var content           = _services.GetInstance <ContentManager>();

            // Check if the game object manager has another ProceduralObject instance.
            var otherProceduralObject = gameObjectService.Objects
                                        .OfType <ProceduralObject>()
                                        .FirstOrDefault(o => o != this);
            Mesh mesh;

            if (otherProceduralObject != null)
            {
                // This ProceduralObject is not the first. We re-use rigid body data and
                // the mesh from the existing instance.
                var otherBody = otherProceduralObject._rigidBody;
                _rigidBody = new RigidBody(otherBody.Shape, otherBody.MassFrame, otherBody.Material);
                mesh       = otherProceduralObject._meshNode.Mesh;
            }
            else
            {
                // This is the first ProceduralObject instance.
                // Create a a new rigid body.
                var shape = new MinkowskiSumShape(new GeometricObject(new SphereShape(0.05f)), new GeometricObject(new BoxShape(0.5f, 0.5f, 0.5f)));
                _rigidBody = new RigidBody(shape);

                // Create a new mesh. See SampleHelper.CreateMesh for more details.
                mesh      = SampleHelper.CreateMesh(content, graphicsService, _rigidBody.Shape);
                mesh.Name = "ProceduralObject";
            }

            // Create a scene graph node for the mesh.
            _meshNode = new MeshNode(mesh);

            // Set a random pose.
            var randomPosition = new Vector3(
                RandomHelper.Random.NextFloat(-10, 10),
                RandomHelper.Random.NextFloat(2, 5),
                RandomHelper.Random.NextFloat(-20, 0));

            _rigidBody.Pose     = new Pose(randomPosition, RandomHelper.Random.NextQuaternion());
            _meshNode.PoseWorld = _rigidBody.Pose;

            // Add mesh node to scene graph.
            var scene = _services.GetInstance <IScene>();

            scene.Children.Add(_meshNode);

            // Add rigid body to the physics simulation.
            var simulation = _services.GetInstance <Simulation>();

            simulation.RigidBodies.Add(_rigidBody);
        }
        public void SetUp()
        {
            child0 = new GeometricObject(new CircleShape(3), new Pose(new Vector3(), Quaternion.CreateRotationX(ConstantsF.PiOver2)));
              child1 = new GeometricObject(new LineSegmentShape(new Vector3(0, 5, 0), new Vector3(0, -5, 0)), Pose.Identity);

              cs = new MinkowskiSumShape
              {
            ObjectA = child0,
            ObjectB = child1
              };
        }
    // 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 Vector3(-1 * ObjectSize, -2 * ObjectSize, -1 * ObjectSize));
            hull.Points.Add(new Vector3(2 * ObjectSize, -1 * ObjectSize, -0.5f * ObjectSize));
            hull.Points.Add(new Vector3(1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize));
            hull.Points.Add(new Vector3(-1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize));
            hull.Points.Add(new Vector3(-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 Vector3(0, 0, 0))));
            composite.Children.Add(
              new GeometricObject(
                new BoxShape(2 * ObjectSize, ObjectSize, ObjectSize),
                new Pose(new Vector3(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 Vector3(0, 0.5f, 0), Matrix.Identity)));
              compBvh.Children.Add(new GeometricObject(new BoxShape(0.8f, 0.5f, 0.5f), new Pose(new Vector3(0.5f, 0.7f, 0), Matrix.CreateRotationZ(-MathHelper.ToRadians(15)))));
              compBvh.Children.Add(new GeometricObject(new SphereShape(0.3f), new Pose(new Vector3(0, 1.15f, 0), Matrix.Identity)));
              compBvh.Children.Add(new GeometricObject(new CapsuleShape(0.2f, 1), new Pose(new Vector3(0.6f, 1.15f, 0), Matrix.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 Vector3(0, 0.5f * ObjectSize, 0), Quaternion.Identity)));
            comp.Children.Add(new GeometricObject(new BoxShape(0.8f * ObjectSize, 0.5f * ObjectSize, 0.5f * ObjectSize), new Pose(new Vector3(0.3f * ObjectSize, 0.7f * ObjectSize, 0), Quaternion.CreateRotationZ(-MathHelper.ToRadians(45)))));
            comp.Children.Add(new GeometricObject(new SphereShape(0.3f * ObjectSize), new Pose(new Vector3(0, 1.15f * ObjectSize, 0), Quaternion.Identity)));
            shape = comp;
            break;
          case 10:
            shape = new ConvexHullOfPoints(new[]
            {
              new Vector3(-1 * ObjectSize, -2 * ObjectSize, -1 * ObjectSize),
              new Vector3(2 * ObjectSize, -1 * ObjectSize, -0.5f * ObjectSize),
              new Vector3(1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize),
              new Vector3(-1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize),
              new Vector3(-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 Vector3(0, 2 * ObjectSize, 0), Matrix.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 Vector3(0.1f, 0.2f, 0.3f), new Vector3(0.1f, 0.2f, -0.3f).Normalized);
          //break;            
          case 15:
            shape = new LineSegmentShape(
              new Vector3(0.1f, 0.2f, 0.3f), new Vector3(0.1f, 0.2f, 0.3f) + 3 * ObjectSize * new Vector3(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 Vector3(0.2f, 0, -0.12f), new Vector3(1, 2, 3).Normalized, ObjectSize * 2);
            break;
          case 22:
            shape = new RayShape(new Vector3(0.2f, 0, -0.12f), new Vector3(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 Vector3(0.1f, 1, -0.2f))));
            break;
          case 25:
            shape = new TriangleShape(
              new Vector3(ObjectSize, 0, 0), new Vector3(0, ObjectSize, 0), new Vector3(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 Vector3(0, 0.5f, 0), Matrix.Identity)));
          //    compBvh.Children.Add(
          //      new GeometricObject(
          //        new BoxShape(0.8f, 0.5f, 0.5f),
          //        new Pose(new Vector3(0.5f, 0.7f, 0), Matrix.CreateRotationZ(-(float)MathHelper.ToRadians(15)))));
          //    compBvh.Children.Add(new GeometricObject(new SphereShape(0.3f), new Pose(new Vector3(0, 1.15f, 0), Matrix.Identity)));
          //    compBvh.Children.Add(
          //      new GeometricObject(new CapsuleShape(0.2f, 1), new Pose(new Vector3(0.6f, 1.15f, 0), Matrix.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 Vector3(0, 0.5f, 0), Quaternion.Identity)));
          //    compBvh.Children.Add(
          //      new GeometricObject(
          //        new BoxShape(0.8f, 0.5f, 0.5f),
          //        new Pose(new Vector3(0.5f, 0.7f, 0), Quaternion.CreateRotationZ(-(float)MathHelper.ToRadians(15)))));
          //    compBvh.Children.Add(new GeometricObject(new SphereShape(0.3f), new Pose(new Vector3(0, 1.15f, 0), Quaternion.Identity)));
          //    compBvh.Children.Add(
          //      new GeometricObject(new CapsuleShape(0.2f, 1), new Pose(new Vector3(0.6f, 1.15f, 0), Quaternion.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 Vector3(-1 * ObjectSize, -2 * ObjectSize, -1 * ObjectSize),
              new Vector3(2 * ObjectSize, -1 * ObjectSize, -0.5f * ObjectSize),
              new Vector3(1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize),
              new Vector3(-1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize),
              new Vector3(-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.NextVector3(-BoxSize + ObjectSize * 2, BoxSize - ObjectSize * 2),
          random.NextQuaternion());
        var newObject = new MovingGeometricObject
        {
          Pose = randomPose,
          Shape = shape,
          LinearVelocity = random.NextQuaternion().Rotate(new Vector3(MaxLinearVelocity, 0, 0)),
          AngularVelocity = random.NextQuaternion().Rotate(Vector3.Forward)
                            * RandomHelper.Random.NextFloat(0, MaxAngularVelocity),
        };

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

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

        // Create only 1 heightField!
        if (shape is HeightField)
        {
          if (isFirstHeightField)
          {
            isFirstHeightField = true;
            newObject.Pose = new Pose(new Vector3(-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;
      }
    }
        public ShapesSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            // Add basic force effects.
            Simulation.ForceEffects.Add(new Gravity());
            Simulation.ForceEffects.Add(new Damping());

            // Add a ground plane.
            RigidBody groundPlane = new RigidBody(new PlaneShape(Vector3F.UnitY, 0))
            {
                Name       = "GroundPlane", // Names are not required but helpful for debugging.
                MotionType = MotionType.Static,
            };

            Simulation.RigidBodies.Add(groundPlane);

            // ----- Add a sphere.
            Shape sphere = new SphereShape(0.5f);

            Simulation.RigidBodies.Add(new RigidBody(sphere));

            // ----- Add a box.
            BoxShape box = new BoxShape(0.5f, 0.9f, 0.7f);

            Simulation.RigidBodies.Add(new RigidBody(box));

            // ----- Add a capsule.
            CapsuleShape capsule = new CapsuleShape(0.4f, 1.2f);

            Simulation.RigidBodies.Add(new RigidBody(capsule));

            // ----- Add a cone.
            ConeShape cone = new ConeShape(0.5f, 1f);

            Simulation.RigidBodies.Add(new RigidBody(cone));

            // ----- Add a cylinder.
            CylinderShape cylinder = new CylinderShape(0.3f, 1f);

            Simulation.RigidBodies.Add(new RigidBody(cylinder));

            // ----- Add a convex hull of random points.
            ConvexHullOfPoints convexHullOfPoints = new ConvexHullOfPoints();

            for (int i = 0; i < 20; i++)
            {
                convexHullOfPoints.Points.Add(RandomHelper.Random.NextVector3F(-0.5f, 0.5f));
            }
            Simulation.RigidBodies.Add(new RigidBody(convexHullOfPoints));

            // ----- Add a convex polyhedron.
            // (A ConvexPolyhedron is similar to the ConvexHullOfPoints. The difference is that
            // the points in a ConvexHullOfPoints can be changed at runtime. A ConvexPolyhedron
            // cannot be changed at runtime, but it is faster.)
            List <Vector3F> points = new List <Vector3F>();

            for (int i = 0; i < 20; i++)
            {
                points.Add(RandomHelper.Random.NextVector3F(-0.7f, 0.7f));
            }
            ConvexPolyhedron convexPolyhedron = new ConvexPolyhedron(points);

            Simulation.RigidBodies.Add(new RigidBody(convexPolyhedron));

            // ----- Add a composite shape (a table that consists of 5 boxes).
            CompositeShape composite = new CompositeShape();

            composite.Children.Add(new GeometricObject(new BoxShape(0.1f, 0.8f, 0.1f), new Pose(new Vector3F(-0.75f, 0.4f, -0.5f))));
            composite.Children.Add(new GeometricObject(new BoxShape(0.1f, 0.8f, 0.1f), new Pose(new Vector3F(0.75f, 0.4f, -0.5f))));
            composite.Children.Add(new GeometricObject(new BoxShape(0.1f, 0.8f, 0.1f), new Pose(new Vector3F(-0.75f, 0.4f, 0.5f))));
            composite.Children.Add(new GeometricObject(new BoxShape(0.1f, 0.8f, 0.1f), new Pose(new Vector3F(0.75f, 0.4f, 0.5f))));
            composite.Children.Add(new GeometricObject(new BoxShape(1.8f, 0.1f, 1.1f), new Pose(new Vector3F(0, 0.8f, 0))));
            Simulation.RigidBodies.Add(new RigidBody(composite));

            // ----- Add a convex hull of multiple shapes.
            ConvexHullOfShapes convexHullOfShapes = new ConvexHullOfShapes();

            convexHullOfShapes.Children.Add(new GeometricObject(new CylinderShape(0.2f, 0.8f), new Pose(new Vector3F(-0.4f, 0, 0))));
            convexHullOfShapes.Children.Add(new GeometricObject(new CylinderShape(0.2f, 0.8f), new Pose(new Vector3F(+0.4f, 0, 0))));
            Simulation.RigidBodies.Add(new RigidBody(convexHullOfShapes));

            // ----- Add the Minkowski sum of two shapes.
            // (The Minkowski sum is a mathematical operation that combines two shapes.
            // Here a circle is combined with a sphere. The result is a wheel.)
            MinkowskiSumShape minkowskiSum = new MinkowskiSumShape();

            minkowskiSum.ObjectA = new GeometricObject(new SphereShape(0.2f), Pose.Identity);
            minkowskiSum.ObjectB = new GeometricObject(new CircleShape(0.5f), Pose.Identity);
            Simulation.RigidBodies.Add(new RigidBody(minkowskiSum));

            // Create another Minkowski sum. (Here a small sphere is added to a box to create a
            // box with rounded corners.)
            minkowskiSum         = new MinkowskiSumShape();
            minkowskiSum.ObjectA = new GeometricObject(new SphereShape(0.1f), Pose.Identity);
            minkowskiSum.ObjectB = new GeometricObject(new BoxShape(0.2f, 0.5f, 0.8f), Pose.Identity);
            Simulation.RigidBodies.Add(new RigidBody(minkowskiSum));

            // ----- Add a triangle mesh.
            // A triangle mesh could be loaded from a file or built from an XNA model.
            // Here we first create a composite shape and convert the shape into a triangle
            // mesh. (Any Shape in DigitalRune.Geometry can be converted to a triangle mesh.)
            CompositeShape dumbbell = new CompositeShape();

            dumbbell.Children.Add(new GeometricObject(new SphereShape(0.4f), new Pose(new Vector3F(0.6f, 0.0f, 0.0f))));
            dumbbell.Children.Add(new GeometricObject(new SphereShape(0.4f), new Pose(new Vector3F(-0.6f, 0.0f, 0.0f))));
            dumbbell.Children.Add(new GeometricObject(new CylinderShape(0.1f, 0.6f), new Pose(Matrix33F.CreateRotationZ(ConstantsF.PiOver2))));

            TriangleMeshShape triangleMeshShape = new TriangleMeshShape(dumbbell.GetMesh(0.01f, 2));

            // Optional: We can enable "contact welding". When this flag is enabled, the triangle shape
            // precomputes additional internal information for the mesh. The collision detection will
            // be able to compute better contacts (e.g. better normal vectors at triangle edges).
            // Pro: Collision detection can compute better contact information.
            // Con: Contact welding information needs a bit of memory. And the collision detection is
            // a bit slower.
            triangleMeshShape.EnableContactWelding = true;

            // Optional: Assign a spatial partitioning scheme to the triangle mesh. (A spatial partition
            // adds an additional memory overhead, but it improves collision detection speed tremendously!)
            triangleMeshShape.Partition = new AabbTree <int>();

            Simulation.RigidBodies.Add(new RigidBody(triangleMeshShape));

            // ----- Set random positions/orientations.
            // (Start with the second object. The first object is the ground plane which should
            // not be changed.)
            for (int i = 1; i < Simulation.RigidBodies.Count; i++)
            {
                RigidBody body = Simulation.RigidBodies[i];

                Vector3F position = RandomHelper.Random.NextVector3F(-3, 3);
                position.Y = 3; // Position the objects 3m above ground.
                QuaternionF orientation = RandomHelper.Random.NextQuaternionF();
                body.Pose = new Pose(position, orientation);
            }
        }
Exemple #10
0
        public void SetUp()
        {
            child0 = new GeometricObject(new CircleShape(3), new Pose(new Vector3F(), QuaternionF.CreateRotationX(ConstantsF.PiOver2)));
              child1 = new GeometricObject(new LineSegmentShape(new Vector3F(0, 5, 0), new Vector3F(0, -5, 0)), Pose.Identity);

              cs = new MinkowskiSumShape
              {
            ObjectA = child0,
            ObjectB = child1
              };
        }
Exemple #11
0
        public void SerializationBinary()
        {
            Pose poseA = new Pose(new Vector3F(1, 2, 3));
              PointShape pointA = new PointShape(3, 4, 5);
              GeometricObject geometryA = new GeometricObject(pointA, poseA);

              Pose poseB = new Pose(new Vector3F(11, 22, 33));
              PointShape pointB = new PointShape(33, 44, 55);
              GeometricObject geometryB = new GeometricObject(pointB, poseB);

              var a = new MinkowskiSumShape(geometryA, geometryB);

              // Serialize object.
              var stream = new MemoryStream();
              var formatter = new BinaryFormatter();
              formatter.Serialize(stream, a);

              // Deserialize object.
              stream.Position = 0;
              var deserializer = new BinaryFormatter();
              var b = (MinkowskiSumShape)deserializer.Deserialize(stream);

              Assert.AreEqual(a.ObjectA.Pose, b.ObjectA.Pose);
              Assert.AreEqual(a.ObjectB.Pose, b.ObjectB.Pose);
              Assert.AreEqual(((PointShape)a.ObjectA.Shape).Position, ((PointShape)b.ObjectA.Shape).Position);
              Assert.AreEqual(((PointShape)a.ObjectB.Shape).Position, ((PointShape)b.ObjectB.Shape).Position);
        }
Exemple #12
0
        // OnLoad() is called when the GameObject is added to the IGameObjectService.
        protected override void OnLoad()
        {
            var graphicsService   = _services.GetInstance <IGraphicsService>();
            var gameObjectService = _services.GetInstance <IGameObjectService>();

            // Check if the game object manager has another ProceduralObject instance.
            var otherProceduralObject = gameObjectService.Objects
                                        .OfType <ProceduralObject>()
                                        .FirstOrDefault(o => o != this);
            Mesh mesh;

            if (otherProceduralObject != null)
            {
                // This ProceduralObject is not the first. We re-use rigid body data and
                // the mesh from the existing instance.
                var otherBody = otherProceduralObject._rigidBody;
                _rigidBody = new RigidBody(otherBody.Shape, otherBody.MassFrame, otherBody.Material);
                mesh       = otherProceduralObject._meshNode.Mesh;
            }
            else
            {
                // This is the first ProceduralObject instance. We create a new rigid body
                // and a new mesh.
                var shape = new MinkowskiSumShape(new GeometricObject(new SphereShape(0.05f)), new GeometricObject(new BoxShape(0.5f, 0.5f, 0.5f)));
                _rigidBody = new RigidBody(shape);

                // Create a DigitalRune.Geometry.Meshes.TriangleMesh from the RigidBody's
                // shape and convert this to a DigitalRune.Graphics.Mesh.
                var triangleMesh = _rigidBody.Shape.GetMesh(0.01f, 4);
                mesh = new Mesh {
                    Name = "ProceduralObject"
                };
                var submesh = CreateSubmeshWithTexCoords(graphicsService.GraphicsDevice, triangleMesh, MathHelper.ToRadians(70));
                mesh.Submeshes.Add(submesh);

                // Next, we need a material. We can load a predefined material (*.drmat file)
                // with the content manager.
                //var material = content.Load<Material>("Default");

                // Alternatively, we can load some effects and build the material here:
                Material material = new Material();

                // We need an EffectBinding for each render pass.
                // The "Default" pass uses a BasicEffectBinding (which is an EffectBinding
                // for the XNA BasicEffect).
                // Note: The "Default" pass is not used by the DeferredLightingScreen, so
                // we could ignore this pass in this sample project.
                BasicEffectBinding defaultEffectBinding = new BasicEffectBinding(graphicsService, null)
                {
                    LightingEnabled    = true,
                    TextureEnabled     = true,
                    VertexColorEnabled = false
                };
                defaultEffectBinding.Set("Texture", graphicsService.GetDefaultTexture2DWhite());
                defaultEffectBinding.Set("DiffuseColor", new Vector3(1, 1, 1));
                defaultEffectBinding.Set("SpecularColor", new Vector3(1, 1, 1));
                defaultEffectBinding.Set("SpecularPower", 100f);
                material.Add("Default", defaultEffectBinding);

                // EffectBinding for the "ShadowMap" pass.
                // Note: EffectBindings which are used in a Material must be marked with
                // the EffectParameterHint Material.
                var           content = _services.GetInstance <ContentManager>();
                EffectBinding shadowMapEffectBinding = new EffectBinding(
                    graphicsService,
                    content.Load <Effect>("DigitalRune\\Materials\\ShadowMap"),
                    null,
                    EffectParameterHint.Material);
                material.Add("ShadowMap", shadowMapEffectBinding);

                // EffectBinding for the "GBuffer" pass.
                EffectBinding gBufferEffectBinding = new EffectBinding(
                    graphicsService,
                    content.Load <Effect>("DigitalRune\\Materials\\GBuffer"),
                    null,
                    EffectParameterHint.Material);
                gBufferEffectBinding.Set("SpecularPower", 100f);
                material.Add("GBuffer", gBufferEffectBinding);

                // EffectBinding for the "Material" pass.
                EffectBinding materialEffectBinding = new EffectBinding(
                    graphicsService,
                    content.Load <Effect>("DigitalRune\\Materials\\Material"),
                    null,
                    EffectParameterHint.Material);
                materialEffectBinding.Set("DiffuseTexture", graphicsService.GetDefaultTexture2DWhite());
                materialEffectBinding.Set("DiffuseColor", new Vector3(1, 1, 1));
                materialEffectBinding.Set("SpecularColor", new Vector3(1, 1, 1));
                material.Add("Material", materialEffectBinding);

                // Assign this material to the submesh.
                submesh.SetMaterial(material);
            }

            // Create a scene graph node for the mesh.
            _meshNode = new MeshNode(mesh);

            // Set a random pose.
            var randomPosition = new Vector3F(
                RandomHelper.Random.NextFloat(-10, 10),
                RandomHelper.Random.NextFloat(2, 5),
                RandomHelper.Random.NextFloat(-20, 0));

            _rigidBody.Pose     = new Pose(randomPosition, RandomHelper.Random.NextQuaternionF());
            _meshNode.PoseWorld = _rigidBody.Pose;

            // Add mesh node to scene graph.
            var scene = _services.GetInstance <IScene>();

            scene.Children.Add(_meshNode);

            // Add rigid body to the physics simulation.
            var simulation = _services.GetInstance <Simulation>();

            simulation.RigidBodies.Add(_rigidBody);
        }
        public virtual bool russianCalcTimeOfImpact(ref Matrix fromA, ref Matrix toA, ref Matrix fromB, ref Matrix toB, CastResult result)
        {
            MinkowskiSumShape convex = new MinkowskiSumShape(m_convexA, m_convexB);

            Matrix rayFromLocalA;
            Matrix rayToLocalA;

            rayFromLocalA = Matrix.Invert(fromA) * fromB;
            rayToLocalA = Matrix.Invert(toA) * toB;

            m_simplexSolver.Reset();

            //convex.TransformB = rayFromLocalA;
            Matrix temp = Matrix.CreateFromQuaternion(Quaternion.CreateFromRotationMatrix(rayFromLocalA));
            convex.SetTransformB(ref temp);

            float lambda = 0;
            //todo: need to verify this:
            //because of minkowski difference, we need the inverse direction

            Vector3 s = -rayFromLocalA.Translation;
            Vector3 r = -(rayToLocalA.Translation - rayFromLocalA.Translation);
            Vector3 x = s;
            Vector3 v;
            Vector3 arbitraryPoint = convex.LocalGetSupportingVertex(ref r);

            v = x - arbitraryPoint;

            int maxIter = MAX_ITERATIONS;

            Vector3 n = new Vector3();
            float lastLambda = lambda;

            float dist2 = v.LengthSquared();
            float epsilon = 0.0001f;

            Vector3 w = Vector3.Zero, p = Vector3.Zero;
            float VdotR;

            while ((dist2 > epsilon) && (maxIter-- != 0))
            {
                p = convex.LocalGetSupportingVertex(ref v);
                w = x - p;

                float VdotW = Vector3.Dot(v, w);

                if (VdotW > 0)
                {
                    VdotR = Vector3.Dot(v, r);

                    if (VdotR >= -(MathUtil.SIMD_EPSILON * MathUtil.SIMD_EPSILON))
                        return false;
                    else
                    {
                        lambda = lambda - VdotW / VdotR;
                        x = s + lambda * r;
                        m_simplexSolver.Reset();
                        //check next line
                        w = x - p;
                        lastLambda = lambda;
                        n = v;
                    }
                }
                m_simplexSolver.AddVertex(ref w, ref x, ref p);
                if (m_simplexSolver.Closest(ref v))
                {
                    dist2 = v.LengthSquared();
                }
                else
                {
                    dist2 = 0f;
                }
            }
            result.m_fraction = lambda;
            result.m_normal = n;
            return true;
        }