| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023 | /* This file is automatically rebuilt by the Cesium build process. */define(['./AttributeCompression-3cfab808', './Transforms-323408fe', './Matrix2-69c32d33', './defaultValue-94c3e563', './TerrainEncoding-12c7d791', './IndexDatatype-c4099fe9', './RuntimeError-c581ca93', './ComponentDatatype-b1ea011a', './OrientedBoundingBox-a5e39a7d', './createTaskProcessorWorker', './_commonjsHelpers-3aae1032-f55dc0c4', './combine-761d9c3f', './WebGLConstants-7dccdc96', './EllipsoidTangentPlane-1e8d1fc2', './AxisAlignedBoundingBox-df2331b2', './IntersectionTests-d5d945ac', './Plane-069b6800'], (function (AttributeCompression, Transforms, Matrix2, defaultValue, TerrainEncoding, IndexDatatype, RuntimeError, ComponentDatatype, OrientedBoundingBox, createTaskProcessorWorker, _commonjsHelpers3aae1032, combine, WebGLConstants, EllipsoidTangentPlane, AxisAlignedBoundingBox, IntersectionTests, Plane) { 'use strict';  /**   * Contains functions for operating on 2D triangles.   *   * @namespace Intersections2D   */  const Intersections2D = {};  /**   * Splits a 2D triangle at given axis-aligned threshold value and returns the resulting   * polygon on a given side of the threshold.  The resulting polygon may have 0, 1, 2,   * 3, or 4 vertices.   *   * @param {Number} threshold The threshold coordinate value at which to clip the triangle.   * @param {Boolean} keepAbove true to keep the portion of the triangle above the threshold, or false   *                            to keep the portion below.   * @param {Number} u0 The coordinate of the first vertex in the triangle, in counter-clockwise order.   * @param {Number} u1 The coordinate of the second vertex in the triangle, in counter-clockwise order.   * @param {Number} u2 The coordinate of the third vertex in the triangle, in counter-clockwise order.   * @param {Number[]} [result] The array into which to copy the result.  If this parameter is not supplied,   *                            a new array is constructed and returned.   * @returns {Number[]} The polygon that results after the clip, specified as a list of   *                     vertices.  The vertices are specified in counter-clockwise order.   *                     Each vertex is either an index from the existing list (identified as   *                     a 0, 1, or 2) or -1 indicating a new vertex not in the original triangle.   *                     For new vertices, the -1 is followed by three additional numbers: the   *                     index of each of the two original vertices forming the line segment that   *                     the new vertex lies on, and the fraction of the distance from the first   *                     vertex to the second one.   *   * @example   * const result = Cesium.Intersections2D.clipTriangleAtAxisAlignedThreshold(0.5, false, 0.2, 0.6, 0.4);   * // result === [2, 0, -1, 1, 0, 0.25, -1, 1, 2, 0.5]   */  Intersections2D.clipTriangleAtAxisAlignedThreshold = function (    threshold,    keepAbove,    u0,    u1,    u2,    result  ) {    //>>includeStart('debug', pragmas.debug);    if (!defaultValue.defined(threshold)) {      throw new RuntimeError.DeveloperError("threshold is required.");    }    if (!defaultValue.defined(keepAbove)) {      throw new RuntimeError.DeveloperError("keepAbove is required.");    }    if (!defaultValue.defined(u0)) {      throw new RuntimeError.DeveloperError("u0 is required.");    }    if (!defaultValue.defined(u1)) {      throw new RuntimeError.DeveloperError("u1 is required.");    }    if (!defaultValue.defined(u2)) {      throw new RuntimeError.DeveloperError("u2 is required.");    }    //>>includeEnd('debug');    if (!defaultValue.defined(result)) {      result = [];    } else {      result.length = 0;    }    let u0Behind;    let u1Behind;    let u2Behind;    if (keepAbove) {      u0Behind = u0 < threshold;      u1Behind = u1 < threshold;      u2Behind = u2 < threshold;    } else {      u0Behind = u0 > threshold;      u1Behind = u1 > threshold;      u2Behind = u2 > threshold;    }    const numBehind = u0Behind + u1Behind + u2Behind;    let u01Ratio;    let u02Ratio;    let u12Ratio;    let u10Ratio;    let u20Ratio;    let u21Ratio;    if (numBehind === 1) {      if (u0Behind) {        u01Ratio = (threshold - u0) / (u1 - u0);        u02Ratio = (threshold - u0) / (u2 - u0);        result.push(1);        result.push(2);        if (u02Ratio !== 1.0) {          result.push(-1);          result.push(0);          result.push(2);          result.push(u02Ratio);        }        if (u01Ratio !== 1.0) {          result.push(-1);          result.push(0);          result.push(1);          result.push(u01Ratio);        }      } else if (u1Behind) {        u12Ratio = (threshold - u1) / (u2 - u1);        u10Ratio = (threshold - u1) / (u0 - u1);        result.push(2);        result.push(0);        if (u10Ratio !== 1.0) {          result.push(-1);          result.push(1);          result.push(0);          result.push(u10Ratio);        }        if (u12Ratio !== 1.0) {          result.push(-1);          result.push(1);          result.push(2);          result.push(u12Ratio);        }      } else if (u2Behind) {        u20Ratio = (threshold - u2) / (u0 - u2);        u21Ratio = (threshold - u2) / (u1 - u2);        result.push(0);        result.push(1);        if (u21Ratio !== 1.0) {          result.push(-1);          result.push(2);          result.push(1);          result.push(u21Ratio);        }        if (u20Ratio !== 1.0) {          result.push(-1);          result.push(2);          result.push(0);          result.push(u20Ratio);        }      }    } else if (numBehind === 2) {      if (!u0Behind && u0 !== threshold) {        u10Ratio = (threshold - u1) / (u0 - u1);        u20Ratio = (threshold - u2) / (u0 - u2);        result.push(0);        result.push(-1);        result.push(1);        result.push(0);        result.push(u10Ratio);        result.push(-1);        result.push(2);        result.push(0);        result.push(u20Ratio);      } else if (!u1Behind && u1 !== threshold) {        u21Ratio = (threshold - u2) / (u1 - u2);        u01Ratio = (threshold - u0) / (u1 - u0);        result.push(1);        result.push(-1);        result.push(2);        result.push(1);        result.push(u21Ratio);        result.push(-1);        result.push(0);        result.push(1);        result.push(u01Ratio);      } else if (!u2Behind && u2 !== threshold) {        u02Ratio = (threshold - u0) / (u2 - u0);        u12Ratio = (threshold - u1) / (u2 - u1);        result.push(2);        result.push(-1);        result.push(0);        result.push(2);        result.push(u02Ratio);        result.push(-1);        result.push(1);        result.push(2);        result.push(u12Ratio);      }    } else if (numBehind !== 3) {      // Completely in front of threshold      result.push(0);      result.push(1);      result.push(2);    }    // else Completely behind threshold    return result;  };  /**   * Compute the barycentric coordinates of a 2D position within a 2D triangle.   *   * @param {Number} x The x coordinate of the position for which to find the barycentric coordinates.   * @param {Number} y The y coordinate of the position for which to find the barycentric coordinates.   * @param {Number} x1 The x coordinate of the triangle's first vertex.   * @param {Number} y1 The y coordinate of the triangle's first vertex.   * @param {Number} x2 The x coordinate of the triangle's second vertex.   * @param {Number} y2 The y coordinate of the triangle's second vertex.   * @param {Number} x3 The x coordinate of the triangle's third vertex.   * @param {Number} y3 The y coordinate of the triangle's third vertex.   * @param {Cartesian3} [result] The instance into to which to copy the result.  If this parameter   *                     is undefined, a new instance is created and returned.   * @returns {Cartesian3} The barycentric coordinates of the position within the triangle.   *   * @example   * const result = Cesium.Intersections2D.computeBarycentricCoordinates(0.0, 0.0, 0.0, 1.0, -1, -0.5, 1, -0.5);   * // result === new Cesium.Cartesian3(1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0);   */  Intersections2D.computeBarycentricCoordinates = function (    x,    y,    x1,    y1,    x2,    y2,    x3,    y3,    result  ) {    //>>includeStart('debug', pragmas.debug);    if (!defaultValue.defined(x)) {      throw new RuntimeError.DeveloperError("x is required.");    }    if (!defaultValue.defined(y)) {      throw new RuntimeError.DeveloperError("y is required.");    }    if (!defaultValue.defined(x1)) {      throw new RuntimeError.DeveloperError("x1 is required.");    }    if (!defaultValue.defined(y1)) {      throw new RuntimeError.DeveloperError("y1 is required.");    }    if (!defaultValue.defined(x2)) {      throw new RuntimeError.DeveloperError("x2 is required.");    }    if (!defaultValue.defined(y2)) {      throw new RuntimeError.DeveloperError("y2 is required.");    }    if (!defaultValue.defined(x3)) {      throw new RuntimeError.DeveloperError("x3 is required.");    }    if (!defaultValue.defined(y3)) {      throw new RuntimeError.DeveloperError("y3 is required.");    }    //>>includeEnd('debug');    const x1mx3 = x1 - x3;    const x3mx2 = x3 - x2;    const y2my3 = y2 - y3;    const y1my3 = y1 - y3;    const inverseDeterminant = 1.0 / (y2my3 * x1mx3 + x3mx2 * y1my3);    const ymy3 = y - y3;    const xmx3 = x - x3;    const l1 = (y2my3 * xmx3 + x3mx2 * ymy3) * inverseDeterminant;    const l2 = (-y1my3 * xmx3 + x1mx3 * ymy3) * inverseDeterminant;    const l3 = 1.0 - l1 - l2;    if (defaultValue.defined(result)) {      result.x = l1;      result.y = l2;      result.z = l3;      return result;    }    return new Matrix2.Cartesian3(l1, l2, l3);  };  /**   * Compute the intersection between 2 line segments   *   * @param {Number} x00 The x coordinate of the first line's first vertex.   * @param {Number} y00 The y coordinate of the first line's first vertex.   * @param {Number} x01 The x coordinate of the first line's second vertex.   * @param {Number} y01 The y coordinate of the first line's second vertex.   * @param {Number} x10 The x coordinate of the second line's first vertex.   * @param {Number} y10 The y coordinate of the second line's first vertex.   * @param {Number} x11 The x coordinate of the second line's second vertex.   * @param {Number} y11 The y coordinate of the second line's second vertex.   * @param {Cartesian2} [result] The instance into to which to copy the result. If this parameter   *                     is undefined, a new instance is created and returned.   * @returns {Cartesian2} The intersection point, undefined if there is no intersection point or lines are coincident.   *   * @example   * const result = Cesium.Intersections2D.computeLineSegmentLineSegmentIntersection(0.0, 0.0, 0.0, 2.0, -1, 1, 1, 1);   * // result === new Cesium.Cartesian2(0.0, 1.0);   */  Intersections2D.computeLineSegmentLineSegmentIntersection = function (    x00,    y00,    x01,    y01,    x10,    y10,    x11,    y11,    result  ) {    //>>includeStart('debug', pragmas.debug);    RuntimeError.Check.typeOf.number("x00", x00);    RuntimeError.Check.typeOf.number("y00", y00);    RuntimeError.Check.typeOf.number("x01", x01);    RuntimeError.Check.typeOf.number("y01", y01);    RuntimeError.Check.typeOf.number("x10", x10);    RuntimeError.Check.typeOf.number("y10", y10);    RuntimeError.Check.typeOf.number("x11", x11);    RuntimeError.Check.typeOf.number("y11", y11);    //>>includeEnd('debug');    const numerator1A = (x11 - x10) * (y00 - y10) - (y11 - y10) * (x00 - x10);    const numerator1B = (x01 - x00) * (y00 - y10) - (y01 - y00) * (x00 - x10);    const denominator1 = (y11 - y10) * (x01 - x00) - (x11 - x10) * (y01 - y00);    // If denominator = 0, then lines are parallel. If denominator = 0 and both numerators are 0, then coincident    if (denominator1 === 0) {      return;    }    const ua1 = numerator1A / denominator1;    const ub1 = numerator1B / denominator1;    if (ua1 >= 0 && ua1 <= 1 && ub1 >= 0 && ub1 <= 1) {      if (!defaultValue.defined(result)) {        result = new Matrix2.Cartesian2();      }      result.x = x00 + ua1 * (x01 - x00);      result.y = y00 + ua1 * (y01 - y00);      return result;    }  };  const maxShort = 32767;  const halfMaxShort = (maxShort / 2) | 0;  const clipScratch = [];  const clipScratch2 = [];  const verticesScratch = [];  const cartographicScratch = new Matrix2.Cartographic();  let cartesian3Scratch = new Matrix2.Cartesian3();  const uScratch = [];  const vScratch = [];  const heightScratch = [];  const indicesScratch = [];  const normalsScratch = [];  const horizonOcclusionPointScratch = new Matrix2.Cartesian3();  const boundingSphereScratch = new Transforms.BoundingSphere();  const orientedBoundingBoxScratch = new OrientedBoundingBox.OrientedBoundingBox();  const decodeTexCoordsScratch = new Matrix2.Cartesian2();  const octEncodedNormalScratch = new Matrix2.Cartesian3();  function upsampleQuantizedTerrainMesh(parameters, transferableObjects) {    const isEastChild = parameters.isEastChild;    const isNorthChild = parameters.isNorthChild;    const minU = isEastChild ? halfMaxShort : 0;    const maxU = isEastChild ? maxShort : halfMaxShort;    const minV = isNorthChild ? halfMaxShort : 0;    const maxV = isNorthChild ? maxShort : halfMaxShort;    const uBuffer = uScratch;    const vBuffer = vScratch;    const heightBuffer = heightScratch;    const normalBuffer = normalsScratch;    uBuffer.length = 0;    vBuffer.length = 0;    heightBuffer.length = 0;    normalBuffer.length = 0;    const indices = indicesScratch;    indices.length = 0;    const vertexMap = {};    const parentVertices = parameters.vertices;    let parentIndices = parameters.indices;    parentIndices = parentIndices.subarray(0, parameters.indexCountWithoutSkirts);    const encoding = TerrainEncoding.TerrainEncoding.clone(parameters.encoding);    const hasVertexNormals = encoding.hasVertexNormals;    let vertexCount = 0;    const quantizedVertexCount = parameters.vertexCountWithoutSkirts;    const parentMinimumHeight = parameters.minimumHeight;    const parentMaximumHeight = parameters.maximumHeight;    const parentUBuffer = new Array(quantizedVertexCount);    const parentVBuffer = new Array(quantizedVertexCount);    const parentHeightBuffer = new Array(quantizedVertexCount);    const parentNormalBuffer = hasVertexNormals      ? new Array(quantizedVertexCount * 2)      : undefined;    const threshold = 20;    let height;    let i, n;    let u, v;    for (i = 0, n = 0; i < quantizedVertexCount; ++i, n += 2) {      const texCoords = encoding.decodeTextureCoordinates(        parentVertices,        i,        decodeTexCoordsScratch      );      height = encoding.decodeHeight(parentVertices, i);      u = ComponentDatatype.CesiumMath.clamp((texCoords.x * maxShort) | 0, 0, maxShort);      v = ComponentDatatype.CesiumMath.clamp((texCoords.y * maxShort) | 0, 0, maxShort);      parentHeightBuffer[i] = ComponentDatatype.CesiumMath.clamp(        (((height - parentMinimumHeight) /          (parentMaximumHeight - parentMinimumHeight)) *          maxShort) |          0,        0,        maxShort      );      if (u < threshold) {        u = 0;      }      if (v < threshold) {        v = 0;      }      if (maxShort - u < threshold) {        u = maxShort;      }      if (maxShort - v < threshold) {        v = maxShort;      }      parentUBuffer[i] = u;      parentVBuffer[i] = v;      if (hasVertexNormals) {        const encodedNormal = encoding.getOctEncodedNormal(          parentVertices,          i,          octEncodedNormalScratch        );        parentNormalBuffer[n] = encodedNormal.x;        parentNormalBuffer[n + 1] = encodedNormal.y;      }      if (        ((isEastChild && u >= halfMaxShort) ||          (!isEastChild && u <= halfMaxShort)) &&        ((isNorthChild && v >= halfMaxShort) ||          (!isNorthChild && v <= halfMaxShort))      ) {        vertexMap[i] = vertexCount;        uBuffer.push(u);        vBuffer.push(v);        heightBuffer.push(parentHeightBuffer[i]);        if (hasVertexNormals) {          normalBuffer.push(parentNormalBuffer[n]);          normalBuffer.push(parentNormalBuffer[n + 1]);        }        ++vertexCount;      }    }    const triangleVertices = [];    triangleVertices.push(new Vertex());    triangleVertices.push(new Vertex());    triangleVertices.push(new Vertex());    const clippedTriangleVertices = [];    clippedTriangleVertices.push(new Vertex());    clippedTriangleVertices.push(new Vertex());    clippedTriangleVertices.push(new Vertex());    let clippedIndex;    let clipped2;    for (i = 0; i < parentIndices.length; i += 3) {      const i0 = parentIndices[i];      const i1 = parentIndices[i + 1];      const i2 = parentIndices[i + 2];      const u0 = parentUBuffer[i0];      const u1 = parentUBuffer[i1];      const u2 = parentUBuffer[i2];      triangleVertices[0].initializeIndexed(        parentUBuffer,        parentVBuffer,        parentHeightBuffer,        parentNormalBuffer,        i0      );      triangleVertices[1].initializeIndexed(        parentUBuffer,        parentVBuffer,        parentHeightBuffer,        parentNormalBuffer,        i1      );      triangleVertices[2].initializeIndexed(        parentUBuffer,        parentVBuffer,        parentHeightBuffer,        parentNormalBuffer,        i2      );      // Clip triangle on the east-west boundary.      const clipped = Intersections2D.clipTriangleAtAxisAlignedThreshold(        halfMaxShort,        isEastChild,        u0,        u1,        u2,        clipScratch      );      // Get the first clipped triangle, if any.      clippedIndex = 0;      if (clippedIndex >= clipped.length) {        continue;      }      clippedIndex = clippedTriangleVertices[0].initializeFromClipResult(        clipped,        clippedIndex,        triangleVertices      );      if (clippedIndex >= clipped.length) {        continue;      }      clippedIndex = clippedTriangleVertices[1].initializeFromClipResult(        clipped,        clippedIndex,        triangleVertices      );      if (clippedIndex >= clipped.length) {        continue;      }      clippedIndex = clippedTriangleVertices[2].initializeFromClipResult(        clipped,        clippedIndex,        triangleVertices      );      // Clip the triangle against the North-south boundary.      clipped2 = Intersections2D.clipTriangleAtAxisAlignedThreshold(        halfMaxShort,        isNorthChild,        clippedTriangleVertices[0].getV(),        clippedTriangleVertices[1].getV(),        clippedTriangleVertices[2].getV(),        clipScratch2      );      addClippedPolygon(        uBuffer,        vBuffer,        heightBuffer,        normalBuffer,        indices,        vertexMap,        clipped2,        clippedTriangleVertices,        hasVertexNormals      );      // If there's another vertex in the original clipped result,      // it forms a second triangle.  Clip it as well.      if (clippedIndex < clipped.length) {        clippedTriangleVertices[2].clone(clippedTriangleVertices[1]);        clippedTriangleVertices[2].initializeFromClipResult(          clipped,          clippedIndex,          triangleVertices        );        clipped2 = Intersections2D.clipTriangleAtAxisAlignedThreshold(          halfMaxShort,          isNorthChild,          clippedTriangleVertices[0].getV(),          clippedTriangleVertices[1].getV(),          clippedTriangleVertices[2].getV(),          clipScratch2        );        addClippedPolygon(          uBuffer,          vBuffer,          heightBuffer,          normalBuffer,          indices,          vertexMap,          clipped2,          clippedTriangleVertices,          hasVertexNormals        );      }    }    const uOffset = isEastChild ? -maxShort : 0;    const vOffset = isNorthChild ? -maxShort : 0;    const westIndices = [];    const southIndices = [];    const eastIndices = [];    const northIndices = [];    let minimumHeight = Number.MAX_VALUE;    let maximumHeight = -minimumHeight;    const cartesianVertices = verticesScratch;    cartesianVertices.length = 0;    const ellipsoid = Matrix2.Ellipsoid.clone(parameters.ellipsoid);    const rectangle = Matrix2.Rectangle.clone(parameters.childRectangle);    const north = rectangle.north;    const south = rectangle.south;    let east = rectangle.east;    const west = rectangle.west;    if (east < west) {      east += ComponentDatatype.CesiumMath.TWO_PI;    }    for (i = 0; i < uBuffer.length; ++i) {      u = Math.round(uBuffer[i]);      if (u <= minU) {        westIndices.push(i);        u = 0;      } else if (u >= maxU) {        eastIndices.push(i);        u = maxShort;      } else {        u = u * 2 + uOffset;      }      uBuffer[i] = u;      v = Math.round(vBuffer[i]);      if (v <= minV) {        southIndices.push(i);        v = 0;      } else if (v >= maxV) {        northIndices.push(i);        v = maxShort;      } else {        v = v * 2 + vOffset;      }      vBuffer[i] = v;      height = ComponentDatatype.CesiumMath.lerp(        parentMinimumHeight,        parentMaximumHeight,        heightBuffer[i] / maxShort      );      if (height < minimumHeight) {        minimumHeight = height;      }      if (height > maximumHeight) {        maximumHeight = height;      }      heightBuffer[i] = height;      cartographicScratch.longitude = ComponentDatatype.CesiumMath.lerp(west, east, u / maxShort);      cartographicScratch.latitude = ComponentDatatype.CesiumMath.lerp(south, north, v / maxShort);      cartographicScratch.height = height;      ellipsoid.cartographicToCartesian(cartographicScratch, cartesian3Scratch);      cartesianVertices.push(cartesian3Scratch.x);      cartesianVertices.push(cartesian3Scratch.y);      cartesianVertices.push(cartesian3Scratch.z);    }    const boundingSphere = Transforms.BoundingSphere.fromVertices(      cartesianVertices,      Matrix2.Cartesian3.ZERO,      3,      boundingSphereScratch    );    const orientedBoundingBox = OrientedBoundingBox.OrientedBoundingBox.fromRectangle(      rectangle,      minimumHeight,      maximumHeight,      ellipsoid,      orientedBoundingBoxScratch    );    const occluder = new TerrainEncoding.EllipsoidalOccluder(ellipsoid);    const horizonOcclusionPoint = occluder.computeHorizonCullingPointFromVerticesPossiblyUnderEllipsoid(      boundingSphere.center,      cartesianVertices,      3,      boundingSphere.center,      minimumHeight,      horizonOcclusionPointScratch    );    const heightRange = maximumHeight - minimumHeight;    const vertices = new Uint16Array(      uBuffer.length + vBuffer.length + heightBuffer.length    );    for (i = 0; i < uBuffer.length; ++i) {      vertices[i] = uBuffer[i];    }    let start = uBuffer.length;    for (i = 0; i < vBuffer.length; ++i) {      vertices[start + i] = vBuffer[i];    }    start += vBuffer.length;    for (i = 0; i < heightBuffer.length; ++i) {      vertices[start + i] =        (maxShort * (heightBuffer[i] - minimumHeight)) / heightRange;    }    const indicesTypedArray = IndexDatatype.IndexDatatype.createTypedArray(      uBuffer.length,      indices    );    let encodedNormals;    if (hasVertexNormals) {      const normalArray = new Uint8Array(normalBuffer);      transferableObjects.push(        vertices.buffer,        indicesTypedArray.buffer,        normalArray.buffer      );      encodedNormals = normalArray.buffer;    } else {      transferableObjects.push(vertices.buffer, indicesTypedArray.buffer);    }    return {      vertices: vertices.buffer,      encodedNormals: encodedNormals,      indices: indicesTypedArray.buffer,      minimumHeight: minimumHeight,      maximumHeight: maximumHeight,      westIndices: westIndices,      southIndices: southIndices,      eastIndices: eastIndices,      northIndices: northIndices,      boundingSphere: boundingSphere,      orientedBoundingBox: orientedBoundingBox,      horizonOcclusionPoint: horizonOcclusionPoint,    };  }  function Vertex() {    this.vertexBuffer = undefined;    this.index = undefined;    this.first = undefined;    this.second = undefined;    this.ratio = undefined;  }  Vertex.prototype.clone = function (result) {    if (!defaultValue.defined(result)) {      result = new Vertex();    }    result.uBuffer = this.uBuffer;    result.vBuffer = this.vBuffer;    result.heightBuffer = this.heightBuffer;    result.normalBuffer = this.normalBuffer;    result.index = this.index;    result.first = this.first;    result.second = this.second;    result.ratio = this.ratio;    return result;  };  Vertex.prototype.initializeIndexed = function (    uBuffer,    vBuffer,    heightBuffer,    normalBuffer,    index  ) {    this.uBuffer = uBuffer;    this.vBuffer = vBuffer;    this.heightBuffer = heightBuffer;    this.normalBuffer = normalBuffer;    this.index = index;    this.first = undefined;    this.second = undefined;    this.ratio = undefined;  };  Vertex.prototype.initializeFromClipResult = function (    clipResult,    index,    vertices  ) {    let nextIndex = index + 1;    if (clipResult[index] !== -1) {      vertices[clipResult[index]].clone(this);    } else {      this.vertexBuffer = undefined;      this.index = undefined;      this.first = vertices[clipResult[nextIndex]];      ++nextIndex;      this.second = vertices[clipResult[nextIndex]];      ++nextIndex;      this.ratio = clipResult[nextIndex];      ++nextIndex;    }    return nextIndex;  };  Vertex.prototype.getKey = function () {    if (this.isIndexed()) {      return this.index;    }    return JSON.stringify({      first: this.first.getKey(),      second: this.second.getKey(),      ratio: this.ratio,    });  };  Vertex.prototype.isIndexed = function () {    return defaultValue.defined(this.index);  };  Vertex.prototype.getH = function () {    if (defaultValue.defined(this.index)) {      return this.heightBuffer[this.index];    }    return ComponentDatatype.CesiumMath.lerp(this.first.getH(), this.second.getH(), this.ratio);  };  Vertex.prototype.getU = function () {    if (defaultValue.defined(this.index)) {      return this.uBuffer[this.index];    }    return ComponentDatatype.CesiumMath.lerp(this.first.getU(), this.second.getU(), this.ratio);  };  Vertex.prototype.getV = function () {    if (defaultValue.defined(this.index)) {      return this.vBuffer[this.index];    }    return ComponentDatatype.CesiumMath.lerp(this.first.getV(), this.second.getV(), this.ratio);  };  let encodedScratch = new Matrix2.Cartesian2();  // An upsampled triangle may be clipped twice before it is assigned an index  // In this case, we need a buffer to handle the recursion of getNormalX() and getNormalY().  let depth = -1;  const cartesianScratch1 = [new Matrix2.Cartesian3(), new Matrix2.Cartesian3()];  const cartesianScratch2 = [new Matrix2.Cartesian3(), new Matrix2.Cartesian3()];  function lerpOctEncodedNormal(vertex, result) {    ++depth;    let first = cartesianScratch1[depth];    let second = cartesianScratch2[depth];    first = AttributeCompression.AttributeCompression.octDecode(      vertex.first.getNormalX(),      vertex.first.getNormalY(),      first    );    second = AttributeCompression.AttributeCompression.octDecode(      vertex.second.getNormalX(),      vertex.second.getNormalY(),      second    );    cartesian3Scratch = Matrix2.Cartesian3.lerp(      first,      second,      vertex.ratio,      cartesian3Scratch    );    Matrix2.Cartesian3.normalize(cartesian3Scratch, cartesian3Scratch);    AttributeCompression.AttributeCompression.octEncode(cartesian3Scratch, result);    --depth;    return result;  }  Vertex.prototype.getNormalX = function () {    if (defaultValue.defined(this.index)) {      return this.normalBuffer[this.index * 2];    }    encodedScratch = lerpOctEncodedNormal(this, encodedScratch);    return encodedScratch.x;  };  Vertex.prototype.getNormalY = function () {    if (defaultValue.defined(this.index)) {      return this.normalBuffer[this.index * 2 + 1];    }    encodedScratch = lerpOctEncodedNormal(this, encodedScratch);    return encodedScratch.y;  };  const polygonVertices = [];  polygonVertices.push(new Vertex());  polygonVertices.push(new Vertex());  polygonVertices.push(new Vertex());  polygonVertices.push(new Vertex());  function addClippedPolygon(    uBuffer,    vBuffer,    heightBuffer,    normalBuffer,    indices,    vertexMap,    clipped,    triangleVertices,    hasVertexNormals  ) {    if (clipped.length === 0) {      return;    }    let numVertices = 0;    let clippedIndex = 0;    while (clippedIndex < clipped.length) {      clippedIndex = polygonVertices[numVertices++].initializeFromClipResult(        clipped,        clippedIndex,        triangleVertices      );    }    for (let i = 0; i < numVertices; ++i) {      const polygonVertex = polygonVertices[i];      if (!polygonVertex.isIndexed()) {        const key = polygonVertex.getKey();        if (defaultValue.defined(vertexMap[key])) {          polygonVertex.newIndex = vertexMap[key];        } else {          const newIndex = uBuffer.length;          uBuffer.push(polygonVertex.getU());          vBuffer.push(polygonVertex.getV());          heightBuffer.push(polygonVertex.getH());          if (hasVertexNormals) {            normalBuffer.push(polygonVertex.getNormalX());            normalBuffer.push(polygonVertex.getNormalY());          }          polygonVertex.newIndex = newIndex;          vertexMap[key] = newIndex;        }      } else {        polygonVertex.newIndex = vertexMap[polygonVertex.index];        polygonVertex.uBuffer = uBuffer;        polygonVertex.vBuffer = vBuffer;        polygonVertex.heightBuffer = heightBuffer;        if (hasVertexNormals) {          polygonVertex.normalBuffer = normalBuffer;        }      }    }    if (numVertices === 3) {      // A triangle.      indices.push(polygonVertices[0].newIndex);      indices.push(polygonVertices[1].newIndex);      indices.push(polygonVertices[2].newIndex);    } else if (numVertices === 4) {      // A quad - two triangles.      indices.push(polygonVertices[0].newIndex);      indices.push(polygonVertices[1].newIndex);      indices.push(polygonVertices[2].newIndex);      indices.push(polygonVertices[0].newIndex);      indices.push(polygonVertices[2].newIndex);      indices.push(polygonVertices[3].newIndex);    }  }  var upsampleQuantizedTerrainMesh$1 = createTaskProcessorWorker(upsampleQuantizedTerrainMesh);  return upsampleQuantizedTerrainMesh$1;}));
 |