Exemple #1
0
        public static void ExtractModelMeshPartData(ModelMesh mm, ModelMeshPart mmp, ref Matrix xform,
                                                    List <Vector3> vertices, List <TriangleVertexIndices> indices, string name)
        {
            int offset = vertices.Count;

            Vector3[] a = new Vector3[mmp.NumVertices];
            mm.VertexBuffer.GetData <Vector3>(mmp.StreamOffset + mmp.BaseVertex * mmp.VertexStride,
                                              a, 0, mmp.NumVertices, mmp.VertexStride);
            for (int i = 0; i != a.Length; ++i)
            {
                Vector3.Transform(ref a[i], ref xform, out a[i]);
            }
            vertices.AddRange(a);

            if (mm.IndexBuffer.IndexElementSize != IndexElementSize.SixteenBits)
            {
                throw new Exception(
                          String.Format("Model {0} uses 32-bit indices, which are not supported.",
                                        name));
            }
            short[] s = new short[mmp.PrimitiveCount * 3];
            mm.IndexBuffer.GetData <short>(mmp.StartIndex * 2, s, 0, mmp.PrimitiveCount * 3);
            TriangleVertexIndices[] tvi = new TriangleVertexIndices[mmp.PrimitiveCount];
            for (int i = 0; i != tvi.Length; ++i)
            {
                tvi[i].I0 = s[i * 3 + 0] + offset;
                tvi[i].I1 = s[i * 3 + 1] + offset;
                tvi[i].I2 = s[i * 3 + 2] + offset;
            }
            indices.AddRange(tvi);
        }
        public static void ExtractModelMeshPartData(ModelMesh mm, ModelMeshPart mmp, ref Matrix xform,
            List<Vector3> vertices, List<TriangleVertexIndices> indices, string name)
        {
            int offset = vertices.Count;
            Vector3[] a = new Vector3[mmp.NumVertices];
            mm.VertexBuffer.GetData<Vector3>(mmp.StreamOffset + mmp.BaseVertex * mmp.VertexStride,
                a, 0, mmp.NumVertices, mmp.VertexStride);
            for (int i = 0; i != a.Length; ++i)
                Vector3.Transform(ref a[i], ref xform, out a[i]);
            vertices.AddRange(a);

            if (mm.IndexBuffer.IndexElementSize != IndexElementSize.SixteenBits)
                throw new Exception(
                    String.Format("Model {0} uses 32-bit indices, which are not supported.",
                                  name));
            short[] s = new short[mmp.PrimitiveCount * 3];
            mm.IndexBuffer.GetData<short>(mmp.StartIndex * 2, s, 0, mmp.PrimitiveCount * 3);
            TriangleVertexIndices[] tvi = new TriangleVertexIndices[mmp.PrimitiveCount];
            for (int i = 0; i != tvi.Length; ++i)
            {
                tvi[i].I0 = s[i * 3 + 0] + offset;
                tvi[i].I1 = s[i * 3 + 1] + offset;
                tvi[i].I2 = s[i * 3 + 2] + offset;
            }
            indices.AddRange(tvi);
        }
