//增加读取纹理坐标 private unsafe uint ReadVertexData(uint vertexOffset, VertexData vertexData) { VertexElement posElem = vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_POSITION); HardwareVertexBufferSharedPtr vertexBuffer = vertexData.vertexBufferBinding.GetBuffer(posElem.Source); byte * vertexMemory = (byte *)vertexBuffer.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY); float *pElem; bool needrecomputeVertex = false; if (this._quaoffset != Quaternion.IDENTITY || this._posoffset != Vector3.ZERO) { needrecomputeVertex = true; } //texture if (_readTextureCoordinate) { ReadTextureCoordData(vertexOffset, vertexMemory, vertexBuffer.VertexSize, vertexData); } if (needrecomputeVertex) { for (uint i = 0; i < vertexData.vertexCount; i++) { posElem.BaseVertexPointerToElement(vertexMemory, &pElem); Vector3 point = new Vector3(pElem[0], pElem[1], pElem[2]); // vertices[current_offset + j] = (orientation * (pt * scale)) + position; _vertices[vertexOffset] = GetVextexTrans(point, this._quaoffset, this._scale, this._posoffset); //point * this.scale; vertexMemory += vertexBuffer.VertexSize; vertexOffset++; } } else { for (uint i = 0; i < vertexData.vertexCount; i++) { posElem.BaseVertexPointerToElement(vertexMemory, &pElem); Vector3 point = new Vector3(pElem[0], pElem[1], pElem[2]); _vertices[vertexOffset] = point * this._scale; vertexMemory += vertexBuffer.VertexSize; vertexOffset++; } } vertexBuffer.Unlock(); // SGD :2013/6/8 13:43:51 // 说明:销毁指针引用 防止.NET回收 vertexBuffer.Dispose(); return(vertexOffset); }
private unsafe uint ReadVertexData(uint vertexOffset, VertexData vertexData) { VertexElement posElem = vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_POSITION); HardwareVertexBufferSharedPtr vertexBuffer = vertexData.vertexBufferBinding.GetBuffer(posElem.Source); byte * vertexMemory = (byte *)vertexBuffer.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY); float *pElem; for (uint i = 0; i < vertexData.vertexCount; i++) { posElem.BaseVertexPointerToElement(vertexMemory, &pElem); Vector3 point = new Vector3(pElem[0], pElem[1], pElem[2]); vertices[vertexOffset] = point * this.scale; vertexMemory += vertexBuffer.VertexSize; vertexOffset++; } vertexBuffer.Unlock(); return(vertexOffset); }
// SGD :2013/6/18 15:02:51 // 说明:顶点纹理坐标 private unsafe void ReadTextureCoordData(uint vertexOffset, byte *vertexBuffer_Lock, uint vertexBuffer_VertexSize, VertexData vertexData) { VertexElement texElem = vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_TEXTURE_COORDINATES); float * tReal; if (texElem == null) { for (uint i = 0; i < vertexData.vertexCount; i++) { this._textureCroodnitas[vertexOffset + i] = new Vector2(0f, 0f); } } else { //byte* vextex = vertexBuffer_Lock; //for (uint i = 0; i < vertexData.vertexCount; i++) { // texElem.BaseVertexPointerToElement(vextex, &tReal); // this._textureCroodnitas[vertexOffset + i] = new Vector2(tReal[0], tReal[1]); // vextex += vertexBuffer_VertexSize; //} //读取纹理坐标修正 2013/12/18 VertexData vertex_data = vertexData; HardwareVertexBufferSharedPtr vbufPtr_tex = vertex_data.vertexBufferBinding.GetBuffer(texElem.Source); byte *vertex_tex = (byte *)vbufPtr_tex.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY); for (uint i = 0; i < vertex_data.vertexCount; ++i, /*vertex += vbufPtr.VertexSize,*/ vertex_tex += vbufPtr_tex.VertexSize) { //posElem.BaseVertexPointerToElement(vertex, &pReal); texElem.BaseVertexPointerToElement(vertex_tex, &tReal); this._textureCroodnitas[vertexOffset + i] = new Vector2(tReal[0], tReal[1]); vertex_tex += vertexBuffer_VertexSize; //Vector3 pt = new Vector3(pReal[0], pReal[1], pReal[2]); //vertices[current_offset + j] = (orientation * (pt * scale)) + position; //tex_Cors[current_offset + j] = new Vector2(tReal[0], tReal[1]); } vbufPtr_tex.Unlock(); vbufPtr_tex.Dispose(); } }
private void _populateVertexBuffer() { unsafe { // lock the buffer if we haven't already. if (mVertexBufferPtr == null) { // Note that locking with HBL_DISCARD will give us new, blank memory. mVertexBufferPtr = (QuickGUIVertex *)mVertexBuffer.Lock(HardwareVertexBuffer.LockOptions.HBL_DISCARD); } int vertexCount = 0; foreach (QuickGUIQuad q in mRenderList) { // for each quad, add its 6 vertices to the buffer for (int vertIndex = 0; vertIndex < QuickGUIQuad.VERTEX_PER_QUAD; ++vertIndex) { QuickGUIVertex v = q.getVertex(vertIndex); mVertexBufferPtr[vertIndex].pos = v.pos; mRenderSystem.ConvertColourValue(ColourValue.White, out mVertexBufferPtr[vertIndex].color); mVertexBufferPtr[vertIndex].uv = v.uv; ++vertexCount; } mVertexBufferPtr += QuickGUIQuad.VERTEX_PER_QUAD; } mVertexBuffer.Unlock(); mVertexBufferPtr = null; mVertexBufferUsage = vertexCount; mRenderListDirty = false; } }
/**************** 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()); }
public virtual void CreateVertexBuffer(uint numVerts, HardwareBuffer.Usage usage, bool useShadowBuffer) { mVertexSize = offset; mNumVerts = numVerts; mvbuf = HardwareBufferManager.Singleton.CreateVertexBuffer( mVertexSize, mNumVerts, usage, useShadowBuffer); unsafe { pVBuffStart = mvbuf.Lock(HardwareBuffer.LockOptions.HBL_DISCARD); } }
//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; } }
private void CreateGrassMesh() { // Each grass section is 3 planes at 60 degrees to each other // Normals point straight up to simulate correct lighting Mesh msh = MeshManager.Singleton.CreateManual(GRASS_MESH_NAME, ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME, null); SubMesh sm = msh.CreateSubMesh(); sm.useSharedVertices = false; sm.vertexData = new VertexData(); sm.vertexData.vertexStart = 0; sm.vertexData.vertexCount = 12; VertexDeclaration dcl = sm.vertexData.vertexDeclaration; uint offset = 0; dcl.AddElement(0, offset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION); offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3); dcl.AddElement(0, offset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_NORMAL); offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3); dcl.AddElement(0, offset, VertexElementType.VET_FLOAT2, VertexElementSemantic.VES_TEXTURE_COORDINATES); offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT2); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager.Singleton.CreateVertexBuffer(offset, 12, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY); int i; unsafe { float *pData = (float *)(vbuf.Lock(HardwareBuffer.LockOptions.HBL_DISCARD)); Vector3 baseVec = new Vector3(GRASS_WIDTH / 2, 0, 0); Vector3 vec = baseVec; Quaternion rot = new Quaternion(); rot.FromAngleAxis(Math.DegreesToRadians(60), Vector3.UNIT_Y); for (i = 0; i < 3; ++i) { //position *pData++ = -vec.x; *pData++ = GRASS_HEIGHT; *pData++ = -vec.z; // normal *pData++ = 0; *pData++ = 1; *pData++ = 0; // uv *pData++ = 0; *pData++ = 0; // position *pData++ = vec.x; *pData++ = GRASS_HEIGHT; *pData++ = vec.z; // normal *pData++ = 0; *pData++ = 1; *pData++ = 0; // uv *pData++ = 1; *pData++ = 0; // position *pData++ = -vec.x; *pData++ = 0; *pData++ = -vec.z; // normal *pData++ = 0; *pData++ = 1; *pData++ = 0; // uv *pData++ = 0; *pData++ = 1; // position *pData++ = vec.x; *pData++ = 0; *pData++ = vec.z; // normal *pData++ = 0; *pData++ = 1; *pData++ = 0; // uv *pData++ = 1; *pData++ = 1; vec = rot * vec; } //for } //unsafe vbuf.Unlock(); sm.vertexData.vertexBufferBinding.SetBinding(0, vbuf); sm.indexData.indexCount = 6 * 3; sm.indexData.indexBuffer = HardwareBufferManager.Singleton.CreateIndexBuffer(HardwareIndexBuffer.IndexType.IT_16BIT, 6 * 3, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY); unsafe { ushort *pI = (ushort *)(sm.indexData.indexBuffer.Lock(HardwareBuffer.LockOptions.HBL_DISCARD)); for (i = 0; i < 3; ++i) { int off = i * 4; * pI++ = (ushort)(off); * pI++ = (ushort)(off + 3); * pI++ = (ushort)(off + 1); *pI++ = (ushort)(off + 0); *pI++ = (ushort)(off + 2); *pI++ = (ushort)(off + 3); } } sm.indexData.indexBuffer.Unlock(); sm.SetMaterialName(GRASS_MATERIAL); msh.Load(); }