Пример #1
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="x">
        ///     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>
        /// <param name="y">
        ///     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>
        /// <param name="type"></param>
        /// <param name="RegionSizeX"></param>
        /// <param name="RegionSizeY"></param>
        /// <returns></returns>
        public static LayerDataPacket CreateLandPacket(short[] heightmap, int[] x, int[] y, byte type, int RegionSizeX,
                                                       int RegionSizeY)
        {
            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, 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);
        }
Пример #2
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);
        }
Пример #3
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 / quantize;
            float   mult     = ooq * header.Range;
            float   addval   = mult * (1 << (prequant - 1)) + header.DCOffset;

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

                float[] ftemp = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize];

                for (int o = 0; o < Constants.TerrainPatchSize; o++)
                {
                    IDCTColumn16(block, ftemp, o);
                }
                for (int o = 0; o < Constants.TerrainPatchSize; o++)
                {
                    IDCTLine16(ftemp, block, o);
                }
            }
            else
            {
                for (int n = 0; n < Constants.TerrainPatchSize * 2 * Constants.TerrainPatchSize * 2; 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);
        }
        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);
        }