public void Setup()
        {
            // Make a unit cube.
            _mesh = new TriangleMesh();
            // Bottom
            _mesh.Add(new Triangle(new Vector3F(0, 0, 0), new Vector3F(1, 1, 0), new Vector3F(1, 0, 0)), true);
            _mesh.Add(new Triangle(new Vector3F(0, 0, 0), new Vector3F(0, 1, 0), new Vector3F(1, 1, 0)), true);
            // Top
            _mesh.Add(new Triangle(new Vector3F(0, 0, 1), new Vector3F(1, 0, 1), new Vector3F(1, 1, 1)), true);
            _mesh.Add(new Triangle(new Vector3F(0, 0, 1), new Vector3F(1, 1, 1), new Vector3F(0, 1, 1)), true);
            // Left
            _mesh.Add(new Triangle(new Vector3F(0, 0, 0), new Vector3F(1, 0, 0), new Vector3F(1, 0, 1)), true);
            _mesh.Add(new Triangle(new Vector3F(0, 0, 0), new Vector3F(1, 0, 1), new Vector3F(0, 0, 1)), true);
            // Right
            _mesh.Add(new Triangle(new Vector3F(0, 1, 0), new Vector3F(0, 1, 1), new Vector3F(1, 1, 1)), true);
            _mesh.Add(new Triangle(new Vector3F(0, 1, 0), new Vector3F(1, 1, 1), new Vector3F(1, 1, 0)), true);
            // Front
            _mesh.Add(new Triangle(new Vector3F(1, 0, 0), new Vector3F(1, 1, 0), new Vector3F(1, 1, 1)), true);
            _mesh.Add(new Triangle(new Vector3F(1, 0, 0), new Vector3F(1, 1, 1), new Vector3F(1, 0, 1)), true);
            // Back
            _mesh.Add(new Triangle(new Vector3F(0, 0, 0), new Vector3F(0, 0, 1), new Vector3F(0, 1, 1)), true);
            _mesh.Add(new Triangle(new Vector3F(0, 0, 0), new Vector3F(0, 1, 1), new Vector3F(0, 1, 0)), true);

            _meshShape = new TriangleMeshShape {
                Mesh = _mesh
            };
        }
Esempio n. 2
0
        public ModelShape(Model model)
        {
            var positionsByteArray  = model.Meshes[0].Attributes["POSITION"].BufferData;
            var positionsFloatArray = new float[positionsByteArray.Length / 4];

            Buffer.BlockCopy(positionsByteArray, 0, positionsFloatArray, 0, positionsByteArray.Length);

            var positions = new List <JVector>();

            for (var i = 0; i < positionsFloatArray.Length / 3; i++)
            {
                positions.Add(new JVector(positionsFloatArray[i * 3], positionsFloatArray[i * 3 + 1], positionsFloatArray[i * 3 + 2]));
            }

            var indicesByteArray  = model.Meshes[0].Attributes["INDEX"].BufferData;
            var indicesShortArray = new short[indicesByteArray.Length / 2];

            Buffer.BlockCopy(indicesByteArray, 0, indicesShortArray, 0, indicesByteArray.Length);

            var tris = new List <TriangleVertexIndices>();

            for (var i = 0; i < indicesShortArray.Length / 3; i++)
            {
                tris.Add(new TriangleVertexIndices(indicesShortArray[i * 3], indicesShortArray[i * 3 + 1], indicesShortArray[i * 3 + 2]));
            }

            var octree = new Octree(positions, tris);

            octree.BuildOctree();
            Shape = new TriangleMeshShape(octree);
        }
Esempio n. 3
0
        public void ComputeCollisionBvh()
        {
            CollisionObject a     = new CollisionObject();
            TriangleMesh    meshA = new TriangleMesh();

            meshA.Add(new Triangle(new Vector3F(0, 0, 0), new Vector3F(0, 0, 1), new Vector3F(1, 0, 0)), false);
            var meshShapeA = new TriangleMeshShape();

            meshShapeA.Mesh      = meshA;
            meshShapeA.Partition = new AabbTree <int>();
            ((GeometricObject)a.GeometricObject).Shape = meshShapeA;

            CollisionObject b     = new CollisionObject();
            TriangleMesh    meshB = new TriangleMesh();

            meshB.Add(new Triangle(new Vector3F(2, 0, 0), new Vector3F(2, 0, 1), new Vector3F(3, 0, 0)), false);
            TriangleMeshShape meshShapeB = new TriangleMeshShape();

            meshShapeB.Mesh      = meshB;
            meshShapeB.Partition = new AabbTree <int>();
            ((GeometricObject)b.GeometricObject).Shape = meshShapeB;
            ((GeometricObject)b.GeometricObject).Pose  = new Pose(new Vector3F(-2, 0, 0));

            CollisionAlgorithm algo = new TriangleMeshAlgorithm(new CollisionDetection());

            Assert.AreEqual(true, algo.HaveContact(a, b));
        }
Esempio n. 4
0
 internal void AddObjects(IEnumerable <LatipiumObject> objects)
 {
     foreach (LatipiumObject obj in objects)
     {
         LatipiumObject type = obj.InvokeFunction <LatipiumObject>("Type");
         if (type != null)
         {
             if (!InitializedTypes.Contains(type))
             {
                 type.InvokeProcedure <Action <IEnumerable <LatipiumObject> > >("Initialize", UpdatedCallback);
             }
             Com.Latipium.Core.Tuple <float[], int[]> data = type.InvokeFunction <Com.Latipium.Core.Tuple <float[], int[]> >("GetPhysicsData");
             if (data != null && data.Object1 != null && data.Object2 != null)
             {
                 List <JVector> points             = new List <JVector>();
                 List <TriangleVertexIndices> tris = new List <TriangleVertexIndices>();
                 for (int i = 0; i < data.Object1.Length - 2; i += 3)
                 {
                     points.Add(new JVector(data.Object1[i], data.Object1[i + 1], data.Object1[i + 2]));
                 }
                 for (int i = 0; i < data.Object2.Length - 2; i += 3)
                 {
                     tris.Add(new TriangleVertexIndices(data.Object2[i], data.Object2[i + 1], data.Object2[i + 2]));
                 }
                 Octree      octree     = new Octree(points, tris);
                 Shape       shape      = new TriangleMeshShape(octree);
                 RigidBody   body       = new RigidBody(shape);
                 Func <bool> UseGravity = type.GetFunction <bool>("UseGravity");
                 body.AffectedByGravity = UseGravity == null || UseGravity();
                 Bodies.Add(obj, body);
                 World.AddBody(body);
             }
         }
     }
 }
