123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714 |
- /**
- * @license
- * Cesium - https://github.com/CesiumGS/cesium
- * Version 1.95
- *
- * Copyright 2011-2022 Cesium Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Columbus View (Pat. Pend.)
- *
- * Portions licensed separately.
- * See https://github.com/CesiumGS/cesium/blob/main/LICENSE.md for full licensing details.
- */
- define(['exports', './AttributeCompression-f202be44', './Matrix2-9e1c22e2', './RuntimeError-4f8ec8a2', './defaultValue-97284df2', './ComponentDatatype-4eeb6d9b', './Transforms-273eeb44', './EncodedCartesian3-491ac596', './GeometryAttribute-9be2d2e5', './IndexDatatype-f228f5fd', './IntersectionTests-ea138127', './Plane-76b84425'], (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;
- }));
- //# sourceMappingURL=GeometryPipeline-d7363877.js.map
|