public MeshBuilderHelper(String name, String resourcegroup, bool usesharedvertices, uint vertexstart, uint vertexcount) { mName = name; mResourceGroup = resourcegroup; mVertextStart = vertexstart; mVertexCount = vertexcount; if (MeshManager.Singleton.ResourceExists(name)) throw (new ArgumentNullException("mesh name already used")); mMeshPtr = MeshManager.Singleton.CreateManual(mName, mResourceGroup); mSubMesh = mMeshPtr.CreateSubMesh(); mSubMesh.useSharedVertices = usesharedvertices; mSubMesh.vertexData = new VertexData(); mSubMesh.vertexData.vertexStart = mVertextStart; mSubMesh.vertexData.vertexCount = mVertexCount; offset = 0; mIndexType = HardwareIndexBuffer.IndexType.IT_16BIT; }
/// <summary> /// Convert Obj Model File to Ogre Mesh format /// </summary> /// <param name="fileStream">Obj File Stream</param> /// <returns>Ogre Mesh</returns> public MeshPtr ConvertObjToMesh(Stream fileStream) { List <Vector3> vertexObj = new List <Vector3>(); List <Vector3> faceObj = new List <Vector3>(); float[] vertices; float[] faces; StreamReader reader = new StreamReader(fileStream); string line; Regex floatNumber = new Regex(@"[\d\-][\d\.]*"); Regex ushortNumber = new Regex(@"\d+"); MatchCollection matchList; while ((line = reader.ReadLine()) != null) { //Read vertices if (line.Substring(0, 2) == "v ") { matchList = floatNumber.Matches(line); float x = Convert.ToSingle(matchList[0].ToString()); float y = Convert.ToSingle(matchList[1].ToString()); float z = Convert.ToSingle(matchList[2].ToString()); vertexObj.Add(new Vector3(x, y, z)); } //Read faces else if (line.Substring(0, 2) == "f ") { //Error here where invalid indices were given. This is because the OBJ file started indexing the verts from 1 instead of 0. matchList = ushortNumber.Matches(line); int v1 = -1 + Convert.ToUInt16(matchList[0].ToString()); int v2 = -1 + Convert.ToUInt16(matchList[1].ToString()); int v3 = -1 + Convert.ToUInt16(matchList[2].ToString()); faceObj.Add(new Vector3((ushort)v1, (ushort)v2, (ushort)v3)); } } int vertexNum = vertexObj.Count; vertices = new float[vertexNum * 3]; for (int i = 0; i < vertexNum; i++) { vertices[i * 3 + 0] = vertexObj[i].x; vertices[i * 3 + 1] = vertexObj[i].y; vertices[i * 3 + 2] = vertexObj[i].z; } int faceNum = faceObj.Count; faces = new float[faceNum * 3]; for (int i = 0; i < faceNum; i++) { faces[i * 3 + 0] = faceObj[i].x; faces[i * 3 + 1] = faceObj[i].y; faces[i * 3 + 2] = faceObj[i].z; } MeshPtr mesh = MeshManager.Singleton.CreateManual("mesh1", ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME); SubMesh subMesh = mesh.CreateSubMesh(); mesh.sharedVertexData = new VertexData(); mesh.sharedVertexData.vertexCount = (uint)vertexObj.Count; VertexDeclaration vdecl = mesh.sharedVertexData.vertexDeclaration; VertexBufferBinding vbind = mesh.sharedVertexData.vertexBufferBinding; vdecl.AddElement(0, 0, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION); HardwareVertexBufferSharedPtr vertexBuff = HardwareBufferManager.Singleton.CreateVertexBuffer((uint)(3 * System.Runtime.InteropServices.Marshal.SizeOf(typeof(float))), (uint)vertexObj.Count, HardwareBuffer.Usage.HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); unsafe { GCHandle handle = GCHandle.Alloc(vertices, GCHandleType.Pinned); void * pVertex = (void *)handle.AddrOfPinnedObject(); vertexBuff.WriteData(0, vertexBuff.SizeInBytes, pVertex, true); handle.Free(); vbind.SetBinding(0, vertexBuff); } HardwareIndexBufferSharedPtr indexBuff = HardwareBufferManager.Singleton.CreateIndexBuffer(HardwareIndexBuffer.IndexType.IT_32BIT, (uint)(3 * faceObj.Count), HardwareBuffer.Usage.HBU_STATIC, true); unsafe { GCHandle handle = GCHandle.Alloc(faces, GCHandleType.Pinned); void * pFaces = (void *)handle.AddrOfPinnedObject(); indexBuff.WriteData(0, indexBuff.SizeInBytes, pFaces, true); handle.Free(); } subMesh.useSharedVertices = true; subMesh.indexData.indexBuffer = indexBuff; subMesh.indexData.indexStart = 0; subMesh.indexData.indexCount = (uint)(3 * faceObj.Count); mesh._setBounds(new AxisAlignedBox(-100, -100, -100, 100, 100, 100)); mesh.Touch(); reader.Close(); return(mesh); }
//MeshPtr CreateMesh(string Name, string Group, IndexData IndexDataArg, VertexData VertexDataArg, AxisAlignedBox BoundingBox) { // Mogre.Mesh Mesh = Mogre.MeshManager.Singleton.CreateManual(Name, Group,null); // SubMesh SubMesh = Mesh.CreateSubMesh(); // //Shallow copy the IndexBuffer argument into the SubMesh's indexData property // SubMesh.indexData.indexBuffer = IndexDataArg.indexBuffer; // SubMesh.indexData.indexCount = IndexDataArg.indexCount; // //Deep copy the VertexData argument into the Mesh's sharedVertexData // SubMesh.useSharedVertices = true; // Mesh.sharedVertexData = new VertexData(); // Mesh.sharedVertexData.vertexBufferBinding.SetBinding(0, VertexDataArg.vertexBufferBinding.GetBuffer(0)); // Mesh.sharedVertexData.vertexDeclaration = VertexDataArg.vertexDeclaration.Clone(); // Mesh.sharedVertexData.vertexCount = VertexDataArg.vertexCount; // Mesh._setBounds(BoundingBox); // Mesh.Load(); // return Mesh; //} unsafe static public void CreateSphere(string strName, float r, int nRings, int nSegments) { MeshPtr pSphere = Mogre.MeshManager.Singleton.CreateManual(strName, ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME); SubMesh pSphereVertex = pSphere.CreateSubMesh(); pSphere.sharedVertexData = new VertexData(); VertexData vertexData = pSphere.sharedVertexData; // define the vertex format VertexDeclaration vertexDecl = vertexData.vertexDeclaration; uint currOffset = 0; // positions vertexDecl.AddElement(0, currOffset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION); currOffset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3); // normals vertexDecl.AddElement(0, currOffset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_NORMAL); currOffset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3); // two dimensional texture coordinates vertexDecl.AddElement(0, currOffset, VertexElementType.VET_FLOAT2, VertexElementSemantic.VES_TEXTURE_COORDINATES, 0); currOffset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT2); // allocate the vertex buffer vertexData.vertexCount = (uint)((nRings + 1) * (nSegments + 1)); HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager.Singleton.CreateVertexBuffer(vertexDecl.GetVertexSize(0), vertexData.vertexCount, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY, false); VertexBufferBinding binding = vertexData.vertexBufferBinding; binding.SetBinding(0, vBuf); float *pVertex = (float *)vBuf.Lock(HardwareBuffer.LockOptions.HBL_DISCARD); // allocate index buffer pSphereVertex.indexData.indexCount = (uint)(6 * nRings * (nSegments + 1)); pSphereVertex.indexData.indexBuffer = HardwareBufferManager.Singleton.CreateIndexBuffer(Mogre.HardwareIndexBuffer.IndexType.IT_16BIT, pSphereVertex.indexData.indexCount, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY, false); HardwareIndexBufferSharedPtr iBuf = pSphereVertex.indexData.indexBuffer; ushort *pIndices = (ushort *)iBuf.Lock(HardwareBuffer.LockOptions.HBL_DISCARD); float fDeltaRingAngle = (float)(Mogre.Math.PI / nRings); float fDeltaSegAngle = (float)(2 * Mogre.Math.PI / nSegments); ushort wVerticeIndex = 0; // Generate the group of rings for the sphere for (int ring = 0; ring <= nRings; ring++) { float r0 = r * Mogre.Math.Sin(ring * fDeltaRingAngle); float y0 = r * Mogre.Math.Cos(ring * fDeltaRingAngle); // Generate the group of segments for the current ring for (int seg = 0; seg <= nSegments; seg++) { float x0 = r0 * Mogre.Math.Sin(seg * fDeltaSegAngle); float z0 = r0 * Mogre.Math.Cos(seg * fDeltaSegAngle); // Add one vertex to the strip which makes up the sphere *pVertex++ = x0; *pVertex++ = y0; *pVertex++ = z0; Mogre.Vector3 vNormal = (new Mogre.Vector3(x0, y0, z0)).NormalisedCopy; *pVertex++ = vNormal.x; *pVertex++ = vNormal.y; *pVertex++ = vNormal.z; *pVertex++ = (float)seg / (float)nSegments; *pVertex++ = (float)ring / (float)nRings; if (ring != nRings) { // each vertex (except the last) has six indices pointing to it *pIndices++ = (ushort)(wVerticeIndex + nSegments + 1); *pIndices++ = wVerticeIndex; *pIndices++ = (ushort)(wVerticeIndex + nSegments); *pIndices++ = (ushort)(wVerticeIndex + nSegments + 1); *pIndices++ = (ushort)(wVerticeIndex + 1); *pIndices++ = wVerticeIndex; wVerticeIndex++; } } ; // end for seg } // end for ring // Unlock vBuf.Unlock(); iBuf.Unlock(); // Generate face list pSphereVertex.useSharedVertices = true; // the original code was missing this line: pSphere._setBounds(new AxisAlignedBox(new Mogre.Vector3(-r, -r, -r), new Mogre.Vector3(r, r, r)), false); pSphere._setBoundingSphereRadius(r); // this line makes clear the mesh is loaded (avoids memory leaks) pSphere.Load(); }
} // CreateTetrahedron unsafe static public void CreateTetrahedron2(string strName) { float r = 1f; int nRings = 8; int nSegments = 8; Single scale = 1; Mogre.Vector3 position = new Mogre.Vector3(); MeshPtr pTetra = MeshManager.Singleton.CreateManual(strName, ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME); SubMesh pTetraVertex = pTetra.CreateSubMesh(); pTetra.sharedVertexData = new VertexData(); VertexData vertexData = pTetra.sharedVertexData; // define the vertex format VertexDeclaration vertexDecl = vertexData.vertexDeclaration; uint currOffset = 0; // positions vertexDecl.AddElement(0, currOffset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION); currOffset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3); // normals vertexDecl.AddElement(0, currOffset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_NORMAL); currOffset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3); // two dimensional texture coordinates vertexDecl.AddElement(0, currOffset, VertexElementType.VET_FLOAT2, VertexElementSemantic.VES_TEXTURE_COORDINATES, 0); currOffset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT2); // allocate the vertex buffer vertexData.vertexCount = 4; //(uint)((nRings + 1) * (nSegments + 1)); HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager.Singleton.CreateVertexBuffer(vertexDecl.GetVertexSize(0), vertexData.vertexCount, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY, false); VertexBufferBinding binding = vertexData.vertexBufferBinding; binding.SetBinding(0, vBuf); float *pVertex = (float *)vBuf.Lock(HardwareBuffer.LockOptions.HBL_DISCARD); uint numIndexes = (uint)(6 * 4); // allocate index buffer pTetraVertex.indexData.indexCount = numIndexes; pTetraVertex.indexData.indexBuffer = HardwareBufferManager.Singleton.CreateIndexBuffer(HardwareIndexBuffer.IndexType.IT_16BIT, pTetraVertex.indexData.indexCount, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY, false); HardwareIndexBufferSharedPtr iBuf = pTetraVertex.indexData.indexBuffer; ushort *pIndices = (ushort *)iBuf.Lock(HardwareBuffer.LockOptions.HBL_DISCARD); //float fDeltaRingAngle = (float)(Mogre.Math.PI / nRings); //float fDeltaSegAngle = (float)(2 * Mogre.Math.PI / nSegments); ushort wVerticeIndex = 0; // calculate corners of tetrahedron (with point of origin in middle of volume) Single mbot = scale * 0.2f; // distance middle to bottom Single mtop = scale * 0.62f; // distance middle to top Single mf = scale * 0.289f; // distance middle to front Single mb = scale * 0.577f; // distance middle to back Single mlr = scale * 0.5f; // distance middle to left right // width / height / depth Mogre.Vector3[] c = new Mogre.Vector3[4]; // corners c[0] = new Mogre.Vector3(-mlr, -mbot, mf); // left bottom front c[1] = new Mogre.Vector3(mlr, -mbot, mf); // right bottom front c[2] = new Mogre.Vector3(0, -mbot, -mb); // (middle) bottom back c[3] = new Mogre.Vector3(0, mtop, 0); // (middle) top (middle) // add position offset for all corners (move tetrahedron) for (Int16 i = 0; i <= 3; i++) { c[i] += position; } Mogre.Vector3 vNormal = new Mogre.Vector3(); *pVertex++ = c[0].x; *pVertex++ = c[0].y; *pVertex++ = c[0].z; vNormal = (new Mogre.Vector3(c[0].x, c[0].y, c[0].z)).NormalisedCopy; *pVertex++ = vNormal.x; *pVertex++ = vNormal.y; *pVertex++ = vNormal.z; *pVertex++ = (float).25; *pVertex++ = (float).25; *pIndices++ = (ushort)(wVerticeIndex + numIndexes + 1); *pIndices++ = wVerticeIndex; *pIndices++ = (ushort)(wVerticeIndex + numIndexes); *pIndices++ = (ushort)(wVerticeIndex + numIndexes + 1); *pIndices++ = (ushort)(wVerticeIndex + 1); *pIndices++ = wVerticeIndex; wVerticeIndex++; *pVertex++ = c[1].x; *pVertex++ = c[1].y; *pVertex++ = c[1].z; vNormal = (new Mogre.Vector3(c[1].x, c[1].y, c[1].z)).NormalisedCopy; *pVertex++ = vNormal.x; *pVertex++ = vNormal.y; *pVertex++ = vNormal.z; *pVertex++ = (float).50; *pVertex++ = (float).50; *pIndices++ = (ushort)(wVerticeIndex + numIndexes + 1); *pIndices++ = wVerticeIndex; *pIndices++ = (ushort)(wVerticeIndex + numIndexes); *pIndices++ = (ushort)(wVerticeIndex + numIndexes + 1); *pIndices++ = (ushort)(wVerticeIndex + 1); *pIndices++ = wVerticeIndex; wVerticeIndex++; *pVertex++ = c[2].x; *pVertex++ = c[2].y; *pVertex++ = c[2].z; vNormal = (new Mogre.Vector3(c[2].x, c[2].y, c[2].z)).NormalisedCopy; *pVertex++ = vNormal.x; *pVertex++ = vNormal.y; *pVertex++ = vNormal.z; *pVertex++ = (float).75; *pVertex++ = (float).75; *pIndices++ = (ushort)(wVerticeIndex + numIndexes + 1); *pIndices++ = wVerticeIndex; *pIndices++ = (ushort)(wVerticeIndex + numIndexes); *pIndices++ = (ushort)(wVerticeIndex + numIndexes + 1); *pIndices++ = (ushort)(wVerticeIndex + 1); *pIndices++ = wVerticeIndex; wVerticeIndex++; *pVertex++ = c[3].x; *pVertex++ = c[3].y; *pVertex++ = c[3].z; vNormal = (new Mogre.Vector3(c[3].x, c[3].y, c[3].z)).NormalisedCopy; *pVertex++ = vNormal.x; *pVertex++ = vNormal.y; *pVertex++ = vNormal.z; *pVertex++ = (float)1; *pVertex++ = (float)1; *pIndices++ = (ushort)(wVerticeIndex + numIndexes + 1); *pIndices++ = wVerticeIndex; *pIndices++ = (ushort)(wVerticeIndex + numIndexes); *pIndices++ = (ushort)(wVerticeIndex + numIndexes + 1); *pIndices++ = (ushort)(wVerticeIndex + 1); *pIndices++ = wVerticeIndex; wVerticeIndex++; //manObTetra.Begin(materialName, RenderOperation.OperationTypes.OT_TRIANGLE_LIST); //manObTetra.Position(c[2]); //manObTetra.Position(c[1]); //manObTetra.Position(c[0]); //manObTetra.Triangle(0, 1, 2); //manObTetra.End(); //// create right back side //manObTetra.Begin(materialName, RenderOperation.OperationTypes.OT_TRIANGLE_LIST); //manObTetra.Position(c[1]); //manObTetra.Position(c[2]); //manObTetra.Position(c[3]); //manObTetra.Triangle(0, 1, 2); //manObTetra.End(); //// create left back side //manObTetra.Begin(materialName, RenderOperation.OperationTypes.OT_TRIANGLE_LIST); //manObTetra.Position(c[3]); //manObTetra.Position(c[2]); //manObTetra.Position(c[0]); //manObTetra.Triangle(0, 1, 2); //manObTetra.End(); //// create front side //manObTetra.Begin(materialName, RenderOperation.OperationTypes.OT_TRIANGLE_LIST); //manObTetra.Position(c[0]); //manObTetra.Position(c[1]); //manObTetra.Position(c[3]); //manObTetra.Triangle(0, 1, 2); //manObTetra.End(); //return manObTetra; //// Generate the group of rings for the sphere //for (int ring = 0; ring <= nRings; ring++) //{ // float r0 = r * Mogre.Math.Sin(ring * fDeltaRingAngle); // float y0 = r * Mogre.Math.Cos(ring * fDeltaRingAngle); // // Generate the group of segments for the current ring // for (int seg = 0; seg <= nSegments; seg++) // { // float x0 = r0 * Mogre.Math.Sin(seg * fDeltaSegAngle); // float z0 = r0 * Mogre.Math.Cos(seg * fDeltaSegAngle); // // Add one vertex to the strip which makes up the sphere // *pVertex++ = x0; // *pVertex++ = y0; // *pVertex++ = z0; // Mogre.Vector3 vNormal = (new Mogre.Vector3(x0, y0, z0)).NormalisedCopy; // *pVertex++ = vNormal.x; // *pVertex++ = vNormal.y; // *pVertex++ = vNormal.z; // *pVertex++ = (float)seg / (float)nSegments; // *pVertex++ = (float)ring / (float)nRings; // if (ring != nRings) // { // // each vertex (except the last) has six indices pointing to it // *pIndices++ = (ushort)(wVerticeIndex + nSegments + 1); // *pIndices++ = wVerticeIndex; // *pIndices++ = (ushort)(wVerticeIndex + nSegments); // *pIndices++ = (ushort)(wVerticeIndex + nSegments + 1); // *pIndices++ = (ushort)(wVerticeIndex + 1); // *pIndices++ = wVerticeIndex; // wVerticeIndex++; // } // }; // end for seg //} // end for ring // Unlock vBuf.Unlock(); iBuf.Unlock(); // Generate face list pTetraVertex.useSharedVertices = true; // the original code was missing this line: pTetra._setBounds(new AxisAlignedBox(new Mogre.Vector3(-r, -r, -r), new Mogre.Vector3(r, r, r)), false); pTetra._setBoundingSphereRadius(r); // this line makes clear the mesh is loaded (avoids memory leaks) pTetra.Load(); }
public unsafe void createMesh() { /// Create the mesh via the MeshManager MeshPtr msh = MeshManager.Singleton.CreateManual("ColourCube", "General"); /// Create one submesh SubMesh sub = msh.CreateSubMesh(); /// Define the vertices (8 vertices, each consisting of 2 groups of 3 floats //const int nVertices = 8; //int row = recordno; // int col = demcol; int row = recordno; int col = 1100; int step = 10; int vbufCount; uint nVertices = (uint)(col * row); float[] vertices = CreateVertices(row, col, step, out vbufCount); /// Define 12 triangles (two triangles per cube face) /// The values in this table refer to vertices in the above table uint ibufCount; ushort[] faces = CreateFaces(row, col, out ibufCount); /// Create vertex data structure for 8 vertices shared between submeshes msh.sharedVertexData = new VertexData(); msh.sharedVertexData.vertexCount = nVertices; /// Create declaration (memory format) of vertex data VertexDeclaration decl = msh.sharedVertexData.vertexDeclaration; uint offset = 0; // 1st buffer decl.AddElement(0, offset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION); offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3); decl.AddElement(0, offset, VertexElementType.VET_FLOAT2, VertexElementSemantic.VES_TEXTURE_COORDINATES); offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT2); /// Allocate vertex buffer of the requested number of vertices (vertexCount) /// and bytes per vertex (offset) HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager.Singleton.CreateVertexBuffer(offset, msh.sharedVertexData.vertexCount, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY); /// Upload the vertex data to the card fixed(void *p = vertices) { vbuf.WriteData(0, vbuf.SizeInBytes, p, true);// writeData(0, vbuf->getSizeInBytes(), vertices, true); } /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer VertexBufferBinding bind = msh.sharedVertexData.vertexBufferBinding;// msh->sharedVertexData->vertexBufferBinding; bind.SetBinding(0, vbuf); /// Allocate index buffer of the requested number of vertices (ibufCount) HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager.Singleton.CreateIndexBuffer(HardwareIndexBuffer.IndexType.IT_16BIT, ibufCount, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY); /// Upload the index data to the card fixed(void *p = faces) { ibuf.WriteData(0, ibuf.SizeInBytes, p, true); } /// Set parameters of the submesh sub.useSharedVertices = true; sub.indexData.indexBuffer = ibuf; sub.indexData.indexCount = ibufCount; sub.indexData.indexStart = 0; /// Set bounding information (for culling) msh._setBounds(new AxisAlignedBox(min, max)); // msh._setBoundingSphereRadius(Mogre.Math.Sqrt(3 * 100 * 100)); /// Notify Mesh object that it has been loaded msh.Load(); }
private unsafe void createCube(string name, Mogre.Vector3 gpose, double d) { MeshPtr msh = MeshManager.Singleton.CreateManual(name, "General"); SubMesh sub1 = msh.CreateSubMesh("1"); const float sqrt13 = 0.577350269f; /* sqrt(1/3) */ const int nVertices = 8; const int vbufCount = 3 * 2 * nVertices; float[] vertices = new float[vbufCount] { (float)(gpose.x - d / 2), (float)(gpose.y + d / 2), (float)(gpose.z - d / 2), //0 position -sqrt13, sqrt13, -sqrt13, //0 normal A (float)(gpose.x + d / 2), (float)(gpose.y + d / 2), (float)(gpose.z - d / 2), //1 position sqrt13, sqrt13, -sqrt13, //1 normal B (float)(gpose.x + d / 2), (float)(gpose.y - d / 2), (float)(gpose.z - d / 2), //2 position sqrt13, -sqrt13, -sqrt13, //2 normal F (float)(gpose.x - d / 2), (float)(gpose.y - d / 2), (float)(gpose.z - d / 2), //3 position -sqrt13, -sqrt13, -sqrt13, //3 normal H (float)(gpose.x - d / 2), (float)(gpose.y + d / 2), (float)(gpose.z + d / 2), -sqrt13, sqrt13, sqrt13, //4 normal C (float)(gpose.x + d / 2), (float)(gpose.y + d / 2), (float)(gpose.z + d / 2), sqrt13, sqrt13, sqrt13, //5 normal D (float)(gpose.x + d / 2), (float)(gpose.y - d / 2), (float)(gpose.z + d / 2), sqrt13, -sqrt13, sqrt13, //6 normal E (float)(gpose.x - d / 2), (float)(gpose.y - d / 2), (float)(gpose.z + d / 2), -sqrt13, -sqrt13, sqrt13, //7 normal G }; const int ibufCount = 36; ushort[] faces = new ushort[ibufCount] { //back 0, 2, 3, 0, 1, 2, //right 1, 6, 2, 1, 5, 6, //front 4, 6, 5, 4, 7, 6, //left 0, 7, 4, 0, 3, 7, //top 0, 5, 1, 0, 4, 5, //bottom 2, 7, 3, 2, 6, 7 }; sub1.vertexData = new VertexData(); sub1.vertexData.vertexCount = nVertices; VertexDeclaration decl = sub1.vertexData.vertexDeclaration; uint offset = 0; //position decl.AddElement(0, offset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION); offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3); //normal decl.AddElement(0, offset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_NORMAL); offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager.Singleton.CreateVertexBuffer(offset, sub1.vertexData.vertexCount, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY); VertexBufferBinding bind = sub1.vertexData.vertexBufferBinding; void *pVertices; fixed(float *pFVertice = vertices) { pVertices = (void *)pFVertice; } vbuf.WriteData(0, vbuf.SizeInBytes, pVertices, true); bind.SetBinding(0, vbuf); void *pFaces; fixed(ushort *pUFaces = faces) { pFaces = (void *)pUFaces; } HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager.Singleton.CreateIndexBuffer(HardwareIndexBuffer.IndexType.IT_16BIT, ibufCount, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY); ibuf.WriteData(0, ibuf.SizeInBytes, pFaces, true); sub1.useSharedVertices = false; sub1.indexData.indexBuffer = ibuf; sub1.indexData.indexCount = ibufCount; sub1.indexData.indexStart = 0; sub1.SetMaterialName("Examples/10PointBlock"); msh._setBounds(new AxisAlignedBox(-100, -100, -100, 100, 100, 100)); msh._setBoundingSphereRadius(Mogre.Math.Sqrt(3 * 100 * 100)); msh.Load(); }