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();
                    patch.Data = heightmap;
                    patch.X = x;
                    patch.Y = y;
                    simulator.Terrain[y * 16 + x] = patch;
                }
            }
        }
示例#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();
            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;
        }
        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;
        }
示例#4
0
        public static int GetParcelArea(SceneParcel parcel, out Vector3 aabbMin, out Vector3 aabbMax)
        {
            int minX = 64;
            int minY = 64;
            int maxX = 0;
            int maxY = 0;
            int area = 0;

            System.Diagnostics.Debug.Assert(parcel.Bitmap != null);
            System.Diagnostics.Debug.Assert(parcel.Bitmap.Length == 512);

            BitPack bitmap = new BitPack(parcel.Bitmap, 0);
            for (int y = 0; y < 64; y++)
            {
                for (int x = 0; x < 64; x++)
                {
                    if (bitmap.UnpackBits(1) != 0)
                    {
                        int x4 = x * 4;
                        int y4 = y * 4;

                        if (minX > x4) minX = x4;
                        if (minY > y4) minY = y4;
                        if (maxX < x4) maxX = x4;
                        if (maxX < y4) maxY = y4;
                        area += 16;
                    }
                }
            }

            aabbMin = new Vector3(minX, minY, 0f);
            aabbMax = new Vector3(maxX, maxY, 0f);
            return area;
        }
示例#5
0
        public void BitUnpacking()
        {
            byte[] data = new byte[] { 0x80, 0x00, 0x0F, 0x50, 0x83, 0x7D };
            BitPack bitpacker = new BitPack(data, 0);

            int b = bitpacker.UnpackBits(1);
            Assert.IsTrue(b == 1, "Unpacked " + b + " instead of 1");

            b = bitpacker.UnpackBits(1);
            Assert.IsTrue(b == 0, "Unpacked " + b + " instead of 0");

            bitpacker = new BitPack(data, 2);

            b = bitpacker.UnpackBits(4);
            Assert.IsTrue(b == 0, "Unpacked " + b + " instead of 0");

            b = bitpacker.UnpackBits(8);
            Assert.IsTrue(b == 0xF5, "Unpacked " + b + " instead of 0xF5");

            b = bitpacker.UnpackBits(4);
            Assert.IsTrue(b == 0, "Unpacked " + b + " instead of 0");

            b = bitpacker.UnpackBits(10);
            Assert.IsTrue(b == 0x0183, "Unpacked " + b + " instead of 0x0183");
        }
示例#6
0
        public void BitPacking()
        {
            byte[] packedBytes = new byte[12];
            BitPack bitpacker = new BitPack(packedBytes, 0);

            bitpacker.PackBits(0x0ABBCCDD, 32);
            bitpacker.PackBits(25, 5);
            bitpacker.PackFloat(123.321f);
            bitpacker.PackBits(1000, 16);

            bitpacker = new BitPack(packedBytes, 0);

            int b = bitpacker.UnpackBits(32);
            Assert.IsTrue(b == 0x0ABBCCDD, "Unpacked " + b + " instead of 2864434397");

            b = bitpacker.UnpackBits(5);
            Assert.IsTrue(b == 25, "Unpacked " + b + " instead of 25");

            float f = bitpacker.UnpackFloat();
            Assert.IsTrue(f == 123.321f, "Unpacked " + f + " instead of 123.321");

            b = bitpacker.UnpackBits(16);
            Assert.IsTrue(b == 1000, "Unpacked " + b + " instead of 1000");

            packedBytes = new byte[1];
            bitpacker = new BitPack(packedBytes, 0);
            bitpacker.PackBit(true);

            bitpacker = new BitPack(packedBytes, 0);
            b = bitpacker.UnpackBits(1);
            Assert.IsTrue(b == 1, "Unpacked " + b + " instead of 1");

            packedBytes = new byte[1] { Byte.MaxValue };
            bitpacker = new BitPack(packedBytes, 0);
            bitpacker.PackBit(false);

            bitpacker = new BitPack(packedBytes, 0);
            b = bitpacker.UnpackBits(1);
            Assert.IsTrue(b == 0, "Unpacked " + b + " instead of 0");
        }
示例#7
0
        private static void EncodePatch(BitPack output, int[] patch, int postquant, int wbits)
        {
            int temp;
            bool eob;

            if (postquant > 16 * 16 || postquant < 0)
            {
                Logger.Log("Postquant is outside the range of allowed values in EncodePatch()", Helpers.LogLevel.Error);
                return;
            }

            if (postquant != 0) patch[16 * 16 - postquant] = 0;

            for (int i = 0; i < 16 * 16; i++)
            {
                eob = false;
                temp = patch[i];

                if (temp == 0)
                {
                    eob = true;

                    for (int j = i; j < 16 * 16 - postquant; j++)
                    {
                        if (patch[j] != 0)
                        {
                            eob = false;
                            break;
                        }
                    }

                    if (eob)
                    {
                        output.PackBits(ZERO_EOB, 2);
                        return;
                    }
                    else
                    {
                        output.PackBits(ZERO_CODE, 1);
                    }
                }
                else
                {
                    if (temp < 0)
                    {
                        temp *= -1;

                        if (temp > (1 << wbits)) temp = (1 << wbits);

                        output.PackBits(NEGATIVE_VALUE, 3);
                        output.PackBits(temp, wbits);
                    }
                    else
                    {
                        if (temp > (1 << wbits)) temp = (1 << wbits);

                        output.PackBits(POSITIVE_VALUE, 3);
                        output.PackBits(temp, wbits);
                    }
                }
            }
        }