Esempio n. 5
0
        CollisionShape BuildLargeMesh()
        {
            //int vertStride = sizeof(IndexedVector3);
            //int indexStride = 3*sizeof(int);

            int vertStride  = 1;
            int indexStride = 3;

            ObjectArray <IndexedVector3> vertexArray = new ObjectArray <IndexedVector3>();

            for (int i = 0; i < vertices.Length; ++i)
            {
                vertexArray.Add(vertices[i]);
            }

            ObjectArray <int> intArray = new ObjectArray <int>();

            for (int i = 0; i < indices.Length; ++i)
            {
                intArray.Add(indices[i]);
            }
            //TriangleIndexVertexArray indexVertexArray = new TriangleIndexVertexArray(DemoMeshes.BUNNY_NUM_TRIANGLES, DemoMeshes.gBunnyIndices, 3, DemoMeshes.BUNNY_NUM_VERTICES, DemoMeshes.gBunnyVertices, 3);

            TriangleIndexVertexArray indexVertexArray = new TriangleIndexVertexArray(numTriangles, intArray, indexStride, vertexArray.Count, vertexArray, vertStride);
            TriangleMeshShape        triangleMesh     = new TriangleMeshShape(indexVertexArray);

            //TriangleMeshShape triangleMesh = new BvhTriangleMeshShape(indexVertexArray,true,true);
            return(triangleMesh);
        }
Esempio n. 6
0
        public void GeneralShape()
        {
            var       s = new CylinderShape(1, 3);
            float     m0;
            Vector3F  com0;
            Matrix33F i0;

            MassHelper.GetMass(s, new Vector3F(1, -2, -3), 0.7f, true, 0.001f, 4, out m0, out com0, out i0);

            var       m  = s.GetMesh(0.001f, 10);
            var       s2 = new TriangleMeshShape(m);
            float     m1;
            Vector3F  com1;
            Matrix33F i1;

            MassHelper.GetMass(s2, new Vector3F(1, -2, -3), 0.7f, true, 0.001f, 4, out m1, out com1, out i1);

            const float e = 0.01f;

            Assert.IsTrue(Numeric.AreEqual(m0, m1, e * (1 + m0)));
            Assert.IsTrue(Vector3F.AreNumericallyEqual(com0, com1, e * (1 + com0.Length)));
            Assert.IsTrue(Matrix33F.AreNumericallyEqual(i0, i1, e * (1 + i0.Trace)));

            // Try with target mass.
            float     m2;
            Vector3F  com2;
            Matrix33F i2;

            MassHelper.GetMass(s2, new Vector3F(1, -2, -3), 23, false, 0.001f, 4, out m2, out com2, out i2);
            Assert.IsTrue(Numeric.AreEqual(23, m2, e * (1 + m0)));
            Assert.IsTrue(Vector3F.AreNumericallyEqual(com0, com2, e * (1 + com0.Length)));
            Assert.IsTrue(Matrix33F.AreNumericallyEqual(i0 * 23 / m0, i2, e * (1 + i0.Trace)));
        }
        public override void Build()
        {
            model          = Demo.Content.Load <Model>("Model/staticmesh");
            boneTransforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(boneTransforms);

            List <TriangleVertexIndices> indices = new List <TriangleVertexIndices>();
            List <Vector3> vertices = new List <Vector3>();

            ExtractData(vertices, indices, model);

            List <JVector> jvertices = new List <JVector>(vertices.Count);

            foreach (Vector3 vertex in vertices)
            {
                jvertices.Add(Conversion.ToJitterVector(vertex));
            }

            Octree octree = new Octree(jvertices, indices);

            TriangleMeshShape tms  = new TriangleMeshShape(octree);
            RigidBody         body = new RigidBody(tms);

            body.IsStatic = true;
            //body.EnableDebugDraw = true;
            body.Tag = BodyTag.DontDrawMe;

            Demo.World.AddBody(body);

            //AddCar(new JVector(-20, 20, 0));
            AddCar(new JVector(1, 20, 0));
        }
        private void CloneMeshWithPartition(ISpatialPartition <int> partition)
        {
            TriangleMeshShape meshShape = (TriangleMeshShape)_meshShape.Clone();

            meshShape.Partition = partition;

            TriangleMeshShape clone = meshShape.Clone() as TriangleMeshShape;

            Assert.IsNotNull(clone);
            Assert.IsNotNull(clone.Mesh);
            Assert.IsTrue(clone.Mesh is TriangleMesh);
            Assert.AreSame(_mesh, clone.Mesh);
            Assert.AreEqual(_mesh.NumberOfTriangles, clone.Mesh.NumberOfTriangles);
            for (int i = 0; i < _mesh.NumberOfTriangles; i++)
            {
                Triangle t = _mesh.GetTriangle(i);

                Triangle tCloned = clone.Mesh.GetTriangle(i);

                Assert.AreEqual(t.Vertex0, tCloned.Vertex0);
                Assert.AreEqual(t.Vertex1, tCloned.Vertex1);
                Assert.AreEqual(t.Vertex2, tCloned.Vertex2);
            }

            Assert.IsNotNull(clone.Partition);
            Assert.IsInstanceOf(partition.GetType(), clone.Partition);
            Assert.AreEqual(_mesh.NumberOfTriangles, clone.Partition.Count);
            Assert.AreNotSame(partition, clone.Partition);
        }
