Пример #1
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;
         }
     }
 }
Пример #2
0
        private static int[] CompressPatch(float[] patchData, TerrainPatch.Header header, int prequant, out int wbits)
        {
            float[] block    = new float[Constants.TerrainPatchSize * Constants.TerrainPatchSize];
            int     wordsize = (prequant - 2) & 0x0f;
            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;
            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] * 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);
        }
Пример #3
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, 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);
        }
        // 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);
        }
Пример #5
0
        private static TerrainPatch.Header PrescanPatch(float[] patch)
        {
            TerrainPatch.Header header = new TerrainPatch.Header();
            float zmax = -99999999.0f;
            float zmin = 99999999.0f;

            for (int i = 0; i < Constants.TerrainPatchSize * Constants.TerrainPatchSize; i++)
            {
                float val = patch[i];
                if (val > zmax)
                {
                    zmax = val;
                }
                if (val < zmin)
                {
                    zmin = val;
                }
            }

            header.DCOffset = zmin;
            header.Range    = (int)((zmax - zmin) + 1.0f);

            return(header);
        }
Пример #6
0
        private static int[] CompressPatch(short[] 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;

            premult /= Constants.TerrainCompression; // put here short to float factor

            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);
        }
Пример #7
0
        private static int EncodePatchHeader(BitPack output, TerrainPatch.Header header, int[] patch, int RegionSizeX,
                                             int RegionSizeY, 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 (RegionSizeX > Constants.RegionSize || RegionSizeY > Constants.RegionSize)
            {
                output.PackBits(header.PatchIDs, 32);
            }
            else
            {
                output.PackBits(header.PatchIDs, 10);
            }

            return(wbits);
        }
        private static int[] CompressPatch(HeightMapTerrainData 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);
        }