Exemple #3
0
        public void ExtractData(List <Vector3> vertices, List <TriangleVertexIndices> indices, Model model)
        {
            var bones = new Matrix[model.Bones.Count];

            model.CopyAbsoluteBoneTransformsTo(bones);
            foreach (var mm in model.Meshes)
            {
                var offset = vertices.Count;
                var xform  = bones[mm.ParentBone.Index];
                foreach (var mmp in mm.MeshParts)
                {
                    var a      = new Vector3[mmp.NumVertices];
                    var stride = mmp.VertexBuffer.VertexDeclaration.VertexStride;

                    mmp.VertexBuffer.GetData(mmp.VertexOffset * stride, a, 0, mmp.NumVertices, stride);

                    for (var i = 0; i != a.Length; ++i)
                    {
                        Vector3.Transform(ref a[i], ref xform, out a[i]);
                    }
                    vertices.AddRange(a);


                    if (mmp.IndexBuffer.IndexElementSize != IndexElementSize.SixteenBits)
                    {
                        throw new Exception(string.Format("Model uses 32-bit indices, which are not supported."));
                    }

                    var s = new short[mmp.PrimitiveCount * 3];

                    mmp.IndexBuffer.GetData(mmp.StartIndex * 2, s, 0, mmp.PrimitiveCount * 3);

                    var tvi = new TriangleVertexIndices[mmp.PrimitiveCount];
                    for (var i = 0; i != tvi.Length; ++i)
                    {
                        tvi[i].I0 = s[i * 3 + 2] + offset;
                        tvi[i].I1 = s[i * 3 + 1] + offset;
                        tvi[i].I2 = s[i * 3 + 0] + offset;
                    }

                    indices.AddRange(tvi);
                }
            }
        }
Exemple #4
0
        private void AddPointsAndSprings(List <TriangleVertexIndices> indices, List <JVector> vertices)
        {
            for (int i = 0; i < vertices.Count; i++)
            {
                MassPoint point = new MassPoint(sphere, this, material);
                point.Position = vertices[i];

                point.Mass = 0.1f;

                points.Add(point);
            }

            for (int i = 0; i < indices.Count; i++)
            {
                TriangleVertexIndices index = indices[i];

                Triangle t = new Triangle(this);

                t.indices = index;
                triangles.Add(t);

                t.boundingBox = JBBox.SmallBox;
                t.boundingBox.AddPoint(points[t.indices.I0].position);
                t.boundingBox.AddPoint(points[t.indices.I1].position);
                t.boundingBox.AddPoint(points[t.indices.I2].position);

                t.dynamicTreeID = dynamicTree.AddProxy(ref t.boundingBox, t);
            }

            HashSet <Edge> edges = GetEdges(indices);

            int count = 0;

            foreach (Edge edge in edges)
            {
                Spring spring = new Spring(points[edge.Index1], points[edge.Index2]);
                spring.Softness   = 0.01f; spring.BiasFactor = 0.1f;
                spring.SpringType = SpringType.EdgeSpring;

                springs.Add(spring);
                count++;
            }
        }
Exemple #5
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);
        }
        /// <summary>
        /// Helper Method to get the vertex and index List from the model.
        /// </summary>
        /// <param name="vertices"></param>
        /// <param name="indices"></param>
        /// <param name="model"></param>
        public void ExtractData(List <Vector3> vertices, List <TriangleVertexIndices> indices, Model model)
        {
            Demo.Camera.Position = new Vector3(12, 10, 25);
            Demo.Camera.Target   = Demo.Camera.Position + Vector3.Normalize(new Vector3(10, 5, 20));
            Matrix[] bones_ = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(bones_);
            foreach (ModelMesh mm in model.Meshes)
            {
                Matrix xform = bones_[mm.ParentBone.Index];
                foreach (ModelMeshPart mmp in mm.MeshParts)
                {
                    int       offset = vertices.Count;
                    Vector3[] a      = new Vector3[mmp.NumVertices];
                    mmp.VertexBuffer.GetData <Vector3>(mmp.VertexOffset * mmp.VertexBuffer.VertexDeclaration.VertexStride,
                                                       a, 0, mmp.NumVertices, mmp.VertexBuffer.VertexDeclaration.VertexStride);
                    for (int i = 0; i != a.Length; ++i)
                    {
                        Vector3.Transform(ref a[i], ref xform, out a[i]);
                    }
                    vertices.AddRange(a);

                    if (mmp.IndexBuffer.IndexElementSize != IndexElementSize.SixteenBits)
                    {
                        throw new Exception(
                                  String.Format("Model uses 32-bit indices, which are not supported."));
                    }
                    short[] s = new short[mmp.PrimitiveCount * 3];
                    mmp.IndexBuffer.GetData <short>(mmp.StartIndex * 2, s, 0, mmp.PrimitiveCount * 3);
                    TriangleVertexIndices[] tvi = new TriangleVertexIndices[mmp.PrimitiveCount];
                    for (int i = 0; i != tvi.Length; ++i)
                    {
                        tvi[i].I0 = s[i * 3 + 0] + offset;
                        tvi[i].I1 = s[i * 3 + 1] + offset;
                        tvi[i].I2 = s[i * 3 + 2] + offset;
                    }
                    indices.AddRange(tvi);
                }
            }
        }
