Creating a mesh with multiple subsetsBy Rim van Wersch, March 12 2006 |
A mesh object can be used to hold all geometric data of a game object. The original SDK documentation already shows how to create a mesh with a single subset, but for defining multiple subsets (or attribute ranges) some more work is needed. This little snippet shows how to set up a simple cube with two subsets.
int numberVerts = 8; short[] indices = { 0,1,2, // Front Face 1,3,2, // Front Face 4,5,6, // Back Face 6,5,7, // Back Face 0,5,4, // Top Face 0,2,5, // Top Face 1,6,7, // Bottom Face 1,7,3, // Bottom Face 0,6,1, // Left Face 4,6,0, // Left Face 2,3,7, // Right Face 5,2,7 // Right Face }; // create the mesh object Mesh mesh = new Mesh(indices.Length / 3, numberVerts, MeshFlags.Managed, CustomVertex.PositionColored.Format, device); // set vertex buffer data using(VertexBuffer vb = mesh.VertexBuffer) { GraphicsStream data = vb.Lock(0, 0, LockFlags.None); data.Write(new CustomVertex.PositionColored(-1.0f, 1.0f, 1.0f, 0x00ff00ff)); data.Write(new CustomVertex.PositionColored(-1.0f, -1.0f, 1.0f, 0x00ffff00)); data.Write(new CustomVertex.PositionColored(1.0f, 1.0f, 1.0f, 0x0000ffff)); data.Write(new CustomVertex.PositionColored(1.0f, -1.0f, 1.0f, 0x00ff0000)); data.Write(new CustomVertex.PositionColored(-1.0f, 1.0f, -1.0f, 0x000000ff)); data.Write(new CustomVertex.PositionColored(1.0f, 1.0f, -1.0f, 0x0000ff00)); data.Write(new CustomVertex.PositionColored(-1.0f, -1.0f, -1.0f, 0x00ffffff)); data.Write(new CustomVertex.PositionColored(1.0f, -1.0f, -1.0f, 0x00000000)); vb.Unlock(); } // set index buffer data using (IndexBuffer ib = mesh.IndexBuffer) { ib.SetData(indices, 0, LockFlags.None); } // Set attribute buffer data, setting the attribute // ID (subset #) for each face in the attribute buffer int[] attribBuffer = mesh.LockAttributeBufferArray(LockFlags.None); // first 6 faces will be subset 0 for( int i = 0; i < 6; i++) { attribBuffer[i] = 0; } // last 6 faces will be subset 1 for( int i = 0; i < 6; i++) { attribBuffer[i + 6] = 1; } // unlock and update the buffer mesh.UnlockAttributeBuffer(attribBuffer); // Here we manually create the attribute table for the mesh, // notice that this does NOT affect the vertices, but only // updates the internal attribute table for future reference. AttributeRange subset1 = new AttributeRange(); subset1.AttributeId = 0; subset1.FaceStart = 0; subset1.FaceCount = 6; subset1.VertexCount = 36; subset1.VertexStart = 0; AttributeRange subset2 = new AttributeRange(); subset2.AttributeId = 1; subset2.FaceStart = 6; subset2.FaceCount = 6; subset2.VertexCount = 36; subset2.VertexStart = 0; mesh.SetAttributeTable( new AttributeRange[] { subset1, subset2 }); // Updating the attribute table can also be done automatically // by optimizing the mesh in place, like this: /* int[] adj = new int[indices.Length]; mesh.GenerateAdjacency(0.1f, adj); mesh.OptimizeInPlace( MeshFlags.OptimizeAttributeSort, adj); */ System.Diagnostics.Debug.WriteLine("New number of subsets in mesh: " + mesh.NumberAttributes);
Further reading