Esempio n. 9
0
        protected override void LoadContent()
        {
            boxModel   = Content.Load <Model>("box");
            torusModel = Content.Load <Model>("torus");

            // Get the vertex information out of the model
            List <JVector> positions = new List <JVector>();
            List <JOctree.TriangleVertexIndices> indices = new List <JOctree.TriangleVertexIndices>();

            ExtractData(positions, indices, torusModel);

            // Build an octree of it
            JOctree octree = new JOctree(positions, indices);

            octree.BuildOctree();

            // Pass it to a new instance of the triangleMeshShape
            TriangleMeshShape triangleMeshShape = new TriangleMeshShape(octree);

            // Create a body, using the triangleMeshShape
            RigidBody triangleBody = new RigidBody(triangleMeshShape);

            triangleBody.Tag      = Color.LightGray;
            triangleBody.Position = new JVector(0, 3, 0);

            // Add the mesh to the world.
            world.AddBody(triangleBody);

            base.LoadContent();
        }
Esempio n. 10
0
        /// <summary>
        /// Converts mesh content to model content with a <see cref="TriangleMeshShape"/>.
        /// </summary>
        /// <param name="input">The root node content.</param>
        /// <param name="context">Context for the specified processor.</param>
        /// <returns>The <see cref="Shape"/>.</returns>
        public override DRModelNodeContent Process(NodeContent input, ContentProcessorContext context)
        {
            // ----- Process Model
            var model = base.Process(input, context);

            // ----- Extract Triangles
            var triangleMesh = new TriangleMesh();

            // The input node is usually a tree of nodes. We need to collect all MeshContent nodes
            // in the tree. The DigitalRune Helper library provides a TreeHelper that can be used
            // to traverse trees using LINQ.
            // The following returns an IEnumerable that returns all nodes of the tree.
            var nodes = TreeHelper.GetSubtree(input, n => n.Children);

            // We only need nodes of type MeshContent.
            var meshes = nodes.OfType <MeshContent>();

            foreach (var mesh in meshes)
            {
                // Apply any transformations to vertices.
                Matrix transform = mesh.AbsoluteTransform;
                for (int i = 0; i < mesh.Positions.Count; i++)
                {
                    mesh.Positions[i] = Vector3.Transform(mesh.Positions[i], transform);
                }

                // Extract triangles from submeshes.
                foreach (var geometry in mesh.Geometry)
                {
                    int numberOfTriangles = geometry.Indices.Count / 3;
                    for (int i = 0; i < numberOfTriangles; i++)
                    {
                        int index0 = geometry.Indices[3 * i + 0];
                        int index1 = geometry.Indices[3 * i + 2]; // Note: DigitalRune Geometry uses a different winding
                        int index2 = geometry.Indices[3 * i + 1]; // order. Therefore, the indices need to be swapped.

                        Vector3F vertex0 = (Vector3F)geometry.Vertices.Positions[index0];
                        Vector3F vertex1 = (Vector3F)geometry.Vertices.Positions[index1];
                        Vector3F vertex2 = (Vector3F)geometry.Vertices.Positions[index2];

                        triangleMesh.Add(new Triangle(vertex0, vertex1, vertex2), false, Numeric.EpsilonF, true);
                    }
                }
            }

            // Remove duplicate vertices.
            triangleMesh.WeldVertices();

            // ----- Create TriangleMeshShape
            // Create a TriangleMeshShape that can be used for collision detection.
            // Note:
            // - Contact-welding is enabled to improve the results of the collision detection.
            // - A CompressedAabbTree is used for spatial partitioning to speed up collision detection.
            var triangleMeshShape = new TriangleMeshShape(triangleMesh, true, new CompressedAabbTree());

            // Export the ModelNode together with the TriangleMeshShape.
            model.UserData = triangleMeshShape;
            return(model);
        }
        public void PropertiesTest()
        {
            TriangleMeshShape shape = new TriangleMeshShape();

            Assert.AreNotEqual(_mesh, shape.Mesh);
            shape.Mesh = _mesh;
            Assert.AreEqual(_mesh, shape.Mesh);
        }
Esempio n. 12
0
        public static TriangleMeshShape Load(string filename)
        {
            int lineIndex = 2;

            // This function is very similar to the main mesh loading function, but physics meshes generally contain
            // less data (fewer vertices and no texture coordinates). Physics meshes also aren't cached in the same way
            // as regular models (since triangle meshes tend to be loaded in large chunks infrequently as the player
            // moves around the world).
            string[] lines = File.ReadAllLines(Paths.Meshes + filename);
            string   line  = lines[lineIndex];

            // Parse points.
            List <JVector> points = new List <JVector>();

            do
            {
                points.Add(ParseJVector(line));
                line = lines[++lineIndex];
            }while (line[0] == 'v' && line[1] != 'n');

            // Normals may or may not be present in the exported .obj file.
            while (line[1] == 'n')
            {
                line = lines[++lineIndex];
            }

            // The next line is smoothing ("s off"), which isn't relevant.
            lineIndex++;

            // Parse triangles. All remaining lines should be faces.
            List <TriangleVertexIndices> tris = new List <TriangleVertexIndices>();

            do
            {
                // With only indices exported, each face line looks like "f 1 2 3".
                string[] tokens = lines[lineIndex++].Split(' ');

                // If normals were exported, each token will look like "1/2/3" instead. Also note that assigning
                // indices in the opposite order (2-1-0 rather than 0-1-2) causes Jitter to process triangles in the
                // correct direction (without having to flip normals in Blender).
                int i2 = int.Parse(tokens[1].Split('/')[0]) - 1;
                int i1 = int.Parse(tokens[2].Split('/')[0]) - 1;
                int i0 = int.Parse(tokens[3].Split('/')[0]) - 1;

                tris.Add(new TriangleVertexIndices(i0, i1, i2));
            }while (lineIndex < lines.Length);

            var octree = new Octree(points, tris);

            octree.BuildOctree();

            // TODO: Lists are attached to the triangle mesh for debug rendering. They should be removed later.
            var shape = new TriangleMeshShape(octree);

            shape.Tag = new Tuple <List <JVector>, List <TriangleVertexIndices> >(points, tris);

            return(shape);
        }
