/// <summary> /// Get all the triangles from each mesh part (Changed for XNA 4) /// </summary> private static void ExtractModelMeshPartData(ModelMeshPart meshPart, ref Matrix transform, List<Vector3> vertices, List<Triangle> indices) { // Before we add any more where are we starting from int offset = vertices.Count; // Vertices // 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 // 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 Triangle[] tvi = new Triangle[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); }