示例#8
0
        private static void EncodePatch(BitPack output, int[] patch, int postquant, int wbits)
        {
            int maxwbitssize = (1 << wbits) - 1;

            if (postquant > Constants.TerrainPatchSize*Constants.TerrainPatchSize || postquant < 0)
            {
                Logger.Log("Postquant is outside the range of allowed values in EncodePatch()", Helpers.LogLevel.Error);
                return;
            }

            if (postquant != 0) patch[Constants.TerrainPatchSize*Constants.TerrainPatchSize - postquant] = 0;

            for (int i = 0; i < Constants.TerrainPatchSize*Constants.TerrainPatchSize; i++)
            {
                int temp = patch[i];

                if (temp == 0)
                {
                    bool eob = true;

                    for (int j = i; j < Constants.TerrainPatchSize*Constants.TerrainPatchSize - postquant; j++)
                    {
                        if (patch[j] != 0)
                        {
                            eob = false;
                            break;
                        }
                    }

                    if (eob)
                    {
                        output.PackBits(ZERO_EOB, 2);
                        return;
                    }
                    output.PackBits(ZERO_CODE, 1);
                }
                else
                {
                    if (temp < 0)
                    {
                        temp *= -1;

                        if (temp > maxwbitssize) temp = maxwbitssize;

                        output.PackBits(NEGATIVE_VALUE, 3);
                        output.PackBits(temp, wbits);
                    }
                    else
                    {
                        if (temp > maxwbitssize) temp = maxwbitssize;

                        output.PackBits(POSITIVE_VALUE, 3);
                        output.PackBits(temp, wbits);
                    }
                }
            }
        }
示例#9
0
 private void DecompressCloud(Simulator simulator, BitPack bitpack, TerrainPatch.GroupHeader group)
 {
     // FIXME:
 }
示例#10
0
        /// <summary>
        ///     Add a patch of terrain to a BitPacker
        /// </summary>
        /// <param name="output">BitPacker to write the patch to</param>
        /// <param name="heightmap">
        ///     Heightmap of the simulator. Presumed to be an sizeX*sizeY array.
        /// </param>
        /// <param name="patchX">
        ///     X offset of the patch to create.
        /// </param>
        /// <param name="patchY">
        ///     Y offset of the patch to create.
        /// </param>
        /// <param name="pRegionSizeX"></param>
        /// <param name="pRegionSizeY"></param>
        public static void CreatePatchFromHeightmap(BitPack output, TerrainData terrData, int patchX, int patchY)
        {
            TerrainPatch.Header header = PrescanPatch(terrData, patchX, patchY);
            header.QuantWBits = 136;

            // If larger than legacy region size, pack patch X and Y info differently.
            if (terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize)
            {
                header.PatchIDs = (patchY & 0xFFFF);
                header.PatchIDs += (patchX << 16);
            }
            else
            {
                header.PatchIDs = (patchY & 0x1F);
                header.PatchIDs += (patchX << 5);
            }

            // m_log.DebugFormat("{0} CreatePatchFromHeightmap. patchX={1}, patchY={2}, DCOffset={3}, range={4}",
            //                         LogHeader, patchX, patchY, header.DCOffset, header.Range);

            // NOTE: No idea what prequant and postquant should be or what they do
            int wbits;
            int[] patch = CompressPatch(terrData, patchX, patchY, header, 10, out wbits);
            wbits = EncodePatchHeader(output, header, patch, (uint)terrData.SizeX, (uint)terrData.SizeY, wbits);
            EncodePatch(output, patch, 0, wbits);
        }
示例#11
0
        private static int EncodePatchHeader(BitPack output, TerrainPatch.Header header, int[] patch, uint pRegionSizeX,
                                             uint pRegionSizeY, int wbits)
        {
            /*
                    int temp;
                    int wbits = (header.QuantWBits & 0x0f) + 2;
                    uint maxWbits = (uint)wbits + 5;
                    uint minWbits = ((uint)wbits >> 1);
                    int wbitsMaxValue;
        */
            // goal is to determ minimum number of bits to use so all data fits
            /*
                    wbits = (int)minWbits;
                    wbitsMaxValue = (1 << wbits);

                    for (int i = 0; i < patch.Length; i++)
                    {
                        temp = patch[i];
                        if (temp != 0)
                        {
                            // Get the absolute value
                            if (temp < 0) temp *= -1;

         no coments..

                            for (int j = (int)maxWbits; j > (int)minWbits; j--)
                            {
                                if ((temp & (1 << j)) != 0)
                                {
                                    if (j > wbits) wbits = j;
                                    break;
                                }
                            }
 
                            while (temp > wbitsMaxValue)
                                {
                                wbits++;
                                if (wbits == maxWbits)
                                    goto Done;
                                wbitsMaxValue = 1 << wbits;
                                }
                        }
                    }

                Done:

                    //            wbits += 1;
         */
            // better check
            if (wbits > 17)
                wbits = 16;
            else if (wbits < 3)
                wbits = 3;

            header.QuantWBits &= 0xf0;

            header.QuantWBits |= (wbits - 2);

            output.PackBits(header.QuantWBits, 8);
            output.PackFloat(header.DCOffset);
            output.PackBits(header.Range, 16);
            if (pRegionSizeX > Constants.RegionSize || pRegionSizeY > Constants.RegionSize)
                output.PackBits(header.PatchIDs, 32);
            else
                output.PackBits(header.PatchIDs, 10);

            return wbits;
        }
