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
        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;
        }
示例#3
0
        // Used to send cloud and wind patches
        public static LayerDataPacket CreateLayerDataPacket(TerrainPatch[] patches, byte type, int pRegionSizeX,
                                                            int pRegionSizeY)
        {
            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, pRegionSizeX, pRegionSizeY);

            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
        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;
                }
            }
        }
示例#5
0
        /// <summary>
        /// Retrieve the terrain height at a given coordinate
        /// </summary>
        /// <param name="x">Sim X coordinate, valid range is from 0 to 255</param>
        /// <param name="y">Sim Y coordinate, valid range is from 0 to 255</param>
        /// <param name="height">The terrain height at the given point if the
        /// lookup was successful, otherwise 0.0f</param>
        /// <returns>True if the lookup was successful, otherwise false</returns>
        public bool TerrainHeightAtPoint(int x, int y, out float height)
        {
            if (Terrain != null && x >= 0 && x < 256 && y >= 0 && y < 256)
            {
                int patchX = x / 16;
                int patchY = y / 16;
                x = x % 16;
                y = y % 16;

                TerrainPatch patch = Terrain[patchY * 16 + patchX];
                if (patch != null)
                {
                    height = patch.Data[y * 16 + x];
                    return(true);
                }
            }

            height = 0.0f;
            return(false);
        }
        static float[,] GetHeightMap(TerrainPatch[] Terrain)
        {
            float average = 23;
            float[,] height = new float[256, 256];
            for (int x = 0; x < 256; x++)
            {
                for (int y = 0; y < 256; y++)
                {
                    int patchX = x / 16;
                    int patchY = y / 16;

                    TerrainPatch patch = Terrain[patchY * 16 + patchX];
                    if (patch != null)
                    {
                        height[x, y] = average = patch.Data[(y % 16) * 16 + (x % 16)];
                    }
                    else
                    {
                        height[x, y] = average;
                    }
                }
            }
            return height;
        }
示例#7
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;
        }
示例#8
0
        private static int[] CompressPatch(float[] heightmap, int patchX, int patchY, TerrainPatch.Header header, int prequant)
        {
            float[] block = new float[16 * 16];
            int wordsize = prequant;
            float oozrange = 1.0f / (float)header.Range;
            float range = (float)(1 << prequant);
            float premult = oozrange * range;
            float sub = (float)(1 << (prequant - 1)) + header.DCOffset * premult;

            header.QuantWBits = wordsize - 2;
            header.QuantWBits |= (prequant - 2) << 4;

            int k = 0;
            for (int j = patchY * 16; j < (patchY + 1) * 16; j++)
            {
                for (int i = patchX * 16; i < (patchX + 1) * 16; i++)
                    block[k++] = heightmap[j * 256 + i] * premult - sub;
            }

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

            for (int o = 0; o < 16; o++)
                DCTLine16(block, ftemp, o);
            for (int o = 0; o < 16; o++)
                DCTColumn16(ftemp, itemp, o);

            return itemp;
        }
示例#9
0
        private static int[] CompressPatch(TerrainData terrData, int patchX, int patchY, TerrainPatch.Header header,
                                                               int prequant, out int wbits)
        {
            float[] block = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize];
            int[] iout = new int[Constants.TerrainPatchSize * Constants.TerrainPatchSize];

            float oozrange = 1.0f / header.Range;
            float invprequat = (1 << prequant);
            float premult = oozrange * invprequat;

            float sub = 0.5f * header.Range + header.DCOffset;

            int wordsize = (prequant - 2) & 0x0f;
            header.QuantWBits = wordsize;
            header.QuantWBits |= wordsize << 4;

            int k = 0;
            int startX = patchX * Constants.TerrainPatchSize;
            int startY = patchY * Constants.TerrainPatchSize;
            for (int y = startY; y < startY + Constants.TerrainPatchSize; y++)
            {
                for (int x = startX; x < startX + Constants.TerrainPatchSize; x++)
                {
                    block[k++] = (terrData[x, y] - sub) * premult;
                }
            }
 
            wbits = (prequant >> 1);

            dct16x16(block, iout, ref wbits);

            return iout;
        }
