function QuantizedMeshTerrainData(options) {
  //>>includeStart('debug', pragmas.debug)
  if (!defined(options) || !defined(options.quantizedVertices)) {
    throw new DeveloperError("options.quantizedVertices is required.");
  }
  if (!defined(options.indices)) {
    throw new DeveloperError("options.indices is required.");
  }
  if (!defined(options.minimumHeight)) {
    throw new DeveloperError("options.minimumHeight is required.");
  }
  if (!defined(options.maximumHeight)) {
    throw new DeveloperError("options.maximumHeight is required.");
  }
  if (!defined(options.maximumHeight)) {
    throw new DeveloperError("options.maximumHeight is required.");
  }
  if (!defined(options.boundingSphere)) {
    throw new DeveloperError("options.boundingSphere is required.");
  }
  if (!defined(options.horizonOcclusionPoint)) {
    throw new DeveloperError("options.horizonOcclusionPoint is required.");
  }
  if (!defined(options.westIndices)) {
    throw new DeveloperError("options.westIndices is required.");
  }
  if (!defined(options.southIndices)) {
    throw new DeveloperError("options.southIndices is required.");
  }
  if (!defined(options.eastIndices)) {
    throw new DeveloperError("options.eastIndices is required.");
  }
  if (!defined(options.northIndices)) {
    throw new DeveloperError("options.northIndices is required.");
  }
  if (!defined(options.westSkirtHeight)) {
    throw new DeveloperError("options.westSkirtHeight is required.");
  }
  if (!defined(options.southSkirtHeight)) {
    throw new DeveloperError("options.southSkirtHeight is required.");
  }
  if (!defined(options.eastSkirtHeight)) {
    throw new DeveloperError("options.eastSkirtHeight is required.");
  }
  if (!defined(options.northSkirtHeight)) {
    throw new DeveloperError("options.northSkirtHeight is required.");
  }
  //>>includeEnd('debug');

  this._quantizedVertices = options.quantizedVertices;
  this._encodedNormals = options.encodedNormals;
  this._indices = options.indices;
  this._minimumHeight = options.minimumHeight;
  this._maximumHeight = options.maximumHeight;
  this._boundingSphere = options.boundingSphere;
  this._orientedBoundingBox = options.orientedBoundingBox;
  this._horizonOcclusionPoint = options.horizonOcclusionPoint;
  this._credits = options.credits;

  const vertexCount = this._quantizedVertices.length / 3;
  const uValues = (this._uValues = this._quantizedVertices.subarray(
    0,
    vertexCount,
  ));
  const vValues = (this._vValues = this._quantizedVertices.subarray(
    vertexCount,
    2 * vertexCount,
  ));
  this._heightValues = this._quantizedVertices.subarray(
    2 * vertexCount,
    3 * vertexCount,
  );

  // We don't assume that we can count on the edge vertices being sorted by u or v.
  function sortByV(a, b) {
    return vValues[a] - vValues[b];
  }

  function sortByU(a, b) {
    return uValues[a] - uValues[b];
  }

  this._westIndices = sortIndicesIfNecessary(
    options.westIndices,
    sortByV,
    vertexCount,
  );
  this._southIndices = sortIndicesIfNecessary(
    options.southIndices,
    sortByU,
    vertexCount,
  );
  this._eastIndices = sortIndicesIfNecessary(
    options.eastIndices,
    sortByV,
    vertexCount,
  );
  this._northIndices = sortIndicesIfNecessary(
    options.northIndices,
    sortByU,
    vertexCount,
  );

  this._westSkirtHeight = options.westSkirtHeight;
  this._southSkirtHeight = options.southSkirtHeight;
  this._eastSkirtHeight = options.eastSkirtHeight;
  this._northSkirtHeight = options.northSkirtHeight;

  this._childTileMask = options.childTileMask ?? 15;

  this._createdByUpsampling = options.createdByUpsampling ?? false;
  this._waterMask = options.waterMask;

  this._mesh = undefined;
}
Terrain data for a single tile where the terrain data is represented as a quantized mesh.  A quantized
mesh consists of three vertex attributes, longitude, latitude, and height.  All attributes are expressed
as 16-bit values in the range 0 to 32767.  Longitude and latitude are zero at the southwest corner
of the tile and 32767 at the northeast corner.  Height is zero at the minimum height in the tile
and 32767 at the maximum height in the tile.