示例#12
0
        private void UpdateParcelOverlay(SceneParcel parcel)
        {
            BitPack bitmap = new BitPack(parcel.Bitmap, 0);

            for (int y = 0; y < 64; y++)
            {
                for (int x = 0; x < 64; x++)
                {
                    if (bitmap.UnpackBits(1) != 0)
                        m_parcelOverlay[y * 64 + x] = parcel.LocalID;
                }
            }
        }
示例#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="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;
        }
示例#14
0
        public byte[] GetCompressedPatch(int patchx, int patchy, out int bitlength, uint lastSerialNo, out uint serialNo)
        {
            lock(m_PackedSerialLock)
            {
#if UPDATE_TERRAIN_ONLY_WHEN_NECESSARY
                if(m_PackedTerrainPatches[patchx, patchy].Serial == lastSerialNo && 0 != lastSerialNo)
                {
                    /* signal no change via null */
                    serialNo = lastSerialNo;
                    bitlength = 0;
                    return null;
                }

                if(m_PackedTerrainPatches[patchx, patchy].Serial != m_TerrainPatchSerial[patchx, patchy])
#endif
                {

                    m_PackedTerrainPatches[patchx, patchy].Serial = m_TerrainPatchSerial[patchx, patchy];
                    m_PackedTerrainPatches[patchx, patchy].CompressedPatch = new byte[651]; /* maximum length of a single compressed patch */
                    BitPack bitpack = new BitPack(m_PackedTerrainPatches[patchx, patchy].CompressedPatch, 0);
                    OpenSimTerrainCompressor.CreatePatchFromHeightmap(bitpack, this, patchx, patchy);
                    m_PackedTerrainPatches[patchx, patchy].BitLength = 8 * bitpack.BytePos + bitpack.BitPos;
                    if(0 == bitpack.BitPos)
                    {
                        m_PackedTerrainPatches[patchx, patchy].BitLength += 8;
                    }
                }

                bitlength = m_PackedTerrainPatches[patchx, patchy].BitLength;
                byte[] copy = new byte[m_PackedTerrainPatches[patchx, patchy].CompressedPatch.Length];
                Buffer.BlockCopy(m_PackedTerrainPatches[patchx, patchy].CompressedPatch, 0, copy, 0, copy.Length);
                serialNo = m_PackedTerrainPatches[patchx, patchy].Serial;

                return copy;
            }

        }
示例#15
0
        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);
            ulong handle = simulator.Handle;
            Vector2[] windSpeeds;
            lock (WindSpeeds.Dictionary)
            {
                if (!WindSpeeds.TryGetValue(handle,out windSpeeds))
                {
                    windSpeeds = WindSpeeds[handle] = new Vector2[256]; 
                }
            }
            for (int i = 0; i < 256; i++)
                windSpeeds[i] = new Vector2(xvalues[i], yvalues[i]);
        }
        private static int EncodePatchHeader(BitPack output, TerrainPatch.Header header, int[] patch, int RegionSizeX,
            int RegionSizeY, int wbits)
        {
            // better check
            if (wbits > 17)
                wbits = 16;
            else if (wbits < 3)
                wbits = 3;

            header.QuantWBits &= 0xf0;

            header.QuantWBits |= (wbits - 2);

            output.PackBits(header.QuantWBits, 8);
            output.PackFloat(header.DCOffset);
            output.PackBits(header.Range, 16);
            if (RegionSizeX > Constants.RegionSize || RegionSizeY > Constants.RegionSize)
                output.PackBits(header.PatchIDs, 32);
            else
                output.PackBits(header.PatchIDs, 10);

            return wbits;
        }