示例#10
0
 private void DecompressCloud(Simulator simulator, BitPack bitpack, TerrainPatch.GroupHeader group)
 {
     // FIXME:
 }
示例#11
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;
        }
示例#12
0
        private static int[] CompressPatch(TerrainData terrData, int patchX, int patchY, TerrainPatch.Header header,
                                                               int prequant, out int wbits)
        {
            float[] block = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
            int wordsize = prequant;
            float oozrange = 1.0f/header.Range;
            float range = (1 << prequant);
            float premult = oozrange*range;
            float sub = (1 << (prequant - 1)) + header.DCOffset*premult;

            header.QuantWBits = wordsize - 2;
            header.QuantWBits |= (prequant - 2) << 4;

            int k = 0;

            int yPatchLimit = patchY >= (terrData.SizeY / Constants.TerrainPatchSize) ?
                            (terrData.SizeY - Constants.TerrainPatchSize) / Constants.TerrainPatchSize : patchY;
            yPatchLimit = (yPatchLimit + 1) * Constants.TerrainPatchSize;

            int xPatchLimit = patchX >= (terrData.SizeX / Constants.TerrainPatchSize) ?
                            (terrData.SizeX - Constants.TerrainPatchSize) / Constants.TerrainPatchSize : patchX;
            xPatchLimit = (xPatchLimit + 1) * Constants.TerrainPatchSize;

            for (int yy = patchY * Constants.TerrainPatchSize; yy < yPatchLimit; yy++)
            {
                for (int xx = patchX * Constants.TerrainPatchSize; xx < xPatchLimit; xx++)
                {
                    block[k++] = terrData[xx, yy] * premult - sub;
                }
            }

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

            int maxWbits = prequant + 5;
            wbits = (prequant >> 1);

            for (int o = 0; o < Constants.TerrainPatchSize; o++)
                DCTLine16(block, ftemp, o);
            for (int o = 0; o < Constants.TerrainPatchSize; o++)
                wbits = DCTColumn16Wbits(ftemp, itemp, o, wbits, maxWbits);

            return itemp;
        }
示例#13
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.PatchIDs >> 5;
                y = header.PatchIDs & 0x1F;

                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]);

                        SimPatches[simulator.Handle][y * 16 + x] = new TerrainPatch();
                        SimPatches[simulator.Handle][y * 16 + x].Heightmap = heightmap;
                    }
                }
            }
        }
示例#14
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;
        }
示例#15
0
        public void SendLayerData(int[] x, int[] y, float[] map, TerrainPatch.LayerType type)
        {

        }
