Home Articles Tutorials Resources About

Creating a mesh with multiple subsets


By 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

?
MDX info is an initiative by vector4. All content is copyright ? 2005-2006 by its respective authors | About MDX info | Terms of Use |
Coming soon!