示例#17
0
        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]);
            }
        }
        /// <summary>
        ///     Add a patch of terrain to a BitPacker
        /// </summary>
        /// <param name="output">BitPacker to write the patch to</param>
        /// <param name="heightmap">
        ///     Heightmap of the simulator, must be a 256 *
        ///     256 float array
        /// </param>
        /// <param name="x">
        ///     X offset of the patch to create, valid values are
        ///     from 0 to 15
        /// </param>
        /// <param name="y">
        ///     Y offset of the patch to create, valid values are
        ///     from 0 to 15
        /// </param>
        /// <param name="RegionSizeX"></param>
        /// <param name="RegionSizeY"></param>
        public static void CreatePatchFromHeightmap(BitPack output, short[] heightmap, int x, int y, int RegionSizeX,
            int RegionSizeY)
        {
            TerrainPatch.Header header = PrescanPatch(heightmap, x, y, RegionSizeX, RegionSizeY);
            header.QuantWBits = 136;
            if (RegionSizeX > Constants.RegionSize || RegionSizeY > Constants.RegionSize)
            {
                header.PatchIDs = (y & 0xFFFF);
                header.PatchIDs += (x << 16);
            }
            else
            {
                header.PatchIDs = (y & 0x1F);
                header.PatchIDs += (x << 5);
            }

            // NOTE: No idea what prequant and postquant should be or what they do
            int wbits;
            int[] patch = CompressPatch(heightmap, x, y, header, 10, RegionSizeX, RegionSizeY, out wbits);
            wbits = EncodePatchHeader(output, header, patch, RegionSizeX, RegionSizeY, wbits);
            EncodePatch(output, patch, 0, wbits);
        }
示例#19
0
            /// <summary>
            /// Generate byte[] array from particle data
            /// </summary>
            /// <returns>Byte array</returns>
            public byte[] GetBytes()
            {
                int size = LegacyDataBlockSize;

                if (!IsLegacyCompatible())
                {
                    size += 8;                        // two new ints for size
                }
                if (HasGlow())
                {
                    size += 2;            // two bytes for start and end glow
                }
                if (HasBlendFunc())
                {
                    size += 2;                 // two bytes for start end end blend function
                }
                byte[]  bytes = new byte[size];
                BitPack pack  = new BitPack(bytes, 0);

                if (IsLegacyCompatible())
                {
                    PackSystemBytes(ref pack);
                    PackLegacyData(ref pack);
                }
                else
                {
                    if (HasGlow())
                    {
                        PartDataFlags |= ParticleDataFlags.DataGlow;
                    }
                    if (HasBlendFunc())
                    {
                        PartDataFlags |= ParticleDataFlags.DataBlend;
                    }

                    pack.PackBitsFromUInt((uint)SysDataSize);
                    PackSystemBytes(ref pack);
                    int partSize = PartDataSize;
                    if (HasGlow())
                    {
                        partSize += 2;            // two bytes for start and end glow
                    }
                    if (HasBlendFunc())
                    {
                        partSize += 2;                 // two bytes for start end end blend function
                    }
                    pack.PackBitsFromUInt((uint)partSize);
                    PackLegacyData(ref pack);

                    if (HasGlow())
                    {
                        pack.PackBitsFromByte((byte)(PartStartGlow * 255f));
                        pack.PackBitsFromByte((byte)(PartEndGlow * 255f));
                    }

                    if (HasBlendFunc())
                    {
                        pack.PackBitsFromByte(BlendFuncSource);
                        pack.PackBitsFromByte(BlendFuncDest);
                    }
                }

                return(bytes);
            }
            /// <summary>
            /// Decodes a byte[] array into a ParticleSystem Object
            /// </summary>
            /// <param name="data">ParticleSystem object</param>
            /// <param name="pos">Start position for BitPacker</param>
            public ParticleSystem(byte[] data, int pos)
            {
                // TODO: Not sure exactly how many bytes we need here, so partial
                // (truncated) data will cause an exception to be thrown
                if (data.Length > 0)
                {
                    BitPack pack = new BitPack(data, pos);

                    CRC            = pack.UnpackUBits(32);
                    PartFlags      = pack.UnpackUBits(32);
                    Pattern        = (SourcePattern)pack.UnpackByte();
                    MaxAge         = pack.UnpackFixed(false, 8, 8);
                    StartAge       = pack.UnpackFixed(false, 8, 8);
                    InnerAngle     = pack.UnpackFixed(false, 3, 5);
                    OuterAngle     = pack.UnpackFixed(false, 3, 5);
                    BurstRate      = pack.UnpackFixed(false, 8, 8);
                    BurstRadius    = pack.UnpackFixed(false, 8, 8);
                    BurstSpeedMin  = pack.UnpackFixed(false, 8, 8);
                    BurstSpeedMax  = pack.UnpackFixed(false, 8, 8);
                    BurstPartCount = pack.UnpackByte();
                    float x = pack.UnpackFixed(true, 8, 7);
                    float y = pack.UnpackFixed(true, 8, 7);
                    float z = pack.UnpackFixed(true, 8, 7);
                    AngularVelocity = new Vector3(x, y, z);
                    x = pack.UnpackFixed(true, 8, 7);
                    y = pack.UnpackFixed(true, 8, 7);
                    z = pack.UnpackFixed(true, 8, 7);
                    PartAcceleration = new Vector3(x, y, z);
                    Texture          = pack.UnpackUUID();
                    Target           = pack.UnpackUUID();

                    PartDataFlags = (ParticleDataFlags)pack.UnpackUBits(32);
                    PartMaxAge    = pack.UnpackFixed(false, 8, 8);
                    byte r = pack.UnpackByte();
                    byte g = pack.UnpackByte();
                    byte b = pack.UnpackByte();
                    byte a = pack.UnpackByte();
                    PartStartColor = new Color4(r, g, b, a);
                    r               = pack.UnpackByte();
                    g               = pack.UnpackByte();
                    b               = pack.UnpackByte();
                    a               = pack.UnpackByte();
                    PartEndColor    = new Color4(r, g, b, a);
                    PartStartScaleX = pack.UnpackFixed(false, 3, 5);
                    PartStartScaleY = pack.UnpackFixed(false, 3, 5);
                    PartEndScaleX   = pack.UnpackFixed(false, 3, 5);
                    PartEndScaleY   = pack.UnpackFixed(false, 3, 5);
                }
                else
                {
                    CRC               = PartFlags = 0;
                    Pattern           = SourcePattern.None;
                    MaxAge            = StartAge = InnerAngle = OuterAngle = BurstRate = BurstRadius = BurstSpeedMin =
                        BurstSpeedMax = 0.0f;
                    BurstPartCount    = 0;
                    AngularVelocity   = PartAcceleration = Vector3.Zero;
                    Texture           = Target = UUID.Zero;
                    PartDataFlags     = ParticleDataFlags.None;
                    PartMaxAge        = 0.0f;
                    PartStartColor    = PartEndColor = Color4.Black;
                    PartStartScaleX   = PartStartScaleY = PartEndScaleX = PartEndScaleY = 0.0f;
                }
            }