示例#16
0
 private void DecompressWind(Simulator simulator, BitPack bitpack, TerrainPatch.GroupHeader group)
 {
     ;
 }
        private void UpdateHeightMap(RegionContextBase reg)
        {
            int stride  = TerrainPatchStride;
            int stride2 = stride * TerrainPatchWidth;

            lock (this) {
                float[,] newHM = new float[TerrainPatchWidth, TerrainPatchLength];
                float minHeight = 999999f;
                float maxHeight = 0f;

                if ((reg == null) || !(reg is LLRegionContext))
                {
                    // things are not set up so create a default, flat heightmap
                    LogManager.Log.Log(LogLevel.DWORLDDETAIL,
                                       "LLTerrainInfo: Building default zero terrain");
                    CreateZeroHeight(ref newHM);
                    minHeight = maxHeight = 0f;
                }
                else
                {
                    try {
                        LLRegionContext llreg = (LLRegionContext)reg;
                        OMV.Simulator   sim   = llreg.Simulator;

                        int nullPatchCount = 0;
                        for (int px = 0; px < stride; px++)
                        {
                            for (int py = 0; py < stride; py++)
                            {
                                OMV.TerrainPatch pat = sim.Terrain[px + py * stride];
                                if (pat == null)
                                {
                                    // if no patch, it's all zeros
                                    if (0.0f < minHeight)
                                    {
                                        minHeight = 0.0f;
                                    }
                                    if (0.0f > maxHeight)
                                    {
                                        maxHeight = 0.0f;
                                    }
                                    for (int xx = 0; xx < stride; xx++)
                                    {
                                        for (int yy = 0; yy < stride; yy++)
                                        {
                                            // newHM[(py * stride + yy), (px * stride + xx)] = 0.0f;
                                            newHM[(px * stride + xx), (py * stride + yy)] = 0.0f;
                                        }
                                    }
                                    nullPatchCount++;
                                }
                                else
                                {
                                    for (int xx = 0; xx < stride; xx++)
                                    {
                                        for (int yy = 0; yy < stride; yy++)
                                        {
                                            float height = pat.Data[xx + yy * stride];
                                            // newHM[(py * stride + yy), (px * stride + xx)] = height;
                                            newHM[(px * stride + xx), (py * stride + yy)] = height;
                                            if (height < minHeight)
                                            {
                                                minHeight = height;
                                            }
                                            if (height > maxHeight)
                                            {
                                                maxHeight = height;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        // LogManager.Log.Log(LogLevel.DWORLDDETAIL,
                        //         "LLTerrainInfo: UpdateHeightMap: {0} null patches = {1}", sim.Name, nullPatchCount);
                    }
                    catch {
                        // this usually happens when first starting a region
                        LogManager.Log.Log(LogLevel.DWORLDDETAIL,
                                           "LLTerrainInfo: Exception building terrain. Defaulting to zero.");
                        CreateZeroHeight(ref newHM);
                        minHeight = maxHeight = 0f;
                    }
                }
                m_heightMap       = newHM;
                m_heightMapWidth  = TerrainPatchWidth; // X
                m_heightMapLength = TerrainPatchLength;
                m_minimumHeight   = minHeight;
                m_maximumHeight   = maxHeight;
                LogManager.Log.Log(LogLevel.DWORLDDETAIL,
                                   "LLTerrainInfo: New terrain:"
                                   + " min=" + m_minimumHeight.ToString()
                                   + " max=" + m_maximumHeight.ToString()
                                   );
            }
        }
示例#18
0
        private static int[] CompressPatch(float[] patchData, TerrainPatch.Header header, int prequant, out int wbits)
        {
            float[] block = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize];
            float oozrange = 1.0f / header.Range;
            float range = (1 << prequant);
            float premult = oozrange * range;


            float sub = 0.5f * header.Range + header.DCOffset;

            int wordsize = (prequant - 2) & 0x0f;
            header.QuantWBits = wordsize;
            header.QuantWBits |= wordsize << 4;

            int k = 0;
            for (int j = 0; j < Constants.TerrainPatchSize; j++)
            {
                for (int i = 0; i < Constants.TerrainPatchSize; i++)
                    block[k++] = (patchData[j * Constants.TerrainPatchSize + i] - sub) * premult;
            }

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

            wbits = (prequant >> 1);

            dct16x16(block, iout, ref wbits);

            return iout;
        }
示例#19
0
        void LoadTerrain(string mapFile)
        {
            byte[] rgbValues = new byte[256 * 256 * 3];

            if (File.Exists(mapFile))
            {
                lock (heightmap)
                {
                    Bitmap bmp = LoadTGAClass.LoadTGA(mapFile);

                    if (bmp.Width == 256 && bmp.Height == 256)
                    {
                        Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
                        BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                        Marshal.Copy(bmpData.Scan0, rgbValues, 0, rgbValues.Length);
                        bmp.UnlockBits(bmpData);
                    }
                    else
                    {
                        Logger.Log("Map file " + mapFile + " has the wrong dimensions or wrong pixel format (must be 256x256 RGB). Defaulting to 25m",
                            Helpers.LogLevel.Warning);
                        for (int i = 0; i < rgbValues.Length; i++)
                            rgbValues[i] = 25;
                    }
                }
            }
            else
            {
                Logger.Log("Map file " + mapFile + " not found, defaulting to 25m", Helpers.LogLevel.Info);
                for (int i = 0; i < rgbValues.Length; i++)
                    rgbValues[i] = 25;
            }

            uint patchX = 0, patchY = 0, x = 0, y = 0;
            for (int i = 0; i < rgbValues.Length; i += 3)
            {
                if (heightmap[patchY, patchX] == null)
                    heightmap[patchY, patchX] = new TerrainPatch(16, 16);

                heightmap[patchY, patchX].Height[y, x] = (float)rgbValues[i];

                ++x;
                if (x > 15)
                {
                    if (y == 15)
                    {
                        if (OnTerrainUpdate != null)
                            OnTerrainUpdate(this, patchX, patchY, heightmap[patchY, patchX].Height);
                    }

                    x = 0;
                    ++patchX;
                }

                if (patchX > 15)
                {
                    patchX = 0;
                    ++y;
                }

                if (y > 15)
                {
                    y = 0;
                    ++patchY;
                }
            }
        }
示例#20
0
        private static int[] CompressPatch(float[] patchData, TerrainPatch.Header header, int prequant)
        {
            float[] block = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize];
            int wordsize = prequant;
            float oozrange = 1.0f / (float)header.Range;
            float range = (float)(1 << prequant);
            float premult = oozrange * range;
            float sub = (float)(1 << (prequant - 1)) + header.DCOffset * premult;

            header.QuantWBits = wordsize - 2;
            header.QuantWBits |= (prequant - 2) << 4;

            int k = 0;
            for (int j = 0; j < Constants.TerrainPatchSize; j++)
            {
                for (int i = 0; i < Constants.TerrainPatchSize; i++)
                    block[k++] = patchData[j * Constants.TerrainPatchSize + i] * premult - sub;
            }

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

            for (int o = 0; o < Constants.TerrainPatchSize; o++)
                DCTLine16(block, ftemp, o);
            for (int o = 0; o < Constants.TerrainPatchSize; o++)
                DCTColumn16(ftemp, itemp, o);

            return itemp;
        }
示例#21
0
        private static int EncodePatchHeader(BitPack output, TerrainPatch.Header header, int[] patch, int RegionSizeX, int RegionSizeY)
        {
            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;

            header.QuantWBits |= (wbits - 2);

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

            return wbits;
        }
示例#22
0
        private static int[] CompressPatch(float[] heightmap, int patchX, int patchY, TerrainPatch.Header header,
                                           int prequant, int RegionSizeX, int RegionSizeY, out int wbits)
        {
            float[] block = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize];
            int wordsize = prequant;
            float oozrange = 1.0f / header.Range;
            float range = (1 << prequant);
            float premult = oozrange * range;
            float sub = (1 << (prequant - 1)) + header.DCOffset * premult;

            header.QuantWBits = wordsize - 2;
            header.QuantWBits |= (prequant - 2) << 4;

            int k = 0;

            for (int j = patchY * Constants.TerrainPatchSize;
                 j <
                 ((patchY >= (RegionSizeY / Constants.TerrainPatchSize)
                       ? (RegionSizeY - Constants.TerrainPatchSize) / Constants.TerrainPatchSize
                       : patchY) + 1) * Constants.TerrainPatchSize;
                 j++)
            {
                for (int i = patchX * Constants.TerrainPatchSize;
                     i <
                     ((patchX >= (RegionSizeX / Constants.TerrainPatchSize)
                           ? (RegionSizeX - Constants.TerrainPatchSize) / Constants.TerrainPatchSize
                           : patchX) + 1) * Constants.TerrainPatchSize;
                     i++)
                {
                    block[k++] = (heightmap[j * RegionSizeX + i]) * premult - sub;
                }
            }

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

            int maxWbits = prequant + 5;
            wbits = (prequant >> 1);

            for (int o = 0; o < Constants.TerrainPatchSize; o++)
                DCTLine16(block, ftemp, o);
            for (int o = 0; o < Constants.TerrainPatchSize; o++)
                wbits = DCTColumn16Wbits(ftemp, itemp, o, wbits, maxWbits);

            return itemp;
        }
示例#23
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]);
            }
        }
