HelmutG

TriangleMesh.FromModel

Feb 7th, 2012
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.79 KB | None | 0 0
  1. public static TriangleMesh FromModel(Model model)
  2. {
  3.   var triangleMesh = new TriangleMesh();
  4.  
  5.   foreach (var modelMesh in model.Meshes)
  6.   {
  7.     // Get bone transformation.
  8.     Matrix transform = GetAbsoluteTransform(modelMesh.ParentBone);
  9.  
  10.     foreach (var modelMeshPart in modelMesh.MeshParts)
  11.     {
  12.       // Get vertex element info.
  13.       var vertexDeclaration = modelMeshPart.VertexBuffer.VertexDeclaration;
  14.       var vertexElements = vertexDeclaration.GetVertexElements();
  15.  
  16.       // Get the vertex positions.
  17.       var positionElement = vertexElements.First(e => e.VertexElementUsage == VertexElementUsage.Position);
  18.       if (positionElement.VertexElementFormat != VertexElementFormat.Vector3)
  19.         throw new NotSupportedException("For vertex positions only VertexElementFormat.Vector3 is supported.");
  20.       var positions = new Vector3[modelMeshPart.NumVertices];
  21.       modelMeshPart.VertexBuffer.GetData(
  22.         modelMeshPart.VertexOffset * vertexDeclaration.VertexStride + positionElement.Offset,
  23.         positions,
  24.         0,
  25.         modelMeshPart.NumVertices,
  26.         vertexDeclaration.VertexStride);
  27.  
  28.       // Apply bone transformation.
  29.       for (int i = 0; i < positions.Length; i++)
  30.         positions[i] = Vector3.Transform(positions[i], transform);
  31.  
  32.       // Get indices.
  33.       var indexElementSize = (modelMeshPart.IndexBuffer.IndexElementSize == IndexElementSize.SixteenBits) ? 2 : 4;
  34.       if (indexElementSize != 2)
  35.         throw new NotSupportedException("Only 16 bit indices are supported.");
  36.  
  37.       var indices = new short[modelMeshPart.PrimitiveCount * 3];
  38.       modelMeshPart.IndexBuffer.GetData(
  39.         modelMeshPart.StartIndex * 2,
  40.         indices,
  41.         0,
  42.         modelMeshPart.PrimitiveCount * 3);
  43.  
  44.       // Remember the number of vertices already in the mesh.
  45.       int vertexCount = triangleMesh.Vertices.Count;
  46.  
  47.       // Add the vertices of the current modelMeshPart.
  48.       foreach (var p in positions)
  49.         triangleMesh.Vertices.Add((Vector3F)p);
  50.  
  51.       // Add indices to triangle mesh.
  52.       for (int i = 0; i < modelMeshPart.PrimitiveCount; i++)
  53.       {
  54.         // The three indices of the next triangle.
  55.         // We add 'vertexCount' because the triangleMesh already contains other mesh parts.
  56.         var i0 = indices[i * 3 + 0] + vertexCount;
  57.         var i1 = indices[i * 3 + 1] + vertexCount;
  58.         var i2 = indices[i * 3 + 2] + vertexCount;
  59.  
  60.         triangleMesh.Indices.Add(i0);
  61.         triangleMesh.Indices.Add(i2);     // DigitalRune Geometry uses other winding order!
  62.         triangleMesh.Indices.Add(i1);
  63.       }
  64.     }
  65.   }
  66.  
  67.   return triangleMesh;
  68. }
  69.  
  70.  
  71. private static Matrix GetAbsoluteTransform(ModelBone bone)
  72. {
  73.   if (bone == null)
  74.     return Matrix.Identity;
  75.   return bone.Transform * GetAbsoluteTransform(bone.Parent);
  76. }
Advertisement
Add Comment
Please, Sign In to add comment