示例#21
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;
        }
示例#22
0
 private void DecompressCloud(Simulator simulator, BitPack bitpack, TerrainPatch.GroupHeader group)
 {
     // FIXME:
 }
示例#23
0
        public void SplitParcel(SceneParcel parcel, int startX, int endX, int startY, int endY)
        {
            SceneParcel newParcel = new SceneParcel(parcel);
            newParcel.ID = UUID.Random();
            newParcel.LocalID = System.Threading.Interlocked.Increment(ref m_currentParcelID);
            newParcel.ClaimDate = DateTime.UtcNow;
            newParcel.Dwell = 0f;

            m_parcels.Add(newParcel.ID, newParcel.LocalID, newParcel);

            // Update parcel bitmaps
            BitPack origParcelBitmap = new BitPack(parcel.Bitmap, 0);
            BitPack parcelBitmap = new BitPack(new byte[512], 0);
            BitPack newParcelBitmap = new BitPack(newParcel.Bitmap, 0);

            for (int y = 0; y < 64; y++)
            {
                for (int x = 0; x < 64; x++)
                {
                    bool origParcelBit = (origParcelBitmap.UnpackBits(1) != 0);

                    if (x >= startX && x <= endX && y >= startY && y <= endY)
                    {
                        // Inside the new parcel
                        parcelBitmap.PackBit(false);
                        newParcelBitmap.PackBit(true);
                        m_parcelOverlay[y * 64 + x] = newParcel.LocalID;
                    }
                    else
                    {
                        // Not inside the new parcel
                        parcelBitmap.PackBit(origParcelBit);
                        newParcelBitmap.PackBit(false);
                    }
                }
            }

            // Update parcel landing info
            SceneParcel landingParcel;
            if (TryGetParcel(newParcel.LandingLocation, out landingParcel) && landingParcel == parcel)
            {
                newParcel.Landing = LandingType.None;
                newParcel.LandingLocation = Vector3.Zero;
            }
            else
            {
                parcel.Landing = LandingType.None;
                parcel.LandingLocation = Vector3.Zero;
            }

            // Update max prim counts
            Vector3 aabbMin, aabbMax;
            int area = GetParcelArea(parcel, out aabbMin, out aabbMax);
            parcel.MaxPrims = (int)Math.Round((float)area * m_primsPerSquareMeter);
            area = GetParcelArea(newParcel, out aabbMin, out aabbMax);
            newParcel.MaxPrims = (int)Math.Round((float)area * m_primsPerSquareMeter);

            Serialize();
        }
示例#24
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;
            }
        }