示例#24
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;
         }
     }
 }
示例#25
0
        private static int[] CompressPatch(float[] heightmap, int patchX, int patchY, TerrainPatch.Header header, int prequant, int RegionSizeX, int RegionSizeY)
        {
            float[] block = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize];
            int wordsize = prequant;
            float oozrange = 1.0f / (float)header.Range;
            float range = (float)(1 << prequant);
            float premult = oozrange * range;
            float sub = (float)(1 << (prequant - 1)) + header.DCOffset * premult;

            header.QuantWBits = wordsize - 2;
            header.QuantWBits |= (prequant - 2) << 4;

            int k = 0;
//            int sqrt = (int)Math.Sqrt(heightmap.Length);
            //OpenSim.Framework.Console.MainConsole.Instance.Output(sqrt + "," + patchX + "," + patchY + ","+
            //    patchX * Constants.TerrainPatchSize + "," + 
            //    ((patchX >= (RegionSizeX / Constants.TerrainPatchSize) ? (RegionSizeX - Constants.TerrainPatchSize) / Constants.TerrainPatchSize : patchX) + 1) * Constants.TerrainPatchSize + "," +
            //    patchY * Constants.TerrainPatchSize + "," +
            //    ((patchY >= (RegionSizeY / Constants.TerrainPatchSize) ? (RegionSizeY - Constants.TerrainPatchSize) / Constants.TerrainPatchSize : patchY) + 1) * Constants.TerrainPatchSize);

            for (int j = patchY * Constants.TerrainPatchSize; j < ((patchY >= (RegionSizeY / Constants.TerrainPatchSize) ? (RegionSizeY - Constants.TerrainPatchSize) / Constants.TerrainPatchSize : patchY) + 1) * Constants.TerrainPatchSize; j++)
            {
                for (int i = patchX * Constants.TerrainPatchSize; i < ((patchX >= (RegionSizeX / Constants.TerrainPatchSize) ? (RegionSizeX - Constants.TerrainPatchSize) / Constants.TerrainPatchSize : patchX) + 1) * Constants.TerrainPatchSize; i++)
//                    block[k++] = heightmap[j * sqrt + i] * premult - sub;
                    block[k++] = heightmap[j * RegionSizeX + i] * premult - sub;
            }

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

            for (int o = 0; o < Constants.TerrainPatchSize; o++)
                DCTLine16(block, ftemp, o);
            for (int o = 0; o < Constants.TerrainPatchSize; o++)
                DCTColumn16(ftemp, itemp, o);

            return itemp;
        }
