| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689 | /* This file is automatically rebuilt by the Cesium build process. */define(['exports', './AttributeCompression-3cfab808', './Matrix2-69c32d33', './RuntimeError-c581ca93', './defaultValue-94c3e563', './ComponentDatatype-b1ea011a', './Transforms-323408fe', './EncodedCartesian3-b1f97f8a', './GeometryAttribute-cb73bb3f', './IndexDatatype-c4099fe9', './IntersectionTests-d5d945ac', './Plane-069b6800'], (function (exports, AttributeCompression, Matrix2, RuntimeError, defaultValue, ComponentDatatype, Transforms, EncodedCartesian3, GeometryAttribute, IndexDatatype, IntersectionTests, Plane) { 'use strict';  const scratchCartesian1 = new Matrix2.Cartesian3();  const scratchCartesian2$1 = new Matrix2.Cartesian3();  const scratchCartesian3$1 = new Matrix2.Cartesian3();  /**   * Computes the barycentric coordinates for a point with respect to a triangle.   *   * @function   *   * @param {Cartesian2|Cartesian3} point The point to test.   * @param {Cartesian2|Cartesian3} p0 The first point of the triangle, corresponding to the barycentric x-axis.   * @param {Cartesian2|Cartesian3} p1 The second point of the triangle, corresponding to the barycentric y-axis.   * @param {Cartesian2|Cartesian3} p2 The third point of the triangle, corresponding to the barycentric z-axis.   * @param {Cartesian3} [result] The object onto which to store the result.   * @returns {Cartesian3|undefined} The modified result parameter or a new Cartesian3 instance if one was not provided. If the triangle is degenerate the function will return undefined.   *   * @example   * // Returns Cartesian3.UNIT_X   * const p = new Cesium.Cartesian3(-1.0, 0.0, 0.0);   * const b = Cesium.barycentricCoordinates(p,   *   new Cesium.Cartesian3(-1.0, 0.0, 0.0),   *   new Cesium.Cartesian3( 1.0, 0.0, 0.0),   *   new Cesium.Cartesian3( 0.0, 1.0, 1.0));   */  function barycentricCoordinates(point, p0, p1, p2, result) {    //>>includeStart('debug', pragmas.debug);    RuntimeError.Check.defined("point", point);    RuntimeError.Check.defined("p0", p0);    RuntimeError.Check.defined("p1", p1);    RuntimeError.Check.defined("p2", p2);    //>>includeEnd('debug');    if (!defaultValue.defined(result)) {      result = new Matrix2.Cartesian3();    }    // Implementation based on http://www.blackpawn.com/texts/pointinpoly/default.html.    let v0;    let v1;    let v2;    let dot00;    let dot01;    let dot02;    let dot11;    let dot12;    if (!defaultValue.defined(p0.z)) {      if (Matrix2.Cartesian2.equalsEpsilon(point, p0, ComponentDatatype.CesiumMath.EPSILON14)) {        return Matrix2.Cartesian3.clone(Matrix2.Cartesian3.UNIT_X, result);      }      if (Matrix2.Cartesian2.equalsEpsilon(point, p1, ComponentDatatype.CesiumMath.EPSILON14)) {        return Matrix2.Cartesian3.clone(Matrix2.Cartesian3.UNIT_Y, result);      }      if (Matrix2.Cartesian2.equalsEpsilon(point, p2, ComponentDatatype.CesiumMath.EPSILON14)) {        return Matrix2.Cartesian3.clone(Matrix2.Cartesian3.UNIT_Z, result);      }      v0 = Matrix2.Cartesian2.subtract(p1, p0, scratchCartesian1);      v1 = Matrix2.Cartesian2.subtract(p2, p0, scratchCartesian2$1);      v2 = Matrix2.Cartesian2.subtract(point, p0, scratchCartesian3$1);      dot00 = Matrix2.Cartesian2.dot(v0, v0);      dot01 = Matrix2.Cartesian2.dot(v0, v1);      dot02 = Matrix2.Cartesian2.dot(v0, v2);      dot11 = Matrix2.Cartesian2.dot(v1, v1);      dot12 = Matrix2.Cartesian2.dot(v1, v2);    } else {      if (Matrix2.Cartesian3.equalsEpsilon(point, p0, ComponentDatatype.CesiumMath.EPSILON14)) {        return Matrix2.Cartesian3.clone(Matrix2.Cartesian3.UNIT_X, result);      }      if (Matrix2.Cartesian3.equalsEpsilon(point, p1, ComponentDatatype.CesiumMath.EPSILON14)) {        return Matrix2.Cartesian3.clone(Matrix2.Cartesian3.UNIT_Y, result);      }      if (Matrix2.Cartesian3.equalsEpsilon(point, p2, ComponentDatatype.CesiumMath.EPSILON14)) {        return Matrix2.Cartesian3.clone(Matrix2.Cartesian3.UNIT_Z, result);      }      v0 = Matrix2.Cartesian3.subtract(p1, p0, scratchCartesian1);      v1 = Matrix2.Cartesian3.subtract(p2, p0, scratchCartesian2$1);      v2 = Matrix2.Cartesian3.subtract(point, p0, scratchCartesian3$1);      dot00 = Matrix2.Cartesian3.dot(v0, v0);      dot01 = Matrix2.Cartesian3.dot(v0, v1);      dot02 = Matrix2.Cartesian3.dot(v0, v2);      dot11 = Matrix2.Cartesian3.dot(v1, v1);      dot12 = Matrix2.Cartesian3.dot(v1, v2);    }    result.y = dot11 * dot02 - dot01 * dot12;    result.z = dot00 * dot12 - dot01 * dot02;    const q = dot00 * dot11 - dot01 * dot01;    // Triangle is degenerate    if (q === 0) {      return undefined;    }    result.y /= q;    result.z /= q;    result.x = 1.0 - result.y - result.z;    return result;  }  /**   * Encapsulates an algorithm to optimize triangles for the post   * vertex-shader cache.  This is based on the 2007 SIGGRAPH paper   * 'Fast Triangle Reordering for Vertex Locality and Reduced Overdraw.'   * The runtime is linear but several passes are made.   *   * @namespace Tipsify   *   * @see <a href='http://gfx.cs.princeton.edu/pubs/Sander_2007_%3ETR/tipsy.pdf'>   * Fast Triangle Reordering for Vertex Locality and Reduced Overdraw</a>   * by Sander, Nehab, and Barczak   *   * @private   */  const Tipsify = {};  /**   * Calculates the average cache miss ratio (ACMR) for a given set of indices.   *   * @param {Object} options Object with the following properties:   * @param {Number[]} options.indices Lists triads of numbers corresponding to the indices of the vertices   *                        in the vertex buffer that define the geometry's triangles.   * @param {Number} [options.maximumIndex] The maximum value of the elements in <code>args.indices</code>.   *                                     If not supplied, this value will be computed.   * @param {Number} [options.cacheSize=24] The number of vertices that can be stored in the cache at any one time.   * @returns {Number} The average cache miss ratio (ACMR).   *   * @exception {DeveloperError} indices length must be a multiple of three.   * @exception {DeveloperError} cacheSize must be greater than two.   *   * @example   * const indices = [0, 1, 2, 3, 4, 5];   * const maxIndex = 5;   * const cacheSize = 3;   * const acmr = Cesium.Tipsify.calculateACMR({indices : indices, maxIndex : maxIndex, cacheSize : cacheSize});   */  Tipsify.calculateACMR = function (options) {    options = defaultValue.defaultValue(options, defaultValue.defaultValue.EMPTY_OBJECT);    const indices = options.indices;    let maximumIndex = options.maximumIndex;    const cacheSize = defaultValue.defaultValue(options.cacheSize, 24);    //>>includeStart('debug', pragmas.debug);    if (!defaultValue.defined(indices)) {      throw new RuntimeError.DeveloperError("indices is required.");    }    //>>includeEnd('debug');    const numIndices = indices.length;    //>>includeStart('debug', pragmas.debug);    if (numIndices < 3 || numIndices % 3 !== 0) {      throw new RuntimeError.DeveloperError("indices length must be a multiple of three.");    }    if (maximumIndex <= 0) {      throw new RuntimeError.DeveloperError("maximumIndex must be greater than zero.");    }    if (cacheSize < 3) {      throw new RuntimeError.DeveloperError("cacheSize must be greater than two.");    }    //>>includeEnd('debug');    // Compute the maximumIndex if not given    if (!defaultValue.defined(maximumIndex)) {      maximumIndex = 0;      let currentIndex = 0;      let intoIndices = indices[currentIndex];      while (currentIndex < numIndices) {        if (intoIndices > maximumIndex) {          maximumIndex = intoIndices;        }        ++currentIndex;        intoIndices = indices[currentIndex];      }    }    // Vertex time stamps    const vertexTimeStamps = [];    for (let i = 0; i < maximumIndex + 1; i++) {      vertexTimeStamps[i] = 0;    }    // Cache processing    let s = cacheSize + 1;    for (let j = 0; j < numIndices; ++j) {      if (s - vertexTimeStamps[indices[j]] > cacheSize) {        vertexTimeStamps[indices[j]] = s;        ++s;      }    }    return (s - cacheSize + 1) / (numIndices / 3);  };  /**   * Optimizes triangles for the post-vertex shader cache.   *   * @param {Object} options Object with the following properties:   * @param {Number[]} options.indices Lists triads of numbers corresponding to the indices of the vertices   *                        in the vertex buffer that define the geometry's triangles.   * @param {Number} [options.maximumIndex] The maximum value of the elements in <code>args.indices</code>.   *                                     If not supplied, this value will be computed.   * @param {Number} [options.cacheSize=24] The number of vertices that can be stored in the cache at any one time.   * @returns {Number[]} A list of the input indices in an optimized order.   *   * @exception {DeveloperError} indices length must be a multiple of three.   * @exception {DeveloperError} cacheSize must be greater than two.   *   * @example   * const indices = [0, 1, 2, 3, 4, 5];   * const maxIndex = 5;   * const cacheSize = 3;   * const reorderedIndices = Cesium.Tipsify.tipsify({indices : indices, maxIndex : maxIndex, cacheSize : cacheSize});   */  Tipsify.tipsify = function (options) {    options = defaultValue.defaultValue(options, defaultValue.defaultValue.EMPTY_OBJECT);    const indices = options.indices;    const maximumIndex = options.maximumIndex;    const cacheSize = defaultValue.defaultValue(options.cacheSize, 24);    let cursor;    function skipDeadEnd(vertices, deadEnd, indices, maximumIndexPlusOne) {      while (deadEnd.length >= 1) {        // while the stack is not empty        const d = deadEnd[deadEnd.length - 1]; // top of the stack        deadEnd.splice(deadEnd.length - 1, 1); // pop the stack        if (vertices[d].numLiveTriangles > 0) {          return d;        }      }      while (cursor < maximumIndexPlusOne) {        if (vertices[cursor].numLiveTriangles > 0) {          ++cursor;          return cursor - 1;        }        ++cursor;      }      return -1;    }    function getNextVertex(      indices,      cacheSize,      oneRing,      vertices,      s,      deadEnd,      maximumIndexPlusOne    ) {      let n = -1;      let p;      let m = -1;      let itOneRing = 0;      while (itOneRing < oneRing.length) {        const index = oneRing[itOneRing];        if (vertices[index].numLiveTriangles) {          p = 0;          if (            s -              vertices[index].timeStamp +              2 * vertices[index].numLiveTriangles <=            cacheSize          ) {            p = s - vertices[index].timeStamp;          }          if (p > m || m === -1) {            m = p;            n = index;          }        }        ++itOneRing;      }      if (n === -1) {        return skipDeadEnd(vertices, deadEnd, indices, maximumIndexPlusOne);      }      return n;    }    //>>includeStart('debug', pragmas.debug);    if (!defaultValue.defined(indices)) {      throw new RuntimeError.DeveloperError("indices is required.");    }    //>>includeEnd('debug');    const numIndices = indices.length;    //>>includeStart('debug', pragmas.debug);    if (numIndices < 3 || numIndices % 3 !== 0) {      throw new RuntimeError.DeveloperError("indices length must be a multiple of three.");    }    if (maximumIndex <= 0) {      throw new RuntimeError.DeveloperError("maximumIndex must be greater than zero.");    }    if (cacheSize < 3) {      throw new RuntimeError.DeveloperError("cacheSize must be greater than two.");    }    //>>includeEnd('debug');    // Determine maximum index    let maximumIndexPlusOne = 0;    let currentIndex = 0;    let intoIndices = indices[currentIndex];    const endIndex = numIndices;    if (defaultValue.defined(maximumIndex)) {      maximumIndexPlusOne = maximumIndex + 1;    } else {      while (currentIndex < endIndex) {        if (intoIndices > maximumIndexPlusOne) {          maximumIndexPlusOne = intoIndices;        }        ++currentIndex;        intoIndices = indices[currentIndex];      }      if (maximumIndexPlusOne === -1) {        return 0;      }      ++maximumIndexPlusOne;    }    // Vertices    const vertices = [];    let i;    for (i = 0; i < maximumIndexPlusOne; i++) {      vertices[i] = {        numLiveTriangles: 0,        timeStamp: 0,        vertexTriangles: [],      };    }    currentIndex = 0;    let triangle = 0;    while (currentIndex < endIndex) {      vertices[indices[currentIndex]].vertexTriangles.push(triangle);      ++vertices[indices[currentIndex]].numLiveTriangles;      vertices[indices[currentIndex + 1]].vertexTriangles.push(triangle);      ++vertices[indices[currentIndex + 1]].numLiveTriangles;      vertices[indices[currentIndex + 2]].vertexTriangles.push(triangle);      ++vertices[indices[currentIndex + 2]].numLiveTriangles;      ++triangle;      currentIndex += 3;    }    // Starting index    let f = 0;    // Time Stamp    let s = cacheSize + 1;    cursor = 1;    // Process    let oneRing = [];    const deadEnd = []; //Stack    let vertex;    let intoVertices;    let currentOutputIndex = 0;    const outputIndices = [];    const numTriangles = numIndices / 3;    const triangleEmitted = [];    for (i = 0; i < numTriangles; i++) {      triangleEmitted[i] = false;    }    let index;    let limit;    while (f !== -1) {      oneRing = [];      intoVertices = vertices[f];      limit = intoVertices.vertexTriangles.length;      for (let k = 0; k < limit; ++k) {        triangle = intoVertices.vertexTriangles[k];        if (!triangleEmitted[triangle]) {          triangleEmitted[triangle] = true;          currentIndex = triangle + triangle + triangle;          for (let j = 0; j < 3; ++j) {            // Set this index as a possible next index            index = indices[currentIndex];            oneRing.push(index);            deadEnd.push(index);            // Output index            outputIndices[currentOutputIndex] = index;            ++currentOutputIndex;            // Cache processing            vertex = vertices[index];            --vertex.numLiveTriangles;            if (s - vertex.timeStamp > cacheSize) {              vertex.timeStamp = s;              ++s;            }            ++currentIndex;          }        }      }      f = getNextVertex(        indices,        cacheSize,        oneRing,        vertices,        s,        deadEnd,        maximumIndexPlusOne      );    }    return outputIndices;  };  /**   * Content pipeline functions for geometries.   *   * @namespace GeometryPipeline   *   * @see Geometry   */  const GeometryPipeline = {};  function addTriangle(lines, index, i0, i1, i2) {    lines[index++] = i0;    lines[index++] = i1;    lines[index++] = i1;    lines[index++] = i2;    lines[index++] = i2;    lines[index] = i0;  }  function trianglesToLines(triangles) {    const count = triangles.length;    const size = (count / 3) * 6;    const lines = IndexDatatype.IndexDatatype.createTypedArray(count, size);    let index = 0;    for (let i = 0; i < count; i += 3, index += 6) {      addTriangle(lines, index, triangles[i], triangles[i + 1], triangles[i + 2]);    }    return lines;  }  function triangleStripToLines(triangles) {    const count = triangles.length;    if (count >= 3) {      const size = (count - 2) * 6;      const lines = IndexDatatype.IndexDatatype.createTypedArray(count, size);      addTriangle(lines, 0, triangles[0], triangles[1], triangles[2]);      let index = 6;      for (let i = 3; i < count; ++i, index += 6) {        addTriangle(          lines,          index,          triangles[i - 1],          triangles[i],          triangles[i - 2]        );      }      return lines;    }    return new Uint16Array();  }  function triangleFanToLines(triangles) {    if (triangles.length > 0) {      const count = triangles.length - 1;      const size = (count - 1) * 6;      const lines = IndexDatatype.IndexDatatype.createTypedArray(count, size);      const base = triangles[0];      let index = 0;      for (let i = 1; i < count; ++i, index += 6) {        addTriangle(lines, index, base, triangles[i], triangles[i + 1]);      }      return lines;    }    return new Uint16Array();  }  /**   * Converts a geometry's triangle indices to line indices.  If the geometry has an <code>indices</code>   * and its <code>primitiveType</code> is <code>TRIANGLES</code>, <code>TRIANGLE_STRIP</code>,   * <code>TRIANGLE_FAN</code>, it is converted to <code>LINES</code>; otherwise, the geometry is not changed.   * <p>   * This is commonly used to create a wireframe geometry for visual debugging.   * </p>   *   * @param {Geometry} geometry The geometry to modify.   * @returns {Geometry} The modified <code>geometry</code> argument, with its triangle indices converted to lines.   *   * @exception {DeveloperError} geometry.primitiveType must be TRIANGLES, TRIANGLE_STRIP, or TRIANGLE_FAN.   *   * @example   * geometry = Cesium.GeometryPipeline.toWireframe(geometry);   */  GeometryPipeline.toWireframe = function (geometry) {    //>>includeStart('debug', pragmas.debug);    if (!defaultValue.defined(geometry)) {      throw new RuntimeError.DeveloperError("geometry is required.");    }    //>>includeEnd('debug');    const indices = geometry.indices;    if (defaultValue.defined(indices)) {      switch (geometry.primitiveType) {        case GeometryAttribute.PrimitiveType.TRIANGLES:          geometry.indices = trianglesToLines(indices);          break;        case GeometryAttribute.PrimitiveType.TRIANGLE_STRIP:          geometry.indices = triangleStripToLines(indices);          break;        case GeometryAttribute.PrimitiveType.TRIANGLE_FAN:          geometry.indices = triangleFanToLines(indices);          break;        //>>includeStart('debug', pragmas.debug);        default:          throw new RuntimeError.DeveloperError(            "geometry.primitiveType must be TRIANGLES, TRIANGLE_STRIP, or TRIANGLE_FAN."          );        //>>includeEnd('debug');      }      geometry.primitiveType = GeometryAttribute.PrimitiveType.LINES;    }    return geometry;  };  /**   * Creates a new {@link Geometry} with <code>LINES</code> representing the provided   * attribute (<code>attributeName</code>) for the provided geometry.  This is used to   * visualize vector attributes like normals, tangents, and bitangents.   *   * @param {Geometry} geometry The <code>Geometry</code> instance with the attribute.   * @param {String} [attributeName='normal'] The name of the attribute.   * @param {Number} [length=10000.0] The length of each line segment in meters.  This can be negative to point the vector in the opposite direction.   * @returns {Geometry} A new <code>Geometry</code> instance with line segments for the vector.   *   * @exception {DeveloperError} geometry.attributes must have an attribute with the same name as the attributeName parameter.   *   * @example   * const geometry = Cesium.GeometryPipeline.createLineSegmentsForVectors(instance.geometry, 'bitangent', 100000.0);   */  GeometryPipeline.createLineSegmentsForVectors = function (    geometry,    attributeName,    length  ) {    attributeName = defaultValue.defaultValue(attributeName, "normal");    //>>includeStart('debug', pragmas.debug);    if (!defaultValue.defined(geometry)) {      throw new RuntimeError.DeveloperError("geometry is required.");    }    if (!defaultValue.defined(geometry.attributes.position)) {      throw new RuntimeError.DeveloperError("geometry.attributes.position is required.");    }    if (!defaultValue.defined(geometry.attributes[attributeName])) {      throw new RuntimeError.DeveloperError(        `geometry.attributes must have an attribute with the same name as the attributeName parameter, ${attributeName}.`      );    }    //>>includeEnd('debug');    length = defaultValue.defaultValue(length, 10000.0);    const positions = geometry.attributes.position.values;    const vectors = geometry.attributes[attributeName].values;    const positionsLength = positions.length;    const newPositions = new Float64Array(2 * positionsLength);    let j = 0;    for (let i = 0; i < positionsLength; i += 3) {      newPositions[j++] = positions[i];      newPositions[j++] = positions[i + 1];      newPositions[j++] = positions[i + 2];      newPositions[j++] = positions[i] + vectors[i] * length;      newPositions[j++] = positions[i + 1] + vectors[i + 1] * length;      newPositions[j++] = positions[i + 2] + vectors[i + 2] * length;    }    let newBoundingSphere;    const bs = geometry.boundingSphere;    if (defaultValue.defined(bs)) {      newBoundingSphere = new Transforms.BoundingSphere(bs.center, bs.radius + length);    }    return new GeometryAttribute.Geometry({      attributes: {        position: new GeometryAttribute.GeometryAttribute({          componentDatatype: ComponentDatatype.ComponentDatatype.DOUBLE,          componentsPerAttribute: 3,          values: newPositions,        }),      },      primitiveType: GeometryAttribute.PrimitiveType.LINES,      boundingSphere: newBoundingSphere,    });  };  /**   * Creates an object that maps attribute names to unique locations (indices)   * for matching vertex attributes and shader programs.   *   * @param {Geometry} geometry The geometry, which is not modified, to create the object for.   * @returns {Object} An object with attribute name / index pairs.   *   * @example   * const attributeLocations = Cesium.GeometryPipeline.createAttributeLocations(geometry);   * // Example output   * // {   * //   'position' : 0,   * //   'normal' : 1   * // }   */  GeometryPipeline.createAttributeLocations = function (geometry) {    //>>includeStart('debug', pragmas.debug);    if (!defaultValue.defined(geometry)) {      throw new RuntimeError.DeveloperError("geometry is required.");    }    //>>includeEnd('debug')    // There can be a WebGL performance hit when attribute 0 is disabled, so    // assign attribute locations to well-known attributes.    const semantics = [      "position",      "positionHigh",      "positionLow",      // From VertexFormat.position - after 2D projection and high-precision encoding      "position3DHigh",      "position3DLow",      "position2DHigh",      "position2DLow",      // From Primitive      "pickColor",      // From VertexFormat      "normal",      "st",      "tangent",      "bitangent",      // For shadow volumes      "extrudeDirection",      // From compressing texture coordinates and normals      "compressedAttributes",    ];    const attributes = geometry.attributes;    const indices = {};    let j = 0;    let i;    const len = semantics.length;    // Attribute locations for well-known attributes    for (i = 0; i < len; ++i) {      const semantic = semantics[i];      if (defaultValue.defined(attributes[semantic])) {        indices[semantic] = j++;      }    }    // Locations for custom attributes    for (const name in attributes) {      if (attributes.hasOwnProperty(name) && !defaultValue.defined(indices[name])) {        indices[name] = j++;      }    }    return indices;  };  /**   * Reorders a geometry's attributes and <code>indices</code> to achieve better performance from the GPU's pre-vertex-shader cache.   *   * @param {Geometry} geometry The geometry to modify.   * @returns {Geometry} The modified <code>geometry</code> argument, with its attributes and indices reordered for the GPU's pre-vertex-shader cache.   *   * @exception {DeveloperError} Each attribute array in geometry.attributes must have the same number of attributes.   *   *   * @example   * geometry = Cesium.GeometryPipeline.reorderForPreVertexCache(geometry);   *   * @see GeometryPipeline.reorderForPostVertexCache   */  GeometryPipeline.reorderForPreVertexCache = function (geometry) {    //>>includeStart('debug', pragmas.debug);    if (!defaultValue.defined(geometry)) {      throw new RuntimeError.DeveloperError("geometry is required.");    }    //>>includeEnd('debug');    const numVertices = GeometryAttribute.Geometry.computeNumberOfVertices(geometry);    const indices = geometry.indices;    if (defaultValue.defined(indices)) {      const indexCrossReferenceOldToNew = new Int32Array(numVertices);      for (let i = 0; i < numVertices; i++) {        indexCrossReferenceOldToNew[i] = -1;      }      // Construct cross reference and reorder indices      const indicesIn = indices;      const numIndices = indicesIn.length;      const indicesOut = IndexDatatype.IndexDatatype.createTypedArray(numVertices, numIndices);      let intoIndicesIn = 0;      let intoIndicesOut = 0;      let nextIndex = 0;      let tempIndex;      while (intoIndicesIn < numIndices) {        tempIndex = indexCrossReferenceOldToNew[indicesIn[intoIndicesIn]];        if (tempIndex !== -1) {          indicesOut[intoIndicesOut] = tempIndex;        } else {          tempIndex = indicesIn[intoIndicesIn];          indexCrossReferenceOldToNew[tempIndex] = nextIndex;          indicesOut[intoIndicesOut] = nextIndex;          ++nextIndex;        }        ++intoIndicesIn;        ++intoIndicesOut;      }      geometry.indices = indicesOut;      // Reorder attributes      const attributes = geometry.attributes;      for (const property in attributes) {        if (          attributes.hasOwnProperty(property) &&          defaultValue.defined(attributes[property]) &&          defaultValue.defined(attributes[property].values)        ) {          const attribute = attributes[property];          const elementsIn = attribute.values;          let intoElementsIn = 0;          const numComponents = attribute.componentsPerAttribute;          const elementsOut = ComponentDatatype.ComponentDatatype.createTypedArray(            attribute.componentDatatype,            nextIndex * numComponents          );          while (intoElementsIn < numVertices) {            const temp = indexCrossReferenceOldToNew[intoElementsIn];            if (temp !== -1) {              for (let j = 0; j < numComponents; j++) {                elementsOut[numComponents * temp + j] =                  elementsIn[numComponents * intoElementsIn + j];              }            }            ++intoElementsIn;          }          attribute.values = elementsOut;        }      }    }    return geometry;  };  /**   * Reorders a geometry's <code>indices</code> to achieve better performance from the GPU's   * post vertex-shader cache by using the Tipsify algorithm.  If the geometry <code>primitiveType</code>   * is not <code>TRIANGLES</code> or the geometry does not have an <code>indices</code>, this function has no effect.   *   * @param {Geometry} geometry The geometry to modify.   * @param {Number} [cacheCapacity=24] The number of vertices that can be held in the GPU's vertex cache.   * @returns {Geometry} The modified <code>geometry</code> argument, with its indices reordered for the post-vertex-shader cache.   *   * @exception {DeveloperError} cacheCapacity must be greater than two.   *   *   * @example   * geometry = Cesium.GeometryPipeline.reorderForPostVertexCache(geometry);   *   * @see GeometryPipeline.reorderForPreVertexCache   * @see {@link http://gfx.cs.princ0eton.edu/pubs/Sander_2007_%3ETR/tipsy.pdf|Fast Triangle Reordering for Vertex Locality and Reduced Overdraw}   * by Sander, Nehab, and Barczak   */  GeometryPipeline.reorderForPostVertexCache = function (    geometry,    cacheCapacity  ) {    //>>includeStart('debug', pragmas.debug);    if (!defaultValue.defined(geometry)) {      throw new RuntimeError.DeveloperError("geometry is required.");    }    //>>includeEnd('debug');    const indices = geometry.indices;    if (geometry.primitiveType === GeometryAttribute.PrimitiveType.TRIANGLES && defaultValue.defined(indices)) {      const numIndices = indices.length;      let maximumIndex = 0;      for (let j = 0; j < numIndices; j++) {        if (indices[j] > maximumIndex) {          maximumIndex = indices[j];        }      }      geometry.indices = Tipsify.tipsify({        indices: indices,        maximumIndex: maximumIndex,        cacheSize: cacheCapacity,      });    }    return geometry;  };  function copyAttributesDescriptions(attributes) {    const newAttributes = {};    for (const attribute in attributes) {      if (        attributes.hasOwnProperty(attribute) &&        defaultValue.defined(attributes[attribute]) &&        defaultValue.defined(attributes[attribute].values)      ) {        const attr = attributes[attribute];        newAttributes[attribute] = new GeometryAttribute.GeometryAttribute({          componentDatatype: attr.componentDatatype,          componentsPerAttribute: attr.componentsPerAttribute,          normalize: attr.normalize,          values: [],        });      }    }    return newAttributes;  }  function copyVertex(destinationAttributes, sourceAttributes, index) {    for (const attribute in sourceAttributes) {      if (        sourceAttributes.hasOwnProperty(attribute) &&        defaultValue.defined(sourceAttributes[attribute]) &&        defaultValue.defined(sourceAttributes[attribute].values)      ) {        const attr = sourceAttributes[attribute];        for (let k = 0; k < attr.componentsPerAttribute; ++k) {          destinationAttributes[attribute].values.push(            attr.values[index * attr.componentsPerAttribute + k]          );        }      }    }  }  /**   * Splits a geometry into multiple geometries, if necessary, to ensure that indices in the   * <code>indices</code> fit into unsigned shorts.  This is used to meet the WebGL requirements   * when unsigned int indices are not supported.   * <p>   * If the geometry does not have any <code>indices</code>, this function has no effect.   * </p>   *   * @param {Geometry} geometry The geometry to be split into multiple geometries.   * @returns {Geometry[]} An array of geometries, each with indices that fit into unsigned shorts.   *   * @exception {DeveloperError} geometry.primitiveType must equal to PrimitiveType.TRIANGLES, PrimitiveType.LINES, or PrimitiveType.POINTS   * @exception {DeveloperError} All geometry attribute lists must have the same number of attributes.   *   * @example   * const geometries = Cesium.GeometryPipeline.fitToUnsignedShortIndices(geometry);   */  GeometryPipeline.fitToUnsignedShortIndices = function (geometry) {    //>>includeStart('debug', pragmas.debug);    if (!defaultValue.defined(geometry)) {      throw new RuntimeError.DeveloperError("geometry is required.");    }    if (      defaultValue.defined(geometry.indices) &&      geometry.primitiveType !== GeometryAttribute.PrimitiveType.TRIANGLES &&      geometry.primitiveType !== GeometryAttribute.PrimitiveType.LINES &&      geometry.primitiveType !== GeometryAttribute.PrimitiveType.POINTS    ) {      throw new RuntimeError.DeveloperError(        "geometry.primitiveType must equal to PrimitiveType.TRIANGLES, PrimitiveType.LINES, or PrimitiveType.POINTS."      );    }    //>>includeEnd('debug');    const geometries = [];    // If there's an index list and more than 64K attributes, it is possible that    // some indices are outside the range of unsigned short [0, 64K - 1]    const numberOfVertices = GeometryAttribute.Geometry.computeNumberOfVertices(geometry);    if (      defaultValue.defined(geometry.indices) &&      numberOfVertices >= ComponentDatatype.CesiumMath.SIXTY_FOUR_KILOBYTES    ) {      let oldToNewIndex = [];      let newIndices = [];      let currentIndex = 0;      let newAttributes = copyAttributesDescriptions(geometry.attributes);      const originalIndices = geometry.indices;      const numberOfIndices = originalIndices.length;      let indicesPerPrimitive;      if (geometry.primitiveType === GeometryAttribute.PrimitiveType.TRIANGLES) {        indicesPerPrimitive = 3;      } else if (geometry.primitiveType === GeometryAttribute.PrimitiveType.LINES) {        indicesPerPrimitive = 2;      } else if (geometry.primitiveType === GeometryAttribute.PrimitiveType.POINTS) {        indicesPerPrimitive = 1;      }      for (let j = 0; j < numberOfIndices; j += indicesPerPrimitive) {        for (let k = 0; k < indicesPerPrimitive; ++k) {          const x = originalIndices[j + k];          let i = oldToNewIndex[x];          if (!defaultValue.defined(i)) {            i = currentIndex++;            oldToNewIndex[x] = i;            copyVertex(newAttributes, geometry.attributes, x);          }          newIndices.push(i);        }        if (          currentIndex + indicesPerPrimitive >=          ComponentDatatype.CesiumMath.SIXTY_FOUR_KILOBYTES        ) {          geometries.push(            new GeometryAttribute.Geometry({              attributes: newAttributes,              indices: newIndices,              primitiveType: geometry.primitiveType,              boundingSphere: geometry.boundingSphere,              boundingSphereCV: geometry.boundingSphereCV,            })          );          // Reset for next vertex-array          oldToNewIndex = [];          newIndices = [];          currentIndex = 0;          newAttributes = copyAttributesDescriptions(geometry.attributes);        }      }      if (newIndices.length !== 0) {        geometries.push(          new GeometryAttribute.Geometry({            attributes: newAttributes,            indices: newIndices,            primitiveType: geometry.primitiveType,            boundingSphere: geometry.boundingSphere,            boundingSphereCV: geometry.boundingSphereCV,          })        );      }    } else {      // No need to split into multiple geometries      geometries.push(geometry);    }    return geometries;  };  const scratchProjectTo2DCartesian3 = new Matrix2.Cartesian3();  const scratchProjectTo2DCartographic = new Matrix2.Cartographic();  /**   * Projects a geometry's 3D <code>position</code> attribute to 2D, replacing the <code>position</code>   * attribute with separate <code>position3D</code> and <code>position2D</code> attributes.   * <p>   * If the geometry does not have a <code>position</code>, this function has no effect.   * </p>   *   * @param {Geometry} geometry The geometry to modify.   * @param {String} attributeName The name of the attribute.   * @param {String} attributeName3D The name of the attribute in 3D.   * @param {String} attributeName2D The name of the attribute in 2D.   * @param {Object} [projection=new GeographicProjection()] The projection to use.   * @returns {Geometry} The modified <code>geometry</code> argument with <code>position3D</code> and <code>position2D</code> attributes.   *   * @exception {DeveloperError} geometry must have attribute matching the attributeName argument.   * @exception {DeveloperError} The attribute componentDatatype must be ComponentDatatype.DOUBLE.   * @exception {DeveloperError} Could not project a point to 2D.   *   * @example   * geometry = Cesium.GeometryPipeline.projectTo2D(geometry, 'position', 'position3D', 'position2D');   */  GeometryPipeline.projectTo2D = function (    geometry,    attributeName,    attributeName3D,    attributeName2D,    projection  ) {    //>>includeStart('debug', pragmas.debug);    if (!defaultValue.defined(geometry)) {      throw new RuntimeError.DeveloperError("geometry is required.");    }    if (!defaultValue.defined(attributeName)) {      throw new RuntimeError.DeveloperError("attributeName is required.");    }    if (!defaultValue.defined(attributeName3D)) {      throw new RuntimeError.DeveloperError("attributeName3D is required.");    }    if (!defaultValue.defined(attributeName2D)) {      throw new RuntimeError.DeveloperError("attributeName2D is required.");    }    if (!defaultValue.defined(geometry.attributes[attributeName])) {      throw new RuntimeError.DeveloperError(        `geometry must have attribute matching the attributeName argument: ${attributeName}.`      );    }    if (      geometry.attributes[attributeName].componentDatatype !==      ComponentDatatype.ComponentDatatype.DOUBLE    ) {      throw new RuntimeError.DeveloperError(        "The attribute componentDatatype must be ComponentDatatype.DOUBLE."      );    }    //>>includeEnd('debug');    const attribute = geometry.attributes[attributeName];    projection = defaultValue.defined(projection) ? projection : new Transforms.GeographicProjection();    const ellipsoid = projection.ellipsoid;    // Project original values to 2D.    const values3D = attribute.values;    const projectedValues = new Float64Array(values3D.length);    let index = 0;    for (let i = 0; i < values3D.length; i += 3) {      const value = Matrix2.Cartesian3.fromArray(        values3D,        i,        scratchProjectTo2DCartesian3      );      const lonLat = ellipsoid.cartesianToCartographic(        value,        scratchProjectTo2DCartographic      );      //>>includeStart('debug', pragmas.debug);      if (!defaultValue.defined(lonLat)) {        throw new RuntimeError.DeveloperError(          `Could not project point (${value.x}, ${value.y}, ${value.z}) to 2D.`        );      }      //>>includeEnd('debug');      const projectedLonLat = projection.project(        lonLat,        scratchProjectTo2DCartesian3      );      projectedValues[index++] = projectedLonLat.x;      projectedValues[index++] = projectedLonLat.y;      projectedValues[index++] = projectedLonLat.z;    }    // Rename original cartesians to WGS84 cartesians.    geometry.attributes[attributeName3D] = attribute;    // Replace original cartesians with 2D projected cartesians    geometry.attributes[attributeName2D] = new GeometryAttribute.GeometryAttribute({      componentDatatype: ComponentDatatype.ComponentDatatype.DOUBLE,      componentsPerAttribute: 3,      values: projectedValues,    });    delete geometry.attributes[attributeName];    return geometry;  };  const encodedResult = {    high: 0.0,    low: 0.0,  };  /**   * Encodes floating-point geometry attribute values as two separate attributes to improve   * rendering precision.   * <p>   * This is commonly used to create high-precision position vertex attributes.   * </p>   *   * @param {Geometry} geometry The geometry to modify.   * @param {String} attributeName The name of the attribute.   * @param {String} attributeHighName The name of the attribute for the encoded high bits.   * @param {String} attributeLowName The name of the attribute for the encoded low bits.   * @returns {Geometry} The modified <code>geometry</code> argument, with its encoded attribute.   *   * @exception {DeveloperError} geometry must have attribute matching the attributeName argument.   * @exception {DeveloperError} The attribute componentDatatype must be ComponentDatatype.DOUBLE.   *   * @example   * geometry = Cesium.GeometryPipeline.encodeAttribute(geometry, 'position3D', 'position3DHigh', 'position3DLow');   */  GeometryPipeline.encodeAttribute = function (    geometry,    attributeName,    attributeHighName,    attributeLowName  ) {    //>>includeStart('debug', pragmas.debug);    if (!defaultValue.defined(geometry)) {      throw new RuntimeError.DeveloperError("geometry is required.");    }    if (!defaultValue.defined(attributeName)) {      throw new RuntimeError.DeveloperError("attributeName is required.");    }    if (!defaultValue.defined(attributeHighName)) {      throw new RuntimeError.DeveloperError("attributeHighName is required.");    }    if (!defaultValue.defined(attributeLowName)) {      throw new RuntimeError.DeveloperError("attributeLowName is required.");    }    if (!defaultValue.defined(geometry.attributes[attributeName])) {      throw new RuntimeError.DeveloperError(        `geometry must have attribute matching the attributeName argument: ${attributeName}.`      );    }    if (      geometry.attributes[attributeName].componentDatatype !==      ComponentDatatype.ComponentDatatype.DOUBLE    ) {      throw new RuntimeError.DeveloperError(        "The attribute componentDatatype must be ComponentDatatype.DOUBLE."      );    }    //>>includeEnd('debug');    const attribute = geometry.attributes[attributeName];    const values = attribute.values;    const length = values.length;    const highValues = new Float32Array(length);    const lowValues = new Float32Array(length);    for (let i = 0; i < length; ++i) {      EncodedCartesian3.EncodedCartesian3.encode(values[i], encodedResult);      highValues[i] = encodedResult.high;      lowValues[i] = encodedResult.low;    }    const componentsPerAttribute = attribute.componentsPerAttribute;    geometry.attributes[attributeHighName] = new GeometryAttribute.GeometryAttribute({      componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,      componentsPerAttribute: componentsPerAttribute,      values: highValues,    });    geometry.attributes[attributeLowName] = new GeometryAttribute.GeometryAttribute({      componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,      componentsPerAttribute: componentsPerAttribute,      values: lowValues,    });    delete geometry.attributes[attributeName];    return geometry;  };  let scratchCartesian3 = new Matrix2.Cartesian3();  function transformPoint(matrix, attribute) {    if (defaultValue.defined(attribute)) {      const values = attribute.values;      const length = values.length;      for (let i = 0; i < length; i += 3) {        Matrix2.Cartesian3.unpack(values, i, scratchCartesian3);        Matrix2.Matrix4.multiplyByPoint(matrix, scratchCartesian3, scratchCartesian3);        Matrix2.Cartesian3.pack(scratchCartesian3, values, i);      }    }  }  function transformVector(matrix, attribute) {    if (defaultValue.defined(attribute)) {      const values = attribute.values;      const length = values.length;      for (let i = 0; i < length; i += 3) {        Matrix2.Cartesian3.unpack(values, i, scratchCartesian3);        Matrix2.Matrix3.multiplyByVector(matrix, scratchCartesian3, scratchCartesian3);        scratchCartesian3 = Matrix2.Cartesian3.normalize(          scratchCartesian3,          scratchCartesian3        );        Matrix2.Cartesian3.pack(scratchCartesian3, values, i);      }    }  }  const inverseTranspose = new Matrix2.Matrix4();  const normalMatrix = new Matrix2.Matrix3();  /**   * Transforms a geometry instance to world coordinates.  This changes   * the instance's <code>modelMatrix</code> to {@link Matrix4.IDENTITY} and transforms the   * following attributes if they are present: <code>position</code>, <code>normal</code>,   * <code>tangent</code>, and <code>bitangent</code>.   *   * @param {GeometryInstance} instance The geometry instance to modify.   * @returns {GeometryInstance} The modified <code>instance</code> argument, with its attributes transforms to world coordinates.   *   * @example   * Cesium.GeometryPipeline.transformToWorldCoordinates(instance);   */  GeometryPipeline.transformToWorldCoordinates = function (instance) {    //>>includeStart('debug', pragmas.debug);    if (!defaultValue.defined(instance)) {      throw new RuntimeError.DeveloperError("instance is required.");    }    //>>includeEnd('debug');    const modelMatrix = instance.modelMatrix;    if (Matrix2.Matrix4.equals(modelMatrix, Matrix2.Matrix4.IDENTITY)) {      // Already in world coordinates      return instance;    }    const attributes = instance.geometry.attributes;    // Transform attributes in known vertex formats    transformPoint(modelMatrix, attributes.position);    transformPoint(modelMatrix, attributes.prevPosition);    transformPoint(modelMatrix, attributes.nextPosition);    if (      defaultValue.defined(attributes.normal) ||      defaultValue.defined(attributes.tangent) ||      defaultValue.defined(attributes.bitangent)    ) {      Matrix2.Matrix4.inverse(modelMatrix, inverseTranspose);      Matrix2.Matrix4.transpose(inverseTranspose, inverseTranspose);      Matrix2.Matrix4.getMatrix3(inverseTranspose, normalMatrix);      transformVector(normalMatrix, attributes.normal);      transformVector(normalMatrix, attributes.tangent);      transformVector(normalMatrix, attributes.bitangent);    }    const boundingSphere = instance.geometry.boundingSphere;    if (defaultValue.defined(boundingSphere)) {      instance.geometry.boundingSphere = Transforms.BoundingSphere.transform(        boundingSphere,        modelMatrix,        boundingSphere      );    }    instance.modelMatrix = Matrix2.Matrix4.clone(Matrix2.Matrix4.IDENTITY);    return instance;  };  function findAttributesInAllGeometries(instances, propertyName) {    const length = instances.length;    const attributesInAllGeometries = {};    const attributes0 = instances[0][propertyName].attributes;    let name;    for (name in attributes0) {      if (        attributes0.hasOwnProperty(name) &&        defaultValue.defined(attributes0[name]) &&        defaultValue.defined(attributes0[name].values)      ) {        const attribute = attributes0[name];        let numberOfComponents = attribute.values.length;        let inAllGeometries = true;        // Does this same attribute exist in all geometries?        for (let i = 1; i < length; ++i) {          const otherAttribute = instances[i][propertyName].attributes[name];          if (            !defaultValue.defined(otherAttribute) ||            attribute.componentDatatype !== otherAttribute.componentDatatype ||            attribute.componentsPerAttribute !==              otherAttribute.componentsPerAttribute ||            attribute.normalize !== otherAttribute.normalize          ) {            inAllGeometries = false;            break;          }          numberOfComponents += otherAttribute.values.length;        }        if (inAllGeometries) {          attributesInAllGeometries[name] = new GeometryAttribute.GeometryAttribute({            componentDatatype: attribute.componentDatatype,            componentsPerAttribute: attribute.componentsPerAttribute,            normalize: attribute.normalize,            values: ComponentDatatype.ComponentDatatype.createTypedArray(              attribute.componentDatatype,              numberOfComponents            ),          });        }      }    }    return attributesInAllGeometries;  }  const tempScratch = new Matrix2.Cartesian3();  function combineGeometries(instances, propertyName) {    const length = instances.length;    let name;    let i;    let j;    let k;    const m = instances[0].modelMatrix;    const haveIndices = defaultValue.defined(instances[0][propertyName].indices);    const primitiveType = instances[0][propertyName].primitiveType;    //>>includeStart('debug', pragmas.debug);    for (i = 1; i < length; ++i) {      if (!Matrix2.Matrix4.equals(instances[i].modelMatrix, m)) {        throw new RuntimeError.DeveloperError("All instances must have the same modelMatrix.");      }      if (defaultValue.defined(instances[i][propertyName].indices) !== haveIndices) {        throw new RuntimeError.DeveloperError(          "All instance geometries must have an indices or not have one."        );      }      if (instances[i][propertyName].primitiveType !== primitiveType) {        throw new RuntimeError.DeveloperError(          "All instance geometries must have the same primitiveType."        );      }    }    //>>includeEnd('debug');    // Find subset of attributes in all geometries    const attributes = findAttributesInAllGeometries(instances, propertyName);    let values;    let sourceValues;    let sourceValuesLength;    // Combine attributes from each geometry into a single typed array    for (name in attributes) {      if (attributes.hasOwnProperty(name)) {        values = attributes[name].values;        k = 0;        for (i = 0; i < length; ++i) {          sourceValues = instances[i][propertyName].attributes[name].values;          sourceValuesLength = sourceValues.length;          for (j = 0; j < sourceValuesLength; ++j) {            values[k++] = sourceValues[j];          }        }      }    }    // Combine index lists    let indices;    if (haveIndices) {      let numberOfIndices = 0;      for (i = 0; i < length; ++i) {        numberOfIndices += instances[i][propertyName].indices.length;      }      const numberOfVertices = GeometryAttribute.Geometry.computeNumberOfVertices(        new GeometryAttribute.Geometry({          attributes: attributes,          primitiveType: GeometryAttribute.PrimitiveType.POINTS,        })      );      const destIndices = IndexDatatype.IndexDatatype.createTypedArray(        numberOfVertices,        numberOfIndices      );      let destOffset = 0;      let offset = 0;      for (i = 0; i < length; ++i) {        const sourceIndices = instances[i][propertyName].indices;        const sourceIndicesLen = sourceIndices.length;        for (k = 0; k < sourceIndicesLen; ++k) {          destIndices[destOffset++] = offset + sourceIndices[k];        }        offset += GeometryAttribute.Geometry.computeNumberOfVertices(instances[i][propertyName]);      }      indices = destIndices;    }    // Create bounding sphere that includes all instances    let center = new Matrix2.Cartesian3();    let radius = 0.0;    let bs;    for (i = 0; i < length; ++i) {      bs = instances[i][propertyName].boundingSphere;      if (!defaultValue.defined(bs)) {        // If any geometries have an undefined bounding sphere, then so does the combined geometry        center = undefined;        break;      }      Matrix2.Cartesian3.add(bs.center, center, center);    }    if (defaultValue.defined(center)) {      Matrix2.Cartesian3.divideByScalar(center, length, center);      for (i = 0; i < length; ++i) {        bs = instances[i][propertyName].boundingSphere;        const tempRadius =          Matrix2.Cartesian3.magnitude(            Matrix2.Cartesian3.subtract(bs.center, center, tempScratch)          ) + bs.radius;        if (tempRadius > radius) {          radius = tempRadius;        }      }    }    return new GeometryAttribute.Geometry({      attributes: attributes,      indices: indices,      primitiveType: primitiveType,      boundingSphere: defaultValue.defined(center)        ? new Transforms.BoundingSphere(center, radius)        : undefined,    });  }  /**   * Combines geometry from several {@link GeometryInstance} objects into one geometry.   * This concatenates the attributes, concatenates and adjusts the indices, and creates   * a bounding sphere encompassing all instances.   * <p>   * If the instances do not have the same attributes, a subset of attributes common   * to all instances is used, and the others are ignored.   * </p>   * <p>   * This is used by {@link Primitive} to efficiently render a large amount of static data.   * </p>   *   * @private   *   * @param {GeometryInstance[]} [instances] The array of {@link GeometryInstance} objects whose geometry will be combined.   * @returns {Geometry} A single geometry created from the provided geometry instances.   *   * @exception {DeveloperError} All instances must have the same modelMatrix.   * @exception {DeveloperError} All instance geometries must have an indices or not have one.   * @exception {DeveloperError} All instance geometries must have the same primitiveType.   *   *   * @example   * for (let i = 0; i < instances.length; ++i) {   *   Cesium.GeometryPipeline.transformToWorldCoordinates(instances[i]);   * }   * const geometries = Cesium.GeometryPipeline.combineInstances(instances);   *   * @see GeometryPipeline.transformToWorldCoordinates   */  GeometryPipeline.combineInstances = function (instances) {    //>>includeStart('debug', pragmas.debug);    if (!defaultValue.defined(instances) || instances.length < 1) {      throw new RuntimeError.DeveloperError(        "instances is required and must have length greater than zero."      );    }    //>>includeEnd('debug');    const instanceGeometry = [];    const instanceSplitGeometry = [];    const length = instances.length;    for (let i = 0; i < length; ++i) {      const instance = instances[i];      if (defaultValue.defined(instance.geometry)) {        instanceGeometry.push(instance);      } else if (        defaultValue.defined(instance.westHemisphereGeometry) &&        defaultValue.defined(instance.eastHemisphereGeometry)      ) {        instanceSplitGeometry.push(instance);      }    }    const geometries = [];    if (instanceGeometry.length > 0) {      geometries.push(combineGeometries(instanceGeometry, "geometry"));    }    if (instanceSplitGeometry.length > 0) {      geometries.push(        combineGeometries(instanceSplitGeometry, "westHemisphereGeometry")      );      geometries.push(        combineGeometries(instanceSplitGeometry, "eastHemisphereGeometry")      );    }    return geometries;  };  const normal = new Matrix2.Cartesian3();  const v0 = new Matrix2.Cartesian3();  const v1 = new Matrix2.Cartesian3();  const v2 = new Matrix2.Cartesian3();  /**   * Computes per-vertex normals for a geometry containing <code>TRIANGLES</code> by averaging the normals of   * all triangles incident to the vertex.  The result is a new <code>normal</code> attribute added to the geometry.   * This assumes a counter-clockwise winding order.   *   * @param {Geometry} geometry The geometry to modify.   * @returns {Geometry} The modified <code>geometry</code> argument with the computed <code>normal</code> attribute.   *   * @exception {DeveloperError} geometry.indices length must be greater than 0 and be a multiple of 3.   * @exception {DeveloperError} geometry.primitiveType must be {@link PrimitiveType.TRIANGLES}.   *   * @example   * Cesium.GeometryPipeline.computeNormal(geometry);   */  GeometryPipeline.computeNormal = function (geometry) {    //>>includeStart('debug', pragmas.debug);    if (!defaultValue.defined(geometry)) {      throw new RuntimeError.DeveloperError("geometry is required.");    }    if (      !defaultValue.defined(geometry.attributes.position) ||      !defaultValue.defined(geometry.attributes.position.values)    ) {      throw new RuntimeError.DeveloperError(        "geometry.attributes.position.values is required."      );    }    if (!defaultValue.defined(geometry.indices)) {      throw new RuntimeError.DeveloperError("geometry.indices is required.");    }    if (geometry.indices.length < 2 || geometry.indices.length % 3 !== 0) {      throw new RuntimeError.DeveloperError(        "geometry.indices length must be greater than 0 and be a multiple of 3."      );    }    if (geometry.primitiveType !== GeometryAttribute.PrimitiveType.TRIANGLES) {      throw new RuntimeError.DeveloperError(        "geometry.primitiveType must be PrimitiveType.TRIANGLES."      );    }    //>>includeEnd('debug');    const indices = geometry.indices;    const attributes = geometry.attributes;    const vertices = attributes.position.values;    const numVertices = attributes.position.values.length / 3;    const numIndices = indices.length;    const normalsPerVertex = new Array(numVertices);    const normalsPerTriangle = new Array(numIndices / 3);    const normalIndices = new Array(numIndices);    let i;    for (i = 0; i < numVertices; i++) {      normalsPerVertex[i] = {        indexOffset: 0,        count: 0,        currentCount: 0,      };    }    let j = 0;    for (i = 0; i < numIndices; i += 3) {      const i0 = indices[i];      const i1 = indices[i + 1];      const i2 = indices[i + 2];      const i03 = i0 * 3;      const i13 = i1 * 3;      const i23 = i2 * 3;      v0.x = vertices[i03];      v0.y = vertices[i03 + 1];      v0.z = vertices[i03 + 2];      v1.x = vertices[i13];      v1.y = vertices[i13 + 1];      v1.z = vertices[i13 + 2];      v2.x = vertices[i23];      v2.y = vertices[i23 + 1];      v2.z = vertices[i23 + 2];      normalsPerVertex[i0].count++;      normalsPerVertex[i1].count++;      normalsPerVertex[i2].count++;      Matrix2.Cartesian3.subtract(v1, v0, v1);      Matrix2.Cartesian3.subtract(v2, v0, v2);      normalsPerTriangle[j] = Matrix2.Cartesian3.cross(v1, v2, new Matrix2.Cartesian3());      j++;    }    let indexOffset = 0;    for (i = 0; i < numVertices; i++) {      normalsPerVertex[i].indexOffset += indexOffset;      indexOffset += normalsPerVertex[i].count;    }    j = 0;    let vertexNormalData;    for (i = 0; i < numIndices; i += 3) {      vertexNormalData = normalsPerVertex[indices[i]];      let index = vertexNormalData.indexOffset + vertexNormalData.currentCount;      normalIndices[index] = j;      vertexNormalData.currentCount++;      vertexNormalData = normalsPerVertex[indices[i + 1]];      index = vertexNormalData.indexOffset + vertexNormalData.currentCount;      normalIndices[index] = j;      vertexNormalData.currentCount++;      vertexNormalData = normalsPerVertex[indices[i + 2]];      index = vertexNormalData.indexOffset + vertexNormalData.currentCount;      normalIndices[index] = j;      vertexNormalData.currentCount++;      j++;    }    const normalValues = new Float32Array(numVertices * 3);    for (i = 0; i < numVertices; i++) {      const i3 = i * 3;      vertexNormalData = normalsPerVertex[i];      Matrix2.Cartesian3.clone(Matrix2.Cartesian3.ZERO, normal);      if (vertexNormalData.count > 0) {        for (j = 0; j < vertexNormalData.count; j++) {          Matrix2.Cartesian3.add(            normal,            normalsPerTriangle[normalIndices[vertexNormalData.indexOffset + j]],            normal          );        }        // We can run into an issue where a vertex is used with 2 primitives that have opposite winding order.        if (          Matrix2.Cartesian3.equalsEpsilon(Matrix2.Cartesian3.ZERO, normal, ComponentDatatype.CesiumMath.EPSILON10)        ) {          Matrix2.Cartesian3.clone(            normalsPerTriangle[normalIndices[vertexNormalData.indexOffset]],            normal          );        }      }      // We end up with a zero vector probably because of a degenerate triangle      if (        Matrix2.Cartesian3.equalsEpsilon(Matrix2.Cartesian3.ZERO, normal, ComponentDatatype.CesiumMath.EPSILON10)      ) {        // Default to (0,0,1)        normal.z = 1.0;      }      Matrix2.Cartesian3.normalize(normal, normal);      normalValues[i3] = normal.x;      normalValues[i3 + 1] = normal.y;      normalValues[i3 + 2] = normal.z;    }    geometry.attributes.normal = new GeometryAttribute.GeometryAttribute({      componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,      componentsPerAttribute: 3,      values: normalValues,    });    return geometry;  };  const normalScratch = new Matrix2.Cartesian3();  const normalScale = new Matrix2.Cartesian3();  const tScratch = new Matrix2.Cartesian3();  /**   * Computes per-vertex tangents and bitangents for a geometry containing <code>TRIANGLES</code>.   * The result is new <code>tangent</code> and <code>bitangent</code> attributes added to the geometry.   * This assumes a counter-clockwise winding order.   * <p>   * Based on <a href="http://www.terathon.com/code/tangent.html">Computing Tangent Space Basis Vectors   * for an Arbitrary Mesh</a> by Eric Lengyel.   * </p>   *   * @param {Geometry} geometry The geometry to modify.   * @returns {Geometry} The modified <code>geometry</code> argument with the computed <code>tangent</code> and <code>bitangent</code> attributes.   *   * @exception {DeveloperError} geometry.indices length must be greater than 0 and be a multiple of 3.   * @exception {DeveloperError} geometry.primitiveType must be {@link PrimitiveType.TRIANGLES}.   *   * @example   * Cesium.GeometryPipeline.computeTangentAndBiTangent(geometry);   */  GeometryPipeline.computeTangentAndBitangent = function (geometry) {    //>>includeStart('debug', pragmas.debug);    if (!defaultValue.defined(geometry)) {      throw new RuntimeError.DeveloperError("geometry is required.");    }    //>>includeEnd('debug');    const attributes = geometry.attributes;    const indices = geometry.indices;    //>>includeStart('debug', pragmas.debug);    if (!defaultValue.defined(attributes.position) || !defaultValue.defined(attributes.position.values)) {      throw new RuntimeError.DeveloperError(        "geometry.attributes.position.values is required."      );    }    if (!defaultValue.defined(attributes.normal) || !defaultValue.defined(attributes.normal.values)) {      throw new RuntimeError.DeveloperError("geometry.attributes.normal.values is required.");    }    if (!defaultValue.defined(attributes.st) || !defaultValue.defined(attributes.st.values)) {      throw new RuntimeError.DeveloperError("geometry.attributes.st.values is required.");    }    if (!defaultValue.defined(indices)) {      throw new RuntimeError.DeveloperError("geometry.indices is required.");    }    if (indices.length < 2 || indices.length % 3 !== 0) {      throw new RuntimeError.DeveloperError(        "geometry.indices length must be greater than 0 and be a multiple of 3."      );    }    if (geometry.primitiveType !== GeometryAttribute.PrimitiveType.TRIANGLES) {      throw new RuntimeError.DeveloperError(        "geometry.primitiveType must be PrimitiveType.TRIANGLES."      );    }    //>>includeEnd('debug');    const vertices = geometry.attributes.position.values;    const normals = geometry.attributes.normal.values;    const st = geometry.attributes.st.values;    const numVertices = geometry.attributes.position.values.length / 3;    const numIndices = indices.length;    const tan1 = new Array(numVertices * 3);    let i;    for (i = 0; i < tan1.length; i++) {      tan1[i] = 0;    }    let i03;    let i13;    let i23;    for (i = 0; i < numIndices; i += 3) {      const i0 = indices[i];      const i1 = indices[i + 1];      const i2 = indices[i + 2];      i03 = i0 * 3;      i13 = i1 * 3;      i23 = i2 * 3;      const i02 = i0 * 2;      const i12 = i1 * 2;      const i22 = i2 * 2;      const ux = vertices[i03];      const uy = vertices[i03 + 1];      const uz = vertices[i03 + 2];      const wx = st[i02];      const wy = st[i02 + 1];      const t1 = st[i12 + 1] - wy;      const t2 = st[i22 + 1] - wy;      const r = 1.0 / ((st[i12] - wx) * t2 - (st[i22] - wx) * t1);      const sdirx = (t2 * (vertices[i13] - ux) - t1 * (vertices[i23] - ux)) * r;      const sdiry =        (t2 * (vertices[i13 + 1] - uy) - t1 * (vertices[i23 + 1] - uy)) * r;      const sdirz =        (t2 * (vertices[i13 + 2] - uz) - t1 * (vertices[i23 + 2] - uz)) * r;      tan1[i03] += sdirx;      tan1[i03 + 1] += sdiry;      tan1[i03 + 2] += sdirz;      tan1[i13] += sdirx;      tan1[i13 + 1] += sdiry;      tan1[i13 + 2] += sdirz;      tan1[i23] += sdirx;      tan1[i23 + 1] += sdiry;      tan1[i23 + 2] += sdirz;    }    const tangentValues = new Float32Array(numVertices * 3);    const bitangentValues = new Float32Array(numVertices * 3);    for (i = 0; i < numVertices; i++) {      i03 = i * 3;      i13 = i03 + 1;      i23 = i03 + 2;      const n = Matrix2.Cartesian3.fromArray(normals, i03, normalScratch);      const t = Matrix2.Cartesian3.fromArray(tan1, i03, tScratch);      const scalar = Matrix2.Cartesian3.dot(n, t);      Matrix2.Cartesian3.multiplyByScalar(n, scalar, normalScale);      Matrix2.Cartesian3.normalize(Matrix2.Cartesian3.subtract(t, normalScale, t), t);      tangentValues[i03] = t.x;      tangentValues[i13] = t.y;      tangentValues[i23] = t.z;      Matrix2.Cartesian3.normalize(Matrix2.Cartesian3.cross(n, t, t), t);      bitangentValues[i03] = t.x;      bitangentValues[i13] = t.y;      bitangentValues[i23] = t.z;    }    geometry.attributes.tangent = new GeometryAttribute.GeometryAttribute({      componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,      componentsPerAttribute: 3,      values: tangentValues,    });    geometry.attributes.bitangent = new GeometryAttribute.GeometryAttribute({      componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,      componentsPerAttribute: 3,      values: bitangentValues,    });    return geometry;  };  const scratchCartesian2 = new Matrix2.Cartesian2();  const toEncode1 = new Matrix2.Cartesian3();  const toEncode2 = new Matrix2.Cartesian3();  const toEncode3 = new Matrix2.Cartesian3();  let encodeResult2 = new Matrix2.Cartesian2();  /**   * Compresses and packs geometry normal attribute values to save memory.   *   * @param {Geometry} geometry The geometry to modify.   * @returns {Geometry} The modified <code>geometry</code> argument, with its normals compressed and packed.   *   * @example   * geometry = Cesium.GeometryPipeline.compressVertices(geometry);   */  GeometryPipeline.compressVertices = function (geometry) {    //>>includeStart('debug', pragmas.debug);    if (!defaultValue.defined(geometry)) {      throw new RuntimeError.DeveloperError("geometry is required.");    }    //>>includeEnd('debug');    const extrudeAttribute = geometry.attributes.extrudeDirection;    let i;    let numVertices;    if (defaultValue.defined(extrudeAttribute)) {      //only shadow volumes use extrudeDirection, and shadow volumes use vertexFormat: POSITION_ONLY so we don't need to check other attributes      const extrudeDirections = extrudeAttribute.values;      numVertices = extrudeDirections.length / 3.0;      const compressedDirections = new Float32Array(numVertices * 2);      let i2 = 0;      for (i = 0; i < numVertices; ++i) {        Matrix2.Cartesian3.fromArray(extrudeDirections, i * 3.0, toEncode1);        if (Matrix2.Cartesian3.equals(toEncode1, Matrix2.Cartesian3.ZERO)) {          i2 += 2;          continue;        }        encodeResult2 = AttributeCompression.AttributeCompression.octEncodeInRange(          toEncode1,          65535,          encodeResult2        );        compressedDirections[i2++] = encodeResult2.x;        compressedDirections[i2++] = encodeResult2.y;      }      geometry.attributes.compressedAttributes = new GeometryAttribute.GeometryAttribute({        componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,        componentsPerAttribute: 2,        values: compressedDirections,      });      delete geometry.attributes.extrudeDirection;      return geometry;    }    const normalAttribute = geometry.attributes.normal;    const stAttribute = geometry.attributes.st;    const hasNormal = defaultValue.defined(normalAttribute);    const hasSt = defaultValue.defined(stAttribute);    if (!hasNormal && !hasSt) {      return geometry;    }    const tangentAttribute = geometry.attributes.tangent;    const bitangentAttribute = geometry.attributes.bitangent;    const hasTangent = defaultValue.defined(tangentAttribute);    const hasBitangent = defaultValue.defined(bitangentAttribute);    let normals;    let st;    let tangents;    let bitangents;    if (hasNormal) {      normals = normalAttribute.values;    }    if (hasSt) {      st = stAttribute.values;    }    if (hasTangent) {      tangents = tangentAttribute.values;    }    if (hasBitangent) {      bitangents = bitangentAttribute.values;    }    const length = hasNormal ? normals.length : st.length;    const numComponents = hasNormal ? 3.0 : 2.0;    numVertices = length / numComponents;    let compressedLength = numVertices;    let numCompressedComponents = hasSt && hasNormal ? 2.0 : 1.0;    numCompressedComponents += hasTangent || hasBitangent ? 1.0 : 0.0;    compressedLength *= numCompressedComponents;    const compressedAttributes = new Float32Array(compressedLength);    let normalIndex = 0;    for (i = 0; i < numVertices; ++i) {      if (hasSt) {        Matrix2.Cartesian2.fromArray(st, i * 2.0, scratchCartesian2);        compressedAttributes[          normalIndex++        ] = AttributeCompression.AttributeCompression.compressTextureCoordinates(scratchCartesian2);      }      const index = i * 3.0;      if (hasNormal && defaultValue.defined(tangents) && defaultValue.defined(bitangents)) {        Matrix2.Cartesian3.fromArray(normals, index, toEncode1);        Matrix2.Cartesian3.fromArray(tangents, index, toEncode2);        Matrix2.Cartesian3.fromArray(bitangents, index, toEncode3);        AttributeCompression.AttributeCompression.octPack(          toEncode1,          toEncode2,          toEncode3,          scratchCartesian2        );        compressedAttributes[normalIndex++] = scratchCartesian2.x;        compressedAttributes[normalIndex++] = scratchCartesian2.y;      } else {        if (hasNormal) {          Matrix2.Cartesian3.fromArray(normals, index, toEncode1);          compressedAttributes[            normalIndex++          ] = AttributeCompression.AttributeCompression.octEncodeFloat(toEncode1);        }        if (hasTangent) {          Matrix2.Cartesian3.fromArray(tangents, index, toEncode1);          compressedAttributes[            normalIndex++          ] = AttributeCompression.AttributeCompression.octEncodeFloat(toEncode1);        }        if (hasBitangent) {          Matrix2.Cartesian3.fromArray(bitangents, index, toEncode1);          compressedAttributes[            normalIndex++          ] = AttributeCompression.AttributeCompression.octEncodeFloat(toEncode1);        }      }    }    geometry.attributes.compressedAttributes = new GeometryAttribute.GeometryAttribute({      componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,      componentsPerAttribute: numCompressedComponents,      values: compressedAttributes,    });    if (hasNormal) {      delete geometry.attributes.normal;    }    if (hasSt) {      delete geometry.attributes.st;    }    if (hasBitangent) {      delete geometry.attributes.bitangent;    }    if (hasTangent) {      delete geometry.attributes.tangent;    }    return geometry;  };  function indexTriangles(geometry) {    if (defaultValue.defined(geometry.indices)) {      return geometry;    }    const numberOfVertices = GeometryAttribute.Geometry.computeNumberOfVertices(geometry);    //>>includeStart('debug', pragmas.debug);    if (numberOfVertices < 3) {      throw new RuntimeError.DeveloperError("The number of vertices must be at least three.");    }    if (numberOfVertices % 3 !== 0) {      throw new RuntimeError.DeveloperError(        "The number of vertices must be a multiple of three."      );    }    //>>includeEnd('debug');    const indices = IndexDatatype.IndexDatatype.createTypedArray(      numberOfVertices,      numberOfVertices    );    for (let i = 0; i < numberOfVertices; ++i) {      indices[i] = i;    }    geometry.indices = indices;    return geometry;  }  function indexTriangleFan(geometry) {    const numberOfVertices = GeometryAttribute.Geometry.computeNumberOfVertices(geometry);    //>>includeStart('debug', pragmas.debug);    if (numberOfVertices < 3) {      throw new RuntimeError.DeveloperError("The number of vertices must be at least three.");    }    //>>includeEnd('debug');    const indices = IndexDatatype.IndexDatatype.createTypedArray(      numberOfVertices,      (numberOfVertices - 2) * 3    );    indices[0] = 1;    indices[1] = 0;    indices[2] = 2;    let indicesIndex = 3;    for (let i = 3; i < numberOfVertices; ++i) {      indices[indicesIndex++] = i - 1;      indices[indicesIndex++] = 0;      indices[indicesIndex++] = i;    }    geometry.indices = indices;    geometry.primitiveType = GeometryAttribute.PrimitiveType.TRIANGLES;    return geometry;  }  function indexTriangleStrip(geometry) {    const numberOfVertices = GeometryAttribute.Geometry.computeNumberOfVertices(geometry);    //>>includeStart('debug', pragmas.debug);    if (numberOfVertices < 3) {      throw new RuntimeError.DeveloperError("The number of vertices must be at least 3.");    }    //>>includeEnd('debug');    const indices = IndexDatatype.IndexDatatype.createTypedArray(      numberOfVertices,      (numberOfVertices - 2) * 3    );    indices[0] = 0;    indices[1] = 1;    indices[2] = 2;    if (numberOfVertices > 3) {      indices[3] = 0;      indices[4] = 2;      indices[5] = 3;    }    let indicesIndex = 6;    for (let i = 3; i < numberOfVertices - 1; i += 2) {      indices[indicesIndex++] = i;      indices[indicesIndex++] = i - 1;      indices[indicesIndex++] = i + 1;      if (i + 2 < numberOfVertices) {        indices[indicesIndex++] = i;        indices[indicesIndex++] = i + 1;        indices[indicesIndex++] = i + 2;      }    }    geometry.indices = indices;    geometry.primitiveType = GeometryAttribute.PrimitiveType.TRIANGLES;    return geometry;  }  function indexLines(geometry) {    if (defaultValue.defined(geometry.indices)) {      return geometry;    }    const numberOfVertices = GeometryAttribute.Geometry.computeNumberOfVertices(geometry);    //>>includeStart('debug', pragmas.debug);    if (numberOfVertices < 2) {      throw new RuntimeError.DeveloperError("The number of vertices must be at least two.");    }    if (numberOfVertices % 2 !== 0) {      throw new RuntimeError.DeveloperError("The number of vertices must be a multiple of 2.");    }    //>>includeEnd('debug');    const indices = IndexDatatype.IndexDatatype.createTypedArray(      numberOfVertices,      numberOfVertices    );    for (let i = 0; i < numberOfVertices; ++i) {      indices[i] = i;    }    geometry.indices = indices;    return geometry;  }  function indexLineStrip(geometry) {    const numberOfVertices = GeometryAttribute.Geometry.computeNumberOfVertices(geometry);    //>>includeStart('debug', pragmas.debug);    if (numberOfVertices < 2) {      throw new RuntimeError.DeveloperError("The number of vertices must be at least two.");    }    //>>includeEnd('debug');    const indices = IndexDatatype.IndexDatatype.createTypedArray(      numberOfVertices,      (numberOfVertices - 1) * 2    );    indices[0] = 0;    indices[1] = 1;    let indicesIndex = 2;    for (let i = 2; i < numberOfVertices; ++i) {      indices[indicesIndex++] = i - 1;      indices[indicesIndex++] = i;    }    geometry.indices = indices;    geometry.primitiveType = GeometryAttribute.PrimitiveType.LINES;    return geometry;  }  function indexLineLoop(geometry) {    const numberOfVertices = GeometryAttribute.Geometry.computeNumberOfVertices(geometry);    //>>includeStart('debug', pragmas.debug);    if (numberOfVertices < 2) {      throw new RuntimeError.DeveloperError("The number of vertices must be at least two.");    }    //>>includeEnd('debug');    const indices = IndexDatatype.IndexDatatype.createTypedArray(      numberOfVertices,      numberOfVertices * 2    );    indices[0] = 0;    indices[1] = 1;    let indicesIndex = 2;    for (let i = 2; i < numberOfVertices; ++i) {      indices[indicesIndex++] = i - 1;      indices[indicesIndex++] = i;    }    indices[indicesIndex++] = numberOfVertices - 1;    indices[indicesIndex] = 0;    geometry.indices = indices;    geometry.primitiveType = GeometryAttribute.PrimitiveType.LINES;    return geometry;  }  function indexPrimitive(geometry) {    switch (geometry.primitiveType) {      case GeometryAttribute.PrimitiveType.TRIANGLE_FAN:        return indexTriangleFan(geometry);      case GeometryAttribute.PrimitiveType.TRIANGLE_STRIP:        return indexTriangleStrip(geometry);      case GeometryAttribute.PrimitiveType.TRIANGLES:        return indexTriangles(geometry);      case GeometryAttribute.PrimitiveType.LINE_STRIP:        return indexLineStrip(geometry);      case GeometryAttribute.PrimitiveType.LINE_LOOP:        return indexLineLoop(geometry);      case GeometryAttribute.PrimitiveType.LINES:        return indexLines(geometry);    }    return geometry;  }  function offsetPointFromXZPlane(p, isBehind) {    if (Math.abs(p.y) < ComponentDatatype.CesiumMath.EPSILON6) {      if (isBehind) {        p.y = -ComponentDatatype.CesiumMath.EPSILON6;      } else {        p.y = ComponentDatatype.CesiumMath.EPSILON6;      }    }  }  function offsetTriangleFromXZPlane(p0, p1, p2) {    if (p0.y !== 0.0 && p1.y !== 0.0 && p2.y !== 0.0) {      offsetPointFromXZPlane(p0, p0.y < 0.0);      offsetPointFromXZPlane(p1, p1.y < 0.0);      offsetPointFromXZPlane(p2, p2.y < 0.0);      return;    }    const p0y = Math.abs(p0.y);    const p1y = Math.abs(p1.y);    const p2y = Math.abs(p2.y);    let sign;    if (p0y > p1y) {      if (p0y > p2y) {        sign = ComponentDatatype.CesiumMath.sign(p0.y);      } else {        sign = ComponentDatatype.CesiumMath.sign(p2.y);      }    } else if (p1y > p2y) {      sign = ComponentDatatype.CesiumMath.sign(p1.y);    } else {      sign = ComponentDatatype.CesiumMath.sign(p2.y);    }    const isBehind = sign < 0.0;    offsetPointFromXZPlane(p0, isBehind);    offsetPointFromXZPlane(p1, isBehind);    offsetPointFromXZPlane(p2, isBehind);  }  const c3 = new Matrix2.Cartesian3();  function getXZIntersectionOffsetPoints(p, p1, u1, v1) {    Matrix2.Cartesian3.add(      p,      Matrix2.Cartesian3.multiplyByScalar(        Matrix2.Cartesian3.subtract(p1, p, c3),        p.y / (p.y - p1.y),        c3      ),      u1    );    Matrix2.Cartesian3.clone(u1, v1);    offsetPointFromXZPlane(u1, true);    offsetPointFromXZPlane(v1, false);  }  const u1 = new Matrix2.Cartesian3();  const u2 = new Matrix2.Cartesian3();  const q1 = new Matrix2.Cartesian3();  const q2 = new Matrix2.Cartesian3();  const splitTriangleResult = {    positions: new Array(7),    indices: new Array(3 * 3),  };  function splitTriangle(p0, p1, p2) {    // In WGS84 coordinates, for a triangle approximately on the    // ellipsoid to cross the IDL, first it needs to be on the    // negative side of the plane x = 0.    if (p0.x >= 0.0 || p1.x >= 0.0 || p2.x >= 0.0) {      return undefined;    }    offsetTriangleFromXZPlane(p0, p1, p2);    const p0Behind = p0.y < 0.0;    const p1Behind = p1.y < 0.0;    const p2Behind = p2.y < 0.0;    let numBehind = 0;    numBehind += p0Behind ? 1 : 0;    numBehind += p1Behind ? 1 : 0;    numBehind += p2Behind ? 1 : 0;    const indices = splitTriangleResult.indices;    if (numBehind === 1) {      indices[1] = 3;      indices[2] = 4;      indices[5] = 6;      indices[7] = 6;      indices[8] = 5;      if (p0Behind) {        getXZIntersectionOffsetPoints(p0, p1, u1, q1);        getXZIntersectionOffsetPoints(p0, p2, u2, q2);        indices[0] = 0;        indices[3] = 1;        indices[4] = 2;        indices[6] = 1;      } else if (p1Behind) {        getXZIntersectionOffsetPoints(p1, p2, u1, q1);        getXZIntersectionOffsetPoints(p1, p0, u2, q2);        indices[0] = 1;        indices[3] = 2;        indices[4] = 0;        indices[6] = 2;      } else if (p2Behind) {        getXZIntersectionOffsetPoints(p2, p0, u1, q1);        getXZIntersectionOffsetPoints(p2, p1, u2, q2);        indices[0] = 2;        indices[3] = 0;        indices[4] = 1;        indices[6] = 0;      }    } else if (numBehind === 2) {      indices[2] = 4;      indices[4] = 4;      indices[5] = 3;      indices[7] = 5;      indices[8] = 6;      if (!p0Behind) {        getXZIntersectionOffsetPoints(p0, p1, u1, q1);        getXZIntersectionOffsetPoints(p0, p2, u2, q2);        indices[0] = 1;        indices[1] = 2;        indices[3] = 1;        indices[6] = 0;      } else if (!p1Behind) {        getXZIntersectionOffsetPoints(p1, p2, u1, q1);        getXZIntersectionOffsetPoints(p1, p0, u2, q2);        indices[0] = 2;        indices[1] = 0;        indices[3] = 2;        indices[6] = 1;      } else if (!p2Behind) {        getXZIntersectionOffsetPoints(p2, p0, u1, q1);        getXZIntersectionOffsetPoints(p2, p1, u2, q2);        indices[0] = 0;        indices[1] = 1;        indices[3] = 0;        indices[6] = 2;      }    }    const positions = splitTriangleResult.positions;    positions[0] = p0;    positions[1] = p1;    positions[2] = p2;    positions.length = 3;    if (numBehind === 1 || numBehind === 2) {      positions[3] = u1;      positions[4] = u2;      positions[5] = q1;      positions[6] = q2;      positions.length = 7;    }    return splitTriangleResult;  }  function updateGeometryAfterSplit(geometry, computeBoundingSphere) {    const attributes = geometry.attributes;    if (attributes.position.values.length === 0) {      return undefined;    }    for (const property in attributes) {      if (        attributes.hasOwnProperty(property) &&        defaultValue.defined(attributes[property]) &&        defaultValue.defined(attributes[property].values)      ) {        const attribute = attributes[property];        attribute.values = ComponentDatatype.ComponentDatatype.createTypedArray(          attribute.componentDatatype,          attribute.values        );      }    }    const numberOfVertices = GeometryAttribute.Geometry.computeNumberOfVertices(geometry);    geometry.indices = IndexDatatype.IndexDatatype.createTypedArray(      numberOfVertices,      geometry.indices    );    if (computeBoundingSphere) {      geometry.boundingSphere = Transforms.BoundingSphere.fromVertices(        attributes.position.values      );    }    return geometry;  }  function copyGeometryForSplit(geometry) {    const attributes = geometry.attributes;    const copiedAttributes = {};    for (const property in attributes) {      if (        attributes.hasOwnProperty(property) &&        defaultValue.defined(attributes[property]) &&        defaultValue.defined(attributes[property].values)      ) {        const attribute = attributes[property];        copiedAttributes[property] = new GeometryAttribute.GeometryAttribute({          componentDatatype: attribute.componentDatatype,          componentsPerAttribute: attribute.componentsPerAttribute,          normalize: attribute.normalize,          values: [],        });      }    }    return new GeometryAttribute.Geometry({      attributes: copiedAttributes,      indices: [],      primitiveType: geometry.primitiveType,    });  }  function updateInstanceAfterSplit(instance, westGeometry, eastGeometry) {    const computeBoundingSphere = defaultValue.defined(instance.geometry.boundingSphere);    westGeometry = updateGeometryAfterSplit(westGeometry, computeBoundingSphere);    eastGeometry = updateGeometryAfterSplit(eastGeometry, computeBoundingSphere);    if (defaultValue.defined(eastGeometry) && !defaultValue.defined(westGeometry)) {      instance.geometry = eastGeometry;    } else if (!defaultValue.defined(eastGeometry) && defaultValue.defined(westGeometry)) {      instance.geometry = westGeometry;    } else {      instance.westHemisphereGeometry = westGeometry;      instance.eastHemisphereGeometry = eastGeometry;      instance.geometry = undefined;    }  }  function generateBarycentricInterpolateFunction(    CartesianType,    numberOfComponents  ) {    const v0Scratch = new CartesianType();    const v1Scratch = new CartesianType();    const v2Scratch = new CartesianType();    return function (      i0,      i1,      i2,      coords,      sourceValues,      currentValues,      insertedIndex,      normalize    ) {      const v0 = CartesianType.fromArray(        sourceValues,        i0 * numberOfComponents,        v0Scratch      );      const v1 = CartesianType.fromArray(        sourceValues,        i1 * numberOfComponents,        v1Scratch      );      const v2 = CartesianType.fromArray(        sourceValues,        i2 * numberOfComponents,        v2Scratch      );      CartesianType.multiplyByScalar(v0, coords.x, v0);      CartesianType.multiplyByScalar(v1, coords.y, v1);      CartesianType.multiplyByScalar(v2, coords.z, v2);      const value = CartesianType.add(v0, v1, v0);      CartesianType.add(value, v2, value);      if (normalize) {        CartesianType.normalize(value, value);      }      CartesianType.pack(        value,        currentValues,        insertedIndex * numberOfComponents      );    };  }  const interpolateAndPackCartesian4 = generateBarycentricInterpolateFunction(    Matrix2.Cartesian4,    4  );  const interpolateAndPackCartesian3 = generateBarycentricInterpolateFunction(    Matrix2.Cartesian3,    3  );  const interpolateAndPackCartesian2 = generateBarycentricInterpolateFunction(    Matrix2.Cartesian2,    2  );  const interpolateAndPackBoolean = function (    i0,    i1,    i2,    coords,    sourceValues,    currentValues,    insertedIndex  ) {    const v1 = sourceValues[i0] * coords.x;    const v2 = sourceValues[i1] * coords.y;    const v3 = sourceValues[i2] * coords.z;    currentValues[insertedIndex] = v1 + v2 + v3 > ComponentDatatype.CesiumMath.EPSILON6 ? 1 : 0;  };  const p0Scratch = new Matrix2.Cartesian3();  const p1Scratch = new Matrix2.Cartesian3();  const p2Scratch = new Matrix2.Cartesian3();  const barycentricScratch = new Matrix2.Cartesian3();  function computeTriangleAttributes(    i0,    i1,    i2,    point,    positions,    normals,    tangents,    bitangents,    texCoords,    extrudeDirections,    applyOffset,    currentAttributes,    customAttributeNames,    customAttributesLength,    allAttributes,    insertedIndex  ) {    if (      !defaultValue.defined(normals) &&      !defaultValue.defined(tangents) &&      !defaultValue.defined(bitangents) &&      !defaultValue.defined(texCoords) &&      !defaultValue.defined(extrudeDirections) &&      customAttributesLength === 0    ) {      return;    }    const p0 = Matrix2.Cartesian3.fromArray(positions, i0 * 3, p0Scratch);    const p1 = Matrix2.Cartesian3.fromArray(positions, i1 * 3, p1Scratch);    const p2 = Matrix2.Cartesian3.fromArray(positions, i2 * 3, p2Scratch);    const coords = barycentricCoordinates(point, p0, p1, p2, barycentricScratch);    if (!defaultValue.defined(coords)) {      return;    }    if (defaultValue.defined(normals)) {      interpolateAndPackCartesian3(        i0,        i1,        i2,        coords,        normals,        currentAttributes.normal.values,        insertedIndex,        true      );    }    if (defaultValue.defined(extrudeDirections)) {      const d0 = Matrix2.Cartesian3.fromArray(extrudeDirections, i0 * 3, p0Scratch);      const d1 = Matrix2.Cartesian3.fromArray(extrudeDirections, i1 * 3, p1Scratch);      const d2 = Matrix2.Cartesian3.fromArray(extrudeDirections, i2 * 3, p2Scratch);      Matrix2.Cartesian3.multiplyByScalar(d0, coords.x, d0);      Matrix2.Cartesian3.multiplyByScalar(d1, coords.y, d1);      Matrix2.Cartesian3.multiplyByScalar(d2, coords.z, d2);      let direction;      if (        !Matrix2.Cartesian3.equals(d0, Matrix2.Cartesian3.ZERO) ||        !Matrix2.Cartesian3.equals(d1, Matrix2.Cartesian3.ZERO) ||        !Matrix2.Cartesian3.equals(d2, Matrix2.Cartesian3.ZERO)      ) {        direction = Matrix2.Cartesian3.add(d0, d1, d0);        Matrix2.Cartesian3.add(direction, d2, direction);        Matrix2.Cartesian3.normalize(direction, direction);      } else {        direction = p0Scratch;        direction.x = 0;        direction.y = 0;        direction.z = 0;      }      Matrix2.Cartesian3.pack(        direction,        currentAttributes.extrudeDirection.values,        insertedIndex * 3      );    }    if (defaultValue.defined(applyOffset)) {      interpolateAndPackBoolean(        i0,        i1,        i2,        coords,        applyOffset,        currentAttributes.applyOffset.values,        insertedIndex      );    }    if (defaultValue.defined(tangents)) {      interpolateAndPackCartesian3(        i0,        i1,        i2,        coords,        tangents,        currentAttributes.tangent.values,        insertedIndex,        true      );    }    if (defaultValue.defined(bitangents)) {      interpolateAndPackCartesian3(        i0,        i1,        i2,        coords,        bitangents,        currentAttributes.bitangent.values,        insertedIndex,        true      );    }    if (defaultValue.defined(texCoords)) {      interpolateAndPackCartesian2(        i0,        i1,        i2,        coords,        texCoords,        currentAttributes.st.values,        insertedIndex      );    }    if (customAttributesLength > 0) {      for (let i = 0; i < customAttributesLength; i++) {        const attributeName = customAttributeNames[i];        genericInterpolate(          i0,          i1,          i2,          coords,          insertedIndex,          allAttributes[attributeName],          currentAttributes[attributeName]        );      }    }  }  function genericInterpolate(    i0,    i1,    i2,    coords,    insertedIndex,    sourceAttribute,    currentAttribute  ) {    const componentsPerAttribute = sourceAttribute.componentsPerAttribute;    const sourceValues = sourceAttribute.values;    const currentValues = currentAttribute.values;    switch (componentsPerAttribute) {      case 4:        interpolateAndPackCartesian4(          i0,          i1,          i2,          coords,          sourceValues,          currentValues,          insertedIndex,          false        );        break;      case 3:        interpolateAndPackCartesian3(          i0,          i1,          i2,          coords,          sourceValues,          currentValues,          insertedIndex,          false        );        break;      case 2:        interpolateAndPackCartesian2(          i0,          i1,          i2,          coords,          sourceValues,          currentValues,          insertedIndex,          false        );        break;      default:        currentValues[insertedIndex] =          sourceValues[i0] * coords.x +          sourceValues[i1] * coords.y +          sourceValues[i2] * coords.z;    }  }  function insertSplitPoint(    currentAttributes,    currentIndices,    currentIndexMap,    indices,    currentIndex,    point  ) {    const insertIndex = currentAttributes.position.values.length / 3;    if (currentIndex !== -1) {      const prevIndex = indices[currentIndex];      const newIndex = currentIndexMap[prevIndex];      if (newIndex === -1) {        currentIndexMap[prevIndex] = insertIndex;        currentAttributes.position.values.push(point.x, point.y, point.z);        currentIndices.push(insertIndex);        return insertIndex;      }      currentIndices.push(newIndex);      return newIndex;    }    currentAttributes.position.values.push(point.x, point.y, point.z);    currentIndices.push(insertIndex);    return insertIndex;  }  const NAMED_ATTRIBUTES = {    position: true,    normal: true,    bitangent: true,    tangent: true,    st: true,    extrudeDirection: true,    applyOffset: true,  };  function splitLongitudeTriangles(instance) {    const geometry = instance.geometry;    const attributes = geometry.attributes;    const positions = attributes.position.values;    const normals = defaultValue.defined(attributes.normal)      ? attributes.normal.values      : undefined;    const bitangents = defaultValue.defined(attributes.bitangent)      ? attributes.bitangent.values      : undefined;    const tangents = defaultValue.defined(attributes.tangent)      ? attributes.tangent.values      : undefined;    const texCoords = defaultValue.defined(attributes.st) ? attributes.st.values : undefined;    const extrudeDirections = defaultValue.defined(attributes.extrudeDirection)      ? attributes.extrudeDirection.values      : undefined;    const applyOffset = defaultValue.defined(attributes.applyOffset)      ? attributes.applyOffset.values      : undefined;    const indices = geometry.indices;    const customAttributeNames = [];    for (const attributeName in attributes) {      if (        attributes.hasOwnProperty(attributeName) &&        !NAMED_ATTRIBUTES[attributeName] &&        defaultValue.defined(attributes[attributeName])      ) {        customAttributeNames.push(attributeName);      }    }    const customAttributesLength = customAttributeNames.length;    const eastGeometry = copyGeometryForSplit(geometry);    const westGeometry = copyGeometryForSplit(geometry);    let currentAttributes;    let currentIndices;    let currentIndexMap;    let insertedIndex;    let i;    const westGeometryIndexMap = [];    westGeometryIndexMap.length = positions.length / 3;    const eastGeometryIndexMap = [];    eastGeometryIndexMap.length = positions.length / 3;    for (i = 0; i < westGeometryIndexMap.length; ++i) {      westGeometryIndexMap[i] = -1;      eastGeometryIndexMap[i] = -1;    }    const len = indices.length;    for (i = 0; i < len; i += 3) {      const i0 = indices[i];      const i1 = indices[i + 1];      const i2 = indices[i + 2];      let p0 = Matrix2.Cartesian3.fromArray(positions, i0 * 3);      let p1 = Matrix2.Cartesian3.fromArray(positions, i1 * 3);      let p2 = Matrix2.Cartesian3.fromArray(positions, i2 * 3);      const result = splitTriangle(p0, p1, p2);      if (defaultValue.defined(result) && result.positions.length > 3) {        const resultPositions = result.positions;        const resultIndices = result.indices;        const resultLength = resultIndices.length;        for (let j = 0; j < resultLength; ++j) {          const resultIndex = resultIndices[j];          const point = resultPositions[resultIndex];          if (point.y < 0.0) {            currentAttributes = westGeometry.attributes;            currentIndices = westGeometry.indices;            currentIndexMap = westGeometryIndexMap;          } else {            currentAttributes = eastGeometry.attributes;            currentIndices = eastGeometry.indices;            currentIndexMap = eastGeometryIndexMap;          }          insertedIndex = insertSplitPoint(            currentAttributes,            currentIndices,            currentIndexMap,            indices,            resultIndex < 3 ? i + resultIndex : -1,            point          );          computeTriangleAttributes(            i0,            i1,            i2,            point,            positions,            normals,            tangents,            bitangents,            texCoords,            extrudeDirections,            applyOffset,            currentAttributes,            customAttributeNames,            customAttributesLength,            attributes,            insertedIndex          );        }      } else {        if (defaultValue.defined(result)) {          p0 = result.positions[0];          p1 = result.positions[1];          p2 = result.positions[2];        }        if (p0.y < 0.0) {          currentAttributes = westGeometry.attributes;          currentIndices = westGeometry.indices;          currentIndexMap = westGeometryIndexMap;        } else {          currentAttributes = eastGeometry.attributes;          currentIndices = eastGeometry.indices;          currentIndexMap = eastGeometryIndexMap;        }        insertedIndex = insertSplitPoint(          currentAttributes,          currentIndices,          currentIndexMap,          indices,          i,          p0        );        computeTriangleAttributes(          i0,          i1,          i2,          p0,          positions,          normals,          tangents,          bitangents,          texCoords,          extrudeDirections,          applyOffset,          currentAttributes,          customAttributeNames,          customAttributesLength,          attributes,          insertedIndex        );        insertedIndex = insertSplitPoint(          currentAttributes,          currentIndices,          currentIndexMap,          indices,          i + 1,          p1        );        computeTriangleAttributes(          i0,          i1,          i2,          p1,          positions,          normals,          tangents,          bitangents,          texCoords,          extrudeDirections,          applyOffset,          currentAttributes,          customAttributeNames,          customAttributesLength,          attributes,          insertedIndex        );        insertedIndex = insertSplitPoint(          currentAttributes,          currentIndices,          currentIndexMap,          indices,          i + 2,          p2        );        computeTriangleAttributes(          i0,          i1,          i2,          p2,          positions,          normals,          tangents,          bitangents,          texCoords,          extrudeDirections,          applyOffset,          currentAttributes,          customAttributeNames,          customAttributesLength,          attributes,          insertedIndex        );      }    }    updateInstanceAfterSplit(instance, westGeometry, eastGeometry);  }  const xzPlane = Plane.Plane.fromPointNormal(Matrix2.Cartesian3.ZERO, Matrix2.Cartesian3.UNIT_Y);  const offsetScratch = new Matrix2.Cartesian3();  const offsetPointScratch = new Matrix2.Cartesian3();  function computeLineAttributes(    i0,    i1,    point,    positions,    insertIndex,    currentAttributes,    applyOffset  ) {    if (!defaultValue.defined(applyOffset)) {      return;    }    const p0 = Matrix2.Cartesian3.fromArray(positions, i0 * 3, p0Scratch);    if (Matrix2.Cartesian3.equalsEpsilon(p0, point, ComponentDatatype.CesiumMath.EPSILON10)) {      currentAttributes.applyOffset.values[insertIndex] = applyOffset[i0];    } else {      currentAttributes.applyOffset.values[insertIndex] = applyOffset[i1];    }  }  function splitLongitudeLines(instance) {    const geometry = instance.geometry;    const attributes = geometry.attributes;    const positions = attributes.position.values;    const applyOffset = defaultValue.defined(attributes.applyOffset)      ? attributes.applyOffset.values      : undefined;    const indices = geometry.indices;    const eastGeometry = copyGeometryForSplit(geometry);    const westGeometry = copyGeometryForSplit(geometry);    let i;    const length = indices.length;    const westGeometryIndexMap = [];    westGeometryIndexMap.length = positions.length / 3;    const eastGeometryIndexMap = [];    eastGeometryIndexMap.length = positions.length / 3;    for (i = 0; i < westGeometryIndexMap.length; ++i) {      westGeometryIndexMap[i] = -1;      eastGeometryIndexMap[i] = -1;    }    for (i = 0; i < length; i += 2) {      const i0 = indices[i];      const i1 = indices[i + 1];      const p0 = Matrix2.Cartesian3.fromArray(positions, i0 * 3, p0Scratch);      const p1 = Matrix2.Cartesian3.fromArray(positions, i1 * 3, p1Scratch);      let insertIndex;      if (Math.abs(p0.y) < ComponentDatatype.CesiumMath.EPSILON6) {        if (p0.y < 0.0) {          p0.y = -ComponentDatatype.CesiumMath.EPSILON6;        } else {          p0.y = ComponentDatatype.CesiumMath.EPSILON6;        }      }      if (Math.abs(p1.y) < ComponentDatatype.CesiumMath.EPSILON6) {        if (p1.y < 0.0) {          p1.y = -ComponentDatatype.CesiumMath.EPSILON6;        } else {          p1.y = ComponentDatatype.CesiumMath.EPSILON6;        }      }      let p0Attributes = eastGeometry.attributes;      let p0Indices = eastGeometry.indices;      let p0IndexMap = eastGeometryIndexMap;      let p1Attributes = westGeometry.attributes;      let p1Indices = westGeometry.indices;      let p1IndexMap = westGeometryIndexMap;      const intersection = IntersectionTests.IntersectionTests.lineSegmentPlane(        p0,        p1,        xzPlane,        p2Scratch      );      if (defaultValue.defined(intersection)) {        // move point on the xz-plane slightly away from the plane        const offset = Matrix2.Cartesian3.multiplyByScalar(          Matrix2.Cartesian3.UNIT_Y,          5.0 * ComponentDatatype.CesiumMath.EPSILON9,          offsetScratch        );        if (p0.y < 0.0) {          Matrix2.Cartesian3.negate(offset, offset);          p0Attributes = westGeometry.attributes;          p0Indices = westGeometry.indices;          p0IndexMap = westGeometryIndexMap;          p1Attributes = eastGeometry.attributes;          p1Indices = eastGeometry.indices;          p1IndexMap = eastGeometryIndexMap;        }        const offsetPoint = Matrix2.Cartesian3.add(          intersection,          offset,          offsetPointScratch        );        insertIndex = insertSplitPoint(          p0Attributes,          p0Indices,          p0IndexMap,          indices,          i,          p0        );        computeLineAttributes(          i0,          i1,          p0,          positions,          insertIndex,          p0Attributes,          applyOffset        );        insertIndex = insertSplitPoint(          p0Attributes,          p0Indices,          p0IndexMap,          indices,          -1,          offsetPoint        );        computeLineAttributes(          i0,          i1,          offsetPoint,          positions,          insertIndex,          p0Attributes,          applyOffset        );        Matrix2.Cartesian3.negate(offset, offset);        Matrix2.Cartesian3.add(intersection, offset, offsetPoint);        insertIndex = insertSplitPoint(          p1Attributes,          p1Indices,          p1IndexMap,          indices,          -1,          offsetPoint        );        computeLineAttributes(          i0,          i1,          offsetPoint,          positions,          insertIndex,          p1Attributes,          applyOffset        );        insertIndex = insertSplitPoint(          p1Attributes,          p1Indices,          p1IndexMap,          indices,          i + 1,          p1        );        computeLineAttributes(          i0,          i1,          p1,          positions,          insertIndex,          p1Attributes,          applyOffset        );      } else {        let currentAttributes;        let currentIndices;        let currentIndexMap;        if (p0.y < 0.0) {          currentAttributes = westGeometry.attributes;          currentIndices = westGeometry.indices;          currentIndexMap = westGeometryIndexMap;        } else {          currentAttributes = eastGeometry.attributes;          currentIndices = eastGeometry.indices;          currentIndexMap = eastGeometryIndexMap;        }        insertIndex = insertSplitPoint(          currentAttributes,          currentIndices,          currentIndexMap,          indices,          i,          p0        );        computeLineAttributes(          i0,          i1,          p0,          positions,          insertIndex,          currentAttributes,          applyOffset        );        insertIndex = insertSplitPoint(          currentAttributes,          currentIndices,          currentIndexMap,          indices,          i + 1,          p1        );        computeLineAttributes(          i0,          i1,          p1,          positions,          insertIndex,          currentAttributes,          applyOffset        );      }    }    updateInstanceAfterSplit(instance, westGeometry, eastGeometry);  }  const cartesian2Scratch0 = new Matrix2.Cartesian2();  const cartesian2Scratch1 = new Matrix2.Cartesian2();  const cartesian3Scratch0 = new Matrix2.Cartesian3();  const cartesian3Scratch2 = new Matrix2.Cartesian3();  const cartesian3Scratch3 = new Matrix2.Cartesian3();  const cartesian3Scratch4 = new Matrix2.Cartesian3();  const cartesian3Scratch5 = new Matrix2.Cartesian3();  const cartesian3Scratch6 = new Matrix2.Cartesian3();  const cartesian4Scratch0 = new Matrix2.Cartesian4();  function updateAdjacencyAfterSplit(geometry) {    const attributes = geometry.attributes;    const positions = attributes.position.values;    const prevPositions = attributes.prevPosition.values;    const nextPositions = attributes.nextPosition.values;    const length = positions.length;    for (let j = 0; j < length; j += 3) {      const position = Matrix2.Cartesian3.unpack(positions, j, cartesian3Scratch0);      if (position.x > 0.0) {        continue;      }      const prevPosition = Matrix2.Cartesian3.unpack(        prevPositions,        j,        cartesian3Scratch2      );      if (        (position.y < 0.0 && prevPosition.y > 0.0) ||        (position.y > 0.0 && prevPosition.y < 0.0)      ) {        if (j - 3 > 0) {          prevPositions[j] = positions[j - 3];          prevPositions[j + 1] = positions[j - 2];          prevPositions[j + 2] = positions[j - 1];        } else {          Matrix2.Cartesian3.pack(position, prevPositions, j);        }      }      const nextPosition = Matrix2.Cartesian3.unpack(        nextPositions,        j,        cartesian3Scratch3      );      if (        (position.y < 0.0 && nextPosition.y > 0.0) ||        (position.y > 0.0 && nextPosition.y < 0.0)      ) {        if (j + 3 < length) {          nextPositions[j] = positions[j + 3];          nextPositions[j + 1] = positions[j + 4];          nextPositions[j + 2] = positions[j + 5];        } else {          Matrix2.Cartesian3.pack(position, nextPositions, j);        }      }    }  }  const offsetScalar = 5.0 * ComponentDatatype.CesiumMath.EPSILON9;  const coplanarOffset = ComponentDatatype.CesiumMath.EPSILON6;  function splitLongitudePolyline(instance) {    const geometry = instance.geometry;    const attributes = geometry.attributes;    const positions = attributes.position.values;    const prevPositions = attributes.prevPosition.values;    const nextPositions = attributes.nextPosition.values;    const expandAndWidths = attributes.expandAndWidth.values;    const texCoords = defaultValue.defined(attributes.st) ? attributes.st.values : undefined;    const colors = defaultValue.defined(attributes.color)      ? attributes.color.values      : undefined;    const eastGeometry = copyGeometryForSplit(geometry);    const westGeometry = copyGeometryForSplit(geometry);    let i;    let j;    let index;    let intersectionFound = false;    const length = positions.length / 3;    for (i = 0; i < length; i += 4) {      const i0 = i;      const i2 = i + 2;      const p0 = Matrix2.Cartesian3.fromArray(positions, i0 * 3, cartesian3Scratch0);      const p2 = Matrix2.Cartesian3.fromArray(positions, i2 * 3, cartesian3Scratch2);      // Offset points that are close to the 180 longitude and change the previous/next point      // to be the same offset point so it can be projected to 2D. There is special handling in the      // shader for when position == prevPosition || position == nextPosition.      if (Math.abs(p0.y) < coplanarOffset) {        p0.y = coplanarOffset * (p2.y < 0.0 ? -1.0 : 1.0);        positions[i * 3 + 1] = p0.y;        positions[(i + 1) * 3 + 1] = p0.y;        for (j = i0 * 3; j < i0 * 3 + 4 * 3; j += 3) {          prevPositions[j] = positions[i * 3];          prevPositions[j + 1] = positions[i * 3 + 1];          prevPositions[j + 2] = positions[i * 3 + 2];        }      }      // Do the same but for when the line crosses 180 longitude in the opposite direction.      if (Math.abs(p2.y) < coplanarOffset) {        p2.y = coplanarOffset * (p0.y < 0.0 ? -1.0 : 1.0);        positions[(i + 2) * 3 + 1] = p2.y;        positions[(i + 3) * 3 + 1] = p2.y;        for (j = i0 * 3; j < i0 * 3 + 4 * 3; j += 3) {          nextPositions[j] = positions[(i + 2) * 3];          nextPositions[j + 1] = positions[(i + 2) * 3 + 1];          nextPositions[j + 2] = positions[(i + 2) * 3 + 2];        }      }      let p0Attributes = eastGeometry.attributes;      let p0Indices = eastGeometry.indices;      let p2Attributes = westGeometry.attributes;      let p2Indices = westGeometry.indices;      const intersection = IntersectionTests.IntersectionTests.lineSegmentPlane(        p0,        p2,        xzPlane,        cartesian3Scratch4      );      if (defaultValue.defined(intersection)) {        intersectionFound = true;        // move point on the xz-plane slightly away from the plane        const offset = Matrix2.Cartesian3.multiplyByScalar(          Matrix2.Cartesian3.UNIT_Y,          offsetScalar,          cartesian3Scratch5        );        if (p0.y < 0.0) {          Matrix2.Cartesian3.negate(offset, offset);          p0Attributes = westGeometry.attributes;          p0Indices = westGeometry.indices;          p2Attributes = eastGeometry.attributes;          p2Indices = eastGeometry.indices;        }        const offsetPoint = Matrix2.Cartesian3.add(          intersection,          offset,          cartesian3Scratch6        );        p0Attributes.position.values.push(p0.x, p0.y, p0.z, p0.x, p0.y, p0.z);        p0Attributes.position.values.push(          offsetPoint.x,          offsetPoint.y,          offsetPoint.z        );        p0Attributes.position.values.push(          offsetPoint.x,          offsetPoint.y,          offsetPoint.z        );        p0Attributes.prevPosition.values.push(          prevPositions[i0 * 3],          prevPositions[i0 * 3 + 1],          prevPositions[i0 * 3 + 2]        );        p0Attributes.prevPosition.values.push(          prevPositions[i0 * 3 + 3],          prevPositions[i0 * 3 + 4],          prevPositions[i0 * 3 + 5]        );        p0Attributes.prevPosition.values.push(p0.x, p0.y, p0.z, p0.x, p0.y, p0.z);        p0Attributes.nextPosition.values.push(          offsetPoint.x,          offsetPoint.y,          offsetPoint.z        );        p0Attributes.nextPosition.values.push(          offsetPoint.x,          offsetPoint.y,          offsetPoint.z        );        p0Attributes.nextPosition.values.push(          offsetPoint.x,          offsetPoint.y,          offsetPoint.z        );        p0Attributes.nextPosition.values.push(          offsetPoint.x,          offsetPoint.y,          offsetPoint.z        );        Matrix2.Cartesian3.negate(offset, offset);        Matrix2.Cartesian3.add(intersection, offset, offsetPoint);        p2Attributes.position.values.push(          offsetPoint.x,          offsetPoint.y,          offsetPoint.z        );        p2Attributes.position.values.push(          offsetPoint.x,          offsetPoint.y,          offsetPoint.z        );        p2Attributes.position.values.push(p2.x, p2.y, p2.z, p2.x, p2.y, p2.z);        p2Attributes.prevPosition.values.push(          offsetPoint.x,          offsetPoint.y,          offsetPoint.z        );        p2Attributes.prevPosition.values.push(          offsetPoint.x,          offsetPoint.y,          offsetPoint.z        );        p2Attributes.prevPosition.values.push(          offsetPoint.x,          offsetPoint.y,          offsetPoint.z        );        p2Attributes.prevPosition.values.push(          offsetPoint.x,          offsetPoint.y,          offsetPoint.z        );        p2Attributes.nextPosition.values.push(p2.x, p2.y, p2.z, p2.x, p2.y, p2.z);        p2Attributes.nextPosition.values.push(          nextPositions[i2 * 3],          nextPositions[i2 * 3 + 1],          nextPositions[i2 * 3 + 2]        );        p2Attributes.nextPosition.values.push(          nextPositions[i2 * 3 + 3],          nextPositions[i2 * 3 + 4],          nextPositions[i2 * 3 + 5]        );        const ew0 = Matrix2.Cartesian2.fromArray(          expandAndWidths,          i0 * 2,          cartesian2Scratch0        );        const width = Math.abs(ew0.y);        p0Attributes.expandAndWidth.values.push(-1, width, 1, width);        p0Attributes.expandAndWidth.values.push(-1, -width, 1, -width);        p2Attributes.expandAndWidth.values.push(-1, width, 1, width);        p2Attributes.expandAndWidth.values.push(-1, -width, 1, -width);        let t = Matrix2.Cartesian3.magnitudeSquared(          Matrix2.Cartesian3.subtract(intersection, p0, cartesian3Scratch3)        );        t /= Matrix2.Cartesian3.magnitudeSquared(          Matrix2.Cartesian3.subtract(p2, p0, cartesian3Scratch3)        );        if (defaultValue.defined(colors)) {          const c0 = Matrix2.Cartesian4.fromArray(colors, i0 * 4, cartesian4Scratch0);          const c2 = Matrix2.Cartesian4.fromArray(colors, i2 * 4, cartesian4Scratch0);          const r = ComponentDatatype.CesiumMath.lerp(c0.x, c2.x, t);          const g = ComponentDatatype.CesiumMath.lerp(c0.y, c2.y, t);          const b = ComponentDatatype.CesiumMath.lerp(c0.z, c2.z, t);          const a = ComponentDatatype.CesiumMath.lerp(c0.w, c2.w, t);          for (j = i0 * 4; j < i0 * 4 + 2 * 4; ++j) {            p0Attributes.color.values.push(colors[j]);          }          p0Attributes.color.values.push(r, g, b, a);          p0Attributes.color.values.push(r, g, b, a);          p2Attributes.color.values.push(r, g, b, a);          p2Attributes.color.values.push(r, g, b, a);          for (j = i2 * 4; j < i2 * 4 + 2 * 4; ++j) {            p2Attributes.color.values.push(colors[j]);          }        }        if (defaultValue.defined(texCoords)) {          const s0 = Matrix2.Cartesian2.fromArray(texCoords, i0 * 2, cartesian2Scratch0);          const s3 = Matrix2.Cartesian2.fromArray(            texCoords,            (i + 3) * 2,            cartesian2Scratch1          );          const sx = ComponentDatatype.CesiumMath.lerp(s0.x, s3.x, t);          for (j = i0 * 2; j < i0 * 2 + 2 * 2; ++j) {            p0Attributes.st.values.push(texCoords[j]);          }          p0Attributes.st.values.push(sx, s0.y);          p0Attributes.st.values.push(sx, s3.y);          p2Attributes.st.values.push(sx, s0.y);          p2Attributes.st.values.push(sx, s3.y);          for (j = i2 * 2; j < i2 * 2 + 2 * 2; ++j) {            p2Attributes.st.values.push(texCoords[j]);          }        }        index = p0Attributes.position.values.length / 3 - 4;        p0Indices.push(index, index + 2, index + 1);        p0Indices.push(index + 1, index + 2, index + 3);        index = p2Attributes.position.values.length / 3 - 4;        p2Indices.push(index, index + 2, index + 1);        p2Indices.push(index + 1, index + 2, index + 3);      } else {        let currentAttributes;        let currentIndices;        if (p0.y < 0.0) {          currentAttributes = westGeometry.attributes;          currentIndices = westGeometry.indices;        } else {          currentAttributes = eastGeometry.attributes;          currentIndices = eastGeometry.indices;        }        currentAttributes.position.values.push(p0.x, p0.y, p0.z);        currentAttributes.position.values.push(p0.x, p0.y, p0.z);        currentAttributes.position.values.push(p2.x, p2.y, p2.z);        currentAttributes.position.values.push(p2.x, p2.y, p2.z);        for (j = i * 3; j < i * 3 + 4 * 3; ++j) {          currentAttributes.prevPosition.values.push(prevPositions[j]);          currentAttributes.nextPosition.values.push(nextPositions[j]);        }        for (j = i * 2; j < i * 2 + 4 * 2; ++j) {          currentAttributes.expandAndWidth.values.push(expandAndWidths[j]);          if (defaultValue.defined(texCoords)) {            currentAttributes.st.values.push(texCoords[j]);          }        }        if (defaultValue.defined(colors)) {          for (j = i * 4; j < i * 4 + 4 * 4; ++j) {            currentAttributes.color.values.push(colors[j]);          }        }        index = currentAttributes.position.values.length / 3 - 4;        currentIndices.push(index, index + 2, index + 1);        currentIndices.push(index + 1, index + 2, index + 3);      }    }    if (intersectionFound) {      updateAdjacencyAfterSplit(westGeometry);      updateAdjacencyAfterSplit(eastGeometry);    }    updateInstanceAfterSplit(instance, westGeometry, eastGeometry);  }  /**   * Splits the instances's geometry, by introducing new vertices and indices,that   * intersect the International Date Line and Prime Meridian so that no primitives cross longitude   * -180/180 degrees.  This is not required for 3D drawing, but is required for   * correcting drawing in 2D and Columbus view.   *   * @private   *   * @param {GeometryInstance} instance The instance to modify.   * @returns {GeometryInstance} The modified <code>instance</code> argument, with it's geometry split at the International Date Line.   *   * @example   * instance = Cesium.GeometryPipeline.splitLongitude(instance);   */  GeometryPipeline.splitLongitude = function (instance) {    //>>includeStart('debug', pragmas.debug);    if (!defaultValue.defined(instance)) {      throw new RuntimeError.DeveloperError("instance is required.");    }    //>>includeEnd('debug');    const geometry = instance.geometry;    const boundingSphere = geometry.boundingSphere;    if (defaultValue.defined(boundingSphere)) {      const minX = boundingSphere.center.x - boundingSphere.radius;      if (        minX > 0 ||        Transforms.BoundingSphere.intersectPlane(boundingSphere, Plane.Plane.ORIGIN_ZX_PLANE) !==          Transforms.Intersect.INTERSECTING      ) {        return instance;      }    }    if (geometry.geometryType !== GeometryAttribute.GeometryType.NONE) {      switch (geometry.geometryType) {        case GeometryAttribute.GeometryType.POLYLINES:          splitLongitudePolyline(instance);          break;        case GeometryAttribute.GeometryType.TRIANGLES:          splitLongitudeTriangles(instance);          break;        case GeometryAttribute.GeometryType.LINES:          splitLongitudeLines(instance);          break;      }    } else {      indexPrimitive(geometry);      if (geometry.primitiveType === GeometryAttribute.PrimitiveType.TRIANGLES) {        splitLongitudeTriangles(instance);      } else if (geometry.primitiveType === GeometryAttribute.PrimitiveType.LINES) {        splitLongitudeLines(instance);      }    }    return instance;  };  exports.GeometryPipeline = GeometryPipeline;}));
 |