@alias QuantizedMeshTerrainData
@constructor

@param {object} options Object with the following properties:
@param {Uint16Array} options.quantizedVertices The buffer containing the quantized mesh.
@param {Uint16Array|Uint32Array} options.indices The indices specifying how the quantized vertices are linked
                     together into triangles.  Each three indices specifies one triangle.
@param {number} options.minimumHeight The minimum terrain height within the tile, in meters above the ellipsoid.
@param {number} options.maximumHeight The maximum terrain height within the tile, in meters above the ellipsoid.
@param {BoundingSphere} options.boundingSphere A sphere bounding all of the vertices in the mesh.
@param {OrientedBoundingBox} [options.orientedBoundingBox] An OrientedBoundingBox bounding all of the vertices in the mesh.
@param {Cartesian3} options.horizonOcclusionPoint The horizon occlusion point of the mesh.  If this point
                     is below the horizon, the entire tile is assumed to be below the horizon as well.
                     The point is expressed in ellipsoid-scaled coordinates.
@param {number[]} options.westIndices The indices of the vertices on the western edge of the tile.
@param {number[]} options.southIndices The indices of the vertices on the southern edge of the tile.
@param {number[]} options.eastIndices The indices of the vertices on the eastern edge of the tile.
@param {number[]} options.northIndices The indices of the vertices on the northern edge of the tile.
@param {number} options.westSkirtHeight The height of the skirt to add on the western edge of the tile.
@param {number} options.southSkirtHeight The height of the skirt to add on the southern edge of the tile.
@param {number} options.eastSkirtHeight The height of the skirt to add on the eastern edge of the tile.
@param {number} options.northSkirtHeight The height of the skirt to add on the northern edge of the tile.
@param {number} [options.childTileMask=15] A bit mask indicating which of this tile's four children exist.
                If a child's bit is set, geometry will be requested for that tile as well when it
                is needed.  If the bit is cleared, the child tile is not requested and geometry is
                instead upsampled from the parent.  The bit values are as follows:
                <table>
                 <tr><th>Bit Position</th><th>Bit Value</th><th>Child Tile</th></tr>
                 <tr><td>0</td><td>1</td><td>Southwest</td></tr>
                 <tr><td>1</td><td>2</td><td>Southeast</td></tr>
                 <tr><td>2</td><td>4</td><td>Northwest</td></tr>
                 <tr><td>3</td><td>8</td><td>Northeast</td></tr>
                </table>
@param {boolean} [options.createdByUpsampling=false] True if this instance was created by upsampling another instance;
                 otherwise, false.
@param {Uint8Array} [options.encodedNormals] The buffer containing per vertex normals, encoded using 'oct' encoding
@param {Uint8Array} [options.waterMask] The buffer containing the watermask.
@param {Credit[]} [options.credits] Array of credits for this tile.


@example
const data = new Cesium.QuantizedMeshTerrainData({
    minimumHeight : -100,
    maximumHeight : 2101,
    quantizedVertices : new Uint16Array([// order is SW NW SE NE
                                         // longitude
                                         0, 0, 32767, 32767,
                                         // latitude
                                         0, 32767, 0, 32767,
                                         // heights
                                         16384, 0, 32767, 16384]),
    indices : new Uint16Array([0, 3, 1,
                               0, 2, 3]),
    boundingSphere : new Cesium.BoundingSphere(new Cesium.Cartesian3(1.0, 2.0, 3.0), 10000),
    orientedBoundingBox : new Cesium.OrientedBoundingBox(new Cesium.Cartesian3(1.0, 2.0, 3.0), Cesium.Matrix3.fromRotationX(Cesium.Math.PI, new Cesium.Matrix3())),
    horizonOcclusionPoint : new Cesium.Cartesian3(3.0, 2.0, 1.0),
    westIndices : [0, 1],
    southIndices : [0, 1],
    eastIndices : [2, 3],
    northIndices : [1, 3],
    westSkirtHeight : 1.0,
    southSkirtHeight : 1.0,
    eastSkirtHeight : 1.0,
    northSkirtHeight : 1.0
});

@see TerrainData
@see HeightmapTerrainData
@see GoogleEarthEnterpriseTerrainData