//增加读取纹理坐标 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(); } }
/**************** 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()); }
// 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; } }
// 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; } }