All files / engine/Source/Scene ImplicitAvailabilityBitstream.js

100% Statements 35/35
100% Branches 16/16
100% Functions 5/5
100% Lines 34/34

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135                                            536x 536x     536x     535x 535x   535x   295x   240x 240x 1x               239x 239x 22x       534x 534x 534x 534x                       22x 22x 115x 115x 115x   22x     1x                       5867x                           432x                         1x   20415x 2x       20413x 18636x       1777x 1777x   1777x        
import Check from "../Core/Check.js";
import defined from "../Core/defined.js";
import DeveloperError from "../Core/DeveloperError.js";
import RuntimeError from "../Core/RuntimeError.js";
 
/**
 * An availability bitstream for use in an {@link ImplicitSubtree}. This handles
 * both Uint8Array bitstreams and constant values.
 *
 * @alias ImplicitAvailabilityBitstream
 * @constructor
 *
 * @param {object} options An object with the following properties:
 * @param {number} options.lengthBits The length of the bitstream in bits
 * @param {boolean} [options.constant] A single boolean value indicating the value of all the bits in the bitstream if they are all the same
 * @param {Uint8Array} [options.bitstream] An array of bytes storing the bitstream in binary
 * @param {number} [options.availableCount] A number indicating how many 1 bits are found in the bitstream
 * @param {boolean} [options.computeAvailableCountEnabled=false] If true, and options.availableCount is undefined, the availableCount will be computed from the bitstream.
 * @private
 * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy.
 */
function ImplicitAvailabilityBitstream(options) {
  const lengthBits = options.lengthBits;
  let availableCount = options.availableCount;
 
  //>>includeStart('debug', pragmas.debug);
  Check.typeOf.number("options.lengthBits", lengthBits);
  //>>includeEnd('debug');
 
  const constant = options.constant;
  const bitstream = options.bitstream;
 
  if (defined(constant)) {
    // if defined, constant must be 1 which means all tiles are available
    availableCount = lengthBits;
  } else {
    const expectedLength = Math.ceil(lengthBits / 8);
    if (bitstream.length !== expectedLength) {
      throw new RuntimeError(
        `Availability bitstream must be exactly ${expectedLength} bytes long to store ${lengthBits} bits. Actual bitstream was ${bitstream.length} bytes long.`,
      );
    }
 
    // Only compute the available count if requested, as this involves looping
    // over the bitstream.
    const computeAvailableCountEnabled =
      options.computeAvailableCountEnabled ?? false;
    if (!defined(availableCount) && computeAvailableCountEnabled) {
      availableCount = count1Bits(bitstream, lengthBits);
    }
  }
 
  this._lengthBits = lengthBits;
  this._availableCount = availableCount;
  this._constant = constant;
  this._bitstream = bitstream;
}
 
/**
 * Count the number of bits with value 1 in the bitstream. This is used for
 * computing availableCount if not precomputed
 *
 * @param {Uint8Array} bitstream The bitstream typed array
 * @param {number} lengthBits How many bits are in the bitstream
 * @private
 */
function count1Bits(bitstream, lengthBits) {
  let count = 0;
  for (let i = 0; i < lengthBits; i++) {
    const byteIndex = i >> 3;
    const bitIndex = i % 8;
    count += (bitstream[byteIndex] >> bitIndex) & 1;
  }
  return count;
}
 
Object.defineProperties(ImplicitAvailabilityBitstream.prototype, {
  /**
   * The length of the bitstream in bits.
   *
   * @memberof ImplicitAvailabilityBitstream.prototype
   *
   * @type {number}
   * @readonly
   * @private
   */
  lengthBits: {
    get: function () {
      return this._lengthBits;
    },
  },
  /**
   * The number of bits in the bitstream with value <code>1</code>.
   *
   * @memberof ImplicitAvailabilityBitstream.prototype
   *
   * @type {number}
   * @readonly
   * @private
   */
  availableCount: {
    get: function () {
      return this._availableCount;
    },
  },
});
 
/**
 * Get a bit from the availability bitstream as a Boolean. If the bitstream
 * is a constant, the constant value is returned instead.
 *
 * @param {number} index The integer index of the bit.
 * @returns {boolean} The value of the bit
 * @private
 */
ImplicitAvailabilityBitstream.prototype.getBit = function (index) {
  //>>includeStart('debug', pragmas.debug);
  if (index < 0 || index >= this._lengthBits) {
    throw new DeveloperError("Bit index out of bounds.");
  }
  //>>includeEnd('debug');
 
  if (defined(this._constant)) {
    return this._constant;
  }
 
  // byteIndex is floor(index / 8)
  const byteIndex = index >> 3;
  const bitIndex = index % 8;
 
  return ((this._bitstream[byteIndex] >> bitIndex) & 1) === 1;
};
 
export default ImplicitAvailabilityBitstream;