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; }
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); }