Esempio n. 13
0
        public void ComputeCollision()
        {
            CollisionObject a    = new CollisionObject();
            TriangleMesh    mesh = new TriangleMesh();

            mesh.Add(new Triangle(new Vector3F(0, 0, 0), new Vector3F(0, 0, 1), new Vector3F(1, 0, 0)), false);
            mesh.Add(new Triangle(new Vector3F(1, 0, 0), new Vector3F(0, 0, 1), new Vector3F(1, 0, 1)), false);
            TriangleMeshShape meshShape = new TriangleMeshShape();

            meshShape.Mesh    = mesh;
            a.GeometricObject = new GeometricObject(meshShape, Pose.Identity);

            CollisionObject b = new CollisionObject(new GeometricObject
            {
                Shape = new SphereShape(1),
                Pose  = new Pose(new Vector3F(0, 0.9f, 0)),
            });

            ContactSet            set;
            TriangleMeshAlgorithm algo = new TriangleMeshAlgorithm(new CollisionDetection());

            set = algo.GetClosestPoints(a, b);
            Assert.AreEqual(true, algo.HaveContact(a, b));
            Assert.AreEqual(true, algo.HaveContact(b, a));
            Assert.AreEqual(1, set.Count);
            Assert.IsTrue(Numeric.AreEqual(0.1f, set[0].PenetrationDepth, 0.001f));
            //Assert.IsTrue(Vector3F.AreNumericallyEqual(new Vector3F(0, 0, 0), set[0].PositionALocal, 0.01f));  // MPR will not return the perfect contact point.
            Assert.IsTrue(Vector3F.AreNumericallyEqual(new Vector3F(0, 1, 0), set[0].Normal, 0.1f));

            ((GeometricObject)b.GeometricObject).Pose = new Pose(new Vector3F(0.1f, 0.9f, 0.1f));
            algo.UpdateContacts(set, 0);
            Assert.AreEqual(true, algo.HaveContact(a, b));
            Assert.AreEqual(true, algo.HaveContact(b, a));
            Assert.AreEqual(1, set.Count);
            Assert.IsTrue(Numeric.AreEqual(0.1f, set[0].PenetrationDepth, 0.001f));
            Assert.IsTrue(Vector3F.AreNumericallyEqual(new Vector3F(0.1f, 0, 0.1f), set[0].PositionALocal, 0.01f));
            Assert.IsTrue(Vector3F.AreNumericallyEqual(new Vector3F(0, 1, 0), set[0].Normal, 0.1f));

            // The same with a swapped set.
            set = set.Swapped;
            algo.UpdateContacts(set, 0);
            Assert.AreEqual(1, set.Count);
            Assert.IsTrue(Numeric.AreEqual(0.1f, set[0].PenetrationDepth, 0.001f));
            Assert.IsTrue(Vector3F.AreNumericallyEqual(new Vector3F(0.1f, 0, 0.1f), set[0].PositionBLocal, 0.01f));
            Assert.IsTrue(Vector3F.AreNumericallyEqual(new Vector3F(0, -1, 0), set[0].Normal, 0.1f));

            // Separation.
            ((GeometricObject)b.GeometricObject).Pose = new Pose(new Vector3F(0.2f, 1.2f, 0.3f));
            set = set.Swapped;
            Assert.AreEqual(false, algo.HaveContact(a, b));
            Assert.AreEqual(false, algo.HaveContact(b, a));
            algo.UpdateClosestPoints(set, 0);
            Assert.IsTrue(Numeric.AreEqual(-0.2f, set[0].PenetrationDepth, 0.001f));
            Assert.IsTrue(Vector3F.AreNumericallyEqual(new Vector3F(0.2f, 0, 0.3f), set[0].PositionALocal, 0.01f));
            Assert.IsTrue(Vector3F.AreNumericallyEqual(new Vector3F(0, 1, 0), set[0].Normal, 0.1f));
            algo.UpdateContacts(set, 0);
            Assert.AreEqual(0, set.Count);
        }
Esempio n. 14
0
        public void MakeModelPhysicsGeneric(Model model)
        {
            model.Frame.UpdateHierarchical();

            model.UpdateOctree();

            var shape = new TriangleMeshShape(model.Octree);

            model.PhysicsShape = shape;
        }
