Exemplo n.º 1
0
            /// <summary>
            /// 
            /// </summary>
            /// <returns></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(MaxAge, 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;
            }
Exemplo n.º 2
0
        private void LayerDataHandler(Packet packet, Simulator simulator)
        {
            LayerDataPacket layer = (LayerDataPacket)packet;
            BitPack bitpack = new BitPack(layer.LayerData.Data, 0);
            GroupHeader header = new GroupHeader();
            LayerType type = (LayerType)layer.LayerID.Type;

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

            switch (type)
            {
                case LayerType.Land:
                    if (OnLandPatch != null || Client.Settings.STORE_LAND_PATCHES)
                        DecompressLand(simulator, bitpack, header);
                    break;
                case LayerType.Water:
                    Logger.Log("Got a Water LayerData packet, implement me!", Helpers.LogLevel.Error, Client);
                    break;
                case LayerType.Wind:
                    DecompressWind(simulator, bitpack, header);
                    break;
                case LayerType.Cloud:
                    DecompressCloud(simulator, bitpack, header);
                    break;
                default:
                    Logger.Log("Unrecognized LayerData type " + type.ToString(), Helpers.LogLevel.Warning, Client);
                    break;
            }
        }
Exemplo n.º 3
0
            /// <summary>
            /// 
            /// </summary>
            /// <param name="data"></param>
            /// <param name="pos"></param>
            public ParticleSystem(byte[] data, int pos)
            {
                // TODO: Not sure exactly how many bytes we need here, so partial 
                // (but 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 LLVector3(x, y, z);
                    x = pack.UnpackFixed(true, 8, 7);
                    y = pack.UnpackFixed(true, 8, 7);
                    z = pack.UnpackFixed(true, 8, 7);
                    PartAcceleration = new LLVector3(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 LLColor(r, g, b, a);
                    r = pack.UnpackByte();
                    g = pack.UnpackByte();
                    b = pack.UnpackByte();
                    a = pack.UnpackByte();
                    PartEndColor = new LLColor(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 = LLVector3.Zero;
                    Texture = Target = LLUUID.Zero;
                    PartDataFlags = ParticleDataFlags.None;
                    PartMaxAge = 0.0f;
                    PartStartColor = PartEndColor = LLColor.Black;
                    PartStartScaleX = PartStartScaleY = PartEndScaleX = PartEndScaleY = 0.0f;
                }
            }
Exemplo n.º 4
0
        private void DecompressLand(Simulator simulator, BitPack bitpack, GroupHeader group)
        {
            int x;
            int y;
            int[] patches = new int[32 * 32];
            int count = 0;

            while (true)
            {
                PatchHeader header = DecodePatchHeader(bitpack);

                if (header.QuantWBits == END_OF_PATCHES)
                    break;

                x = header.PatchIDs >> 5;
                y = header.PatchIDs & 0x1F;

                if (x >= PATCHES_PER_EDGE || y >= PATCHES_PER_EDGE)
                {
                    Logger.Log("Invalid LayerData land packet, x = " + x + ", y = " + y + ", dc_offset = " +
                        header.DCOffset + ", range = " + header.Range + ", quant_wbits = " + header.QuantWBits +
                        ", patchids = " + header.PatchIDs + ", count = " + count, Helpers.LogLevel.Warning, Client);
                    return;
                }

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

                // Decompress this patch
                float[] heightmap = 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 Patch[16 * 16]);

                        SimPatches[simulator.Handle][y * 16 + x] = new Patch();
                        SimPatches[simulator.Handle][y * 16 + x].Heightmap = heightmap;
                    }
                }
            }
        }
Exemplo n.º 5
0
 private void DecompressCloud(Simulator simulator, BitPack bitpack, GroupHeader group)
 {
     ;
 }
Exemplo n.º 6
0
 private void DecodePatch(int[] patches, BitPack bitpack, PatchHeader header, int size)
 {
     int temp;
     for (int n = 0; n < size * size; n++)
     {
         // ?
         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;
         }
     }
 }
Exemplo n.º 7
0
        private 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, Client);
                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);
                    }
                }
            }
        }
Exemplo n.º 8
0
        private PatchHeader DecodePatchHeader(BitPack bitpack)
        {
            PatchHeader header = new PatchHeader();

            // Quantized word bits
            header.QuantWBits = bitpack.UnpackBits(8);
            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;
        }
Exemplo n.º 9
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="output"></param>
        /// <param name="header"></param>
        /// <param name="patch"></param>
        /// <returns>wbits</returns>
        private int EncodePatchHeader(BitPack output, PatchHeader 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, Client);
            }

            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;
        }
Exemplo n.º 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, 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 void CreatePatch(BitPack output, float[] heightmap, int x, int y)
        {
            if (heightmap.Length != 256 * 256)
            {
                Logger.Log("Invalid heightmap value of " + heightmap.Length + " passed to CreatePatch()",
                    Helpers.LogLevel.Error, Client);
                return;
            }

            if (x < 0 || x > 15 || y < 0 || y > 15)
            {
                Logger.Log("Invalid x or y patch offset passed to CreatePatch(), x=" + x + ", y=" + y,
                    Helpers.LogLevel.Error, Client);
                return;
            }

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

            // TODO: What is prequant?
            int[] patch = CompressPatch(heightmap, x, y, header, 10);
            int wbits = EncodePatchHeader(output, header, patch);
            // TODO: What is postquant?
            EncodePatch(output, patch, 0, wbits);
        }
Exemplo n.º 11
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 LayerDataPacket CreateLandPacket(float[] heightmap, int[] patches)
        {
            LayerDataPacket layer = new LayerDataPacket();
            layer.LayerID.Type = (byte)LayerType.Land;

            GroupHeader header = new GroupHeader();
            header.Stride = STRIDE;
            header.PatchSize = 16;
            header.Type = 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;
        }
Exemplo n.º 12
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");
        }
Exemplo n.º 13
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");
        }
Exemplo n.º 14
0
            /// <summary>
            ///
            /// </summary>
            /// <param name="data"></param>
            /// <param name="pos"></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 LLVector3(x, y, z);
                    x = pack.UnpackFixed(true, 8, 7);
                    y = pack.UnpackFixed(true, 8, 7);
                    z = pack.UnpackFixed(true, 8, 7);
                    PartAcceleration = new LLVector3(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 LLColor(r, g, b, a);
                    r               = pack.UnpackByte();
                    g               = pack.UnpackByte();
                    b               = pack.UnpackByte();
                    a               = pack.UnpackByte();
                    PartEndColor    = new LLColor(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 = LLVector3.Zero;
                    Texture           = Target = LLUUID.Zero;
                    PartDataFlags     = ParticleDataFlags.None;
                    PartMaxAge        = 0.0f;
                    PartStartColor    = PartEndColor = LLColor.Black;
                    PartStartScaleX   = PartStartScaleY = PartEndScaleX = PartEndScaleY = 0.0f;
                }
            }