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; foreach (int t in patch) { temp = t; if (temp == 0) { continue; } // 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); }
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"); }
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; }
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; }
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; }
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); }
public static void CreatePatchFromTerrainData(BitPack output, TerrainData terrData, int patchX, int patchY) { float frange; TerrainPatch.Header header = PrescanPatch(terrData, patchX, patchY, out frange); header.QuantWBits = 130; bool largeRegion = false; // 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); largeRegion = true; } else { header.PatchIDs = (patchY & 0x1F); header.PatchIDs += (patchX << 5); } if (Math.Round((double)frange, 2) == 1.0) { // flat terrain speed up things header.DCOffset -= 0.5f; header.QuantWBits = 0x00; output.PackBits(header.QuantWBits, 8); output.PackFloat(header.DCOffset); output.PackBits(1, 16); if (largeRegion) output.PackBits(header.PatchIDs, 32); else output.PackBits(header.PatchIDs, 10); // and thats all output.PackBits(ZERO_EOB, 2); return; } int wbits; int[] patch = CompressPatch(terrData, patchX, patchY, header, 10, out wbits); EncodePatchHeader(output, header, patch, largeRegion, ref wbits); EncodePatch(output, patch, 0, wbits); }
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; }