示例#25
0
            /// <summary>
            /// Decodes a byte[] array into a ParticleSystem Object
            /// </summary>
            /// <param name="data">ParticleSystem object</param>
            /// <param name="pos">Start position for BitPacker</param>
            public ParticleSystem(byte[] data, int pos)
            {
                PartStartGlow   = 0f;
                PartEndGlow     = 0f;
                BlendFuncSource = (byte)BlendFunc.SourceAlpha;
                BlendFuncDest   = (byte)BlendFunc.OneMinusSourceAlpha;

                CRC               = PartFlags = 0;
                Pattern           = SourcePattern.None;
                MaxAge            = StartAge = InnerAngle = OuterAngle = BurstRate = BurstRadius = BurstSpeedMin =
                    BurstSpeedMax = 0.0f;
                BurstPartCount    = 0;
                AngularVelocity   = PartAcceleration = Vector3.Zero;
                Texture           = Target = UUID.Zero;
                PartDataFlags     = ParticleDataFlags.None;
                PartMaxAge        = 0.0f;
                PartStartColor    = PartEndColor = Color4.Black;
                PartStartScaleX   = PartStartScaleY = PartEndScaleX = PartEndScaleY = 0.0f;

                int     size = data.Length - pos;
                BitPack pack = new BitPack(data, pos);

                if (size == LegacyDataBlockSize)
                {
                    UnpackSystem(ref pack);
                    UnpackLegacyData(ref pack);
                }
                else if (size > LegacyDataBlockSize && size <= MaxDataBlockSize)
                {
                    int sysSize = pack.UnpackInt();
                    if (sysSize != SysDataSize)
                    {
                        return;                         // unkown particle system data size
                    }
                    UnpackSystem(ref pack);
                    int dataSize = pack.UnpackInt();
                    UnpackLegacyData(ref pack);

                    if ((PartDataFlags & ParticleDataFlags.DataGlow) == ParticleDataFlags.DataGlow)
                    {
                        if (pack.Data.Length - pack.BytePos < 2)
                        {
                            return;
                        }
                        uint glow = pack.UnpackByte();
                        PartStartGlow = glow / 255f;
                        glow          = pack.UnpackByte();
                        PartEndGlow   = glow / 255f;
                    }

                    if ((PartDataFlags & ParticleDataFlags.DataBlend) == ParticleDataFlags.DataBlend)
                    {
                        if (pack.Data.Length - pack.BytePos < 2)
                        {
                            return;
                        }
                        BlendFuncSource = pack.UnpackByte();
                        BlendFuncDest   = pack.UnpackByte();
                    }
                }
            }
示例#26
0
            /// <summary>
            /// Decodes a byte[] array into a ParticleSystem Object
            /// </summary>
            /// <param name="data">ParticleSystem object</param>
            /// <param name="pos">Start position for BitPacker</param>
            public ParticleSystem(byte[] data, int pos)
            {
                // TODO: Not sure exactly how many bytes we need here, so partial
                // (truncated) data will cause an exception to be thrown
                if (data.Length > 0)
                {
                    BitPack pack = new BitPack(data, pos);

                    CRC = pack.UnpackUBits(32);
                    PartFlags = pack.UnpackUBits(32);
                    Pattern = (SourcePattern)pack.UnpackByte();
                    MaxAge = pack.UnpackFixed(false, 8, 8);
                    StartAge = pack.UnpackFixed(false, 8, 8);
                    InnerAngle = pack.UnpackFixed(false, 3, 5);
                    OuterAngle = pack.UnpackFixed(false, 3, 5);
                    BurstRate = pack.UnpackFixed(false, 8, 8);
                    BurstRadius = pack.UnpackFixed(false, 8, 8);
                    BurstSpeedMin = pack.UnpackFixed(false, 8, 8);
                    BurstSpeedMax = pack.UnpackFixed(false, 8, 8);
                    BurstPartCount = pack.UnpackByte();
                    float x = pack.UnpackFixed(true, 8, 7);
                    float y = pack.UnpackFixed(true, 8, 7);
                    float z = pack.UnpackFixed(true, 8, 7);
                    AngularVelocity = new Vector3(x, y, z);
                    x = pack.UnpackFixed(true, 8, 7);
                    y = pack.UnpackFixed(true, 8, 7);
                    z = pack.UnpackFixed(true, 8, 7);
                    PartAcceleration = new Vector3(x, y, z);
                    Texture = pack.UnpackUUID();
                    Target = pack.UnpackUUID();

                    PartDataFlags = (ParticleDataFlags)pack.UnpackUBits(32);
                    PartMaxAge = pack.UnpackFixed(false, 8, 8);
                    byte r = pack.UnpackByte();
                    byte g = pack.UnpackByte();
                    byte b = pack.UnpackByte();
                    byte a = pack.UnpackByte();
                    PartStartColor = new Color4(r, g, b, a);
                    r = pack.UnpackByte();
                    g = pack.UnpackByte();
                    b = pack.UnpackByte();
                    a = pack.UnpackByte();
                    PartEndColor = new Color4(r, g, b, a);
                    PartStartScaleX = pack.UnpackFixed(false, 3, 5);
                    PartStartScaleY = pack.UnpackFixed(false, 3, 5);
                    PartEndScaleX = pack.UnpackFixed(false, 3, 5);
                    PartEndScaleY = pack.UnpackFixed(false, 3, 5);
                }
                else
                {
                    CRC = PartFlags = 0;
                    Pattern = SourcePattern.None;
                    MaxAge = StartAge = InnerAngle = OuterAngle = BurstRate = BurstRadius = BurstSpeedMin =
                        BurstSpeedMax = 0.0f;
                    BurstPartCount = 0;
                    AngularVelocity = PartAcceleration = Vector3.Zero;
                    Texture = Target = UUID.Zero;
                    PartDataFlags = ParticleDataFlags.None;
                    PartMaxAge = 0.0f;
                    PartStartColor = PartEndColor = Color4.Black;
                    PartStartScaleX = PartStartScaleY = PartEndScaleX = PartEndScaleY = 0.0f;
                }
            }
