private static void getVertexList(QuantizedMeshStream pStream, ref VertexData[] pVertexList) { uint numberOfVertex = pStream.ReadUnsigned32Bit(); pVertexList = new VertexData[numberOfVertex]; for (int index = 0; index < numberOfVertex; index++) { pVertexList[index].u = pStream.ReadUnsigned16Bit(); } for (int index = 0; index < numberOfVertex; index++) { pVertexList[index].v = pStream.ReadUnsigned16Bit(); } for (int index = 0; index < numberOfVertex; index++) { pVertexList[index].height = pStream.ReadUnsigned16Bit(); } // Apply ZigZag (data is compressed) var u = 0; var v = 0; var height = 0; for (int index = 0; index < numberOfVertex; ++index) { u += ZigZagDecode((ushort)pVertexList[index].u); v += ZigZagDecode((ushort)pVertexList[index].v); height += ZigZagDecode((ushort)pVertexList[index].height); pVertexList[index].u = u; pVertexList[index].v = v; pVertexList[index].height = height; } }
private static void GetIndices(QuantizedMeshStream pStream, ref uint[] pTriangleIndices, SizePerStruct pSizePerStruct) { byte bytesInStruct = (pSizePerStruct == SizePerStruct.StructSize_32bit) ? (byte)4 : (byte)2; var alignment = pStream.GetPosition() % bytesInStruct; if (alignment != 0) { pStream.ReadPadding((byte)(bytesInStruct - alignment)); } uint triangleCount = pStream.ReadUnsigned32Bit(); pTriangleIndices = new uint[triangleCount * 3]; /* 3 indices for 1 triangle */ for (int index = 0; index < pTriangleIndices.Length; index++) { pTriangleIndices[index] = (pSizePerStruct == SizePerStruct.StructSize_32bit) ? pStream.ReadUnsigned32Bit() : pStream.ReadUnsigned16Bit(); } // Decompress values uint highest = 0; for (var i = 0; i < pTriangleIndices.Length; ++i) { uint code = pTriangleIndices[i]; pTriangleIndices[i] = highest - code; if (code == 0) { ++highest; } } }
private static void getEdgeIndices(QuantizedMeshStream pStream, ref uint[] pEdgeIndices, SizePerStruct pSizePerStruct) { uint triangleCount = pStream.ReadUnsigned32Bit(); pEdgeIndices = new uint[triangleCount]; for (int index = 0; index < pEdgeIndices.Length; index++) { pEdgeIndices[index] = (pSizePerStruct == SizePerStruct.StructSize_32bit) ? pStream.ReadUnsigned32Bit() : pStream.ReadUnsigned16Bit(); } }
private void DecodeFile(Stream pInputStream, bool pIsGzipped) { if (pInputStream == null) { throw new ArgumentNullException("pInputStream"); } using (var quantizedMeshStream = new QuantizedMeshStream(pInputStream, pIsGzipped)) { // Read Header CenterX = quantizedMeshStream.ReadDouble(); CenterY = quantizedMeshStream.ReadDouble(); CenterZ = quantizedMeshStream.ReadDouble(); MinimumHeight = quantizedMeshStream.ReadFloat(); MaximumHeight = quantizedMeshStream.ReadFloat(); BoundingSphereCenterX = quantizedMeshStream.ReadDouble(); BoundingSphereCenterY = quantizedMeshStream.ReadDouble(); BoundingSphereCenterZ = quantizedMeshStream.ReadDouble(); BoundingSphereRadius = quantizedMeshStream.ReadDouble(); HorizonOcclusionPointX = quantizedMeshStream.ReadDouble(); HorizonOcclusionPointY = quantizedMeshStream.ReadDouble(); HorizonOcclusionPointZ = quantizedMeshStream.ReadDouble(); // Read Vertex Data getVertexList(quantizedMeshStream, ref mVertexList); // Read Index data (traingle indices) SizePerStruct structSize = (mVertexList.Length > 65536) ? SizePerStruct.StructSize_32bit : SizePerStruct.StructSize_16bit; GetIndices(quantizedMeshStream, ref mTriangleIndices, structSize); // Read edge indices getEdgeIndices(quantizedMeshStream, ref mWestIndices, structSize); getEdgeIndices(quantizedMeshStream, ref mSouthIndices, structSize); getEdgeIndices(quantizedMeshStream, ref mEastIndices, structSize); getEdgeIndices(quantizedMeshStream, ref mNorthIndices, structSize); Console.Out.WriteLine(String.Format("{0:0.00000000}", CenterX)); for (int index = 0; index < mVertexList.Length; index++) { Console.Out.WriteLine(String.Format("{0:0.00000000} {1:0.00000000} {2:0.00000000}", Normalize(mVertexList[index].u), Normalize(mVertexList[index].v), GetHeightInMeter(index))); } Console.Out.WriteLine(String.Format("{0:0.00000000}", CenterZ)); } }