Exemple #7
0
        private void RemoveDuplicateVertices(List <TriangleVertexIndices> indices,
                                             List <JVector> vertices)
        {
            Dictionary <JVector, int> unique = new Dictionary <JVector, int>(vertices.Count);
            Stack <int> tbr = new Stack <int>(vertices.Count / 3);

            // get all unique vertices and their indices
            for (int i = 0; i < vertices.Count; i++)
            {
                if (!unique.ContainsKey(vertices[i]))
                {
                    unique.Add(vertices[i], unique.Count);
                }
                else
                {
                    tbr.Push(i);
                }
            }

            // reconnect indices
            for (int i = 0; i < indices.Count; i++)
            {
                TriangleVertexIndices tvi = indices[i];

                tvi.I0 = unique[vertices[tvi.I0]];
                tvi.I1 = unique[vertices[tvi.I1]];
                tvi.I2 = unique[vertices[tvi.I2]];

                indices[i] = tvi;
            }

            // remove duplicate vertices
            while (tbr.Count > 0)
            {
                vertices.RemoveAt(tbr.Pop());
            }

            unique.Clear();
        }
Exemple #8
0
        /// <summary>
        /// Creates a 2D-Cloth. Connects Nearest Neighbours (4x, called EdgeSprings) and adds additional
        /// shear/bend constraints (4xShear+4xBend).
        /// </summary>
        /// <param name="sizeX"></param>
        /// <param name="sizeY"></param>
        /// <param name="scale"></param>
        public SoftBody(int sizeX, int sizeY, float scale)
        {
            List <TriangleVertexIndices> indices = new List <TriangleVertexIndices>();
            List <JVector> vertices = new List <JVector>();

            for (int i = 0; i < sizeY; i++)
            {
                for (int e = 0; e < sizeX; e++)
                {
                    vertices.Add(new JVector(i, 0, e) * scale);
                }
            }

            for (int i = 0; i < sizeX - 1; i++)
            {
                for (int e = 0; e < sizeY - 1; e++)
                {
                    TriangleVertexIndices index = new TriangleVertexIndices();
                    {
                        index.I0 = (e + 0) * sizeX + i + 0;
                        index.I1 = (e + 0) * sizeX + i + 1;
                        index.I2 = (e + 1) * sizeX + i + 1;

                        indices.Add(index);

                        index.I0 = (e + 0) * sizeX + i + 0;
                        index.I1 = (e + 1) * sizeX + i + 1;
                        index.I2 = (e + 1) * sizeX + i + 0;

                        indices.Add(index);
                    }
                }
            }

            EdgeSprings  = springs.AsReadOnly();
            VertexBodies = points.AsReadOnly();
            Triangles    = triangles.AsReadOnly();

            AddPointsAndSprings(indices, vertices);

            for (int i = 0; i < sizeX - 1; i++)
            {
                for (int e = 0; e < sizeY - 1; e++)
                {
                    Spring spring = new Spring(points[(e + 0) * sizeX + i + 1], points[(e + 1) * sizeX + i + 0]);
                    spring.Softness = 0.01f; spring.BiasFactor = 0.1f;
                    springs.Add(spring);
                }
            }

            foreach (Spring spring in springs)
            {
                JVector delta = spring.body1.position - spring.body2.position;

                if (delta.Z != 0.0f && delta.X != 0.0f)
                {
                    spring.SpringType = SpringType.ShearSpring;
                }
                else
                {
                    spring.SpringType = SpringType.EdgeSpring;
                }
            }


            for (int i = 0; i < sizeX - 2; i++)
            {
                for (int e = 0; e < sizeY - 2; e++)
                {
                    Spring spring1 = new Spring(points[(e + 0) * sizeX + i + 0], points[(e + 0) * sizeX + i + 2]);
                    spring1.Softness = 0.01f; spring1.BiasFactor = 0.1f;

                    Spring spring2 = new Spring(points[(e + 0) * sizeX + i + 0], points[(e + 2) * sizeX + i + 0]);
                    spring2.Softness = 0.01f; spring2.BiasFactor = 0.1f;

                    spring1.SpringType = SpringType.BendSpring;
                    spring2.SpringType = SpringType.BendSpring;

                    springs.Add(spring1);
                    springs.Add(spring2);
                }
            }
        }
        public static void ExtractData(List <JVector> vertices, List <TriangleVertexIndices> indices, Model model)
        {
            Matrix[] bones_ = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(bones_);
            foreach (ModelMesh modelmesh in model.Meshes)
            {
                JMatrix xform = Helper.ToJitterMatrix(bones_[modelmesh.ParentBone.Index]);
                foreach (ModelMeshPart meshPart in modelmesh.MeshParts)
                {
                    // Before we add any more where are we starting from
                    int offset = vertices.Count;

                    // Read the format of the vertex buffer
                    VertexDeclaration declaration    = meshPart.VertexBuffer.VertexDeclaration;
                    VertexElement[]   vertexElements = declaration.GetVertexElements();
                    // Find the element that holds the position
                    VertexElement vertexPosition = new VertexElement();
                    foreach (VertexElement vert in vertexElements)
                    {
                        if (vert.VertexElementUsage == VertexElementUsage.Position &&
                            vert.VertexElementFormat == VertexElementFormat.Vector3)
                        {
                            vertexPosition = vert;
                            // There should only be one
                            break;
                        }
                    }
                    // Check the position element found is valid
                    if (vertexPosition == null ||
                        vertexPosition.VertexElementUsage != VertexElementUsage.Position ||
                        vertexPosition.VertexElementFormat != VertexElementFormat.Vector3)
                    {
                        throw new Exception("Model uses unsupported vertex format!");
                    }
                    // This where we store the vertices until transformed
                    JVector[] allVertex = new JVector[meshPart.NumVertices];
                    // Read the vertices from the buffer in to the array
                    meshPart.VertexBuffer.GetData <JVector>(
                        meshPart.VertexOffset * declaration.VertexStride + vertexPosition.Offset,
                        allVertex,
                        0,
                        meshPart.NumVertices,
                        declaration.VertexStride);
                    // Transform them based on the relative bone location and the world if provided
                    for (int i = 0; i != allVertex.Length; ++i)
                    {
                        JVector.Transform(ref allVertex[i], ref xform, out allVertex[i]);
                    }
                    // Store the transformed vertices with those from all the other meshes in this model
                    vertices.AddRange(allVertex);

                    // Find out which vertices make up which triangles
                    if (meshPart.IndexBuffer.IndexElementSize != IndexElementSize.SixteenBits)
                    {
                        // This could probably be handled by using int in place of short but is unnecessary
                        throw new Exception("Model uses 32-bit indices, which are not supported.");
                    }
                    // Each primitive is a triangle
                    short[] indexElements = new short[meshPart.PrimitiveCount * 3];
                    meshPart.IndexBuffer.GetData <short>(
                        meshPart.StartIndex * 2,
                        indexElements,
                        0,
                        meshPart.PrimitiveCount * 3);
                    // Each TriangleVertexIndices holds the three indexes to each vertex that makes up a triangle
                    TriangleVertexIndices[] tvi = new TriangleVertexIndices[meshPart.PrimitiveCount];
                    for (int i = 0; i != tvi.Length; ++i)
                    {
                        // The offset is because we are storing them all in the one array and the
                        // vertices were added to the end of the array.
                        tvi[i].I0 = indexElements[i * 3 + 0] + offset;
                        tvi[i].I1 = indexElements[i * 3 + 1] + offset;
                        tvi[i].I2 = indexElements[i * 3 + 2] + offset;
                    }
                    // Store our triangles
                    indices.AddRange(tvi);
                }
            }
        }
        /// <summary>
        /// Get all the triangles from each mesh part (Changed for XNA 4)
        /// </summary>
        public static void ExtractModelMeshPartData(ModelMeshPart meshPart, ref Matrix transform,
            List<Vector3> vertices, List<TriangleVertexIndices> indices)
        {
            // Before we add any more where are we starting from
            int offset = vertices.Count;

            // == Vertices (Changed for XNA 4.0)

            // Read the format of the vertex buffer
            VertexDeclaration declaration = meshPart.VertexBuffer.VertexDeclaration;
            VertexElement[] vertexElements = declaration.GetVertexElements();
            // Find the element that holds the position
            VertexElement vertexPosition = new VertexElement();
            foreach (VertexElement vert in vertexElements)
            {
                if (vert.VertexElementUsage == VertexElementUsage.Position &&
                    vert.VertexElementFormat == VertexElementFormat.Vector3)
                {
                    vertexPosition = vert;
                    // There should only be one
                    break;
                }
            }
            // Check the position element found is valid
            if (vertexPosition == null ||
                vertexPosition.VertexElementUsage != VertexElementUsage.Position ||
                vertexPosition.VertexElementFormat != VertexElementFormat.Vector3)
            {
                throw new Exception("Model uses unsupported vertex format!");
            }
            // This where we store the vertices until transformed
            Vector3[] allVertex = new Vector3[meshPart.NumVertices];
            // Read the vertices from the buffer in to the array
            meshPart.VertexBuffer.GetData<Vector3>(
                meshPart.VertexOffset * declaration.VertexStride + vertexPosition.Offset,
                allVertex,
                0,
                meshPart.NumVertices,
                declaration.VertexStride);
            // Transform them based on the relative bone location and the world if provided
            for (int i = 0; i != allVertex.Length; ++i)
            {
                Vector3.Transform(ref allVertex[i], ref transform, out allVertex[i]);
            }
            // Store the transformed vertices with those from all the other meshes in this model
            vertices.AddRange(allVertex);

            // == Indices (Changed for XNA 4)

            // Find out which vertices make up which triangles
            if (meshPart.IndexBuffer.IndexElementSize != IndexElementSize.SixteenBits)
            {
                // This could probably be handled by using int in place of short but is unnecessary
                throw new Exception("Model uses 32-bit indices, which are not supported.");
            }
            // Each primitive is a triangle
            short[] indexElements = new short[meshPart.PrimitiveCount * 3];
            // It looks like the same index buffer is referenced from each meshPart.
            meshPart.IndexBuffer.GetData<short>(
                meshPart.StartIndex * 2,
                indexElements,
                0,
                meshPart.PrimitiveCount * 3);
            // Each TriangleVertexIndices holds the three indexes to each vertex that makes up a triangle
            TriangleVertexIndices[] tvi = new TriangleVertexIndices[meshPart.PrimitiveCount];
            for (int i = 0; i != tvi.Length; ++i)
            {
                // The offset is because we are storing them all in the one array and the
                // vertices were added to the end of the array.
                tvi[i].A = indexElements[i * 3 + 0] + offset;
                tvi[i].B = indexElements[i * 3 + 1] + offset;
                tvi[i].C = indexElements[i * 3 + 2] + offset;
            }
            // Store our triangles
            indices.AddRange(tvi);
        }