Exemple #1
0
        /// <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)
        {
            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);
                }
            }
        }
        /// <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 = new ReadOnlyCollection<Spring>(springs);
            VertexBodies = new ReadOnlyCollection<MassPoint>(points);
            Triangles = new ReadOnlyCollection<Triangle>(triangles);

            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 = Conversion.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);
                }
            }
        }
Exemple #4
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);
        }
        public static Octree BuildOctree(Model model) {

            List<JVector> vertices = new List<JVector>();
            List<TriangleVertexIndices> indices = new List<TriangleVertexIndices>();           
            Matrix[] bones = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(bones);   
            
            foreach (ModelMesh modelMesh in model.Meshes)
            {               
                JMatrix boneTransform = PhysicsSystem.toJMatrix(bones[modelMesh.ParentBone.Index]);
                foreach (ModelMeshPart meshPart in modelMesh.MeshParts)
                {
                    int offset = vertices.Count;              
                    var meshVertices = meshPart.VertexBuffer.Resource.Buffer.GetData<JVector>();
                    for (int i = 0; i < meshVertices.Length; ++i)
                    {
                        JVector.Transform(ref meshVertices[i], ref boneTransform, out meshVertices[i]);
                    }
                    vertices.AddRange(meshVertices);    // append transformed vertices

                    // there should DEFINITELY be a check here to ensure that the indices used in the model
                    // don't exceed 65535 (max short int). If the model doesn't use shorts, then they get cast all weird.
                    var indexElements = meshPart.IndexBuffer.Resource.GetData<short>();      
             
                    // Each TriangleVertexIndices holds the indices that constitute a triangle primitive
                    TriangleVertexIndices[] tvi = new TriangleVertexIndices[indexElements.Length];
                    for (int i = 0; i <= tvi.Length - 2; i += 3) {
                        tvi[i].I0 = indexElements[i + 0] + offset;
                        tvi[i].I1 = indexElements[i + 1] + offset;
                        tvi[i].I2 = indexElements[i + 2] + offset;
                    }
                    indices.AddRange(tvi);  // append triangles           
                }
            }
            Octree ot = new Octree(vertices, indices);
            //ot.BuildOctree(); // (already happens in Octree constructor)
            return ot;
        }