示例#26
0
        private static int[] CompressPatch(float[,] patchData, TerrainPatch.Header header, int prequant, out int wbits)
        {
            float[] block = new float[Constants.TerrainPatchSize*Constants.TerrainPatchSize];
            float oozrange = 1.0f/header.Range;
            float range = (1 << prequant);
            float premult = oozrange*range;
            float sub = (1 << (prequant - 1)) + header.DCOffset*premult;
            int wordsize = (prequant - 2) & 0x0f;

            header.QuantWBits = wordsize;
            header.QuantWBits |= wordsize << 4;

            int k = 0;
            for (int j = 0; j < Constants.TerrainPatchSize; j++)
            {
                for (int i = 0; i < Constants.TerrainPatchSize; i++)
                    block[k++] = patchData[j, i]*premult - sub;
            }

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

            int maxWbits = prequant + 5;
            wbits = (prequant >> 1);

            for (int o = 0; o < Constants.TerrainPatchSize; o++)
                DCTLine16(block, ftemp, o);
            for (int o = 0; o < Constants.TerrainPatchSize; o++)
                wbits = DCTColumn16Wbits(ftemp, itemp, o, wbits, maxWbits);

            return itemp;
        }
示例#27
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;
        }
示例#29
0
        private static void EncodePatchHeader(BitPack output, TerrainPatch.Header header, int[] patch, bool largeRegion, ref int wbits)
        {
            if (wbits > 17)
                wbits = 17;
            else if (wbits < 2)
                wbits = 2;

            header.QuantWBits &= 0xf0;
            header.QuantWBits |= (wbits - 2);

            output.PackBits(header.QuantWBits, 8);
            output.PackFloat(header.DCOffset);
            output.PackBits(header.Range, 16);
            if (largeRegion)
                output.PackBits(header.PatchIDs, 32);
            else
                output.PackBits(header.PatchIDs, 10);
        }