public Mesh CreateBoneMesh( string name )
{
Mesh mesh = CreateManual( name );
mesh.SkeletonName = name + ".skeleton";
SubMesh subMesh = mesh.CreateSubMesh( "BoneSubMesh" );
subMesh.useSharedVertices = true;
subMesh.MaterialName = "BaseWhite";
// short[] faces = { 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 2, 1, 2, 5, 1, 5, 4, 1, 4, 3, 1, 3, 2 };
// short[] faces = { 0, 3, 2, 0, 4, 3, 0, 5, 4, 0, 2, 5, 1, 5, 2, 1, 4, 5, 1, 3, 4, 1, 2, 3 };
short[] faces = { 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 2, 1, 2, 5, 1, 5, 4, 1, 4, 3, 1, 3, 2,
0, 3, 2, 0, 4, 3, 0, 5, 4, 0, 2, 5, 1, 5, 2, 1, 4, 5, 1, 3, 4, 1, 2, 3 };
int faceCount = faces.Length / 3; // faces per bone
int vertexCount = 6; // vertices per bone
// set up vertex data, use a single shared buffer
mesh.SharedVertexData = new VertexData();
VertexData vertexData = mesh.SharedVertexData;
// set up vertex declaration
VertexDeclaration vertexDeclaration = vertexData.vertexDeclaration;
int currentOffset = 0;
// always need positions
vertexDeclaration.AddElement( 0, currentOffset, VertexElementType.Float3, VertexElementSemantic.Position );
currentOffset += VertexElement.GetTypeSize( VertexElementType.Float3 );
vertexDeclaration.AddElement( 0, currentOffset, VertexElementType.Float3, VertexElementSemantic.Normal );
currentOffset += VertexElement.GetTypeSize( VertexElementType.Float3 );
int boneCount = mesh.Skeleton.BoneCount;
// I want 6 vertices per bone - exclude the root bone
vertexData.vertexCount = boneCount * vertexCount;
// allocate vertex buffer
HardwareVertexBuffer vertexBuffer = HardwareBufferManager.Instance.CreateVertexBuffer( vertexDeclaration.GetVertexSize( 0 ), vertexData.vertexCount, BufferUsage.StaticWriteOnly );
// set up the binding, one source only
VertexBufferBinding binding = vertexData.vertexBufferBinding;
binding.SetBinding( 0, vertexBuffer );
Vector3[] vertices = new Vector3[ vertexData.vertexCount ];
_getVertices( ref vertices, mesh.Skeleton.RootBone );
// Generate vertex data
unsafe
{
// lock the vertex buffer
IntPtr data = vertexBuffer.Lock( BufferLocking.Discard );
float* pData = (float*)data.ToPointer();
foreach ( Vector3 vec in vertices )
{
// assign to geometry
*pData++ = vec.x;
*pData++ = vec.y;
*pData++ = vec.z;
// fake normals
*pData++ = 0;
*pData++ = 1;
*pData++ = 0;
}
// unlock the buffer
vertexBuffer.Unlock();
} // unsafe
// Generate index data
HardwareIndexBuffer indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer( IndexType.Size16, faces.Length * boneCount, BufferUsage.StaticWriteOnly );
subMesh.indexData.indexBuffer = indexBuffer;
subMesh.indexData.indexCount = faces.Length * boneCount;
subMesh.indexData.indexStart = 0;
for ( ushort boneIndex = 0; boneIndex < mesh.Skeleton.BoneCount; ++boneIndex )
{
Axiom.Animating.Bone bone = mesh.Skeleton.GetBone( boneIndex );
short[] tmpFaces = new short[ faces.Length ];
for ( int tmp = 0; tmp < faces.Length; ++tmp )
tmpFaces[ tmp ] = (short)( faces[ tmp ] + vertexCount * bone.Handle );
indexBuffer.WriteData( faces.Length * bone.Handle * sizeof( short ), tmpFaces.Length * sizeof( short ), tmpFaces, true );
}
for ( ushort boneIndex = 0; boneIndex < mesh.Skeleton.BoneCount; ++boneIndex )
{
Axiom.Animating.Bone bone = mesh.Skeleton.GetBone( boneIndex );
Axiom.Animating.Bone parentBone = bone;
if ( bone.Parent != null )
parentBone = (Axiom.Animating.Bone)bone.Parent;
for ( int vertexIndex = 0; vertexIndex < vertexCount; ++vertexIndex )
{
Axiom.Animating.VertexBoneAssignment vba = new Axiom.Animating.VertexBoneAssignment();
// associate the base of the joint display with the bone's parent,
// and the rest of the points with the bone.
vba.boneIndex = parentBone.Handle;
vba.weight = 1.0f;
vba.vertexIndex = vertexCount * bone.Handle + vertexIndex;
mesh.AddBoneAssignment( vba );
}
}
mesh.Load();
mesh.Touch();
return mesh;
}
#endif