Esempio n. 15
0
        void IConstructable.Construct(IDictionary <string, string> param)
        {
            var type = param["type"];

            switch (type)
            {
            case "trimesh":
                var   physData = ResourceFactory.LoadAsset <PhysicsData>(param["physData"]);
                Shape shape    = new TriangleMeshShape(physData.Octree);
                Body = new RigidBody(shape)
                {
                    Material = { Restitution = 0f, KineticFriction = 0f }
                };
                break;

            case "hull":
                physData = ResourceFactory.LoadAsset <PhysicsData>(param["physData"]);
                shape    = new ConvexHullShape(physData.Vertices);
                Body     = new RigidBody(shape);
                break;

            case "sphere":
                shape = new SphereShape(float.Parse(param["radius"], CultureInfo.InvariantCulture));
                Body  = new RigidBody(shape);
                break;

            case "box":
                var d      = param["size"].ConvertToVector();
                var offset = param.Get("offset", "0;0;0").ConvertToVector();
                shape = new BoxShape(2.0f * d.ToJVector());
                Body  = new RigidBody(shape)
                {
                    Position = offset.ToJVector()
                };
                break;

            case "capsule":
                var height = float.Parse(param["height"], CultureInfo.InvariantCulture);
                var radius = float.Parse(param["radius"], CultureInfo.InvariantCulture);
                shape = new CapsuleShape(height, radius);
                Body  = new RigidBody(shape)
                {
                    Position    = JVector.Backward * (0.5f * height + radius),
                    Orientation = JMatrix.CreateRotationX(MathHelper.PiOver2)
                };
                break;

            default:
                throw new Exception("Unknown shape: " + type);
            }
            Body.IsStatic = Convert.ToBoolean(param.Get("static", "false"));
            Body.Material.KineticFriction = 0.5f;
            Body.Material.StaticFriction  = 0.5f;
            Body.Material.Restitution     = 0.5f;
        }
Esempio n. 16
0
        public SpatialPartitionSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            SampleFramework.IsMouseVisible = false;
            GraphicsScreen.ClearBackground = true;
            GraphicsScreen.BackgroundColor = Color.Gray;
            GraphicsScreen.DrawReticle     = true;
            SetCamera(new Vector3(0, 1, 10), 0, 0);

            // Create a spatial partition. DigitalRune Geometry supports several types, see also
            // http://digitalrune.github.io/DigitalRune-Documentation/html/e32cab3b-cc7c-42ee-8ec9-23dd4467edd0.htm#WhichPartition
            // An AabbTree is useful for static objects. A DynamicAabbTree is good for moving objects.
            // The spatial partition can manage different types of items. In this case it manages
            // GeometricObjects. A delegate has to inform the spatial partition how to get the AABB
            // of an object.
            //_spatialPartition = new DynamicAabbTree<GeometricObject>
            _spatialPartition = new AabbTree <GeometricObject>
            {
                GetAabbForItem = geometricObject => geometricObject.Aabb,

                // Optional: The tree is automatically built using a mixed top-down/bottom-up approach.
                // Bottom-up building is slower but produces better trees. If the tree building takes too
                // long, we can lower the BottomUpBuildThreshold (default is 128).
                //BottomUpBuildThreshold = 0,

                // Optional: A filter can be set to disable certain kind of overlaps.
                //Filter = ...
            };

            // Create a triangle mesh.
            var triangleMesh      = new SphereShape(1).GetMesh(0.01f, 4);
            var triangleMeshShape = new TriangleMeshShape(triangleMesh)
            {
                // TriangleMeshShapes can also use a spatial partition to manage triangle.
                // The items in the spatial partition are the triangle indices. The GetAabbForItem
                // delegate is set automatically.
                Partition = new AabbTree <int>(),
            };

            // Spatial partitions are built automatically when needed. However, it is still recommended
            // to call Update to initialize the spatial partition explicitly.
            triangleMeshShape.Partition.Update(false);

            // Add a lot of triangle mesh objects to _spatialPartition.
            var random = new Random();

            for (int i = 0; i < 50; i++)
            {
                var randomPosition  = new Vector3(random.NextFloat(-6, 6), random.NextFloat(-3, 3), random.NextFloat(-10, 0));
                var geometricObject = new GeometricObject(triangleMeshShape, new Pose(randomPosition));
                _spatialPartition.Add(geometricObject);
            }

            _spatialPartition.Update(false);
        }
Esempio n. 17
0
        public void OrthographicViewVolumeTest()
        {
            var s  = new OrthographicViewVolume(-1, 0, -1, 0, 0.1f, 10);
            var v0 = s.GetVolume(0.001f, 10);

            var m  = s.GetMesh(0.001f, 10);
            var s1 = new TriangleMeshShape(m);
            var v1 = m.GetVolume();

            Assert.IsTrue(Numeric.AreEqual(v0, v1, 0.01f * (1 + v0))); // 1% error is allowed.
        }
Esempio n. 18
0
        public void PerspectiveViewVolumeTest()
        {
            var s  = new PerspectiveViewVolume(0.4f, 2, 0.1f, 1f);
            var v0 = s.GetVolume(0.001f, 10);

            var m  = s.GetMesh(0.001f, 10);
            var s1 = new TriangleMeshShape(m);
            var v1 = s1.GetVolume(0.0001f, 10);

            Assert.IsTrue(Numeric.AreEqual(v0, v1, 0.01f * (1 + v0))); // 1% error is allowed.
        }
Esempio n. 19
0
        public void TriangleMeshShapeTest()
        {
            var s  = new CylinderShape(1, 2);
            var v0 = s.GetVolume(0.001f, 10);

            var m  = s.GetMesh(0.001f, 10);
            var s1 = new TriangleMeshShape(m);
            var v1 = m.GetVolume();

            Assert.IsTrue(Numeric.AreEqual(v0, v1, 0.01f * (1 + v0))); // 1% error is allowed.
        }
