function getPositions(featureTable, instancesLength) {
  if (featureTable.hasProperty("POSITION")) {
    // Handle positions.
    return featureTable.getPropertyArray(
      "POSITION",
      ComponentDatatype.FLOAT,
      3,
    );
  } else if (featureTable.hasProperty("POSITION_QUANTIZED")) {
    // Handle quantized positions.
    const quantizedPositions = featureTable.getPropertyArray(
      "POSITION_QUANTIZED",
      ComponentDatatype.UNSIGNED_SHORT,
      3,
    );

    const quantizedVolumeOffset = featureTable.getGlobalProperty(
      "QUANTIZED_VOLUME_OFFSET",
      ComponentDatatype.FLOAT,
      3,
    );
    if (!defined(quantizedVolumeOffset)) {
      throw new RuntimeError(
        "Global property: QUANTIZED_VOLUME_OFFSET must be defined for quantized positions.",
      );
    }

    const quantizedVolumeScale = featureTable.getGlobalProperty(
      "QUANTIZED_VOLUME_SCALE",
      ComponentDatatype.FLOAT,
      3,
    );
    if (!defined(quantizedVolumeScale)) {
      throw new RuntimeError(
        "Global property: QUANTIZED_VOLUME_SCALE must be defined for quantized positions.",
      );
    }

    const decodedPositions = new Float32Array(quantizedPositions.length);
    for (let i = 0; i < quantizedPositions.length / 3; i++) {
      for (let j = 0; j < 3; j++) {
        const index = 3 * i + j;
        decodedPositions[index] =
          (quantizedPositions[index] / 65535.0) * quantizedVolumeScale[j] +
          quantizedVolumeOffset[j];
      }
    }

    return decodedPositions;

    // eslint-disable-next-line no-else-return
  } else {
    throw new RuntimeError(
      "Either POSITION or POSITION_QUANTIZED must be defined for each instance.",
    );
  }
}
Returns a typed array of positions from the i3dm's feature table. The positions
returned are dequantized, if dequantization is applied.

@private