private unsafe int ReadIndexData(int indexOffset, uint vertexOffset, IndexData indexData) { // get index data HardwareIndexBufferSharedPtr indexBuf = indexData.indexBuffer; HardwareIndexBuffer.IndexType indexType = indexBuf.Type; uint * pLong = (uint *)(indexBuf.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY)); ushort *pShort = (ushort *)pLong; for (uint i = 0; i < indexData.indexCount; i++) { if (indexType == HardwareIndexBuffer.IndexType.IT_32BIT) { _indices[indexOffset] = pLong[i] + vertexOffset; } else { _indices[indexOffset] = pShort[i] + vertexOffset; } indexOffset++; } indexBuf.Unlock(); // SGD :2013/6/8 13:42:42 // 说明:销毁指针引用 防止.NET回收 indexBuf.Dispose(); return(indexOffset); }
public virtual void CreateIndexBuffer(uint triaglecount, HardwareIndexBuffer.IndexType itype, HardwareBuffer.Usage usage, bool useShadowBuffer) { mvbuf.Unlock(); mTriagleCount = triaglecount; mIndexType = itype; mSubMesh.vertexData.vertexBufferBinding.SetBinding(0, mvbuf); mSubMesh.indexData.indexCount = mTriagleCount * 3; HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager.Singleton .CreateIndexBuffer(mIndexType, mTriagleCount * 3, usage, useShadowBuffer); mSubMesh.indexData.indexBuffer = ibuf; unsafe { pIBuffStart = ibuf.Lock(HardwareBuffer.LockOptions.HBL_DISCARD); } }
public virtual void CreateIndexBufferForTriStrip(uint indexcount, HardwareIndexBuffer.IndexType itype, HardwareBuffer.Usage usage) { mvbuf.Unlock(); mTriagleCount = 0; mIndexType = itype; mSubMesh.vertexData.vertexBufferBinding.SetBinding(0, mvbuf); mSubMesh.indexData.indexCount = indexcount; HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager.Singleton .CreateIndexBuffer(mIndexType, indexcount, usage, false); mSubMesh.indexData.indexBuffer = ibuf; mSubMesh.operationType = RenderOperation.OperationTypes.OT_TRIANGLE_STRIP; unsafe { pIBuffStart = ibuf.Lock(HardwareBuffer.LockOptions.HBL_DISCARD); pIBuffLastPos = pIBuffStart; } }
/**************** New Functions Begin ***************/ /// <summary> /// Generate navmesh by entity /// </summary> /// <param name="ent">Ogre Entity</param> /// <returns>Navmesh</returns> public static Navmesh LoadNavmesh(Entity ent) { bool addedSharedVertex = false; vertices.Clear(); faces.Clear(); MeshPtr mesh = ent.GetMesh(); Mesh.SubMeshIterator subIterator = mesh.GetSubMeshIterator(); uint vertexNum = 0; uint vertexOffset = mesh.sharedVertexData.vertexStart; MyVector3 <float>[] verticeArray = new MyVector3 <float> [vertexNum]; VertexElement posElem = mesh.sharedVertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_POSITION); HardwareVertexBufferSharedPtr vertexBuffer = mesh.sharedVertexData.vertexBufferBinding.GetBuffer(posElem.Source); while (subIterator.MoveNext()) { SubMesh subMesh = subIterator.Current; VertexData vertexData = subMesh.useSharedVertices ? mesh.sharedVertexData : subMesh.vertexData; HardwareIndexBufferSharedPtr indexBuffer = subMesh.indexData.indexBuffer; HardwareIndexBuffer.IndexType indexType = indexBuffer.Type; uint indexCount = subMesh.indexData.indexCount; uint trisNum = indexCount / 3; uint[] indcies = new uint[indexCount]; uint indexOffset = subMesh.indexData.indexStart; if (subMesh.useSharedVertices) { if (!addedSharedVertex) { vertexNum += mesh.sharedVertexData.vertexCount; addedSharedVertex = true; } } else { vertexNum += subMesh.vertexData.vertexCount; } unsafe { uint * pLong = (uint *)(indexBuffer.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY)); ushort *pShort = (ushort *)pLong; for (int i = 0; i < indexCount; i++) { if (indexType == HardwareIndexBuffer.IndexType.IT_32BIT) { indcies[indexOffset] = pLong[i] + vertexNum; } else { indcies[indexOffset] = pShort[i] + vertexNum; } indexOffset++; } } int indexLength = indcies.Length / 3; for (int i = 0; i < indexLength; i++) { faces.Add(new MyVector3 <ushort>( (ushort)indcies[i * 3 + 0], (ushort)indcies[i * 3 + 1], (ushort)indcies[i * 3 + 2] )); } indexBuffer.Unlock(); if (subMesh.vertexData != null) { vertexNum = subMesh.vertexData.vertexCount; vertexOffset = subMesh.vertexData.vertexStart; verticeArray = new MyVector3 <float> [vertexNum]; posElem = subMesh.vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_POSITION); vertexBuffer = subMesh.vertexData.vertexBufferBinding.GetBuffer(posElem.Source); unsafe { byte * vertexMemory = (byte *)vertexBuffer.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY); float *pVertexBuffer; for (int i = 0; i < vertexNum; i++) { posElem.BaseVertexPointerToElement(vertexMemory, &pVertexBuffer); verticeArray[vertexOffset] = (new MyVector3 <float>( pVertexBuffer[0], pVertexBuffer[1], pVertexBuffer[2] )); vertexMemory += vertexBuffer.VertexSize; vertexOffset++; } } for (int i = 0; i < verticeArray.Length; i++) { vertices.Add(verticeArray[i]); } vertexBuffer.Unlock(); } } vertexNum = mesh.sharedVertexData.vertexCount; vertexOffset = mesh.sharedVertexData.vertexStart; verticeArray = new MyVector3 <float> [vertexNum]; posElem = mesh.sharedVertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_POSITION); vertexBuffer = mesh.sharedVertexData.vertexBufferBinding.GetBuffer(posElem.Source); unsafe { byte * vertexMemory = (byte *)vertexBuffer.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY); float *pVertexBuffer; for (int i = 0; i < vertexNum; i++) { posElem.BaseVertexPointerToElement(vertexMemory, &pVertexBuffer); verticeArray[vertexOffset] = (new MyVector3 <float>( pVertexBuffer[0], pVertexBuffer[1], pVertexBuffer[2] )); vertexMemory += vertexBuffer.VertexSize; vertexOffset++; } } for (int i = 0; i < verticeArray.Length; i++) { vertices.Add(verticeArray[i]); } vertexBuffer.Unlock(); return(GenerateNavmesh()); }
//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(); }
// Get the mesh information for the given mesh. // Code found on this forum link: http://www.ogre3d.org/wiki/index.php/RetrieveVertexData private static unsafe void GetMeshInformation(MeshPtr mesh, out uint vertex_count, out Vector3[] vertices, out uint index_count, out ulong[] indices, Vector3 position, Quaternion orient, Vector3 scale) { bool added_shared = false; uint current_offset = 0; uint shared_offset = 0; uint next_offset = 0; uint index_offset = 0; vertex_count = index_count = 0; // Calculate how many vertices and indices we're going to need for (ushort i = 0; i < mesh.NumSubMeshes; ++i) { SubMesh submesh = mesh.GetSubMesh(i); // We only need to add the shared vertices once if (submesh.useSharedVertices) { if (!added_shared) { vertex_count += mesh.sharedVertexData.vertexCount; added_shared = true; } } else { vertex_count += submesh.vertexData.vertexCount; } // Add the indices index_count += submesh.indexData.indexCount; } // Allocate space for the vertices and indices vertices = new Vector3[vertex_count]; indices = new ulong[index_count]; added_shared = false; // Run through the submeshes again, adding the data into the arrays for (ushort i = 0; i < mesh.NumSubMeshes; ++i) { SubMesh submesh = mesh.GetSubMesh(i); VertexData vertex_data = submesh.useSharedVertices ? mesh.sharedVertexData : submesh.vertexData; if ((!submesh.useSharedVertices) || (submesh.useSharedVertices && !added_shared)) { if (submesh.useSharedVertices) { added_shared = true; shared_offset = current_offset; } VertexElement posElem = vertex_data.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_POSITION); HardwareVertexBufferSharedPtr vbuf = vertex_data.vertexBufferBinding.GetBuffer(posElem.Source); byte *vertex = (byte *)vbuf.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY); // There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double // as second argument. So make it float, to avoid trouble when Ogre::Real will // be comiled/typedefed as double: // Ogre::Real* pReal; float *preal; for (uint j = 0; j < vertex_data.vertexCount; ++j, vertex += vbuf.VertexSize) { posElem.BaseVertexPointerToElement(vertex, &preal); Vector3 pt = new Vector3(preal[0], preal[1], preal[2]); vertices[current_offset + j] = (orient * (pt * scale)) + position; } vbuf.Unlock(); next_offset += vertex_data.vertexCount; } IndexData index_data = submesh.indexData; uint numTris = index_data.indexCount / 3; HardwareIndexBufferSharedPtr ibuf = index_data.indexBuffer; bool use32bitindexes = (ibuf.Type == HardwareIndexBuffer.IndexType.IT_32BIT); ulong * plong = (ulong *)ibuf.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY); ushort *pshort = (ushort *)plong; uint offset = submesh.useSharedVertices ? shared_offset : current_offset; if (use32bitindexes) { for (uint k = 0; k < numTris * 3; ++k) { indices[index_offset++] = (ulong)plong[k] + (ulong)offset; } } else { for (uint k = 0; k < numTris * 3; ++k) { indices[index_offset++] = pshort[k] + (ulong)offset; } } ibuf.Unlock(); current_offset = next_offset; } }
} // 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(); }
// Get the mesh information for the given mesh. // Code found on this forum link: http://www.ogre3d.org/wiki/index.php/RetrieveVertexData private static unsafe void GetMeshInformation(MeshPtr mesh, out Vector3[] vertices, out int[] indices, Vector3 position, Quaternion orient, Vector3 scale) { bool addedShared = false; int currentOffset = 0, sharedOffset = 0, nextOffset = 0, indexOffset = 0; int vertexCount = 0, indexCount = 0; // Calculate how many vertices and indices we're going to need for (ushort i = 0; i < mesh.NumSubMeshes; ++i) { SubMesh submesh = mesh.GetSubMesh(i); // We only need to add the shared vertices once if (submesh.useSharedVertices) { if (!addedShared) { vertexCount += (int)mesh.sharedVertexData.vertexCount; addedShared = true; } } else { vertexCount += (int)submesh.vertexData.vertexCount; } // Add the indices indexCount += (int)submesh.indexData.indexCount; } // Allocate space for the vertices and indices vertices = new Vector3[vertexCount]; indices = new int[indexCount]; addedShared = false; // Run through the submeshes again, adding the data into the arrays for (ushort i = 0; i < mesh.NumSubMeshes; ++i) { SubMesh submesh = mesh.GetSubMesh(i); VertexData vertexData = submesh.useSharedVertices ? mesh.sharedVertexData : submesh.vertexData; if ((!submesh.useSharedVertices) || (submesh.useSharedVertices && !addedShared)) { if (submesh.useSharedVertices) { addedShared = true; sharedOffset = currentOffset; } VertexElement posElem = vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_POSITION); System.Diagnostics.Debug.Assert(posElem.Type == VertexElementType.VET_FLOAT3); using (HardwareVertexBufferSharedPtr vbuf = vertexData.vertexBufferBinding.GetBuffer(posElem.Source)) { byte * vertex = (byte *)vbuf.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY); float *preal; for (uint j = 0; j < vertexData.vertexCount; ++j, vertex += vbuf.VertexSize) { posElem.BaseVertexPointerToElement(vertex, &preal); Vector3 pt = new Vector3(preal[0], preal[1], preal[2]); vertices[currentOffset + j] = (orient * (pt * scale)) + position; } vbuf.Unlock(); } nextOffset += (int)vertexData.vertexCount; } IndexData indexData = submesh.indexData; using (HardwareIndexBufferSharedPtr ibuf = indexData.indexBuffer) { bool use32bitindexes = ibuf.Type == HardwareIndexBuffer.IndexType.IT_32BIT; int * plong = (int *)ibuf.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY); ushort *pshort = (ushort *)plong; int offset = submesh.useSharedVertices ? sharedOffset : currentOffset; if (use32bitindexes) { for (uint k = 0; k < indexData.indexCount; ++k) { indices[indexOffset++] = plong[k] + offset; } } else { for (uint k = 0; k < indexData.indexCount; ++k) { indices[indexOffset++] = pshort[k] + offset; } } ibuf.Unlock(); } currentOffset = nextOffset; } }