Esempio n. 20
0
        Mesh CreateTriangleMeshShape(TriangleMeshShape shape)
        {
            StridingMeshInterface meshInterface = shape.MeshInterface;

            BulletSharp.DataStream verts, indices;
            int           numVerts, numFaces;
            PhyScalarType vertsType, indicesType;
            int           vertexStride, indexStride;

            meshInterface.GetLockedReadOnlyVertexIndexData(out verts, out numVerts, out vertsType, out vertexStride,
                                                           out indices, out indexStride, out numFaces, out indicesType);

            bool index32 = numVerts > 65536;

            Mesh mesh = new Mesh(device, numFaces, numVerts,
                                 MeshFlags.SystemMemory | (index32 ? MeshFlags.Use32Bit : 0), VertexFormat.Position | VertexFormat.Normal);

            SlimDX.DataStream data = mesh.LockVertexBuffer(LockFlags.None);
            while (verts.Position < verts.Length)
            {
                Vector3 v = verts.Read <Vector3>();
                data.Write(v);

                verts.Position += vertexStride - 12;

                // Normals will be calculated later
                data.Position += 12;
            }
            mesh.UnlockVertexBuffer();

            data = mesh.LockIndexBuffer(LockFlags.None);
            while (indices.Position < indices.Length)
            {
                int index = indices.Read <int>();
                if (index32)
                {
                    data.Write(index);
                }
                else
                {
                    data.Write((short)index);
                }
            }
            mesh.UnlockVertexBuffer();

            mesh.ComputeNormals();

            shapes.Add(shape, mesh);
            return(mesh);
        }
Esempio n. 21
0
        private void Draw(TriangleMeshShape shape, Color color)
        {
            var tuple  = (Tuple <List <JVector>, List <TriangleVertexIndices> >)shape.Tag;
            var points = tuple.Item1;
            var tris   = tuple.Item2;

            foreach (TriangleVertexIndices tri in tris)
            {
                vec3 p0 = points[tri.I0].ToVec3();
                vec3 p1 = points[tri.I1].ToVec3();
                vec3 p2 = points[tri.I2].ToVec3();

                primitives.DrawTriangle(p0, p1, p2, color);
            }
        }
Esempio n. 22
0
	private static Shape ConvertMeshToShape(Mesh mesh)
	{
		var vertices = mesh.vertices;
		var vertexList = vertices.Select(p => p.ToJVector()).ToList();

		var indices = mesh.triangles;
		var indexList = new List<TriangleVertexIndices>();
		for (int i = 0; i < indices.Length; i += 3)
		{
			indexList.Add(new TriangleVertexIndices(indices[i + 2], indices[i + 1], indices[i + 0]));
		}

		var octree = new Octree(vertexList, indexList);
		var shape = new TriangleMeshShape(octree);
		return shape;
	}
Esempio n. 23
0
        public void Unload()
        {
            foreach (var bank in _banks)
            {
                bank.Value.Dispose();
            }

            _banks = null;

            Server.PhysicsWorld.RemoveBody(_collisionBody);

            _collisionBody = null;
            _collisionMesh = null;

            Loaded = false;
        }
        public void ContactWelding()
        {
            var mesh = new SphereShape(0.5f).GetMesh(0.0001f, 7);

            Stopwatch watch     = Stopwatch.StartNew();
            var       meshShape = new TriangleMeshShape(mesh, true, null);

            watch.Stop();
            //Assert.AreEqual(0, watch.Elapsed.TotalMilliseconds);

            Assert.AreEqual(mesh.NumberOfTriangles * 3, meshShape.TriangleNeighbors.Count);

            for (int i = 0; i < mesh.NumberOfTriangles; i++)
            {
                Assert.AreNotEqual(-1, meshShape.TriangleNeighbors[i * 3 + 0]);
                Assert.AreNotEqual(-1, meshShape.TriangleNeighbors[i * 3 + 1]);
                Assert.AreNotEqual(-1, meshShape.TriangleNeighbors[i * 3 + 2]);

                var triangle = mesh.GetTriangle(i);

                // Check if each edge neighbor shares two vertices with this triangle.
                for (int e = 0; e < 3; e++)
                {
                    var vertex0 = triangle[(e + 1) % 3];
                    var vertex1 = triangle[(e + 2) % 3];

                    var neighbor = mesh.GetTriangle(meshShape.TriangleNeighbors[i * 3 + e]);

                    int sharedCount = 0;

                    // Count shared vertices.
                    for (int j = 0; j < 3; j++)
                    {
                        if (Vector3F.AreNumericallyEqual(vertex0, neighbor[j]))
                        {
                            sharedCount++;
                        }
                        if (Vector3F.AreNumericallyEqual(vertex1, neighbor[j]))
                        {
                            sharedCount++;
                        }
                    }

                    Assert.AreEqual(2, sharedCount);
                }
            }
        }
Esempio n. 25
0
        public void Load()
        {
            var startTime = Game.Time;

            _banks = MakeBanks(false);

            if (Renderer.Device != null)
            {
                foreach (var bank in _banks)
                {
                    bank.Value.UploadToGPU(Renderer.Device);
                }
            }

            // build collision mesh
            var colBanks     = MakeBanks(true);
            var colPositions = new List <JVector>();
            var colTris      = new List <TriangleVertexIndices>();

            foreach (var bank in colBanks.Values)
            {
                foreach (var vertex in bank.vertices)
                {
                    colPositions.Add(vertex.Position.ToJVector());
                }

                for (int i = 0; i < bank.numIndex; i += 3)
                {
                    colTris.Add(new TriangleVertexIndices(bank.indices[i], bank.indices[i + 1], bank.indices[i + 2]));
                }
            }

            var octree = new Octree(colPositions, colTris);

            _collisionMesh          = new TriangleMeshShape(octree);
            _collisionBody          = new RigidBody(_collisionMesh);
            _collisionBody.IsStatic = true;

            Server.PhysicsWorld.AddBody(_collisionBody);

            Loaded = true;

            var time = Game.Time - startTime;

            Log.Write(LogLevel.Debug, "load cell took {0}msec", time);
        }