示例#27
0
        // Unused: left for historical reference.
        public static void CreatePatch(BitPack output, float[] patchData, int x, int y, int pRegionSizeX, int pRegionSizeY)
        {
            TerrainPatch.Header header = PrescanPatch(patchData);
            header.QuantWBits = 136;
            if (pRegionSizeX > Constants.RegionSize || pRegionSizeY > Constants.RegionSize)
            {
                header.PatchIDs = (y & 0xFFFF);
                header.PatchIDs += (x << 16);
            }
            else
            {
                header.PatchIDs = (y & 0x1F);
                header.PatchIDs += (x << 5);
            }

            // NOTE: No idea what prequant and postquant should be or what they do

            int wbits;
            int[] patch = CompressPatch(patchData, header, 10, out wbits);
            wbits = EncodePatchHeader(output, header, patch, Constants.RegionSize, Constants.RegionSize, wbits);
            EncodePatch(output, patch, 0, wbits);
        }
示例#28
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++;

                if (OnLandPatch != null)
                {
                    try { OnLandPatch(simulator, x, y, group.PatchSize, heightmap); }
                    catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); }
                }

                if (Client.Settings.STORE_LAND_PATCHES)
                {
                    lock (SimPatches)
                    {
                        if (!SimPatches.ContainsKey(simulator.Handle))
                        {
                            SimPatches.Add(simulator.Handle, new TerrainPatch[16 * 16]);
                        }

                        TerrainPatch patch = new TerrainPatch();
                        patch.Data = heightmap;
                        patch.X    = x;
                        patch.Y    = y;

                        SimPatches[simulator.Handle][y * 16 + x] = patch;
                    }
                }
            }
        }
示例#29
0
        public static TerrainPatch.Header DecodePatchHeader(BitPack bitpack)
        {
            TerrainPatch.Header header = new TerrainPatch.Header {QuantWBits = bitpack.UnpackBits(8)};

            // Quantized word bits
            if (header.QuantWBits == END_OF_PATCHES)
                return header;

            // DC offset
            header.DCOffset = bitpack.UnpackFloat();

            // Range
            header.Range = bitpack.UnpackBits(16);

            // Patch IDs (10 bits)
            header.PatchIDs = bitpack.UnpackBits(10);

            // Word bits
            header.WordBits = (uint) ((header.QuantWBits & 0x0f) + 2);

            return header;
        }
示例#30
0
        /// <summary>
        /// Add a patch of terrain to a BitPacker
        /// </summary>
        /// <param name="output">BitPacker to write the patch to</param>
        /// <param name="heightmap">Heightmap of the simulator, must be a 256 *
        /// 256 float array</param>
        /// <param name="x">X offset of the patch to create, valid values are
        /// from 0 to 15</param>
        /// <param name="y">Y offset of the patch to create, valid values are
        /// from 0 to 15</param>
        public static void CreatePatchFromHeightmap(BitPack output, float[] heightmap, int x, int y)
        {
            if (heightmap.Length != 256 * 256)
                throw new ArgumentException("Heightmap data must be 256x256");

            if (x < 0 || x > 15 || y < 0 || y > 15)
                throw new ArgumentException("X and Y patch offsets must be from 0 to 15");

            TerrainPatch.Header header = PrescanPatch(heightmap, x, y);
            header.QuantWBits = 136;
            header.PatchIDs = (y & 0x1F);
            header.PatchIDs += (x << 5);

            // NOTE: No idea what prequant and postquant should be or what they do
            int[] patch = CompressPatch(heightmap, x, y, header, 10);
            int wbits = EncodePatchHeader(output, header, patch);
            EncodePatch(output, patch, 0, wbits);
        }
示例#31
0
 public static void DecodePatch(int[] patches, BitPack bitpack, TerrainPatch.Header header, int size)
 {
     for (int n = 0; n < size*size; n++)
     {
         // ?
         int temp = bitpack.UnpackBits(1);
         if (temp != 0)
         {
             // Value or EOB
             temp = bitpack.UnpackBits(1);
             if (temp != 0)
             {
                 // Value
                 temp = bitpack.UnpackBits(1);
                 if (temp != 0)
                 {
                     // Negative
                     temp = bitpack.UnpackBits((int) header.WordBits);
                     patches[n] = temp*-1;
                 }
                 else
                 {
                     // Positive
                     temp = bitpack.UnpackBits((int) header.WordBits);
                     patches[n] = temp;
                 }
             }
             else
             {
                 // Set the rest to zero
                 // TODO: This might not be necessary
                 for (int o = n; o < size*size; o++)
                 {
                     patches[o] = 0;
                 }
                 break;
             }
         }
         else
         {
             patches[n] = 0;
         }
     }
 }
