Ejemplo n.º 1
0
        public static LayerDataPacket CreateLayerDataPacket(TerrainPatch[] patches, TerrainPatch.LayerType type)
        {
            LayerDataPacket layer = new LayerDataPacket {
                LayerID = { Type = (byte)type }
            };

            TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader
            {
                Stride    = STRIDE,
                PatchSize = 16,
                Type      = type
            };

            // Should be enough to fit even the most poorly packed data
            byte[]  data    = new byte[patches.Length * 16 * 16 * 2];
            BitPack bitpack = new BitPack(data, 0);

            bitpack.PackBits(header.Stride, 16);
            bitpack.PackBits(header.PatchSize, 8);
            bitpack.PackBits((int)header.Type, 8);

            foreach (TerrainPatch t in patches)
            {
                CreatePatch(bitpack, t.Data, t.X, t.Y);
            }

            bitpack.PackBits(END_OF_PATCHES, 8);

            layer.LayerData.Data = new byte[bitpack.BytePos + 1];
            Buffer.BlockCopy(bitpack.Data, 0, layer.LayerData.Data, 0, bitpack.BytePos + 1);

            return(layer);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates a LayerData packet for compressed land data given a full
        /// simulator heightmap and an array of indices of patches to compress
        /// </summary>
        /// <param name="heightmap">A 256 * 256 array of floating point values
        /// specifying the height at each meter in the simulator</param>
        /// <param name="patches">Array of indexes in the 16x16 grid of patches
        /// for this simulator. For example if 1 and 17 are specified, patches
        /// x=1,y=0 and x=1,y=1 are sent</param>
        /// <returns></returns>
        public static LayerDataPacket CreateLandPacket(float[] heightmap, int[] patches)
        {
            LayerDataPacket layer = new LayerDataPacket {
                LayerID = { Type = (byte)TerrainPatch.LayerType.Land }
            };

            TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader
            {
                Stride    = STRIDE,
                PatchSize = 16,
                Type      = TerrainPatch.LayerType.Land
            };

            byte[]  data    = new byte[1536];
            BitPack bitpack = new BitPack(data, 0);

            bitpack.PackBits(header.Stride, 16);
            bitpack.PackBits(header.PatchSize, 8);
            bitpack.PackBits((int)header.Type, 8);

            foreach (int t in patches)
            {
                CreatePatchFromHeightmap(bitpack, heightmap, t % 16, (t - (t % 16)) / 16);
            }

            bitpack.PackBits(END_OF_PATCHES, 8);

            layer.LayerData.Data = new byte[bitpack.BytePos + 1];
            Buffer.BlockCopy(bitpack.Data, 0, layer.LayerData.Data, 0, bitpack.BytePos + 1);

            return(layer);
        }
        /// <summary>
        /// Creates a LayerData packet for compressed land data given a full
        /// simulator heightmap and an array of indices of patches to compress
        /// </summary>
        /// <param name="heightmap">A 256 * 256 array of floating point values
        /// specifying the height at each meter in the simulator</param>
        /// <param name="patches">Array of indexes in the 16x16 grid of patches
        /// for this simulator. For example if 1 and 17 are specified, patches
        /// x=1,y=0 and x=1,y=1 are sent</param>
        /// <returns></returns>
        public static LayerDataPacket CreateLandPacket(float[] heightmap, int[] patches)
        {
            LayerDataPacket layer = new LayerDataPacket();

            layer.LayerID.Type = (byte)TerrainPatch.LayerType.Land;

            TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader();
            header.Stride    = STRIDE;
            header.PatchSize = 16;
            header.Type      = TerrainPatch.LayerType.Land;

            byte[]  data    = new byte[1536];
            BitPack bitpack = new BitPack(data, 0);

            bitpack.PackBits(header.Stride, 16);
            bitpack.PackBits(header.PatchSize, 8);
            bitpack.PackBits((int)header.Type, 8);

            for (int i = 0; i < patches.Length; i++)
            {
                CreatePatchFromHeightmap(bitpack, heightmap, patches[i] % 16, (patches[i] - (patches[i] % 16)) / 16);
            }

            bitpack.PackBits(END_OF_PATCHES, 8);

            layer.LayerData.Data = new byte[bitpack.BytePos + 1];
            Buffer.BlockCopy(bitpack.Data, 0, layer.LayerData.Data, 0, bitpack.BytePos + 1);

            return(layer);
        }
Ejemplo n.º 4
0
        public static LayerDataPacket CreateLayerDataPacket(TerrainPatch[] patches, byte type, int RegionSizeX,
                                                            int RegionSizeY)
        {
            LayerDataPacket layer = new LayerDataPacket {LayerID = {Type = type}};

            TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader
                                                  {Stride = STRIDE, PatchSize = Constants.TerrainPatchSize};

            // Should be enough to fit even the most poorly packed data
            byte[] data = new byte[patches.Length*Constants.TerrainPatchSize*Constants.TerrainPatchSize*2];
            BitPack bitpack = new BitPack(data, 0);
            bitpack.PackBits(header.Stride, 16);
            bitpack.PackBits(header.PatchSize, 8);
            bitpack.PackBits(type, 8);

            foreach (TerrainPatch t in patches)
                CreatePatch(bitpack, t.Data, t.X, t.Y, RegionSizeX, RegionSizeY);

            bitpack.PackBits(END_OF_PATCHES, 8);

            layer.LayerData.Data = new byte[bitpack.BytePos + 1];
            Buffer.BlockCopy(bitpack.Data, 0, layer.LayerData.Data, 0, bitpack.BytePos + 1);

            return layer;
        }
        private void DecompressWind(Simulator simulator, BitPack bitpack, TerrainPatch.GroupHeader group)
        {
            int[] patches = new int[32 * 32];

            // Ignore the simulator stride value
            group.Stride = group.PatchSize;

            // Each wind packet contains the wind speeds and direction for the entire simulator
            // stored as two float arrays. The first array is the X value of the wind speed at
            // each 16x16m block, second is the Y value.
            // wind_speed = distance(x,y to 0,0)
            // wind_direction = vec2(x,y)

            // X values
            TerrainPatch.Header header = TerrainCompressor.DecodePatchHeader(bitpack);
            TerrainCompressor.DecodePatch(patches, bitpack, header, group.PatchSize);
            float[] xvalues = TerrainCompressor.DecompressPatch(patches, header, group);

            // Y values
            header = TerrainCompressor.DecodePatchHeader(bitpack);
            TerrainCompressor.DecodePatch(patches, bitpack, header, group.PatchSize);
            float[] yvalues = TerrainCompressor.DecompressPatch(patches, header, group);

            if (simulator.Client.Settings.STORE_LAND_PATCHES)
            {
                for (int i = 0; i < 256; i++)
                {
                    simulator.WindSpeeds[i] = new Vector2(xvalues[i], yvalues[i]);
                }
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Creates a LayerData packet for compressed land data given a full
        /// simulator heightmap and an array of indices of patches to compress
        /// </summary>
        /// <param name="heightmap">A 256 * 256 array of floating point values
        /// specifying the height at each meter in the simulator</param>
        /// <param name="patches">Array of indexes in the 16x16 grid of patches
        /// for this simulator. For example if 1 and 17 are specified, patches
        /// x=1,y=0 and x=1,y=1 are sent</param>
        /// <returns></returns>
        public static LayerDataPacket CreateLandPacket(float[] heightmap, int[] patches)
        {
            LayerDataPacket layer = new LayerDataPacket();
            layer.LayerID.Type = (byte)TerrainPatch.LayerType.Land;

            TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader();
            header.Stride = STRIDE;
            header.PatchSize = 16;
            header.Type = TerrainPatch.LayerType.Land;

            byte[] data = new byte[1536];
            BitPack bitpack = new BitPack(data, 0);
            bitpack.PackBits(header.Stride, 16);
            bitpack.PackBits(header.PatchSize, 8);
            bitpack.PackBits((int)header.Type, 8);

            for (int i = 0; i < patches.Length; i++)
            {
                CreatePatch(bitpack, heightmap, patches[i] % 16, (patches[i] - (patches[i] % 16)) / 16);
            }

            bitpack.PackBits(END_OF_PATCHES, 8);

            layer.LayerData.Data = new byte[bitpack.BytePos + 1];
            Buffer.BlockCopy(bitpack.Data, 0, layer.LayerData.Data, 0, bitpack.BytePos + 1);

            return layer;
        }
Ejemplo n.º 7
0
        public static LayerDataPacket CreateLandPacket(float[,] patchData, int x, int y)
        {
            LayerDataPacket layer = new LayerDataPacket {
                LayerID = { Type = (byte)TerrainPatch.LayerType.Land }
            };

            TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader
            {
                Stride    = STRIDE,
                PatchSize = 16,
                Type      = TerrainPatch.LayerType.Land
            };

            byte[]  data    = new byte[1536];
            BitPack bitpack = new BitPack(data, 0);

            bitpack.PackBits(header.Stride, 16);
            bitpack.PackBits(header.PatchSize, 8);
            bitpack.PackBits((int)header.Type, 8);

            CreatePatch(bitpack, patchData, x, y);

            bitpack.PackBits(END_OF_PATCHES, 8);

            layer.LayerData.Data = new byte[bitpack.BytePos + 1];
            Buffer.BlockCopy(bitpack.Data, 0, layer.LayerData.Data, 0, bitpack.BytePos + 1);

            return(layer);
        }
Ejemplo n.º 8
0
        private void DecompressLand(Simulator simulator, BitPack bitpack, TerrainPatch.GroupHeader group)
        {
            int x;
            int y;

            int[] patches = new int[32 * 32];
            int   count   = 0;

            while (true)
            {
                TerrainPatch.Header header = TerrainCompressor.DecodePatchHeader(bitpack);

                if (header.QuantWBits == TerrainCompressor.END_OF_PATCHES)
                {
                    break;
                }

                x = header.X;
                y = header.Y;

                if (x >= TerrainCompressor.PATCHES_PER_EDGE || y >= TerrainCompressor.PATCHES_PER_EDGE)
                {
                    Logger.Log(String.Format(
                                   "Invalid LayerData land packet, x={0}, y={1}, dc_offset={2}, range={3}, quant_wbits={4}, patchids={5}, count={6}",
                                   x, y, header.DCOffset, header.Range, header.QuantWBits, header.PatchIDs, count),
                               Helpers.LogLevel.Warning, Client);
                    return;
                }

                // Decode this patch
                TerrainCompressor.DecodePatch(patches, bitpack, header, group.PatchSize);

                // Decompress this patch
                float[] heightmap = TerrainCompressor.DecompressPatch(patches, header, group);

                count++;

                try { OnLandPatchReceived(new LandPatchReceivedEventArgs(simulator, x, y, group.PatchSize, heightmap)); }
                catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); }

                if (Client.Settings.STORE_LAND_PATCHES)
                {
                    TerrainPatch patch = new TerrainPatch
                    {
                        Data = heightmap,
                        X    = x,
                        Y    = y
                    };
                    simulator.Terrain[y * 16 + x] = patch;
                }
            }
        }
        private void LayerDataHandler(object sender, PacketReceivedEventArgs e)
        {
            LayerDataPacket layer   = (LayerDataPacket)e.Packet;
            BitPack         bitpack = new BitPack(layer.LayerData.Data, 0);

            TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader();
            TerrainPatch.LayerType   type   = (TerrainPatch.LayerType)layer.LayerID.Type;

            // Stride
            header.Stride = bitpack.UnpackBits(16);
            // Patch size
            header.PatchSize = bitpack.UnpackBits(8);
            // Layer type
            header.Type = (TerrainPatch.LayerType)bitpack.UnpackBits(8);

            switch (type)
            {
            case TerrainPatch.LayerType.Land:
                if (m_LandPatchReceivedEvent != null || Client.Settings.STORE_LAND_PATCHES)
                {
                    DecompressLand(e.Simulator, bitpack, header);
                }
                break;

            case TerrainPatch.LayerType.Water:
                Logger.Log("Got a Water LayerData packet, implement me!", Helpers.LogLevel.Error, Client);
                break;

            case TerrainPatch.LayerType.Wind:
                DecompressWind(e.Simulator, bitpack, header);
                break;

            case TerrainPatch.LayerType.Cloud:
                DecompressCloud(e.Simulator, bitpack, header);
                break;

            default:
                Logger.Log("Unrecognized LayerData type " + type.ToString(), Helpers.LogLevel.Warning, Client);
                break;
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        ///     Creates a LayerData packet for compressed land data given a full
        ///     simulator heightmap and an array of indices of patches to compress
        /// </summary>
        /// <param name="terrData">
        ///     Terrain data that can result in a meter square heightmap.
        /// </param>
        /// <param name="x">
        ///     Array of indexes in the grid of patches
        ///     for this simulator.
        ///     If creating a packet for multiple patches, there will be entries in
        ///     both the X and Y arrays for each of the patches.
        ///     For example if patches 1 and 17 are to be sent,
        ///     x[] = {1,1} and y[] = {0,1} which specifies the patches at
        ///     indexes <1,0> and <1,1> (presuming the terrain size is 16x16 patches).
        /// </param>
        /// <param name="y">
        ///     Array of indexes in the grid of patches.
        /// </param>
        /// <param name="type"></param>
        /// <param name="pRegionSizeX"></param>
        /// <param name="pRegionSizeY"></param>
        /// <returns></returns>
        public static LayerDataPacket CreateLandPacket(TerrainData terrData, int[] x, int[] y, byte type)
        {
            LayerDataPacket layer = new LayerDataPacket {LayerID = {Type = type}};

            TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader
                                                  {Stride = STRIDE, PatchSize = Constants.TerrainPatchSize};

            byte[] data = new byte[x.Length * Constants.TerrainPatchSize * Constants.TerrainPatchSize * 2];
            BitPack bitpack = new BitPack(data, 0);
            bitpack.PackBits(header.Stride, 16);
            bitpack.PackBits(header.PatchSize, 8);
            bitpack.PackBits(type, 8);

            for (int i = 0; i < x.Length; i++)
                CreatePatchFromHeightmap(bitpack, terrData, x[i], y[i]);

            bitpack.PackBits(END_OF_PATCHES, 8);

            layer.LayerData.Data = new byte[bitpack.BytePos + 1];
            Buffer.BlockCopy(bitpack.Data, 0, layer.LayerData.Data, 0, bitpack.BytePos + 1);

            return layer;
        }
Ejemplo n.º 11
0
        public static LayerDataPacket CreateLayerDataPacket(TerrainPatch[] patches, TerrainPatch.LayerType type)
        {
            LayerDataPacket layer = new LayerDataPacket();
            layer.LayerID.Type = (byte)type;

            TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader();
            header.Stride = STRIDE;
            header.PatchSize = 16;
            header.Type = type;

            // Should be enough to fit even the most poorly packed data
            byte[] data = new byte[patches.Length * 16 * 16 * 2];
            BitPack bitpack = new BitPack(data, 0);
            bitpack.PackBits(header.Stride, 16);
            bitpack.PackBits(header.PatchSize, 8);
            bitpack.PackBits((int)header.Type, 8);

            for (int i = 0; i < patches.Length; i++)
                CreatePatch(bitpack, patches[i].Data, patches[i].X, patches[i].Y);

            bitpack.PackBits(END_OF_PATCHES, 8);

            layer.LayerData.Data = new byte[bitpack.BytePos + 1];
            Buffer.BlockCopy(bitpack.Data, 0, layer.LayerData.Data, 0, bitpack.BytePos + 1);

            return layer;
        }
Ejemplo n.º 12
0
        public static LayerDataPacket CreateLandPacket(float[,] patchData, int x, int y)
        {
            LayerDataPacket layer = new LayerDataPacket();
            layer.LayerID.Type = (byte)TerrainPatch.LayerType.Land;

            TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader();
            header.Stride = STRIDE;
            header.PatchSize = 16;
            header.Type = TerrainPatch.LayerType.Land;

            byte[] data = new byte[1536];
            BitPack bitpack = new BitPack(data, 0);
            bitpack.PackBits(header.Stride, 16);
            bitpack.PackBits(header.PatchSize, 8);
            bitpack.PackBits((int)header.Type, 8);

            CreatePatch(bitpack, patchData, x, y);

            bitpack.PackBits(END_OF_PATCHES, 8);

            layer.LayerData.Data = new byte[bitpack.BytePos + 1];
            Buffer.BlockCopy(bitpack.Data, 0, layer.LayerData.Data, 0, bitpack.BytePos + 1);

            return layer;
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Creates a LayerData packet for compressed land data given a full
        /// simulator heightmap and an array of indices of patches to compress
        /// </summary>
        /// <param name="heightmap">A 256 * 256 array of floating point values
        /// specifying the height at each meter in the simulator</param>
        /// <param name="patches">Array of indexes in the 16x16 grid of patches
        /// for this simulator. For example if 1 and 17 are specified, patches
        /// x=1,y=0 and x=1,y=1 are sent</param>
        /// <returns></returns>
        public static LayerDataPacket CreateLandPacket(short[] heightmap, int[] x, int[] y, byte type, int RegionSizeX, int RegionSizeY)
        {
            LayerDataPacket layer = new LayerDataPacket();
            layer.LayerID.Type = type;

            TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader();
            header.Stride = STRIDE;
            header.PatchSize = Constants.TerrainPatchSize;

            byte[] data = new byte[2112];
            BitPack bitpack = new BitPack(data, 0);
            bitpack.PackBits(header.Stride, 16);
            bitpack.PackBits(header.PatchSize, 8);
            bitpack.PackBits(type, 8);

            for (int i = 0; i < x.Length; i++)
                CreatePatchFromHeightmap(bitpack, heightmap, x[i], y[i], RegionSizeX, RegionSizeY);

            bitpack.PackBits(END_OF_PATCHES, 8);

            layer.LayerData.Data = new byte[bitpack.BytePos + 1];
            Buffer.BlockCopy(bitpack.Data, 0, layer.LayerData.Data, 0, bitpack.BytePos + 1);

            return layer;
        }
 private void DecompressCloud(Simulator simulator, BitPack bitpack, TerrainPatch.GroupHeader group)
 {
     // FIXME:
 }
Ejemplo n.º 15
0
        private void LayerDataHandler(Packet packet, Simulator simulator)
        {
            LayerDataPacket layer = (LayerDataPacket)packet;
            BitPack bitpack = new BitPack(layer.LayerData.Data, 0);
            TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader();
            TerrainPatch.LayerType type = (TerrainPatch.LayerType)layer.LayerID.Type;

            // Stride
            header.Stride = bitpack.UnpackBits(16);
            // Patch size
            header.PatchSize = bitpack.UnpackBits(8);
            // Layer type
            header.Type = (TerrainPatch.LayerType)bitpack.UnpackBits(8);

            switch (type)
            {
                case TerrainPatch.LayerType.Land:
                    if (OnLandPatch != null || Client.Settings.STORE_LAND_PATCHES)
                        DecompressLand(simulator, bitpack, header);
                    break;
                case TerrainPatch.LayerType.Water:
                    Logger.Log("Got a Water LayerData packet, implement me!", Helpers.LogLevel.Error, Client);
                    break;
                case TerrainPatch.LayerType.Wind:
                    DecompressWind(simulator, bitpack, header);
                    break;
                case TerrainPatch.LayerType.Cloud:
                    DecompressCloud(simulator, bitpack, header);
                    break;
                default:
                    Logger.Log("Unrecognized LayerData type " + type.ToString(), Helpers.LogLevel.Warning, Client);
                    break;
            }
        }
Ejemplo n.º 16
0
        public static float[] DecompressPatch(int[] patches, TerrainPatch.Header header, TerrainPatch.GroupHeader group)
        {
            float[] block    = new float[group.PatchSize * group.PatchSize];
            float[] output   = new float[group.PatchSize * group.PatchSize];
            int     prequant = (header.QuantWBits >> 4) + 2;
            int     quantize = 1 << prequant;
            float   ooq      = 1.0f / (float)quantize;
            float   mult     = ooq * (float)header.Range;
            float   addval   = mult * (float)(1 << (prequant - 1)) + header.DCOffset;

            if (group.PatchSize == 16)
            {
                for (int n = 0; n < 16 * 16; n++)
                {
                    block[n] = patches[CopyMatrix16[n]] * DequantizeTable16[n];
                }

                float[] ftemp = new float[16 * 16];

                for (int o = 0; o < 16; o++)
                {
                    IDCTColumn16(block, ftemp, o);
                }
                for (int o = 0; o < 16; o++)
                {
                    IDCTLine16(ftemp, block, o);
                }
            }
            else
            {
                for (int n = 0; n < 32 * 32; n++)
                {
                    block[n] = patches[CopyMatrix32[n]] * DequantizeTable32[n];
                }

                Logger.Log("Implement IDCTPatchLarge", Helpers.LogLevel.Error);
            }

            for (int j = 0; j < block.Length; j++)
            {
                output[j] = block[j] * mult + addval;
            }

            return(output);
        }
Ejemplo n.º 17
0
        public static LayerDataPacket CreateLandPacket(List<PatchInfo> ps, byte type)
        {
            LayerDataPacket layer = new LayerDataPacket { LayerID = { Type = type } };

            TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader { Stride = STRIDE, PatchSize = Constants.TerrainPatchSize };

            byte[] outdata = new byte[1500];
            byte[] indata = BitConverter.GetBytes((ushort)header.Stride);
            if(!BitConverter.IsLittleEndian)
            {
                Array.Reverse(indata);
            }
            outdata[0] = indata[0];
            outdata[1] = indata[1];
            outdata[2] = (byte)header.PatchSize;
            outdata[3] = type;

            int outBitPos = 32;

            PatchInfo eop = new PatchInfo();
            eop.PackedData = new byte[] { END_OF_PATCHES };
            eop.BitLength = 8;
            ps.Add(eop);

            foreach(PatchInfo pi in ps)
            {
                int count = 0;
                int curBytePos = 0;
                int bitCount = pi.BitLength;
                /* this bit pack method has a slight variance allowing it to directly accept BitPacked data */
                while (bitCount > 0)
                {
                    count = bitCount;
                    if (count > 8)
                    {
                        count = 8;
                    }

                    byte srcBits = pi.PackedData[curBytePos];
                    while (count-- > 0)
                    {
                        byte curBitMask = (byte)(0x80 >> (outBitPos % 8));

                        if ((srcBits & 0x80) != 0)
                        {
                            outdata[outBitPos / 8] |= curBitMask;
                        }
                        else
                        {
                            outdata[outBitPos / 8] &= (byte)~curBitMask;
                        }

                        ++outBitPos;
                        srcBits <<= 1;
                    }
                    ++curBytePos;

                    if (bitCount > 8)
                    {
                        bitCount -= 8;
                    }
                    else
                    {
                        bitCount = 0;
                    }
                }
            }

            layer.LayerData.Data = new byte[(outBitPos + 7) / 8];
            Buffer.BlockCopy(outdata, 0, layer.LayerData.Data, 0, (outBitPos + 7) / 8);

            return layer;
        }