Esempio n. 26
0
        private void CreateRigidBody()
        {
            var triangleMesh = new TriangleMesh();

            foreach (var meshNode in _modelNode.GetSubtree().OfType <MeshNode>())
            {
                // Extract the triangle mesh from the DigitalRune Graphics Mesh instance.
                var subTriangleMesh = new TriangleMesh();
                foreach (var submesh in meshNode.Mesh.Submeshes)
                {
                    submesh.ToTriangleMesh(subTriangleMesh);
                }

                // Apply the transformation of the mesh node.
                subTriangleMesh.Transform(meshNode.PoseWorld * Matrix.CreateScale(meshNode.ScaleWorld));

                // Combine into final triangle mesh.
                triangleMesh.Add(subTriangleMesh);
            }

            // Create a collision shape that uses the mesh.
            var triangleMeshShape = new TriangleMeshShape(triangleMesh);

            // 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 CompressedAabbTree
            {
                // The tree is automatically built using a mixed top-down/bottom-up approach. Bottom-up
                // building is slower but produces better trees. If the tree building takes too long,
                // we can lower the BottomUpBuildThreshold (default is 128).
                BottomUpBuildThreshold = 0,
            };

            _rigidBody = new RigidBody(triangleMeshShape, new MassFrame(), null)
            {
                Pose       = _pose,
                Scale      = _scale,
                MotionType = MotionType.Static
            };

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

            simulation.RigidBodies.Add(_rigidBody);
        }
Esempio n. 27
0
        static Vector3[] CreateTriangleMesh(TriangleMeshShape shape)
        {
            StridingMeshInterface meshInterface = shape.MeshInterface;

            BulletSharp.DataStream vertexBuffer, indexBuffer;
            int           numVerts, numFaces;
            PhyScalarType vertsType, indicesType;
            int           vertexStride, indexStride;

            meshInterface.GetLockedReadOnlyVertexIndexData(out vertexBuffer, out numVerts, out vertsType, out vertexStride,
                                                           out indexBuffer, out indexStride, out numFaces, out indicesType);

            Vector3[] vertices = new Vector3[numFaces * 3 * 2];

            // Need to un-index the vertex buffer to make the normals right.
            int v = 0;

            while (indexBuffer.Position < indexBuffer.Length)
            {
                uint i = indexBuffer.Read <uint>();
                vertexBuffer.Position = vertexStride * i;
                Vector3 v0 = vertexBuffer.Read <Vector3>();
                i = indexBuffer.Read <uint>();
                vertexBuffer.Position = vertexStride * i;
                Vector3 v1 = vertexBuffer.Read <Vector3>();
                i = indexBuffer.Read <uint>();
                vertexBuffer.Position = vertexStride * i;
                Vector3 v2 = vertexBuffer.Read <Vector3>();

                Vector3 v01    = v0 - v1;
                Vector3 v02    = v0 - v2;
                Vector3 normal = Vector3.Cross(v01, v02);
                normal.Normalize();

                vertices[v++] = v0;
                vertices[v++] = normal;
                vertices[v++] = v1;
                vertices[v++] = normal;
                vertices[v++] = v2;
                vertices[v++] = normal;
            }

            return(vertices);
        }
Esempio n. 28
0
        public void ContactWelding()
        {
            var mesh = new SphereShape(0.5f).GetMesh(0.0001f, 7);

              Stopwatch watch = Stopwatch.StartNew();
              var meshShape = new TriangleMeshShape(mesh, true, null);
              watch.Stop();
              //Assert.AreEqual(0, watch.Elapsed.TotalMilliseconds);

              Assert.AreEqual(mesh.NumberOfTriangles * 3, meshShape.TriangleNeighbors.Count);

              for (int i = 0; i < mesh.NumberOfTriangles; i++)
              {
            Assert.AreNotEqual(-1, meshShape.TriangleNeighbors[i * 3 + 0]);
            Assert.AreNotEqual(-1, meshShape.TriangleNeighbors[i * 3 + 1]);
            Assert.AreNotEqual(-1, meshShape.TriangleNeighbors[i * 3 + 2]);

            var triangle = mesh.GetTriangle(i);

            // Check if each edge neighbor shares two vertices with this triangle.
            for (int e = 0; e < 3; e++)
            {
              var vertex0 = triangle[(e + 1) % 3];
              var vertex1 = triangle[(e + 2) % 3];

              var neighbor = mesh.GetTriangle(meshShape.TriangleNeighbors[i * 3 + e]);

              int sharedCount = 0;

              // Count shared vertices.
              for (int j = 0; j < 3; j++)
              {
            if (Vector3F.AreNumericallyEqual(vertex0, neighbor[j]))
              sharedCount++;
            if (Vector3F.AreNumericallyEqual(vertex1, neighbor[j]))
              sharedCount++;
              }

              Assert.AreEqual(2, sharedCount);
            }
              }
        }
Esempio n. 29
0
        public void Validate6()
        {
            GlobalSettings.ValidationLevel = 0xff;
            var scene = new Scene();
            // This is allowed.
            var n = new TestSceneNode {
                Shape = Shape.Empty
            };

            scene.Children.Add(n);

            // Invalid changes of already added node:
            var mesh = new TriangleMesh();

            mesh.Add(new Triangle(new Vector3F(1), new Vector3F(2), new Vector3F(3)));
            mesh.Add(new Triangle(new Vector3F(4), new Vector3F(float.NaN, 5, 5), new Vector3F(6)));
            var meshShape = new TriangleMeshShape(mesh);

            Assert.Throws <GraphicsException>(() => n.Shape = meshShape);
        }