示例#32
0
        private static int EncodePatchHeader(BitPack output, TerrainPatch.Header header, int[] patch)
        {
            int temp;
            int wbits = (header.QuantWBits & 0x0f) + 2;
            uint maxWbits = (uint)wbits + 5;
            uint minWbits = ((uint)wbits >> 1);

            wbits = (int)minWbits;

            for (int i = 0; i < patch.Length; i++)
            {
                temp = patch[i];

                if (temp != 0)
                {
                    // Get the absolute value
                    if (temp < 0) temp *= -1;

                    for (int j = (int)maxWbits; j > (int)minWbits; j--)
                    {
                        if ((temp & (1 << j)) != 0)
                        {
                            if (j > wbits) wbits = j;
                            break;
                        }
                    }
                }
            }

            wbits += 1;

            header.QuantWBits &= 0xf0;

            if (wbits > 17 || wbits < 2)
            {
                Logger.Log("Bits needed per word in EncodePatchHeader() are outside the allowed range",
                    Helpers.LogLevel.Error);
            }

            header.QuantWBits |= (wbits - 2);

            output.PackBits(header.QuantWBits, 8);
            output.PackFloat(header.DCOffset);
            output.PackBits(header.Range, 16);
            output.PackBits(header.PatchIDs, 10);

            return wbits;
        }
示例#33
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;
        }
        private static void EncodePatch(BitPack output, int[] patch, int postquant, int wbits)
        {
            int  temp;
            bool eob;

            if (postquant > 16 * 16 || postquant < 0)
            {
                Logger.Log("Postquant is outside the range of allowed values in EncodePatch()", Helpers.LogLevel.Error);
                return;
            }

            if (postquant != 0)
            {
                patch[16 * 16 - postquant] = 0;
            }

            for (int i = 0; i < 16 * 16; i++)
            {
                eob  = false;
                temp = patch[i];

                if (temp == 0)
                {
                    eob = true;

                    for (int j = i; j < 16 * 16 - postquant; j++)
                    {
                        if (patch[j] != 0)
                        {
                            eob = false;
                            break;
                        }
                    }

                    if (eob)
                    {
                        output.PackBits(ZERO_EOB, 2);
                        return;
                    }
                    else
                    {
                        output.PackBits(ZERO_CODE, 1);
                    }
                }
                else
                {
                    if (temp < 0)
                    {
                        temp *= -1;

                        if (temp > (1 << wbits))
                        {
                            temp = (1 << wbits);
                        }

                        output.PackBits(NEGATIVE_VALUE, 3);
                        output.PackBits(temp, wbits);
                    }
                    else
                    {
                        if (temp > (1 << wbits))
                        {
                            temp = (1 << wbits);
                        }

                        output.PackBits(POSITIVE_VALUE, 3);
                        output.PackBits(temp, wbits);
                    }
                }
            }
        }
示例#35
0
            /// <summary>
            /// Generate byte[] array from particle data
            /// </summary>
            /// <returns>Byte array</returns>
            public byte[] GetBytes()
            {
                byte[] bytes = new byte[86];
                BitPack pack = new BitPack(bytes, 0);

                pack.PackBits(CRC, 32);
                pack.PackBits((uint)PartFlags, 32);
                pack.PackBits((uint)Pattern, 8);
                pack.PackFixed(MaxAge, false, 8, 8);
                pack.PackFixed(StartAge, false, 8, 8);
                pack.PackFixed(InnerAngle, false, 3, 5);
                pack.PackFixed(OuterAngle, false, 3, 5);
                pack.PackFixed(BurstRate, false, 8, 8);
                pack.PackFixed(BurstRadius, false, 8, 8);
                pack.PackFixed(BurstSpeedMin, false, 8, 8);
                pack.PackFixed(BurstSpeedMax, false, 8, 8);
                pack.PackBits(BurstPartCount, 8);
                pack.PackFixed(AngularVelocity.X, true, 8, 7);
                pack.PackFixed(AngularVelocity.Y, true, 8, 7);
                pack.PackFixed(AngularVelocity.Z, true, 8, 7);
                pack.PackFixed(PartAcceleration.X, true, 8, 7);
                pack.PackFixed(PartAcceleration.Y, true, 8, 7);
                pack.PackFixed(PartAcceleration.Z, true, 8, 7);
                pack.PackUUID(Texture);
                pack.PackUUID(Target);

                pack.PackBits((uint)PartDataFlags, 32);
                pack.PackFixed(PartMaxAge, false, 8, 8);
                pack.PackColor(PartStartColor);
                pack.PackColor(PartEndColor);
                pack.PackFixed(PartStartScaleX, false, 3, 5);
                pack.PackFixed(PartStartScaleY, false, 3, 5);
                pack.PackFixed(PartEndScaleX, false, 3, 5);
                pack.PackFixed(PartEndScaleY, false, 3, 5);

                return bytes;
            }
示例#36
0
        public static void CreatePatch(BitPack output, float[,] patchData, int x, int y)
        {
            if (patchData.Length != 16 * 16)
                throw new ArgumentException("Patch data must be a 16x16 array");

            TerrainPatch.Header header = PrescanPatch(patchData);
            header.QuantWBits = 136;
            header.PatchIDs = (y & 0x1F);
            header.PatchIDs += (x << 5);

            // NOTE: No idea what prequant and postquant should be or what they do
            int[] patch = CompressPatch(patchData, header, 10);
            int wbits = EncodePatchHeader(output, header, patch);
            EncodePatch(output, patch, 0, wbits);
        }