Esempio n. 30
0
        public CollisionShape BuildCorner()
        {
            // slope.
            IndexedVector3[] vertices = new IndexedVector3[] { new IndexedVector3(0, 0, 0), new IndexedVector3(1, 0, 0), new IndexedVector3(0, 0, 1), new IndexedVector3(1, 0, 1),
                                                               new IndexedVector3(0, 1, 0), new IndexedVector3(1, 1, 0), new IndexedVector3(0, 1, 1), new IndexedVector3(1, 1, 1) };



            //int[] indices = new int[] { 0, 4, 5, 4, 6, 7, 7, 5, 4, 0, 4, 6, 6, 2, 0, 2, 6, 7, 4,5,0,2,2,7,5};
            //int[] indices = new int[] { 0, 4, 5, 4, 6, 7, 7, 5, 4,  6, 4,0,0,2,6, 7, 6, 2, 4, 5, 0, 2, 2, 7, 5 };
            int[] indices = new int[] { 1, 4, 5,
                                        1, 5, 7,
                                        7, 3, 1,
                                        3, 7, 6,
                                        7, 5, 4,
                                        4, 6, 7,
                                        4, 1, 3,
                                        3, 6, 4 };

            int vertStride  = 1;
            int indexStride = 3;

            ObjectArray <IndexedVector3> vertexArray = new ObjectArray <IndexedVector3>();

            for (int i = 0; i < vertices.Length; ++i)
            {
                vertexArray.Add(vertices[i]);
            }

            ObjectArray <int> intArray = new ObjectArray <int>();

            for (int i = 0; i < indices.Length; ++i)
            {
                intArray.Add(indices[i]);
            }
            TriangleIndexVertexArray indexVertexArray = new TriangleIndexVertexArray(indices.Length / 3, intArray, indexStride, vertexArray.Count, vertexArray, vertStride);
            TriangleMeshShape        triangleMesh     = new TriangleMeshShape(indexVertexArray);

            //TriangleMeshShape triangleMesh = new BvhTriangleMeshShape(indexVertexArray,true,true);
            return(triangleMesh);
        }
Esempio n. 31
0
        /// <summary>
        /// Initialize the physic world with the geometric detail of map.
        /// </summary>
        /// <param name="map">The base to create the physic world.</param>
        private void Initialize(Map.Map map)
        {
            List <JVector> vertices = new List <JVector>();
            List <TriangleVertexIndices> indices = new List <TriangleVertexIndices>();

            for (uint i = 0; i < map.Width; i++)
            {
                for (uint j = 0; j < map.Length; j++)
                {
                    for (uint k = 0; k < map.Height; k++)
                    {
                        int   pos   = 0;
                        Block block = map.GetBlock(new Vector3(i, j, k));
                        block.CreateColisions();
                        foreach (JVector vertice in block.CollisionVertices)
                        {
                            vertices.Add(vertice);
                            pos++;
                        }

                        int newPos = vertices.Count - pos;
                        foreach (TriangleVertexIndices indice in block.CollisionTriangles)
                        {
                            TriangleVertexIndices t = new TriangleVertexIndices(indice.I0 + newPos, indice.I1 + newPos, indice.I2 + newPos);
                            indices.Add(t);
                        }
                    }
                }
            }

            //ToDo: The vertices list has duplicated vertices. In the worst case each vertices has 4 different instantiation.
            //Probably some performance can be expected by remove the duplicated ones.
            //However it is also necessary to update the indies List with the correct positions.

            Octree            tree  = new Octree(vertices, indices);
            TriangleMeshShape shape = new TriangleMeshShape(tree);
            RigidBody         body  = new RigidBody(shape);

            body.IsStatic = true;
            world.AddBody(body);
        }
Esempio n. 32
0
 public void PropertiesException()
 {
     TriangleMeshShape shape = new TriangleMeshShape();
       shape.Mesh = null;
 }
Esempio n. 33
0
        public void Setup()
        {
            // Make a unit cube.
              _mesh = new TriangleMesh();
              // Bottom
              _mesh.Add(new Triangle(new Vector3F(0, 0, 0), new Vector3F(1, 1, 0), new Vector3F(1, 0, 0)), true);
              _mesh.Add(new Triangle(new Vector3F(0, 0, 0), new Vector3F(0, 1, 0), new Vector3F(1, 1, 0)), true);
              // Top
              _mesh.Add(new Triangle(new Vector3F(0, 0, 1), new Vector3F(1, 0, 1), new Vector3F(1, 1, 1)), true);
              _mesh.Add(new Triangle(new Vector3F(0, 0, 1), new Vector3F(1, 1, 1), new Vector3F(0, 1, 1)), true);
              // Left
              _mesh.Add(new Triangle(new Vector3F(0, 0, 0), new Vector3F(1, 0, 0), new Vector3F(1, 0, 1)), true);
              _mesh.Add(new Triangle(new Vector3F(0, 0, 0), new Vector3F(1, 0, 1), new Vector3F(0, 0, 1)), true);
              // Right
              _mesh.Add(new Triangle(new Vector3F(0, 1, 0), new Vector3F(0, 1, 1), new Vector3F(1, 1, 1)), true);
              _mesh.Add(new Triangle(new Vector3F(0, 1, 0), new Vector3F(1, 1, 1), new Vector3F(1, 1, 0)), true);
              // Front
              _mesh.Add(new Triangle(new Vector3F(1, 0, 0), new Vector3F(1, 1, 0), new Vector3F(1, 1, 1)), true);
              _mesh.Add(new Triangle(new Vector3F(1, 0, 0), new Vector3F(1, 1, 1), new Vector3F(1, 0, 1)), true);
              // Back
              _mesh.Add(new Triangle(new Vector3F(0, 0, 0), new Vector3F(0, 0, 1), new Vector3F(0, 1, 1)), true);
              _mesh.Add(new Triangle(new Vector3F(0, 0, 0), new Vector3F(0, 1, 1), new Vector3F(0, 1, 0)), true);

              _meshShape = new TriangleMeshShape { Mesh = _mesh };
        }
Esempio n. 34
0
 public void PropertiesTest()
 {
     TriangleMeshShape shape = new TriangleMeshShape();
       Assert.AreNotEqual(_mesh, shape.Mesh);
       shape.Mesh = _mesh;
       Assert.AreEqual(_mesh, shape.Mesh);
 }