babylon.canvas2d.js 1013 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695
  1. BABYLON.Effect.ShadersStore['ellipse2dPixelShader'] = "varying vec4 vColor;\nvoid main(void) {\ngl_FragColor=vColor;\n}";
  2. BABYLON.Effect.ShadersStore['ellipse2dVertexShader'] = "\n#ifdef Instanced\n#define att attribute\n#else\n#define att uniform\n#endif\nattribute float index;\natt vec2 zBias;\natt vec4 transformX;\natt vec4 transformY;\natt vec3 renderingInfo;\natt float opacity;\n#ifdef Border\natt float borderThickness;\n#endif\n#ifdef FillSolid\natt vec4 fillSolidColor;\n#endif\n#ifdef BorderSolid\natt vec4 borderSolidColor;\n#endif\n#ifdef FillGradient\natt vec4 fillGradientColor1;\natt vec4 fillGradientColor2;\natt vec4 fillGradientTY;\n#endif\n#ifdef BorderGradient\natt vec4 borderGradientColor1;\natt vec4 borderGradientColor2;\natt vec4 borderGradientTY;\n#endif\n\natt vec3 properties;\n#define TWOPI 6.28318530\n\nvarying vec2 vUV;\nvarying vec4 vColor;\nvoid main(void) {\nvec2 pos2;\n#ifdef Border\nfloat w=properties.x;\nfloat h=properties.y;\nfloat ms=properties.z;\nvec2 borderOffset=vec2(1.0,1.0);\nfloat segi=index;\nif (index<ms) {\nborderOffset=vec2(1.0-(borderThickness*2.0/w),1.0-(borderThickness*2.0/h));\n}\nelse {\nsegi-=ms;\n}\nfloat angle=TWOPI*segi/ms;\npos2.x=(cos(angle)/2.0)+0.5;\npos2.y=(sin(angle)/2.0)+0.5;\npos2.x=((pos2.x-0.5)*borderOffset.x)+0.5;\npos2.y=((pos2.y-0.5)*borderOffset.y)+0.5;\n#else\nif (index == 0.0) {\npos2=vec2(0.5,0.5);\n}\nelse {\nfloat ms=properties.z;\nfloat angle=TWOPI*(index-1.0)/ms;\npos2.x=(cos(angle)/2.0)+0.5;\npos2.y=(sin(angle)/2.0)+0.5;\n}\n#endif\n#ifdef FillSolid\nvColor=fillSolidColor;\n#endif\n#ifdef BorderSolid\nvColor=borderSolidColor;\n#endif\n#ifdef FillGradient\nfloat v=dot(vec4(pos2.xy,1,1),fillGradientTY);\nvColor=mix(fillGradientColor2,fillGradientColor1,v); \n#endif\n#ifdef BorderGradient\nfloat v=dot(vec4(pos2.xy,1,1),borderGradientTY);\nvColor=mix(borderGradientColor2,borderGradientColor1,v); \n#endif\nvColor.a*=opacity;\nvec4 pos;\npos.xy=pos2.xy*properties.xy;\npos.z=1.0;\npos.w=1.0;\nfloat x=dot(pos,transformX);\nfloat y=dot(pos,transformY);\nif (renderingInfo.z == 1.0) {\nfloat rw=renderingInfo.x;\nfloat rh=renderingInfo.y;\nfloat irw=2.0/rw;\nfloat irh=2.0/rh;\nx=(floor((x/irw)+0.5)*irw)+irw/2.0;\ny=(floor((y/irh)+0.5)*irh)+irh/2.0;\n}\ngl_Position=vec4(x,y,zBias.x,1);\n}";
  3. BABYLON.Effect.ShadersStore['lines2dPixelShader'] = "varying vec4 vColor;\nvoid main(void) {\ngl_FragColor=vColor;\n}";
  4. BABYLON.Effect.ShadersStore['lines2dVertexShader'] = "\n#ifdef Instanced\n#define att attribute\n#else\n#define att uniform\n#endif\nattribute vec2 position;\natt vec2 zBias;\natt vec4 transformX;\natt vec4 transformY;\natt vec3 renderingInfo;\natt float opacity;\n#ifdef FillSolid\natt vec4 fillSolidColor;\n#endif\n#ifdef BorderSolid\natt vec4 borderSolidColor;\n#endif\n#ifdef FillGradient\natt vec2 boundingMin;\natt vec2 boundingMax;\natt vec4 fillGradientColor1;\natt vec4 fillGradientColor2;\natt vec4 fillGradientTY;\n#endif\n#ifdef BorderGradient\natt vec4 borderGradientColor1;\natt vec4 borderGradientColor2;\natt vec4 borderGradientTY;\n#endif\n#define TWOPI 6.28318530\n\nvarying vec2 vUV;\nvarying vec4 vColor;\nvoid main(void) {\n#ifdef FillSolid\nvColor=fillSolidColor;\n#endif\n#ifdef BorderSolid\nvColor=borderSolidColor;\n#endif\n#ifdef FillGradient\nfloat v=dot(vec4((position.xy-boundingMin)/(boundingMax-boundingMin),1,1),fillGradientTY);\nvColor=mix(fillGradientColor2,fillGradientColor1,v); \n#endif\n#ifdef BorderGradient\nfloat v=dot(vec4((position.xy-boundingMin)/(boundingMax-boundingMin),1,1),borderGradientTY);\nvColor=mix(borderGradientColor2,borderGradientColor1,v); \n#endif\nvColor.a*=opacity;\nvec4 pos;\npos.xy=position.xy;\npos.z=1.0;\npos.w=1.0;\nfloat x=dot(pos,transformX);\nfloat y=dot(pos,transformY);\nif (renderingInfo.z == 1.0) {\nfloat rw=renderingInfo.x;\nfloat rh=renderingInfo.y;\nfloat irw=2.0/rw;\nfloat irh=2.0/rh;\nx=(floor((x/irw)+0.5)*irw)+irw/2.0;\ny=(floor((y/irh)+0.5)*irh)+irh/2.0;\n}\ngl_Position=vec4(x,y,zBias.x,1);\n}";
  5. BABYLON.Effect.ShadersStore['rect2dPixelShader'] = "varying vec4 vColor;\nvoid main(void) {\ngl_FragColor=vColor;\n}";
  6. BABYLON.Effect.ShadersStore['rect2dVertexShader'] = "\n#ifdef Instanced\n#define att attribute\n#else\n#define att uniform\n#endif\nattribute float index;\natt vec2 zBias;\natt vec4 transformX;\natt vec4 transformY;\natt vec3 renderingInfo;\natt float opacity;\n#ifdef Border\natt float borderThickness;\n#endif\n#ifdef FillSolid\natt vec4 fillSolidColor;\n#endif\n#ifdef BorderSolid\natt vec4 borderSolidColor;\n#endif\n#ifdef FillGradient\natt vec4 fillGradientColor1;\natt vec4 fillGradientColor2;\natt vec4 fillGradientTY;\n#endif\n#ifdef BorderGradient\natt vec4 borderGradientColor1;\natt vec4 borderGradientColor2;\natt vec4 borderGradientTY;\n#endif\n\natt vec3 properties;\n\n#define rsub0 17.0\n#define rsub1 33.0\n#define rsub2 49.0\n#define rsub3 65.0\n#define rsub 64.0\n#define TWOPI 6.28318530\n\nvarying vec2 vUV;\nvarying vec4 vColor;\nvoid main(void) {\nvec2 pos2;\n\nif (properties.z == 0.0) {\n#ifdef Border\nfloat w=properties.x;\nfloat h=properties.y;\nvec2 borderOffset=vec2(1.0,1.0);\nfloat segi=index;\nif (index<4.0) {\nborderOffset=vec2(1.0-(borderThickness*2.0/w),1.0-(borderThickness*2.0/h));\n}\nelse {\nsegi-=4.0;\n}\nif (segi == 0.0) {\npos2=vec2(1.0,1.0);\n} \nelse if (segi == 1.0) {\npos2=vec2(1.0,0.0);\n}\nelse if (segi == 2.0) {\npos2=vec2(0.0,0.0);\n} \nelse {\npos2=vec2(0.0,1.0);\n}\npos2.x=((pos2.x-0.5)*borderOffset.x)+0.5;\npos2.y=((pos2.y-0.5)*borderOffset.y)+0.5;\n#else\nif (index == 0.0) {\npos2=vec2(0.5,0.5);\n}\nelse if (index == 1.0) {\npos2=vec2(1.0,1.0);\n}\nelse if (index == 2.0) {\npos2=vec2(1.0,0.0);\n}\nelse if (index == 3.0) {\npos2=vec2(0.0,0.0);\n}\nelse {\npos2=vec2(0.0,1.0);\n}\n#endif\n}\nelse\n{\n#ifdef Border\nfloat w=properties.x;\nfloat h=properties.y;\nfloat r=properties.z;\nfloat nru=r/w;\nfloat nrv=r/h;\nvec2 borderOffset=vec2(1.0,1.0);\nfloat segi=index;\nif (index<rsub) {\nborderOffset=vec2(1.0-(borderThickness*2.0/w),1.0-(borderThickness*2.0/h));\n}\nelse {\nsegi-=rsub;\n}\n\nif (segi<rsub0) {\npos2=vec2(1.0-nru,nrv);\n}\n\nelse if (segi<rsub1) {\npos2=vec2(nru,nrv);\n}\n\nelse if (segi<rsub2) {\npos2=vec2(nru,1.0-nrv);\n}\n\nelse {\npos2=vec2(1.0-nru,1.0-nrv);\n}\nfloat angle=TWOPI-((index-1.0)*TWOPI/(rsub-0.5));\npos2.x+=cos(angle)*nru;\npos2.y+=sin(angle)*nrv;\npos2.x=((pos2.x-0.5)*borderOffset.x)+0.5;\npos2.y=((pos2.y-0.5)*borderOffset.y)+0.5;\n#else\nif (index == 0.0) {\npos2=vec2(0.5,0.5);\n}\nelse {\nfloat w=properties.x;\nfloat h=properties.y;\nfloat r=properties.z;\nfloat nru=r/w;\nfloat nrv=r/h;\n\nif (index<rsub0) {\npos2=vec2(1.0-nru,nrv);\n}\n\nelse if (index<rsub1) {\npos2=vec2(nru,nrv);\n}\n\nelse if (index<rsub2) {\npos2=vec2(nru,1.0-nrv);\n}\n\nelse {\npos2=vec2(1.0-nru,1.0-nrv);\n}\nfloat angle=TWOPI-((index-1.0)*TWOPI/(rsub-0.5));\npos2.x+=cos(angle)*nru;\npos2.y+=sin(angle)*nrv;\n}\n#endif\n}\n#ifdef FillSolid\nvColor=fillSolidColor;\n#endif\n#ifdef BorderSolid\nvColor=borderSolidColor;\n#endif\n#ifdef FillGradient\nfloat v=dot(vec4(pos2.xy,1,1),fillGradientTY);\nvColor=mix(fillGradientColor2,fillGradientColor1,v); \n#endif\n#ifdef BorderGradient\nfloat v=dot(vec4(pos2.xy,1,1),borderGradientTY);\nvColor=mix(borderGradientColor2,borderGradientColor1,v); \n#endif\nvColor.a*=opacity;\nvec4 pos;\npos.xy=pos2.xy*properties.xy;\npos.z=1.0;\npos.w=1.0;\nfloat x=dot(pos,transformX);\nfloat y=dot(pos,transformY);\nif (renderingInfo.z == 1.0) {\nfloat rw=renderingInfo.x;\nfloat rh=renderingInfo.y;\nfloat irw=2.0/rw;\nfloat irh=2.0/rh;\nx=(floor((x/irw)+0.5)*irw)+irw/2.0;\ny=(floor((y/irh)+0.5)*irh)+irh/2.0;\n}\ngl_Position=vec4(x,y,zBias.x,1);\n}";
  7. BABYLON.Effect.ShadersStore['sprite2dPixelShader'] = "varying vec2 vUV;\nvarying float vOpacity;\n#ifdef Scale9\nvarying vec2 vTopLeftUV;\nvarying vec2 vBottomRightUV;\nvarying vec4 vScale9;\nvarying vec2 vScaleFactor;\n#endif\nuniform bool alphaTest;\nuniform sampler2D diffuseSampler;\nvoid main(void) {\nvec2 uv=vUV;\n#ifdef Scale9\nvec2 sizeUV=vBottomRightUV-vTopLeftUV;\n\nfloat leftPartUV=vTopLeftUV.x+(vScale9.x/vScaleFactor.x);\nfloat rightPartUV=vTopLeftUV.x+sizeUV.x-((sizeUV.x-vScale9.z)/vScaleFactor.x);\nif (vUV.x<leftPartUV) {\nuv.x=vTopLeftUV.x+((vUV.x- vTopLeftUV.x)*vScaleFactor.x);\n}\nelse if (vUV.x>rightPartUV) {\nuv.x=vTopLeftUV.x+vScale9.z+((vUV.x-rightPartUV)*vScaleFactor.x);\n}\nelse {\nfloat r=(vUV.x-leftPartUV)/(rightPartUV-leftPartUV);\nuv.x=vTopLeftUV.x+vScale9.x+((vScale9.z-vScale9.x)*r);\n}\n\nfloat topPartUV=(vTopLeftUV.y+(vScale9.y/vScaleFactor.y));\nfloat bottomPartUV=(vTopLeftUV.y+sizeUV.y-((sizeUV.y-vScale9.w)/vScaleFactor.y));\nif (vUV.y<topPartUV) {\nuv.y=vTopLeftUV.y+((vUV.y-vTopLeftUV.y)*vScaleFactor.y);\n}\nelse if (vUV.y>bottomPartUV) {\nuv.y=vTopLeftUV.y+vScale9.w+((vUV.y-bottomPartUV)*vScaleFactor.y);\n}\nelse {\nfloat r=(vUV.y-topPartUV)/(bottomPartUV-topPartUV);\nuv.y=vTopLeftUV.y+vScale9.y+((vScale9.w-vScale9.y)*r);\n}\n#endif\nvec4 color=texture2D(diffuseSampler,uv);\nif (alphaTest)\n{\nif (color.a<0.95) {\ndiscard;\n}\n}\ncolor.a*=vOpacity;\ngl_FragColor=color;\n}";
  8. BABYLON.Effect.ShadersStore['sprite2dVertexShader'] = "\n#ifdef Instanced\n#define att attribute\n#else\n#define att uniform\n#endif\n\nattribute float index;\natt vec2 topLeftUV;\natt vec2 sizeUV;\n#ifdef Scale9\natt vec2 scaleFactor;\n#endif\natt vec2 textureSize;\n\natt vec3 properties;\n#ifdef Scale9\natt vec4 scale9;\n#endif\natt vec2 zBias;\natt vec4 transformX;\natt vec4 transformY;\natt vec3 renderingInfo;\natt float opacity;\n\n\nvarying vec2 vUV;\nvarying float vOpacity;\n#ifdef Scale9\nvarying vec2 vTopLeftUV;\nvarying vec2 vBottomRightUV;\nvarying vec4 vScale9;\nvarying vec2 vScaleFactor;\n#endif\nvoid main(void) {\nvec2 pos2;\nfloat frame=properties.x;\nfloat invertY=properties.y;\nfloat alignToPixel=properties.z;\n\nif (index == 0.0) {\npos2=vec2(0.0,0.0);\nvUV=vec2(topLeftUV.x+(frame*sizeUV.x),topLeftUV.y);\n}\n\nelse if (index == 1.0) {\npos2=vec2(0.0,1.0);\nvUV=vec2(topLeftUV.x+(frame*sizeUV.x),(topLeftUV.y+sizeUV.y));\n}\n\nelse if (index == 2.0) {\npos2=vec2( 1.0,1.0);\nvUV=vec2(topLeftUV.x+sizeUV.x+(frame*sizeUV.x),(topLeftUV.y+sizeUV.y));\n}\n\nelse if (index == 3.0) {\npos2=vec2( 1.0,0.0);\nvUV=vec2(topLeftUV.x+sizeUV.x+(frame*sizeUV.x),topLeftUV.y);\n}\nif (invertY == 1.0) {\nvUV.y=1.0-vUV.y;\n}\n\nvec4 pos;\n\n\n\n\npos.xy=pos2.xy*sizeUV*textureSize;\n\n#ifdef Scale9\nif (invertY == 1.0) {\nvTopLeftUV=vec2(topLeftUV.x,1.0-(topLeftUV.y+sizeUV.y));\nvBottomRightUV=vec2(topLeftUV.x+sizeUV.x,1.0-topLeftUV.y);\nvScale9=vec4(scale9.x,sizeUV.y-scale9.w,scale9.z,sizeUV.y-scale9.y);\n}\nelse {\nvTopLeftUV=topLeftUV;\nvBottomRightUV=vec2(topLeftUV.x+sizeUV.x,topLeftUV.y+sizeUV.y);\nvScale9=scale9;\n}\nvScaleFactor=scaleFactor;\n#endif\nvOpacity=opacity;\npos.z=1.0;\npos.w=1.0;\nfloat x=dot(pos,transformX);\nfloat y=dot(pos,transformY);\nif (renderingInfo.z == 1.0) {\nfloat rw=renderingInfo.x;\nfloat rh=renderingInfo.y;\nfloat irw=2.0/rw;\nfloat irh=2.0/rh;\nx=(floor((x/irw))*irw)+irw/2.0;\ny=(floor((y/irh))*irh)+irh/2.0;\n}\ngl_Position=vec4(x,y,zBias.x,1.0);\n} ";
  9. BABYLON.Effect.ShadersStore['text2dPixelShader'] = "\nvarying vec4 vColor;\nvarying vec2 vUV;\n\nuniform sampler2D diffuseSampler;\nvoid main(void) {\n#ifdef SignedDistanceField\nfloat dist=texture2D(diffuseSampler,vUV).r;\nif (dist<0.5) {\ndiscard;\n}\n\n\n\n\n\ngl_FragColor=vec4(vColor.xyz*dist,vColor.a);\n#else\nvec4 color=texture2D(diffuseSampler,vUV);\nif (color.a == 0.0) {\ndiscard;\n}\n#ifdef FontTexture\ngl_FragColor=vec4(color.xxx*vColor.xyz*vColor.a,color.x*vColor.a);\n#else\ngl_FragColor=color*vColor;\n#endif\n#endif\n}";
  10. BABYLON.Effect.ShadersStore['text2dVertexShader'] = "\n#ifdef Instanced\n#define att attribute\n#else\n#define att uniform\n#endif\n\nattribute float index;\natt vec2 zBias;\natt vec4 transformX;\natt vec4 transformY;\natt vec3 renderingInfo;\natt float opacity;\natt vec2 topLeftUV;\natt vec2 sizeUV;\natt vec2 textureSize;\natt vec4 color;\natt float superSampleFactor;\n\nvarying vec2 vUV;\nvarying vec4 vColor;\nvoid main(void) {\nvec2 pos2;\n\nif (index == 0.0) {\npos2=vec2(0.0,0.0);\nvUV=vec2(topLeftUV.x,topLeftUV.y+sizeUV.y);\n}\n\nelse if (index == 1.0) {\npos2=vec2(0.0,1.0);\nvUV=vec2(topLeftUV.x,topLeftUV.y);\n}\n\nelse if (index == 2.0) {\npos2=vec2(1.0,1.0);\nvUV=vec2(topLeftUV.x+sizeUV.x,topLeftUV.y);\n}\n\nelse if (index == 3.0) {\npos2=vec2(1.0,0.0);\nvUV=vec2(topLeftUV.x+sizeUV.x,topLeftUV.y+sizeUV.y);\n}\n\n\n\nvColor=color;\nvColor.a*=opacity;\nvec4 pos;\npos.xy=pos2.xy*superSampleFactor*sizeUV*textureSize;\npos.z=1.0;\npos.w=1.0;\nfloat x=dot(pos,transformX);\nfloat y=dot(pos,transformY);\nif (renderingInfo.z == 1.0) {\nfloat rw=renderingInfo.x;\nfloat rh=renderingInfo.y;\nfloat irw=2.0/rw;\nfloat irh=2.0/rh;\nx=((floor((x/irw)+0.5)*irw)+irw/2.0)+0.5*irw;\ny=((floor((y/irh)+0.5)*irh)+irh/2.0)+0.5*irh;\n}\ngl_Position=vec4(x,y,zBias.x,1.0);\n}";
  11. BABYLON.Effect.ShadersStore['wireframe2dPixelShader'] = "varying vec4 vColor;\nvoid main(void) {\ngl_FragColor=vColor;\n}";
  12. BABYLON.Effect.ShadersStore['wireframe2dVertexShader'] = "\n#ifdef Instanced\n#define att attribute\n#else\n#define att uniform\n#endif\n\nattribute vec2 pos;\nattribute vec4 col;\n\n\n\n\natt vec3 properties;\natt vec2 zBias;\natt vec4 transformX;\natt vec4 transformY;\natt vec3 renderingInfo;\natt float opacity;\n\n\nvarying vec4 vColor;\nvoid main(void) {\nvec4 p=vec4(pos.xy,1.0,1.0);\nvColor=vec4(col.xyz,col.w*opacity);\nfloat x=dot(p,transformX);\nfloat y=dot(p,transformY);\nif (renderingInfo.z == 1.0) {\nfloat rw=renderingInfo.x;\nfloat rh=renderingInfo.y;\nfloat irw=2.0/rw;\nfloat irh=2.0/rh;\nx=(floor((x/irw)+0.5)*irw)+irw/2.0;\ny=(floor((y/irh)+0.5)*irh)+irh/2.0;\n}\ngl_Position=vec4(x,y,zBias.x,1);\n}";
  13. var BABYLON;
  14. (function (BABYLON) {
  15. /**
  16. * A class storing a Matrix2D for 2D transformations
  17. * The stored matrix is a 3*3 Matrix2D
  18. * I [0,1] [mX, mY] R [ CosZ, SinZ] T [ 0, 0] S [Sx, 0]
  19. * D = [2,3] = [nX, nY] O = [-SinZ, CosZ] R = [ 0, 0] C = [ 0, Sy]
  20. * X [4,5] [tX, tY] T [ 0 , 0 ] N [Tx, Ty] L [ 0, 0]
  21. *
  22. * IDX = index, zero based. ROT = Z axis Rotation. TRN = Translation. SCL = Scale.
  23. */
  24. var Matrix2D = (function () {
  25. function Matrix2D() {
  26. this.m = new Float32Array(6);
  27. }
  28. Matrix2D.Zero = function () {
  29. return new Matrix2D();
  30. };
  31. Matrix2D.FromValuesToRef = function (m0, m1, m2, m3, m4, m5, result) {
  32. result.m[0] = m0;
  33. result.m[1] = m1;
  34. result.m[2] = m2;
  35. result.m[3] = m3;
  36. result.m[4] = m4;
  37. result.m[5] = m5;
  38. };
  39. Matrix2D.FromMatrix = function (source) {
  40. var result = new Matrix2D();
  41. Matrix2D.FromMatrixToRef(source, result);
  42. return result;
  43. };
  44. Matrix2D.FromMatrixToRef = function (source, result) {
  45. result.m[0] = source.m[0];
  46. result.m[1] = source.m[1];
  47. result.m[2] = source.m[4];
  48. result.m[3] = source.m[5];
  49. result.m[4] = source.m[8];
  50. result.m[5] = source.m[9];
  51. };
  52. Matrix2D.Rotation = function (angle) {
  53. var result = new Matrix2D();
  54. Matrix2D.RotationToRef(angle, result);
  55. return result;
  56. };
  57. Matrix2D.RotationToRef = function (angle, result) {
  58. var s = Math.sin(angle);
  59. var c = Math.cos(angle);
  60. result.m[0] = c;
  61. result.m[1] = s;
  62. result.m[2] = -s;
  63. result.m[3] = c;
  64. result.m[4] = 0;
  65. result.m[5] = 0;
  66. };
  67. Matrix2D.Translation = function (x, y) {
  68. var result = new Matrix2D();
  69. Matrix2D.TranslationToRef(x, y, result);
  70. return result;
  71. };
  72. Matrix2D.TranslationToRef = function (x, y, result) {
  73. result.m[0] = 1;
  74. result.m[1] = 0;
  75. result.m[2] = 0;
  76. result.m[3] = 1;
  77. result.m[4] = x;
  78. result.m[5] = y;
  79. };
  80. Matrix2D.Scaling = function (x, y) {
  81. var result = new Matrix2D();
  82. Matrix2D.ScalingToRef(x, y, result);
  83. return result;
  84. };
  85. Matrix2D.ScalingToRef = function (x, y, result) {
  86. result.m[0] = x;
  87. result.m[1] = 0;
  88. result.m[2] = 0;
  89. result.m[3] = y;
  90. result.m[4] = 0;
  91. result.m[5] = 0;
  92. };
  93. Matrix2D.Identity = function () {
  94. var res = new Matrix2D();
  95. Matrix2D.IdentityToRef(res);
  96. return res;
  97. };
  98. Matrix2D.IdentityToRef = function (res) {
  99. res.m[1] = res.m[2] = res.m[4] = res[5] = 0;
  100. res.m[0] = res.m[3] = 1;
  101. };
  102. Matrix2D.FromQuaternion = function (quaternion) {
  103. var result = new Matrix2D();
  104. Matrix2D.FromQuaternionToRef(quaternion, result);
  105. return result;
  106. };
  107. Matrix2D.FromQuaternionToRef = function (quaternion, result) {
  108. var xx = quaternion.x * quaternion.x;
  109. var yy = quaternion.y * quaternion.y;
  110. var zz = quaternion.z * quaternion.z;
  111. var xy = quaternion.x * quaternion.y;
  112. var zw = quaternion.z * quaternion.w;
  113. //var zx = quaternion.z * quaternion.x;
  114. //var yw = quaternion.y * quaternion.w;
  115. //var yz = quaternion.y * quaternion.z;
  116. //var xw = quaternion.x * quaternion.w;
  117. result.m[0] = 1.0 - (2.0 * (yy + zz));
  118. result.m[1] = 2.0 * (xy + zw);
  119. //result.m[2] = 2.0 * (zx - yw);
  120. //result.m[3] = 0;
  121. result.m[2] = 2.0 * (xy - zw);
  122. result.m[3] = 1.0 - (2.0 * (zz + xx));
  123. //result.m[6] = 2.0 * (yz + xw);
  124. //result.m[7] = 0;
  125. //result.m[8] = 2.0 * (zx + yw);
  126. //result.m[9] = 2.0 * (yz - xw);
  127. //result.m[10] = 1.0 - (2.0 * (yy + xx));
  128. //result.m[11] = 0;
  129. //result.m[12] = 0;
  130. //result.m[13] = 0;
  131. //result.m[14] = 0;
  132. //result.m[15] = 1.0;
  133. };
  134. Matrix2D.Compose = function (scale, rotation, translation) {
  135. var result = Matrix2D.Scaling(scale.x, scale.y);
  136. var rotationMatrix = Matrix2D.Rotation(rotation);
  137. result = result.multiply(rotationMatrix);
  138. result.setTranslation(translation);
  139. return result;
  140. };
  141. Matrix2D.Invert = function (source) {
  142. var result = new Matrix2D();
  143. source.invertToRef(result);
  144. return result;
  145. };
  146. Matrix2D.prototype.clone = function () {
  147. var result = new Matrix2D();
  148. result.copyFrom(this);
  149. return result;
  150. };
  151. Matrix2D.prototype.copyFrom = function (other) {
  152. for (var i = 0; i < 6; i++) {
  153. this.m[i] = other.m[i];
  154. }
  155. };
  156. Matrix2D.prototype.getTranslation = function () {
  157. return new BABYLON.Vector2(this.m[4], this.m[5]);
  158. };
  159. Matrix2D.prototype.setTranslation = function (translation) {
  160. this.m[4] = translation.x;
  161. this.m[5] = translation.y;
  162. };
  163. Matrix2D.prototype.determinant = function () {
  164. return this.m[0] * this.m[3] - this.m[1] * this.m[2];
  165. };
  166. Matrix2D.prototype.invertToThis = function () {
  167. this.invertToRef(this);
  168. };
  169. Matrix2D.prototype.invert = function () {
  170. var res = new Matrix2D();
  171. this.invertToRef(res);
  172. return res;
  173. };
  174. // http://mathworld.wolfram.com/MatrixInverse.html
  175. Matrix2D.prototype.invertToRef = function (res) {
  176. var l0 = this.m[0];
  177. var l1 = this.m[1];
  178. var l2 = this.m[2];
  179. var l3 = this.m[3];
  180. var l4 = this.m[4];
  181. var l5 = this.m[5];
  182. var det = this.determinant();
  183. if (det < (BABYLON.Epsilon * BABYLON.Epsilon)) {
  184. throw new Error("Can't invert matrix, near null determinant");
  185. }
  186. var detDiv = 1 / det;
  187. var det4 = l2 * l5 - l3 * l4;
  188. var det5 = l1 * l4 - l0 * l5;
  189. res.m[0] = l3 * detDiv;
  190. res.m[1] = -l1 * detDiv;
  191. res.m[2] = -l2 * detDiv;
  192. res.m[3] = l0 * detDiv;
  193. res.m[4] = det4 * detDiv;
  194. res.m[5] = det5 * detDiv;
  195. };
  196. Matrix2D.prototype.multiplyToThis = function (other) {
  197. this.multiplyToRef(other, this);
  198. };
  199. Matrix2D.prototype.multiply = function (other) {
  200. var res = new Matrix2D();
  201. this.multiplyToRef(other, res);
  202. return res;
  203. };
  204. Matrix2D.prototype.multiplyToRef = function (other, result) {
  205. var l0 = this.m[0];
  206. var l1 = this.m[1];
  207. var l2 = this.m[2];
  208. var l3 = this.m[3];
  209. var l4 = this.m[4];
  210. var l5 = this.m[5];
  211. var r0 = other.m[0];
  212. var r1 = other.m[1];
  213. var r2 = other.m[2];
  214. var r3 = other.m[3];
  215. var r4 = other.m[4];
  216. var r5 = other.m[5];
  217. result.m[0] = l0 * r0 + l1 * r2;
  218. result.m[1] = l0 * r1 + l1 * r3;
  219. result.m[2] = l2 * r0 + l3 * r2;
  220. result.m[3] = l2 * r1 + l3 * r3;
  221. result.m[4] = l4 * r0 + l5 * r2 + r4;
  222. result.m[5] = l4 * r1 + l5 * r3 + r5;
  223. };
  224. Matrix2D.prototype.transformFloats = function (x, y) {
  225. var res = BABYLON.Vector2.Zero();
  226. this.transformFloatsToRef(x, y, res);
  227. return res;
  228. };
  229. Matrix2D.prototype.transformFloatsToRef = function (x, y, r) {
  230. r.x = x * this.m[0] + y * this.m[2] + this.m[4];
  231. r.y = x * this.m[1] + y * this.m[3] + this.m[5];
  232. };
  233. Matrix2D.prototype.transformPoint = function (p) {
  234. var res = BABYLON.Vector2.Zero();
  235. this.transformFloatsToRef(p.x, p.y, res);
  236. return res;
  237. };
  238. Matrix2D.prototype.transformPointToRef = function (p, r) {
  239. this.transformFloatsToRef(p.x, p.y, r);
  240. };
  241. Matrix2D.prototype.decompose = function (scale, translation) {
  242. translation.x = this.m[4];
  243. translation.y = this.m[5];
  244. scale.x = Math.sqrt(this.m[0] * this.m[0] + this.m[1] * this.m[1]);
  245. scale.y = Math.sqrt(this.m[2] * this.m[2] + this.m[3] * this.m[3]);
  246. if (scale.x === 0 || scale.y === 0) {
  247. return null;
  248. }
  249. return Math.atan2(-this.m[2] / scale.y, this.m[0] / scale.x);
  250. };
  251. return Matrix2D;
  252. }());
  253. Matrix2D._decomp = new Matrix2D();
  254. BABYLON.Matrix2D = Matrix2D;
  255. /**
  256. * Stores information about a 2D Triangle.
  257. * This class stores the 3 vertices but also the center and radius of the triangle
  258. */
  259. var Tri2DInfo = (function () {
  260. /**
  261. * Construct an instance of Tri2DInfo, you can either pass null to a, b and c and the instance will be allocated "clear", or give actual triangle info and the center/radius will be computed
  262. */
  263. function Tri2DInfo(a, b, c) {
  264. if (a === null && b === null && c === null) {
  265. this.a = BABYLON.Vector2.Zero();
  266. this.b = BABYLON.Vector2.Zero();
  267. this.c = BABYLON.Vector2.Zero();
  268. this.center = BABYLON.Vector2.Zero();
  269. this.radius = 0;
  270. return;
  271. }
  272. this.a = a.clone();
  273. this.b = b.clone();
  274. this.c = c.clone();
  275. this._updateCenterRadius();
  276. }
  277. Tri2DInfo.Zero = function () {
  278. return new Tri2DInfo(null, null, null);
  279. };
  280. Tri2DInfo.prototype.set = function (a, b, c) {
  281. this.a.copyFrom(a);
  282. this.b.copyFrom(b);
  283. this.c.copyFrom(c);
  284. this._updateCenterRadius();
  285. };
  286. Tri2DInfo.prototype.transformInPlace = function (transform) {
  287. transform.transformPointToRef(this.a, this.a);
  288. transform.transformPointToRef(this.b, this.b);
  289. transform.transformPointToRef(this.c, this.c);
  290. //Vector2.TransformToRef(this.a, transform, this.a);
  291. //Vector2.TransformToRef(this.b, transform, this.b);
  292. //Vector2.TransformToRef(this.c, transform, this.c);
  293. this._updateCenterRadius();
  294. };
  295. Tri2DInfo.prototype.doesContain = function (p) {
  296. return BABYLON.Vector2.PointInTriangle(p, this.a, this.b, this.c);
  297. };
  298. Tri2DInfo.prototype._updateCenterRadius = function () {
  299. this.center.x = (this.a.x + this.b.x + this.c.x) / 3;
  300. this.center.y = (this.a.y + this.b.y + this.c.y) / 3;
  301. var la = BABYLON.Vector2.DistanceSquared(this.a, this.center);
  302. var lb = BABYLON.Vector2.DistanceSquared(this.b, this.center);
  303. var lc = BABYLON.Vector2.DistanceSquared(this.c, this.center);
  304. var rs = Math.max(Math.max(la, lb), lc);
  305. this.radius = Math.sqrt(rs);
  306. };
  307. return Tri2DInfo;
  308. }());
  309. BABYLON.Tri2DInfo = Tri2DInfo;
  310. /**
  311. * Stores an array of 2D Triangles.
  312. * Internally the data is stored as a Float32Array to minimize the memory footprint.
  313. * This can use the Tri2DInfo class as proxy for storing/retrieving data.
  314. * The array can't grow, it's fixed size.
  315. */
  316. var Tri2DArray = (function () {
  317. function Tri2DArray(count) {
  318. this._count = count;
  319. this._array = new Float32Array(9 * count);
  320. }
  321. /**
  322. * Clear the content and allocate a new array to store the given count of triangles
  323. * @param count The new count of triangles to store
  324. */
  325. Tri2DArray.prototype.clear = function (count) {
  326. if (this._count === count) {
  327. return;
  328. }
  329. this._count = count;
  330. this._array = new Float32Array(9 * count);
  331. };
  332. /**
  333. * Store a given triangle at the given index
  334. * @param index the 0 based index to store the triangle in the array
  335. * @param a the A vertex of the triangle
  336. * @param b the B vertex of the triangle
  337. * @param c the C vertex of the triangle
  338. */
  339. Tri2DArray.prototype.storeTriangle = function (index, a, b, c) {
  340. var center = new BABYLON.Vector2((a.x + b.x + c.x) / 3, (a.y + b.y + c.y) / 3);
  341. var la = BABYLON.Vector2.DistanceSquared(a, center);
  342. var lb = BABYLON.Vector2.DistanceSquared(b, center);
  343. var lc = BABYLON.Vector2.DistanceSquared(c, center);
  344. var rs = Math.max(Math.max(la, lb), lc);
  345. var radius = Math.sqrt(rs);
  346. var offset = index * 9;
  347. this._array[offset + 0] = a.x;
  348. this._array[offset + 1] = a.y;
  349. this._array[offset + 2] = b.x;
  350. this._array[offset + 3] = b.y;
  351. this._array[offset + 4] = c.x;
  352. this._array[offset + 5] = c.y;
  353. this._array[offset + 6] = center.x;
  354. this._array[offset + 7] = center.y;
  355. this._array[offset + 8] = radius;
  356. };
  357. /**
  358. * Store a triangle in a Tri2DInfo object
  359. * @param index the index of the triangle to store
  360. * @param tri2dInfo the instance that will contain the data, it must be already allocated with its inner object also allocated
  361. */
  362. Tri2DArray.prototype.storeToTri2DInfo = function (index, tri2dInfo) {
  363. if (index >= this._count) {
  364. throw new Error("Can't fetch the triangle at index " + index + ", max index is " + (this._count - 1));
  365. }
  366. var offset = index * 9;
  367. tri2dInfo.a.x = this._array[offset + 0];
  368. tri2dInfo.a.y = this._array[offset + 1];
  369. tri2dInfo.b.x = this._array[offset + 2];
  370. tri2dInfo.b.y = this._array[offset + 3];
  371. tri2dInfo.c.x = this._array[offset + 4];
  372. tri2dInfo.c.y = this._array[offset + 5];
  373. tri2dInfo.center.x = this._array[offset + 6];
  374. tri2dInfo.center.y = this._array[offset + 7];
  375. tri2dInfo.radius = this._array[offset + 8];
  376. };
  377. /**
  378. * Transform the given triangle and store its result in the array
  379. * @param index The index to store the result to
  380. * @param tri2dInfo The triangle to transform
  381. * @param transform The transformation matrix
  382. */
  383. Tri2DArray.prototype.transformAndStoreToTri2DInfo = function (index, tri2dInfo, transform) {
  384. if (index >= this._count) {
  385. throw new Error("Can't fetch the triangle at index " + index + ", max index is " + (this._count - 1));
  386. }
  387. var offset = index * 9;
  388. tri2dInfo.a.x = this._array[offset + 0];
  389. tri2dInfo.a.y = this._array[offset + 1];
  390. tri2dInfo.b.x = this._array[offset + 2];
  391. tri2dInfo.b.y = this._array[offset + 3];
  392. tri2dInfo.c.x = this._array[offset + 4];
  393. tri2dInfo.c.y = this._array[offset + 5];
  394. tri2dInfo.transformInPlace(transform);
  395. };
  396. Object.defineProperty(Tri2DArray.prototype, "count", {
  397. /**
  398. * Get the element count that can be stored in this array
  399. * @returns {}
  400. */
  401. get: function () {
  402. return this._count;
  403. },
  404. enumerable: true,
  405. configurable: true
  406. });
  407. /**
  408. * Check if a given point intersects with at least one of the triangles stored in the array.
  409. * If true is returned the point is intersecting with at least one triangle, false if it doesn't intersect with any of them
  410. * @param p The point to check
  411. */
  412. Tri2DArray.prototype.doesContain = function (p) {
  413. Tri2DArray._checkInitStatics();
  414. var a = Tri2DArray.tempT[0];
  415. for (var i = 0; i < this.count; i++) {
  416. this.storeToTri2DInfo(i, a);
  417. if (a.doesContain(p)) {
  418. return true;
  419. }
  420. }
  421. return false;
  422. };
  423. /**
  424. * Make a intersection test between two sets of triangles. The triangles of setB will be transformed to the frame of reference of the setA using the given bToATransform matrix.
  425. * If true is returned at least one triangle intersects with another of the other set, otherwise false is returned.
  426. * @param setA The first set of triangles
  427. * @param setB The second set of triangles
  428. * @param bToATransform The transformation matrix to transform the setB triangles into the frame of reference of the setA
  429. */
  430. Tri2DArray.doesIntersect = function (setA, setB, bToATransform) {
  431. Tri2DArray._checkInitStatics();
  432. var a = Tri2DArray.tempT[0];
  433. var b = Tri2DArray.tempT[1];
  434. var v0 = Tri2DArray.tempV[0];
  435. for (var curB = 0; curB < setB.count; curB++) {
  436. setB.transformAndStoreToTri2DInfo(curB, b, bToATransform);
  437. for (var curA = 0; curA < setA.count; curA++) {
  438. setA.storeToTri2DInfo(curA, a);
  439. // Fast rejection first
  440. v0.x = a.center.x - b.center.x;
  441. v0.y = a.center.y - b.center.y;
  442. if (v0.lengthSquared() > ((a.radius * a.radius) + (b.radius * b.radius))) {
  443. continue;
  444. }
  445. // Actual intersection test
  446. if (Math2D.TriangleTriangleDosIntersect(a.a, a.b, a.c, b.a, b.b, b.c)) {
  447. return true;
  448. }
  449. }
  450. }
  451. return false;
  452. };
  453. Tri2DArray._checkInitStatics = function () {
  454. if (Tri2DArray.tempT !== null) {
  455. return;
  456. }
  457. Tri2DArray.tempT = new Array(2);
  458. Tri2DArray.tempT[0] = new Tri2DInfo(null, null, null);
  459. Tri2DArray.tempT[1] = new Tri2DInfo(null, null, null);
  460. Tri2DArray.tempV = new Array(6);
  461. for (var i = 0; i < 6; i++) {
  462. Tri2DArray.tempV[i] = BABYLON.Vector2.Zero();
  463. }
  464. };
  465. return Tri2DArray;
  466. }());
  467. Tri2DArray.tempV = null;
  468. Tri2DArray.tempT = null;
  469. BABYLON.Tri2DArray = Tri2DArray;
  470. /**
  471. * Some 2D Math helpers functions
  472. */
  473. var Math2D = (function () {
  474. function Math2D() {
  475. }
  476. Math2D.Dot = function (a, b) {
  477. return a.x * b.x + a.y * b.y;
  478. };
  479. // From http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect
  480. // Note: this one might also be considered with the above one proves to not be good enough: http://jsfiddle.net/justin_c_rounds/Gd2S2/light/
  481. Math2D.LineLineDoesIntersect = function (segA1, segA2, segB1, segB2) {
  482. var s1_x = segA2.x - segA1.x;
  483. var s1_y = segA2.y - segA1.y;
  484. var s2_x = segB2.x - segB1.x;
  485. var s2_y = segB2.y - segB1.y;
  486. var s = (-s1_y * (segA1.x - segB1.x) + s1_x * (segA1.y - segB1.y)) / (-s2_x * s1_y + s1_x * s2_y);
  487. var t = (s2_x * (segA1.y - segB1.y) - s2_y * (segA1.x - segB1.x)) / (-s2_x * s1_y + s1_x * s2_y);
  488. if (s >= 0 && s <= 1 && t >= 0 && t <= 1) {
  489. return true;
  490. }
  491. return false;
  492. };
  493. // From http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect
  494. Math2D.LineLineIntersection = function (p0, p1, p2, p3) {
  495. var s1_x = p1.x - p0.x;
  496. var s1_y = p1.y - p0.y;
  497. var s2_x = p3.x - p2.x;
  498. var s2_y = p3.y - p2.y;
  499. var s = (-s1_y * (p0.x - p2.x) + s1_x * (p0.y - p2.y)) / (-s2_x * s1_y + s1_x * s2_y);
  500. var t = (s2_x * (p0.y - p2.y) - s2_y * (p0.x - p2.x)) / (-s2_x * s1_y + s1_x * s2_y);
  501. if (s >= 0 && s <= 1 && t >= 0 && t <= 1) {
  502. return { res: true, xr: p0.x + (t * s1_x), yr: p0.y + (t * s1_y) };
  503. }
  504. return { res: false, xr: 0, yr: 0 };
  505. };
  506. // Tell me that it's slow and I'll answer: yes it is!
  507. // If you fancy to implement the SAT (Separating Axis Theorem) version: BE MY VERY WELCOMED GUEST!
  508. Math2D.TriangleTriangleDosIntersect = function (tri1A, tri1B, tri1C, tri2A, tri2B, tri2C) {
  509. if (Math2D.LineLineDoesIntersect(tri1A, tri1B, tri2A, tri2B))
  510. return true;
  511. if (Math2D.LineLineDoesIntersect(tri1A, tri1B, tri2A, tri2C))
  512. return true;
  513. if (Math2D.LineLineDoesIntersect(tri1A, tri1B, tri2B, tri2C))
  514. return true;
  515. if (Math2D.LineLineDoesIntersect(tri1A, tri1C, tri2A, tri2B))
  516. return true;
  517. if (Math2D.LineLineDoesIntersect(tri1A, tri1C, tri2A, tri2C))
  518. return true;
  519. if (Math2D.LineLineDoesIntersect(tri1A, tri1C, tri2B, tri2C))
  520. return true;
  521. if (Math2D.LineLineDoesIntersect(tri1B, tri1C, tri2A, tri2B))
  522. return true;
  523. if (Math2D.LineLineDoesIntersect(tri1B, tri1C, tri2A, tri2C))
  524. return true;
  525. if (Math2D.LineLineDoesIntersect(tri1B, tri1C, tri2B, tri2C))
  526. return true;
  527. if (BABYLON.Vector2.PointInTriangle(tri2A, tri1A, tri1B, tri1C) &&
  528. BABYLON.Vector2.PointInTriangle(tri2B, tri1A, tri1B, tri1C) &&
  529. BABYLON.Vector2.PointInTriangle(tri2C, tri1A, tri1B, tri1C))
  530. return true;
  531. if (BABYLON.Vector2.PointInTriangle(tri1A, tri2A, tri2B, tri2C) &&
  532. BABYLON.Vector2.PointInTriangle(tri1B, tri2A, tri2B, tri2C) &&
  533. BABYLON.Vector2.PointInTriangle(tri1C, tri2A, tri2B, tri2C))
  534. return true;
  535. return false;
  536. };
  537. return Math2D;
  538. }());
  539. Math2D.v0 = BABYLON.Vector2.Zero();
  540. Math2D.v1 = BABYLON.Vector2.Zero();
  541. Math2D.v2 = BABYLON.Vector2.Zero();
  542. })(BABYLON || (BABYLON = {}));
  543. //# sourceMappingURL=babylon.math2D.js.map
  544. var BABYLON;
  545. (function (BABYLON) {
  546. var PropertyChangedInfo = (function () {
  547. function PropertyChangedInfo() {
  548. }
  549. return PropertyChangedInfo;
  550. }());
  551. BABYLON.PropertyChangedInfo = PropertyChangedInfo;
  552. /**
  553. * The purpose of this class is to provide a base implementation of the IPropertyChanged interface for the user to avoid rewriting a code needlessly.
  554. * Typical use of this class is to check for equality in a property set(), then call the onPropertyChanged method if values are different after the new value is set. The protected method will notify observers of the change.
  555. * Remark: onPropertyChanged detects reentrant code and acts in a way to make sure everything is fine, fast and allocation friendly (when there no reentrant code which should be 99% of the time)
  556. */
  557. var PropertyChangedBase = (function () {
  558. function PropertyChangedBase() {
  559. this._propertyChanged = null;
  560. }
  561. /**
  562. * Protected method to call when there's a change of value in a property set
  563. * @param propName the name of the concerned property
  564. * @param oldValue its old value
  565. * @param newValue its new value
  566. * @param mask an optional observable mask
  567. */
  568. PropertyChangedBase.prototype.onPropertyChanged = function (propName, oldValue, newValue, mask) {
  569. if (this.propertyChanged.hasObservers()) {
  570. var pci = PropertyChangedBase.calling ? new PropertyChangedInfo() : PropertyChangedBase.pci;
  571. pci.oldValue = oldValue;
  572. pci.newValue = newValue;
  573. pci.propertyName = propName;
  574. try {
  575. PropertyChangedBase.calling = true;
  576. this.propertyChanged.notifyObservers(pci, mask);
  577. }
  578. finally {
  579. PropertyChangedBase.calling = false;
  580. }
  581. }
  582. };
  583. Object.defineProperty(PropertyChangedBase.prototype, "propertyChanged", {
  584. /**
  585. * An observable that is triggered when a property (using of the XXXXLevelProperty decorator) has its value changing.
  586. * You can add an observer that will be triggered only for a given set of Properties using the Mask feature of the Observable and the corresponding Prim2DPropInfo.flagid value (e.g. Prim2DBase.positionProperty.flagid|Prim2DBase.rotationProperty.flagid to be notified only about position or rotation change)
  587. */
  588. get: function () {
  589. if (!this._propertyChanged) {
  590. this._propertyChanged = new BABYLON.Observable();
  591. }
  592. return this._propertyChanged;
  593. },
  594. enumerable: true,
  595. configurable: true
  596. });
  597. return PropertyChangedBase;
  598. }());
  599. PropertyChangedBase.pci = new PropertyChangedInfo();
  600. PropertyChangedBase.calling = false;
  601. BABYLON.PropertyChangedBase = PropertyChangedBase;
  602. })(BABYLON || (BABYLON = {}));
  603. //# sourceMappingURL=babylon.IPropertyChanged.js.map
  604. var BABYLON;
  605. (function (BABYLON) {
  606. // logging stuffs
  607. var C2DLogging = (function () {
  608. function C2DLogging() {
  609. }
  610. C2DLogging.logFrameRender = function (frameCount) {
  611. C2DLogging.snooze = true;
  612. C2DLogging._logFramesCount = frameCount;
  613. };
  614. C2DLogging.setPostMessage = function (message) {
  615. if (C2DLoggingInternals.enableLog) {
  616. C2DLoggingInternals.postMessages[C2DLoggingInternals.callDepth - 1] = message();
  617. }
  618. };
  619. C2DLogging._startFrameRender = function () {
  620. if (C2DLogging._logFramesCount === 0) {
  621. return;
  622. }
  623. C2DLogging.snooze = false;
  624. };
  625. C2DLogging._endFrameRender = function () {
  626. if (C2DLogging._logFramesCount === 0) {
  627. return;
  628. }
  629. C2DLogging.snooze = true;
  630. --C2DLogging._logFramesCount;
  631. };
  632. return C2DLogging;
  633. }());
  634. // Set to true to temporary disable logging.
  635. C2DLogging.snooze = true;
  636. C2DLogging._logFramesCount = 0;
  637. BABYLON.C2DLogging = C2DLogging;
  638. var C2DLoggingInternals = (function () {
  639. function C2DLoggingInternals() {
  640. }
  641. C2DLoggingInternals.computeIndent = function () {
  642. // Compute the indent
  643. var indent = null;
  644. if (C2DLoggingInternals.callDepth < 20) {
  645. indent = C2DLoggingInternals.depths[C2DLoggingInternals.callDepth];
  646. }
  647. else {
  648. indent = "|";
  649. for (var i = 0; i <= C2DLoggingInternals.callDepth; i++) {
  650. indent = indent + "-";
  651. }
  652. }
  653. return indent;
  654. };
  655. C2DLoggingInternals.getFormattedValue = function (a) {
  656. if (a instanceof BABYLON.Prim2DBase) {
  657. return a.id;
  658. }
  659. if (a == null) {
  660. return "[null]";
  661. }
  662. return a.toString();
  663. };
  664. return C2DLoggingInternals;
  665. }());
  666. //-------------FLAG TO CHANGE TO ENABLE/DISABLE LOGGING ACTIVATION--------------
  667. // This flag can't be changed at runtime you must manually change it in the code
  668. C2DLoggingInternals.enableLog = false;
  669. C2DLoggingInternals.callDepth = 0;
  670. C2DLoggingInternals.depths = [
  671. "|-", "|--", "|---", "|----", "|-----", "|------", "|-------", "|--------", "|---------", "|----------",
  672. "|-----------", "|------------", "|-------------", "|--------------", "|---------------", "|----------------", "|-----------------", "|------------------", "|-------------------", "|--------------------"
  673. ];
  674. C2DLoggingInternals.postMessages = [];
  675. function logProp(message, alsoGet, setNoProlog, getNoProlog) {
  676. if (message === void 0) { message = ""; }
  677. if (alsoGet === void 0) { alsoGet = false; }
  678. if (setNoProlog === void 0) { setNoProlog = false; }
  679. if (getNoProlog === void 0) { getNoProlog = false; }
  680. return function (target, propName, descriptor) {
  681. if (!C2DLoggingInternals.enableLog) {
  682. return descriptor;
  683. }
  684. var getter = descriptor.get, setter = descriptor.set;
  685. if (getter && alsoGet) {
  686. descriptor.get = function () {
  687. if (C2DLogging.snooze) {
  688. return getter.call(this);
  689. }
  690. else {
  691. var indent = C2DLoggingInternals.computeIndent();
  692. var id = this.id || "";
  693. if (message !== null && message !== "") {
  694. console.log(message);
  695. }
  696. var isSPP = this instanceof BABYLON.SmartPropertyPrim;
  697. var flags = isSPP ? this._flags : 0;
  698. var depth = C2DLoggingInternals.callDepth;
  699. if (!getNoProlog) {
  700. console.log(indent + " [" + id + "] (" + depth + ") ==> get " + propName + " property");
  701. }
  702. ++C2DLoggingInternals.callDepth;
  703. C2DLogging.setPostMessage(function () { return "[no msg]"; });
  704. // Call the initial getter
  705. var r = getter.call(this);
  706. --C2DLoggingInternals.callDepth;
  707. var flagsStr = "";
  708. if (isSPP) {
  709. var nflags = this._flags;
  710. var newFlags = this._getFlagsDebug((nflags & flags) ^ nflags);
  711. var removedFlags = this._getFlagsDebug((nflags & flags) ^ flags);
  712. flagsStr = "";
  713. if (newFlags !== "") {
  714. flagsStr = " +++[" + newFlags + "]";
  715. }
  716. if (removedFlags !== "") {
  717. if (flagsStr !== "") {
  718. flagsStr += ",";
  719. }
  720. flagsStr += " ---[" + removedFlags + "]";
  721. }
  722. }
  723. console.log(indent + " [" + id + "] (" + depth + ")" + (getNoProlog ? "" : " <==") + " get " + propName + " property => " + C2DLoggingInternals.getFormattedValue(r) + flagsStr + ", " + C2DLoggingInternals.postMessages[C2DLoggingInternals.callDepth]);
  724. return r;
  725. }
  726. };
  727. }
  728. // Overload the property setter implementation to add our own logic
  729. if (setter) {
  730. descriptor.set = function (val) {
  731. if (C2DLogging.snooze) {
  732. setter.call(this, val);
  733. }
  734. else {
  735. var indent = C2DLoggingInternals.computeIndent();
  736. var id = this.id || "";
  737. if (message !== null && message !== "") {
  738. console.log(message);
  739. }
  740. var isSPP = this instanceof BABYLON.SmartPropertyPrim;
  741. var flags = isSPP ? this._flags : 0;
  742. var depth = C2DLoggingInternals.callDepth;
  743. if (!setNoProlog) {
  744. console.log(indent + " [" + id + "] (" + depth + ") ==> set " + propName + " property with " + C2DLoggingInternals.getFormattedValue(val));
  745. }
  746. ++C2DLoggingInternals.callDepth;
  747. C2DLogging.setPostMessage(function () { return "[no msg]"; });
  748. // Change the value
  749. setter.call(this, val);
  750. --C2DLoggingInternals.callDepth;
  751. var flagsStr = "";
  752. if (isSPP) {
  753. var nflags = this._flags;
  754. var newFlags = this._getFlagsDebug((nflags & flags) ^ nflags);
  755. var removedFlags = this._getFlagsDebug((nflags & flags) ^ flags);
  756. flagsStr = "";
  757. if (newFlags !== "") {
  758. flagsStr = " +++[" + newFlags + "]";
  759. }
  760. if (removedFlags !== "") {
  761. if (flagsStr !== "") {
  762. flagsStr += ",";
  763. }
  764. flagsStr += " ---[" + removedFlags + "]";
  765. }
  766. }
  767. console.log(indent + " [" + id + "] (" + depth + ")" + (setNoProlog ? "" : " <==") + " set " + propName + " property, " + C2DLoggingInternals.postMessages[C2DLoggingInternals.callDepth] + flagsStr);
  768. }
  769. };
  770. }
  771. return descriptor;
  772. };
  773. }
  774. BABYLON.logProp = logProp;
  775. function logMethod(message, noProlog) {
  776. if (message === void 0) { message = ""; }
  777. if (noProlog === void 0) { noProlog = false; }
  778. return function (target, key, descriptor) {
  779. if (!C2DLoggingInternals.enableLog) {
  780. return descriptor;
  781. }
  782. if (descriptor === undefined) {
  783. descriptor = Object.getOwnPropertyDescriptor(target, key);
  784. }
  785. var originalMethod = descriptor.value;
  786. //editing the descriptor/value parameter
  787. descriptor.value = function () {
  788. var args = [];
  789. for (var _i = 0; _i < arguments.length; _i++) {
  790. args[_i - 0] = arguments[_i];
  791. }
  792. if (C2DLogging.snooze) {
  793. return originalMethod.apply(this, args);
  794. }
  795. else {
  796. var a = args.map(function (a) { return C2DLoggingInternals.getFormattedValue(a) + ", "; }).join();
  797. a = a.slice(0, a.length - 2);
  798. var indent = C2DLoggingInternals.computeIndent();
  799. var id = this.id || "";
  800. if (message !== null && message !== "") {
  801. console.log(message);
  802. }
  803. var isSPP = this instanceof BABYLON.SmartPropertyPrim;
  804. var flags = isSPP ? this._flags : 0;
  805. var depth = C2DLoggingInternals.callDepth;
  806. if (!noProlog) {
  807. console.log(indent + " [" + id + "] (" + depth + ") ==> call: " + key + " (" + a + ")");
  808. }
  809. ++C2DLoggingInternals.callDepth;
  810. C2DLogging.setPostMessage(function () { return "[no msg]"; });
  811. // Call the method!
  812. var result = originalMethod.apply(this, args);
  813. --C2DLoggingInternals.callDepth;
  814. var flagsStr = "";
  815. if (isSPP) {
  816. var nflags = this._flags;
  817. var newFlags = this._getFlagsDebug((nflags & flags) ^ nflags);
  818. var removedFlags = this._getFlagsDebug((nflags & flags) ^ flags);
  819. flagsStr = "";
  820. if (newFlags !== "") {
  821. flagsStr = " +++[" + newFlags + "]";
  822. }
  823. if (removedFlags !== "") {
  824. if (flagsStr !== "") {
  825. flagsStr += ",";
  826. }
  827. flagsStr += " ---[" + removedFlags + "]";
  828. }
  829. }
  830. console.log(indent + " [" + id + "] (" + depth + ")" + (noProlog ? "" : " <==") + " call: " + key + " (" + a + ") Res: " + C2DLoggingInternals.getFormattedValue(result) + ", " + C2DLoggingInternals.postMessages[C2DLoggingInternals.callDepth] + flagsStr);
  831. return result;
  832. }
  833. };
  834. // return edited descriptor as opposed to overwriting the descriptor
  835. return descriptor;
  836. };
  837. }
  838. BABYLON.logMethod = logMethod;
  839. })(BABYLON || (BABYLON = {}));
  840. //# sourceMappingURL=babylon.c2dlogging.js.map
  841. var __extends = (this && this.__extends) || (function () {
  842. var extendStatics = Object.setPrototypeOf ||
  843. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  844. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  845. return function (d, b) {
  846. extendStatics(d, b);
  847. function __() { this.constructor = d; }
  848. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  849. };
  850. })();
  851. var BABYLON;
  852. (function (BABYLON) {
  853. /**
  854. * Class for the ObservableArray.onArrayChanged observable
  855. */
  856. var ArrayChanged = (function () {
  857. function ArrayChanged() {
  858. this.action = 0;
  859. this.newItems = new Array();
  860. this.removedItems = new Array();
  861. this.changedItems = new Array();
  862. this.newStartingIndex = -1;
  863. this.removedStartingIndex = -1;
  864. }
  865. Object.defineProperty(ArrayChanged, "clearAction", {
  866. /**
  867. * The content of the array was totally cleared
  868. */
  869. get: function () {
  870. return ArrayChanged._clearAction;
  871. },
  872. enumerable: true,
  873. configurable: true
  874. });
  875. Object.defineProperty(ArrayChanged, "newItemsAction", {
  876. /**
  877. * A new item was added, the newItems field contains the key/value pairs
  878. */
  879. get: function () {
  880. return ArrayChanged._newItemsAction;
  881. },
  882. enumerable: true,
  883. configurable: true
  884. });
  885. Object.defineProperty(ArrayChanged, "removedItemsAction", {
  886. /**
  887. * An existing item was removed, the removedKey field contains its key
  888. */
  889. get: function () {
  890. return ArrayChanged._removedItemsAction;
  891. },
  892. enumerable: true,
  893. configurable: true
  894. });
  895. Object.defineProperty(ArrayChanged, "changedItemAction", {
  896. /**
  897. * One or many items in the array were changed, the
  898. */
  899. get: function () {
  900. return ArrayChanged._changedItemAction;
  901. },
  902. enumerable: true,
  903. configurable: true
  904. });
  905. Object.defineProperty(ArrayChanged, "replacedArrayAction", {
  906. /**
  907. * The array's content was totally changed
  908. * Depending on the method that used this mode the ChangedArray object may contains more information
  909. */
  910. get: function () {
  911. return ArrayChanged._replacedArrayAction;
  912. },
  913. enumerable: true,
  914. configurable: true
  915. });
  916. Object.defineProperty(ArrayChanged, "lengthChangedAction", {
  917. /**
  918. * The length of the array changed
  919. */
  920. get: function () {
  921. return ArrayChanged._lengthChangedAction;
  922. },
  923. enumerable: true,
  924. configurable: true
  925. });
  926. ArrayChanged.prototype.clear = function () {
  927. this.action = 0;
  928. this.newItems.splice(0);
  929. this.removedItems.splice(0);
  930. this.changedItems.splice(0);
  931. this.removedStartingIndex = this.removedStartingIndex = this.changedStartingIndex = 0;
  932. };
  933. return ArrayChanged;
  934. }());
  935. ArrayChanged._clearAction = 0x1;
  936. ArrayChanged._newItemsAction = 0x2;
  937. ArrayChanged._removedItemsAction = 0x4;
  938. ArrayChanged._replacedArrayAction = 0x8;
  939. ArrayChanged._lengthChangedAction = 0x10;
  940. ArrayChanged._changedItemAction = 0x20;
  941. BABYLON.ArrayChanged = ArrayChanged;
  942. var OAWatchedObjectChangedInfo = (function () {
  943. function OAWatchedObjectChangedInfo() {
  944. }
  945. return OAWatchedObjectChangedInfo;
  946. }());
  947. BABYLON.OAWatchedObjectChangedInfo = OAWatchedObjectChangedInfo;
  948. /**
  949. * This class mimics the Javascript Array and TypeScript Array<T> classes, adding new features concerning the Observable pattern.
  950. *
  951. */
  952. var ObservableArray = (function (_super) {
  953. __extends(ObservableArray, _super);
  954. /**
  955. * Create an Observable Array.
  956. * @param watchObjectsPropertyChange
  957. * @param array and optional array that will be encapsulated by this ObservableArray instance. That's right, it's NOT a copy!
  958. */
  959. function ObservableArray(watchObjectsPropertyChange, array) {
  960. var _this = _super.call(this) || this;
  961. _this.dci = new ArrayChanged();
  962. _this._callingArrayChanged = false;
  963. _this._array = (array != null) ? array : new Array();
  964. _this.dci = new ArrayChanged();
  965. _this._callingArrayChanged = false;
  966. _this._arrayChanged = null;
  967. _this._callingWatchedObjectChanged = false;
  968. _this._watchObjectsPropertyChange = watchObjectsPropertyChange;
  969. _this._watchedObjectList = _this._watchObjectsPropertyChange ? new BABYLON.StringDictionary() : null;
  970. _this._woci = new OAWatchedObjectChangedInfo();
  971. return _this;
  972. }
  973. Object.defineProperty(ObservableArray.prototype, "length", {
  974. /**
  975. * Gets or sets the length of the array. This is a number one higher than the highest element defined in an array.
  976. */
  977. get: function () {
  978. return this._array.length;
  979. },
  980. set: function (value) {
  981. if (value === this._array.length) {
  982. return;
  983. }
  984. var oldLength = this._array.length;
  985. this._array.length = value;
  986. this.onPropertyChanged("length", oldLength, this._array.length);
  987. },
  988. enumerable: true,
  989. configurable: true
  990. });
  991. ObservableArray.prototype.getAt = function (index) {
  992. return this._array[index];
  993. };
  994. ObservableArray.prototype.setAt = function (index, value) {
  995. if (index < 0) {
  996. return false;
  997. }
  998. var insertion = (index >= this._array.length) || this._array[index] === undefined;
  999. var oldLength = 0;
  1000. if (insertion) {
  1001. oldLength = this._array.length;
  1002. }
  1003. else if (this._watchObjectsPropertyChange) {
  1004. this._removeWatchedElement(this._array[index]);
  1005. }
  1006. this._array[index] = value;
  1007. if (this._watchObjectsPropertyChange) {
  1008. this._addWatchedElement(value);
  1009. }
  1010. if (insertion) {
  1011. this.onPropertyChanged("length", oldLength, this._array.length);
  1012. }
  1013. var ac = this.getArrayChangedObject();
  1014. if (ac) {
  1015. ac.action = insertion ? ArrayChanged.newItemsAction : ArrayChanged.changedItemAction;
  1016. if (insertion) {
  1017. ac.newItems.splice(0, ac.newItems.length, { index: index, value: value });
  1018. ac.newStartingIndex = index;
  1019. ac.changedItems.splice(0);
  1020. }
  1021. else {
  1022. ac.newItems.splice(0);
  1023. ac.changedStartingIndex = index;
  1024. ac.changedItems.splice(0, ac.changedItems.length, { index: index, value: value });
  1025. }
  1026. ac.removedItems.splice(0);
  1027. ac.removedStartingIndex = -1;
  1028. this.callArrayChanged(ac);
  1029. }
  1030. };
  1031. /**
  1032. * Returns a string representation of an array.
  1033. */
  1034. ObservableArray.prototype.toString = function () {
  1035. return this._array.toString();
  1036. };
  1037. ObservableArray.prototype.toLocaleString = function () {
  1038. return this._array.toLocaleString();
  1039. };
  1040. /**
  1041. * Appends new elements to an array, and returns the new length of the array.
  1042. * @param items New elements of the Array.
  1043. */
  1044. ObservableArray.prototype.push = function () {
  1045. var items = [];
  1046. for (var _i = 0; _i < arguments.length; _i++) {
  1047. items[_i] = arguments[_i];
  1048. }
  1049. var oldLength = this._array.length;
  1050. var n = (_a = this._array).push.apply(_a, items);
  1051. if (this._watchObjectsPropertyChange) {
  1052. this._addWatchedElement.apply(this, items);
  1053. }
  1054. this.onPropertyChanged("length", oldLength, this._array.length);
  1055. var ac = this.getArrayChangedObject();
  1056. if (ac) {
  1057. ac.action = ArrayChanged.newItemsAction;
  1058. ac.newStartingIndex = oldLength;
  1059. this.feedNotifArray.apply(this, [ac.newItems, oldLength].concat(items));
  1060. this.callArrayChanged(ac);
  1061. }
  1062. return n;
  1063. var _a;
  1064. };
  1065. /**
  1066. * Removes the last element from an array and returns it.
  1067. */
  1068. ObservableArray.prototype.pop = function () {
  1069. var firstRemove = this._array.length - 1;
  1070. var res = this._array.pop();
  1071. if (res && this._watchObjectsPropertyChange) {
  1072. this._removeWatchedElement(res);
  1073. }
  1074. if (firstRemove !== -1) {
  1075. this.onPropertyChanged("length", this._array.length + 1, this._array.length);
  1076. var ac = this.getArrayChangedObject();
  1077. if (ac) {
  1078. ac.action = ArrayChanged.removedItemsAction;
  1079. ac.removedStartingIndex = firstRemove;
  1080. this.feedNotifArray(ac.removedItems, firstRemove, res);
  1081. }
  1082. }
  1083. return res;
  1084. };
  1085. /**
  1086. * Combines two or more arrays.
  1087. * @param items Additional items to add to the end of array1.
  1088. */
  1089. ObservableArray.prototype.concat = function () {
  1090. var items = [];
  1091. for (var _i = 0; _i < arguments.length; _i++) {
  1092. items[_i] = arguments[_i];
  1093. }
  1094. return new ObservableArray(this._watchObjectsPropertyChange, (_a = this._array).concat.apply(_a, items));
  1095. var _a;
  1096. };
  1097. /**
  1098. * Adds all the elements of an array separated by the specified separator string.
  1099. * @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma.
  1100. */
  1101. ObservableArray.prototype.join = function (separator) {
  1102. return this._array.join(separator);
  1103. };
  1104. /**
  1105. * Reverses the elements in an Array.
  1106. * The arrayChanged action is
  1107. */
  1108. ObservableArray.prototype.reverse = function () {
  1109. var res = this._array.reverse();
  1110. var ac = this.getArrayChangedObject();
  1111. ac.action = ArrayChanged.replacedArrayAction;
  1112. return res;
  1113. };
  1114. /**
  1115. * Removes the first element from an array and returns it, shift all subsequents element one element before.
  1116. * The ArrayChange action is replacedArrayAction, the whole array changes and must be reevaluate as such, the removed element is in removedItems.
  1117. *
  1118. */
  1119. ObservableArray.prototype.shift = function () {
  1120. var oldLength = this._array.length;
  1121. var res = this._array.shift();
  1122. if (this._watchedObjectChanged && res != null) {
  1123. this._removeWatchedElement(res);
  1124. }
  1125. if (oldLength !== 0) {
  1126. this.onPropertyChanged("length", oldLength, this._array.length);
  1127. var ac = this.getArrayChangedObject();
  1128. if (ac) {
  1129. ac.action = ArrayChanged.replacedArrayAction;
  1130. ac.removedItems.splice(0, ac.removedItems.length, { index: 0, value: res });
  1131. ac.newItems.splice(0);
  1132. ac.changedItems.splice(0);
  1133. ac.removedStartingIndex = 0;
  1134. this.callArrayChanged(ac);
  1135. }
  1136. }
  1137. return res;
  1138. };
  1139. /**
  1140. * Returns a section of an array.
  1141. * @param start The beginning of the specified portion of the array.
  1142. * @param end The end of the specified portion of the array.
  1143. */
  1144. ObservableArray.prototype.slice = function (start, end) {
  1145. return new ObservableArray(this._watchObjectsPropertyChange, this._array.slice(start, end));
  1146. };
  1147. /**
  1148. * Sorts an array.
  1149. * @param compareFn The name of the function used to determine the order of the elements. If omitted, the elements are sorted in ascending, ASCII character order.
  1150. * On the contrary of the Javascript Array's implementation, this method returns nothing
  1151. */
  1152. ObservableArray.prototype.sort = function (compareFn) {
  1153. var oldLength = this._array.length;
  1154. this._array.sort(compareFn);
  1155. if (oldLength !== 0) {
  1156. var ac = this.getArrayChangedObject();
  1157. if (ac) {
  1158. ac.clear();
  1159. ac.action = ArrayChanged.replacedArrayAction;
  1160. this.callArrayChanged(ac);
  1161. }
  1162. }
  1163. };
  1164. /**
  1165. * Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements.
  1166. * @param start The zero-based location in the array from which to start removing elements.
  1167. * @param deleteCount The number of elements to remove.
  1168. * @param items Elements to insert into the array in place of the deleted elements.
  1169. */
  1170. ObservableArray.prototype.splice = function (start, deleteCount) {
  1171. var items = [];
  1172. for (var _i = 2; _i < arguments.length; _i++) {
  1173. items[_i - 2] = arguments[_i];
  1174. }
  1175. var oldLength = this._array.length;
  1176. if (this._watchObjectsPropertyChange) {
  1177. for (var i = start; i < start + deleteCount; i++) {
  1178. var val = this._array[i];
  1179. if (this._watchObjectsPropertyChange && val != null) {
  1180. this._removeWatchedElement(val);
  1181. }
  1182. }
  1183. }
  1184. var res = (_a = this._array).splice.apply(_a, [start, deleteCount].concat(items));
  1185. if (this._watchObjectsPropertyChange) {
  1186. this._addWatchedElement.apply(this, items);
  1187. }
  1188. if (oldLength !== this._array.length) {
  1189. this.onPropertyChanged("length", oldLength, this._array.length);
  1190. }
  1191. var ac = this.getArrayChangedObject();
  1192. if (ac) {
  1193. ac.clear();
  1194. ac.action = ArrayChanged.replacedArrayAction;
  1195. this.callArrayChanged(ac);
  1196. }
  1197. return res;
  1198. var _a;
  1199. };
  1200. /**
  1201. * Inserts new elements at the start of an array.
  1202. * @param items Elements to insert at the start of the Array.
  1203. * The ChangedArray action is replacedArrayAction, newItems contains the list of the added items
  1204. */
  1205. ObservableArray.prototype.unshift = function () {
  1206. var items = [];
  1207. for (var _i = 0; _i < arguments.length; _i++) {
  1208. items[_i] = arguments[_i];
  1209. }
  1210. var oldLength = this._array.length;
  1211. var res = (_a = this._array).unshift.apply(_a, items);
  1212. if (this._watchObjectsPropertyChange) {
  1213. this._addWatchedElement.apply(this, items);
  1214. }
  1215. this.onPropertyChanged("length", oldLength, this._array.length);
  1216. var ac = this.getArrayChangedObject();
  1217. if (ac) {
  1218. ac.clear();
  1219. ac.action = ArrayChanged.replacedArrayAction;
  1220. ac.newStartingIndex = 0, this.feedNotifArray.apply(this, [ac.newItems, 0].concat(items));
  1221. this.callArrayChanged(ac);
  1222. }
  1223. return res;
  1224. var _a;
  1225. };
  1226. /**
  1227. * Returns the index of the first occurrence of a value in an array.
  1228. * @param searchElement The value to locate in the array.
  1229. * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0.
  1230. */
  1231. ObservableArray.prototype.indexOf = function (searchElement, fromIndex) {
  1232. return this._array.indexOf(searchElement, fromIndex);
  1233. };
  1234. /**
  1235. * Returns the index of the last occurrence of a specified value in an array.
  1236. * @param searchElement The value to locate in the array.
  1237. * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at the last index in the array.
  1238. */
  1239. ObservableArray.prototype.lastIndexOf = function (searchElement, fromIndex) {
  1240. return this._array.lastIndexOf(searchElement, fromIndex);
  1241. };
  1242. /**
  1243. * Determines whether all the members of an array satisfy the specified test.
  1244. * @param callbackfn A function that accepts up to three arguments. The every method calls the callbackfn function for each element in array1 until the callbackfn returns false, or until the end of the array.
  1245. * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
  1246. */
  1247. ObservableArray.prototype.every = function (callbackfn, thisArg) {
  1248. return this._array.every(callbackfn, thisArg);
  1249. };
  1250. /**
  1251. * Determines whether the specified callback function returns true for any element of an array.
  1252. * @param callbackfn A function that accepts up to three arguments. The some method calls the callbackfn function for each element in array1 until the callbackfn returns true, or until the end of the array.
  1253. * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
  1254. */
  1255. ObservableArray.prototype.some = function (callbackfn, thisArg) {
  1256. return this._array.some(callbackfn, thisArg);
  1257. };
  1258. /**
  1259. * Performs the specified action for each element in an array.
  1260. * @param callbackfn A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array.
  1261. * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
  1262. */
  1263. ObservableArray.prototype.forEach = function (callbackfn, thisArg) {
  1264. return this._array.forEach(callbackfn, thisArg);
  1265. };
  1266. /**
  1267. * Calls a defined callback function on each element of an array, and returns an array that contains the results.
  1268. * @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
  1269. * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
  1270. */
  1271. ObservableArray.prototype.map = function (callbackfn, thisArg) {
  1272. return this._array.map(callbackfn, thisArg);
  1273. };
  1274. /**
  1275. * Returns the elements of an array that meet the condition specified in a callback function.
  1276. * @param callbackfn A function that accepts up to three arguments. The filter method calls the callbackfn function one time for each element in the array.
  1277. * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
  1278. */
  1279. ObservableArray.prototype.filter = function (callbackfn, thisArg) {
  1280. return this._array.filter(callbackfn, thisArg);
  1281. };
  1282. /**
  1283. * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
  1284. * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
  1285. * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
  1286. */
  1287. ObservableArray.prototype.reduce = function (callbackfn, initialValue) {
  1288. return this._array.reduce(callbackfn);
  1289. };
  1290. /**
  1291. * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
  1292. * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array.
  1293. * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
  1294. */
  1295. ObservableArray.prototype.reduceRight = function (callbackfn, initialValue) {
  1296. return this._array.reduceRight(callbackfn);
  1297. };
  1298. Object.defineProperty(ObservableArray.prototype, "arrayChanged", {
  1299. get: function () {
  1300. if (!this._arrayChanged) {
  1301. this._arrayChanged = new BABYLON.Observable();
  1302. }
  1303. return this._arrayChanged;
  1304. },
  1305. enumerable: true,
  1306. configurable: true
  1307. });
  1308. ObservableArray.prototype.getArrayChangedObject = function () {
  1309. if (this._arrayChanged && this._arrayChanged.hasObservers()) {
  1310. var ac = this._callingArrayChanged ? new ArrayChanged() : this.dci;
  1311. return ac;
  1312. }
  1313. return null;
  1314. };
  1315. ObservableArray.prototype.feedNotifArray = function (array, startindIndex) {
  1316. var items = [];
  1317. for (var _i = 2; _i < arguments.length; _i++) {
  1318. items[_i - 2] = arguments[_i];
  1319. }
  1320. array.splice(0);
  1321. for (var i = 0; i < items.length; i++) {
  1322. var value = this._array[i + startindIndex];
  1323. if (value !== undefined) {
  1324. array.push({ index: i + startindIndex, value: value });
  1325. }
  1326. }
  1327. };
  1328. ObservableArray.prototype.callArrayChanged = function (ac) {
  1329. try {
  1330. this._callingArrayChanged = true;
  1331. this.arrayChanged.notifyObservers(ac, ac.action);
  1332. }
  1333. finally {
  1334. this._callingArrayChanged = false;
  1335. }
  1336. };
  1337. Object.defineProperty(ObservableArray.prototype, "watchedObjectChanged", {
  1338. get: function () {
  1339. if (!this._watchedObjectChanged) {
  1340. this._watchedObjectChanged = new BABYLON.Observable();
  1341. }
  1342. return this._watchedObjectChanged;
  1343. },
  1344. enumerable: true,
  1345. configurable: true
  1346. });
  1347. ObservableArray.prototype._addWatchedElement = function () {
  1348. var _this = this;
  1349. var items = [];
  1350. for (var _i = 0; _i < arguments.length; _i++) {
  1351. items[_i] = arguments[_i];
  1352. }
  1353. var _loop_1 = function (curItem) {
  1354. if (curItem["propertyChanged"]) {
  1355. var key_1 = curItem["__ObsArrayObjID__"];
  1356. // The object may already be part of another ObsArray, so there already be a valid ID
  1357. if (!key_1) {
  1358. key_1 = BABYLON.Tools.RandomId();
  1359. curItem["__ObsArrayObjID__"] = key_1;
  1360. }
  1361. this_1._watchedObjectList.add(key_1, curItem.propertyChanged.add(function (e, d) {
  1362. _this.onWatchedObjectChanged(key_1, curItem, e);
  1363. }));
  1364. }
  1365. };
  1366. var this_1 = this;
  1367. for (var _a = 0, items_1 = items; _a < items_1.length; _a++) {
  1368. var curItem = items_1[_a];
  1369. _loop_1(curItem);
  1370. }
  1371. };
  1372. ObservableArray.prototype._removeWatchedElement = function () {
  1373. var items = [];
  1374. for (var _i = 0; _i < arguments.length; _i++) {
  1375. items[_i] = arguments[_i];
  1376. }
  1377. for (var _a = 0, items_2 = items; _a < items_2.length; _a++) {
  1378. var curItem = items_2[_a];
  1379. var key = curItem["__ObsArrayObjID__"];
  1380. if (key != null) {
  1381. var observer = this._watchedObjectList.getAndRemove(key);
  1382. curItem.propertyChanged.remove(observer);
  1383. }
  1384. }
  1385. };
  1386. ObservableArray.prototype.onWatchedObjectChanged = function (key, object, propChanged) {
  1387. if (this._watchedObjectChanged && this._watchedObjectChanged.hasObservers()) {
  1388. var woci = this._callingWatchedObjectChanged ? new OAWatchedObjectChangedInfo() : this._woci;
  1389. woci.object = object;
  1390. woci.propertyChanged = propChanged;
  1391. try {
  1392. this._callingWatchedObjectChanged = true;
  1393. this.watchedObjectChanged.notifyObservers(woci);
  1394. }
  1395. finally {
  1396. this._callingWatchedObjectChanged = false;
  1397. }
  1398. }
  1399. };
  1400. return ObservableArray;
  1401. }(BABYLON.PropertyChangedBase));
  1402. BABYLON.ObservableArray = ObservableArray;
  1403. })(BABYLON || (BABYLON = {}));
  1404. //# sourceMappingURL=babylon.observableArray.js.map
  1405. var __extends = (this && this.__extends) || (function () {
  1406. var extendStatics = Object.setPrototypeOf ||
  1407. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  1408. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  1409. return function (d, b) {
  1410. extendStatics(d, b);
  1411. function __() { this.constructor = d; }
  1412. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  1413. };
  1414. })();
  1415. var BABYLON;
  1416. (function (BABYLON) {
  1417. /**
  1418. * Class for the ObservableStringDictionary.onDictionaryChanged observable
  1419. */
  1420. var DictionaryChanged = (function () {
  1421. function DictionaryChanged() {
  1422. }
  1423. Object.defineProperty(DictionaryChanged, "clearAction", {
  1424. /**
  1425. * The content of the dictionary was totally cleared
  1426. */
  1427. get: function () {
  1428. return DictionaryChanged._clearAction;
  1429. },
  1430. enumerable: true,
  1431. configurable: true
  1432. });
  1433. Object.defineProperty(DictionaryChanged, "newItemAction", {
  1434. /**
  1435. * A new item was added, the newItem field contains the key/value pair
  1436. */
  1437. get: function () {
  1438. return DictionaryChanged._newItemAction;
  1439. },
  1440. enumerable: true,
  1441. configurable: true
  1442. });
  1443. Object.defineProperty(DictionaryChanged, "removedItemAction", {
  1444. /**
  1445. * An existing item was removed, the removedKey field contains its key
  1446. */
  1447. get: function () {
  1448. return DictionaryChanged._removedItemAction;
  1449. },
  1450. enumerable: true,
  1451. configurable: true
  1452. });
  1453. Object.defineProperty(DictionaryChanged, "itemValueChangedAction", {
  1454. /**
  1455. * An existing item had a value change, the changedItem field contains the key/value
  1456. */
  1457. get: function () {
  1458. return DictionaryChanged._itemValueChangedAction;
  1459. },
  1460. enumerable: true,
  1461. configurable: true
  1462. });
  1463. Object.defineProperty(DictionaryChanged, "replacedAction", {
  1464. /**
  1465. * The dictionary's content was reset and replaced by the content of another dictionary.
  1466. * DictionaryChanged<T> contains no further information about this action
  1467. */
  1468. get: function () {
  1469. return DictionaryChanged._replacedAction;
  1470. },
  1471. enumerable: true,
  1472. configurable: true
  1473. });
  1474. return DictionaryChanged;
  1475. }());
  1476. DictionaryChanged._clearAction = 0x1;
  1477. DictionaryChanged._newItemAction = 0x2;
  1478. DictionaryChanged._removedItemAction = 0x4;
  1479. DictionaryChanged._itemValueChangedAction = 0x8;
  1480. DictionaryChanged._replacedAction = 0x10;
  1481. BABYLON.DictionaryChanged = DictionaryChanged;
  1482. var OSDWatchedObjectChangedInfo = (function () {
  1483. function OSDWatchedObjectChangedInfo() {
  1484. }
  1485. return OSDWatchedObjectChangedInfo;
  1486. }());
  1487. BABYLON.OSDWatchedObjectChangedInfo = OSDWatchedObjectChangedInfo;
  1488. var ObservableStringDictionary = (function (_super) {
  1489. __extends(ObservableStringDictionary, _super);
  1490. function ObservableStringDictionary(watchObjectsPropertyChange) {
  1491. var _this = _super.call(this) || this;
  1492. _this._propertyChanged = null;
  1493. _this._dictionaryChanged = null;
  1494. _this.dci = new DictionaryChanged();
  1495. _this._callingDicChanged = false;
  1496. _this._watchedObjectChanged = null;
  1497. _this._callingWatchedObjectChanged = false;
  1498. _this._woci = new OSDWatchedObjectChangedInfo();
  1499. _this._watchObjectsPropertyChange = watchObjectsPropertyChange;
  1500. _this._watchedObjectList = _this._watchObjectsPropertyChange ? new BABYLON.StringDictionary() : null;
  1501. return _this;
  1502. }
  1503. /**
  1504. * This will clear this dictionary and copy the content from the 'source' one.
  1505. * If the T value is a custom object, it won't be copied/cloned, the same object will be used
  1506. * @param source the dictionary to take the content from and copy to this dictionary
  1507. */
  1508. ObservableStringDictionary.prototype.copyFrom = function (source) {
  1509. var _this = this;
  1510. var oldCount = this.count;
  1511. // Don't rely on this class' implementation for clear/add otherwise tons of notification will be thrown
  1512. _super.prototype.clear.call(this);
  1513. source.forEach(function (t, v) { return _this._add(t, v, false, _this._watchObjectsPropertyChange); });
  1514. this.onDictionaryChanged(DictionaryChanged.replacedAction, null, null, null);
  1515. this.onPropertyChanged("count", oldCount, this.count);
  1516. };
  1517. /**
  1518. * Get a value from its key or add it if it doesn't exist.
  1519. * This method will ensure you that a given key/data will be present in the dictionary.
  1520. * @param key the given key to get the matching value from
  1521. * @param factory the factory that will create the value if the key is not present in the dictionary.
  1522. * The factory will only be invoked if there's no data for the given key.
  1523. * @return the value corresponding to the key.
  1524. */
  1525. ObservableStringDictionary.prototype.getOrAddWithFactory = function (key, factory) {
  1526. var _this = this;
  1527. var val = _super.prototype.getOrAddWithFactory.call(this, key, function (k) {
  1528. var v = factory(key);
  1529. _this._add(key, v, true, _this._watchObjectsPropertyChange);
  1530. return v;
  1531. });
  1532. return val;
  1533. };
  1534. /**
  1535. * Add a new key and its corresponding value
  1536. * @param key the key to add
  1537. * @param value the value corresponding to the key
  1538. * @return true if the operation completed successfully, false if we couldn't insert the key/value because there was already this key in the dictionary
  1539. */
  1540. ObservableStringDictionary.prototype.add = function (key, value) {
  1541. return this._add(key, value, true, this._watchObjectsPropertyChange);
  1542. };
  1543. ObservableStringDictionary.prototype.getAndRemove = function (key) {
  1544. var val = _super.prototype.get.call(this, key);
  1545. this._remove(key, true, val);
  1546. return val;
  1547. };
  1548. ObservableStringDictionary.prototype._add = function (key, value, fireNotif, registerWatcher) {
  1549. if (_super.prototype.add.call(this, key, value)) {
  1550. if (fireNotif) {
  1551. this.onDictionaryChanged(DictionaryChanged.newItemAction, { key: key, value: value }, null, null);
  1552. this.onPropertyChanged("count", this.count - 1, this.count);
  1553. }
  1554. if (registerWatcher) {
  1555. this._addWatchedElement(key, value);
  1556. }
  1557. return true;
  1558. }
  1559. return false;
  1560. };
  1561. ObservableStringDictionary.prototype._addWatchedElement = function (key, el) {
  1562. var _this = this;
  1563. if (el["propertyChanged"]) {
  1564. this._watchedObjectList.add(key, el.propertyChanged.add(function (e, d) {
  1565. _this.onWatchedObjectChanged(key, el, e);
  1566. }));
  1567. }
  1568. };
  1569. ObservableStringDictionary.prototype._removeWatchedElement = function (key, el) {
  1570. var observer = this._watchedObjectList.getAndRemove(key);
  1571. if (el["propertyChanged"]) {
  1572. el.propertyChanged.remove(observer);
  1573. }
  1574. };
  1575. ObservableStringDictionary.prototype.set = function (key, value) {
  1576. var oldValue = this.get(key);
  1577. if (this._watchObjectsPropertyChange) {
  1578. this._removeWatchedElement(key, oldValue);
  1579. }
  1580. if (_super.prototype.set.call(this, key, value)) {
  1581. this.onDictionaryChanged(DictionaryChanged.itemValueChangedAction, null, null, { key: key, oldValue: oldValue, newValue: value });
  1582. this._addWatchedElement(key, value);
  1583. return true;
  1584. }
  1585. return false;
  1586. };
  1587. /**
  1588. * Remove a key/value from the dictionary.
  1589. * @param key the key to remove
  1590. * @return true if the item was successfully deleted, false if no item with such key exist in the dictionary
  1591. */
  1592. ObservableStringDictionary.prototype.remove = function (key) {
  1593. return this._remove(key, true);
  1594. };
  1595. ObservableStringDictionary.prototype._remove = function (key, fireNotif, element) {
  1596. if (!element) {
  1597. element = this.get(key);
  1598. }
  1599. if (!element) {
  1600. return false;
  1601. }
  1602. if (_super.prototype.remove.call(this, key) === undefined) {
  1603. return false;
  1604. }
  1605. this.onDictionaryChanged(DictionaryChanged.removedItemAction, null, key, null);
  1606. this.onPropertyChanged("count", this.count + 1, this.count);
  1607. if (this._watchObjectsPropertyChange) {
  1608. this._removeWatchedElement(key, element);
  1609. }
  1610. return true;
  1611. };
  1612. /**
  1613. * Clear the whole content of the dictionary
  1614. */
  1615. ObservableStringDictionary.prototype.clear = function () {
  1616. var _this = this;
  1617. if (this._watchedObjectList) {
  1618. this._watchedObjectList.forEach(function (k, v) {
  1619. var el = _this.get(k);
  1620. _this._removeWatchedElement(k, el);
  1621. });
  1622. this._watchedObjectList.clear();
  1623. }
  1624. var oldCount = this.count;
  1625. _super.prototype.clear.call(this);
  1626. this.onDictionaryChanged(DictionaryChanged.clearAction, null, null, null);
  1627. this.onPropertyChanged("count", oldCount, 0);
  1628. };
  1629. Object.defineProperty(ObservableStringDictionary.prototype, "propertyChanged", {
  1630. get: function () {
  1631. if (!this._propertyChanged) {
  1632. this._propertyChanged = new BABYLON.Observable();
  1633. }
  1634. return this._propertyChanged;
  1635. },
  1636. enumerable: true,
  1637. configurable: true
  1638. });
  1639. ObservableStringDictionary.prototype.onPropertyChanged = function (propName, oldValue, newValue, mask) {
  1640. if (this._propertyChanged && this._propertyChanged.hasObservers()) {
  1641. var pci = ObservableStringDictionary.callingPropChanged ? new BABYLON.PropertyChangedInfo() : ObservableStringDictionary.pci;
  1642. pci.oldValue = oldValue;
  1643. pci.newValue = newValue;
  1644. pci.propertyName = propName;
  1645. try {
  1646. ObservableStringDictionary.callingPropChanged = true;
  1647. this.propertyChanged.notifyObservers(pci, mask);
  1648. }
  1649. finally {
  1650. ObservableStringDictionary.callingPropChanged = false;
  1651. }
  1652. }
  1653. };
  1654. Object.defineProperty(ObservableStringDictionary.prototype, "dictionaryChanged", {
  1655. get: function () {
  1656. if (!this._dictionaryChanged) {
  1657. this._dictionaryChanged = new BABYLON.Observable();
  1658. }
  1659. return this._dictionaryChanged;
  1660. },
  1661. enumerable: true,
  1662. configurable: true
  1663. });
  1664. ObservableStringDictionary.prototype.onDictionaryChanged = function (action, newItem, removedKey, changedItem) {
  1665. if (this._dictionaryChanged && this._dictionaryChanged.hasObservers()) {
  1666. var dci = this._callingDicChanged ? new DictionaryChanged() : this.dci;
  1667. dci.action = action;
  1668. dci.newItem = newItem;
  1669. dci.removedKey = removedKey;
  1670. dci.changedItem = changedItem;
  1671. try {
  1672. this._callingDicChanged = true;
  1673. this.dictionaryChanged.notifyObservers(dci, action);
  1674. }
  1675. finally {
  1676. this._callingDicChanged = false;
  1677. }
  1678. }
  1679. };
  1680. Object.defineProperty(ObservableStringDictionary.prototype, "watchedObjectChanged", {
  1681. get: function () {
  1682. if (!this._watchedObjectChanged) {
  1683. this._watchedObjectChanged = new BABYLON.Observable();
  1684. }
  1685. return this._watchedObjectChanged;
  1686. },
  1687. enumerable: true,
  1688. configurable: true
  1689. });
  1690. ObservableStringDictionary.prototype.onWatchedObjectChanged = function (key, object, propChanged) {
  1691. if (this._watchedObjectChanged && this._watchedObjectChanged.hasObservers()) {
  1692. var woci = this._callingWatchedObjectChanged ? new OSDWatchedObjectChangedInfo() : this._woci;
  1693. woci.key = key;
  1694. woci.object = object;
  1695. woci.propertyChanged = propChanged;
  1696. try {
  1697. this._callingWatchedObjectChanged = true;
  1698. this.watchedObjectChanged.notifyObservers(woci);
  1699. }
  1700. finally {
  1701. this._callingWatchedObjectChanged = false;
  1702. }
  1703. }
  1704. };
  1705. return ObservableStringDictionary;
  1706. }(BABYLON.StringDictionary));
  1707. ObservableStringDictionary.pci = new BABYLON.PropertyChangedInfo();
  1708. ObservableStringDictionary.callingPropChanged = false;
  1709. BABYLON.ObservableStringDictionary = ObservableStringDictionary;
  1710. })(BABYLON || (BABYLON = {}));
  1711. //# sourceMappingURL=babylon.observableStringDictionary.js.map
  1712. var __extends = (this && this.__extends) || (function () {
  1713. var extendStatics = Object.setPrototypeOf ||
  1714. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  1715. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  1716. return function (d, b) {
  1717. extendStatics(d, b);
  1718. function __() { this.constructor = d; }
  1719. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  1720. };
  1721. })();
  1722. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  1723. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  1724. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  1725. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  1726. return c > 3 && r && Object.defineProperty(target, key, r), r;
  1727. };
  1728. var BABYLON;
  1729. (function (BABYLON) {
  1730. /**
  1731. * This class given information about a given character.
  1732. */
  1733. var CharInfo = (function () {
  1734. function CharInfo() {
  1735. }
  1736. return CharInfo;
  1737. }());
  1738. BABYLON.CharInfo = CharInfo;
  1739. /**
  1740. * This is an abstract base class to hold a Texture that will contain a FontMap
  1741. */
  1742. var BaseFontTexture = (function (_super) {
  1743. __extends(BaseFontTexture, _super);
  1744. function BaseFontTexture(url, scene, noMipmap, invertY, samplingMode, premultipliedAlpha) {
  1745. if (noMipmap === void 0) { noMipmap = false; }
  1746. if (invertY === void 0) { invertY = true; }
  1747. if (samplingMode === void 0) { samplingMode = BABYLON.Texture.TRILINEAR_SAMPLINGMODE; }
  1748. if (premultipliedAlpha === void 0) { premultipliedAlpha = false; }
  1749. var _this = _super.call(this, url, scene, noMipmap, invertY, samplingMode) || this;
  1750. _this._cachedFontId = null;
  1751. _this._charInfos = new BABYLON.StringDictionary();
  1752. _this._isPremultipliedAlpha = premultipliedAlpha;
  1753. return _this;
  1754. }
  1755. Object.defineProperty(BaseFontTexture.prototype, "isSuperSampled", {
  1756. /**
  1757. * Is the Font is using Super Sampling (each font texel is doubled).
  1758. */
  1759. get: function () {
  1760. return this._superSample;
  1761. },
  1762. enumerable: true,
  1763. configurable: true
  1764. });
  1765. Object.defineProperty(BaseFontTexture.prototype, "isSignedDistanceField", {
  1766. /**
  1767. * Is the Font was rendered using the Signed Distance Field algorithm
  1768. * @returns {}
  1769. */
  1770. get: function () {
  1771. return this._signedDistanceField;
  1772. },
  1773. enumerable: true,
  1774. configurable: true
  1775. });
  1776. Object.defineProperty(BaseFontTexture.prototype, "isPremultipliedAlpha", {
  1777. /**
  1778. * True if the font was drawn using multiplied alpha
  1779. */
  1780. get: function () {
  1781. return this._isPremultipliedAlpha;
  1782. },
  1783. enumerable: true,
  1784. configurable: true
  1785. });
  1786. Object.defineProperty(BaseFontTexture.prototype, "spaceWidth", {
  1787. /**
  1788. * Get the Width (in pixel) of the Space character
  1789. */
  1790. get: function () {
  1791. return this._spaceWidth;
  1792. },
  1793. enumerable: true,
  1794. configurable: true
  1795. });
  1796. Object.defineProperty(BaseFontTexture.prototype, "lineHeight", {
  1797. /**
  1798. * Get the Line height (in pixel)
  1799. */
  1800. get: function () {
  1801. return this._lineHeight;
  1802. },
  1803. enumerable: true,
  1804. configurable: true
  1805. });
  1806. /**
  1807. * Measure the width/height that will take a given text
  1808. * @param text the text to measure
  1809. * @param tabulationSize the size (in space character) of the tabulation character, default value must be 4
  1810. */
  1811. BaseFontTexture.prototype.measureText = function (text, tabulationSize) {
  1812. var maxWidth = 0;
  1813. var curWidth = 0;
  1814. var lineCount = 1;
  1815. var charxpos = 0;
  1816. // Parse each char of the string
  1817. for (var _i = 0, text_1 = text; _i < text_1.length; _i++) {
  1818. var char = text_1[_i];
  1819. // Next line feed?
  1820. if (char === "\n") {
  1821. maxWidth = Math.max(maxWidth, curWidth);
  1822. charxpos = 0;
  1823. curWidth = 0;
  1824. ++lineCount;
  1825. continue;
  1826. }
  1827. // Tabulation ?
  1828. if (char === "\t") {
  1829. var nextPos = charxpos + tabulationSize;
  1830. nextPos = nextPos - (nextPos % tabulationSize);
  1831. curWidth += (nextPos - charxpos) * this.spaceWidth;
  1832. charxpos = nextPos;
  1833. continue;
  1834. }
  1835. if (char < " ") {
  1836. continue;
  1837. }
  1838. var ci = this.getChar(char);
  1839. if (!ci) {
  1840. throw new Error("Character " + char + " is not supported by FontTexture " + this.name);
  1841. }
  1842. curWidth += ci.charWidth;
  1843. ++charxpos;
  1844. }
  1845. maxWidth = Math.max(maxWidth, curWidth);
  1846. return new BABYLON.Size(maxWidth, lineCount * this.lineHeight);
  1847. };
  1848. return BaseFontTexture;
  1849. }(BABYLON.Texture));
  1850. BABYLON.BaseFontTexture = BaseFontTexture;
  1851. var BitmapFontInfo = (function () {
  1852. function BitmapFontInfo() {
  1853. this.kerningDic = new BABYLON.StringDictionary();
  1854. this.charDic = new BABYLON.StringDictionary();
  1855. }
  1856. return BitmapFontInfo;
  1857. }());
  1858. BABYLON.BitmapFontInfo = BitmapFontInfo;
  1859. var BitmapFontTexture = (function (_super) {
  1860. __extends(BitmapFontTexture, _super);
  1861. function BitmapFontTexture(scene, bmFontUrl, textureUrl, noMipmap, invertY, samplingMode, premultipliedAlpha, onLoad, onError) {
  1862. if (textureUrl === void 0) { textureUrl = null; }
  1863. if (noMipmap === void 0) { noMipmap = false; }
  1864. if (invertY === void 0) { invertY = true; }
  1865. if (samplingMode === void 0) { samplingMode = BABYLON.Texture.TRILINEAR_SAMPLINGMODE; }
  1866. if (premultipliedAlpha === void 0) { premultipliedAlpha = false; }
  1867. if (onLoad === void 0) { onLoad = null; }
  1868. if (onError === void 0) { onError = null; }
  1869. var _this = _super.call(this, null, scene, noMipmap, invertY, samplingMode, premultipliedAlpha) || this;
  1870. _this._usedCounter = 1;
  1871. var xhr = new XMLHttpRequest();
  1872. xhr.onreadystatechange = function () {
  1873. if (xhr.readyState === XMLHttpRequest.DONE) {
  1874. if (xhr.status === 200) {
  1875. var ext = bmFontUrl.split('.').pop().split(/\#|\?/)[0];
  1876. var plugins = BitmapFontTexture.plugins.get(ext.toLocaleLowerCase());
  1877. if (!plugins) {
  1878. if (onError) {
  1879. onError("couldn't find a plugin for this file extension", -1);
  1880. }
  1881. return;
  1882. }
  1883. var _loop_1 = function (p) {
  1884. var ret = p.loadFont(xhr.response, scene, invertY);
  1885. if (ret) {
  1886. var bfi = ret.bfi;
  1887. if (textureUrl != null) {
  1888. bfi.textureUrl = textureUrl;
  1889. }
  1890. else {
  1891. var baseUrl = bmFontUrl.substr(0, bmFontUrl.lastIndexOf("/") + 1);
  1892. bfi.textureUrl = baseUrl + bfi.textureFile;
  1893. }
  1894. _this._texture = scene.getEngine().createTexture(bfi.textureUrl, noMipmap, invertY, scene, samplingMode, function () {
  1895. if (ret.bfi && onLoad) {
  1896. onLoad();
  1897. }
  1898. });
  1899. _this._lineHeight = bfi.lineHeight;
  1900. _this._charInfos.copyFrom(bfi.charDic);
  1901. var ci = _this.getChar(" ");
  1902. if (ci) {
  1903. _this._spaceWidth = ci.charWidth;
  1904. }
  1905. else {
  1906. _this._charInfos.first(function (k, v) { return _this._spaceWidth = v.charWidth; });
  1907. }
  1908. if (!ret.bfi && onError) {
  1909. onError(ret.errorMsg, ret.errorCode);
  1910. }
  1911. return { value: void 0 };
  1912. }
  1913. };
  1914. for (var _i = 0, plugins_1 = plugins; _i < plugins_1.length; _i++) {
  1915. var p = plugins_1[_i];
  1916. var state_1 = _loop_1(p);
  1917. if (typeof state_1 === "object")
  1918. return state_1.value;
  1919. }
  1920. if (onError) {
  1921. onError("No plugin to load this BMFont file format", -1);
  1922. }
  1923. }
  1924. else {
  1925. if (onError) {
  1926. onError("Couldn't load file through HTTP Request, HTTP Status " + xhr.status, xhr.status);
  1927. }
  1928. }
  1929. }
  1930. };
  1931. xhr.open("GET", bmFontUrl, true);
  1932. xhr.send();
  1933. return _this;
  1934. }
  1935. BitmapFontTexture.GetCachedFontTexture = function (scene, fontTexture) {
  1936. var dic = scene.getOrAddExternalDataWithFactory("BitmapFontTextureCache", function () { return new BABYLON.StringDictionary(); });
  1937. var ft = dic.get(fontTexture.uid);
  1938. if (ft) {
  1939. ++ft._usedCounter;
  1940. return ft;
  1941. }
  1942. dic.add(fontTexture.uid, fontTexture);
  1943. return ft;
  1944. };
  1945. BitmapFontTexture.ReleaseCachedFontTexture = function (scene, fontTexture) {
  1946. var dic = scene.getExternalData("BitmapFontTextureCache");
  1947. if (!dic) {
  1948. return;
  1949. }
  1950. var font = dic.get(fontTexture.uid);
  1951. if (--font._usedCounter === 0) {
  1952. dic.remove(fontTexture.uid);
  1953. font.dispose();
  1954. }
  1955. };
  1956. Object.defineProperty(BitmapFontTexture.prototype, "isDynamicFontTexture", {
  1957. /**
  1958. * Is the font dynamically updated, if true is returned then you have to call the update() before using the font in rendering if new character were adding using getChar()
  1959. */
  1960. get: function () {
  1961. return false;
  1962. },
  1963. enumerable: true,
  1964. configurable: true
  1965. });
  1966. /**
  1967. * This method does nothing for a BitmapFontTexture object as it's a static texture
  1968. */
  1969. BitmapFontTexture.prototype.update = function () {
  1970. };
  1971. /**
  1972. * Retrieve the CharInfo object for a given character
  1973. * @param char the character to retrieve the CharInfo object from (e.g.: "A", "a", etc.)
  1974. */
  1975. BitmapFontTexture.prototype.getChar = function (char) {
  1976. return this._charInfos.get(char);
  1977. };
  1978. /**
  1979. * For FontTexture retrieved using GetCachedFontTexture, use this method when you transfer this object's lifetime to another party in order to share this resource.
  1980. * When the other party is done with this object, decCachedFontTextureCounter must be called.
  1981. */
  1982. BitmapFontTexture.prototype.incCachedFontTextureCounter = function () {
  1983. ++this._usedCounter;
  1984. };
  1985. /**
  1986. * Use this method only in conjunction with incCachedFontTextureCounter, call it when you no longer need to use this shared resource.
  1987. */
  1988. BitmapFontTexture.prototype.decCachedFontTextureCounter = function () {
  1989. var dic = this.getScene().getExternalData("BitmapFontTextureCache");
  1990. if (!dic) {
  1991. return;
  1992. }
  1993. if (--this._usedCounter === 0) {
  1994. dic.remove(this._cachedFontId);
  1995. this.dispose();
  1996. }
  1997. };
  1998. BitmapFontTexture.addLoader = function (fileExtension, plugin) {
  1999. var a = BitmapFontTexture.plugins.getOrAddWithFactory(fileExtension.toLocaleLowerCase(), function () { return new Array(); });
  2000. a.push(plugin);
  2001. };
  2002. return BitmapFontTexture;
  2003. }(BaseFontTexture));
  2004. BitmapFontTexture.plugins = new BABYLON.StringDictionary();
  2005. BABYLON.BitmapFontTexture = BitmapFontTexture;
  2006. /**
  2007. * This class is a special kind of texture which generates on the fly characters of a given css style "fontName".
  2008. * The generated texture will be updated when new characters will be retrieved using the getChar() method, but you have
  2009. * to call the update() method for the texture to fetch these changes, you can harmlessly call update any time you want, if no
  2010. * change were made, nothing will happen.
  2011. * The Font Texture can be rendered in three modes: normal size, super sampled size (x2) or using Signed Distance Field rendering.
  2012. * Signed Distance Field should be prefered because the texture can be rendered using AlphaTest instead of Transparency, which is way more faster. More about SDF here (http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf).
  2013. * The only flaw of SDF is that the rendering quality may not be the best or the edges too sharp is the font thickness is too thin.
  2014. */
  2015. var FontTexture = (function (_super) {
  2016. __extends(FontTexture, _super);
  2017. /**
  2018. * Create a new instance of the FontTexture class
  2019. * @param name the name of the texture
  2020. * @param font the font to use, use the W3C CSS notation
  2021. * @param scene the scene that owns the texture
  2022. * @param maxCharCount the approximative maximum count of characters that could fit in the texture. This is an approximation because most of the fonts are proportional (each char has its own Width). The 'W' character's width is used to compute the size of the texture based on the given maxCharCount
  2023. * @param samplingMode the texture sampling mode
  2024. * @param superSample if true the FontTexture will be created with a font of a size twice bigger than the given one but all properties (lineHeight, charWidth, etc.) will be according to the original size. This is made to improve the text quality.
  2025. */
  2026. function FontTexture(name, font, scene, maxCharCount, samplingMode, superSample, signedDistanceField) {
  2027. if (maxCharCount === void 0) { maxCharCount = 200; }
  2028. if (samplingMode === void 0) { samplingMode = BABYLON.Texture.TRILINEAR_SAMPLINGMODE; }
  2029. if (superSample === void 0) { superSample = false; }
  2030. if (signedDistanceField === void 0) { signedDistanceField = false; }
  2031. var _this = _super.call(this, null, scene, true, false, samplingMode) || this;
  2032. _this._curCharCount = 0;
  2033. _this._lastUpdateCharCount = -1;
  2034. _this._usedCounter = 1;
  2035. _this.name = name;
  2036. _this.debugMode = false;
  2037. _this.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE;
  2038. _this.wrapV = BABYLON.Texture.CLAMP_ADDRESSMODE;
  2039. _this._sdfScale = 8;
  2040. _this._signedDistanceField = signedDistanceField;
  2041. _this._superSample = false;
  2042. _this._isPremultipliedAlpha = !signedDistanceField;
  2043. _this.name = "FontTexture " + font;
  2044. // SDF will use super sample no matter what, the resolution is otherwise too poor to produce correct result
  2045. if (superSample || signedDistanceField) {
  2046. var sfont = _this.getSuperSampleFont(font);
  2047. if (sfont) {
  2048. _this._superSample = true;
  2049. font = sfont;
  2050. }
  2051. }
  2052. // First canvas creation to determine the size of the texture to create
  2053. _this._canvas = document.createElement("canvas");
  2054. _this._context = _this._canvas.getContext("2d");
  2055. _this._context.font = font;
  2056. _this._context.fillStyle = "white";
  2057. _this._context.textBaseline = "top";
  2058. var res = _this.getFontHeight(font, "j$|");
  2059. _this._lineHeightSuper = res.height; //+4;
  2060. _this._lineHeight = _this._superSample ? (Math.ceil(_this._lineHeightSuper / 2)) : _this._lineHeightSuper;
  2061. _this._offset = res.offset;
  2062. res = _this.getFontHeight(font, "f");
  2063. _this._baseLine = res.height + res.offset - _this._offset;
  2064. var maxCharWidth = Math.max(_this._context.measureText("W").width, _this._context.measureText("_").width);
  2065. _this._spaceWidthSuper = _this._context.measureText(" ").width;
  2066. _this._spaceWidth = _this._superSample ? (_this._spaceWidthSuper / 2) : _this._spaceWidthSuper;
  2067. _this._xMargin = Math.ceil(maxCharWidth / 32);
  2068. _this._yMargin = _this._xMargin;
  2069. // This is an approximate size, but should always be able to fit at least the maxCharCount
  2070. var totalEstSurface = (Math.ceil(_this._lineHeightSuper) + (_this._yMargin * 2)) * (Math.ceil(maxCharWidth) + (_this._xMargin * 2)) * maxCharCount;
  2071. var edge = Math.sqrt(totalEstSurface);
  2072. var textSize = Math.pow(2, Math.ceil(Math.log(edge) / Math.log(2)));
  2073. // Create the texture that will store the font characters
  2074. _this._texture = scene.getEngine().createDynamicTexture(textSize, textSize, false, samplingMode);
  2075. var textureSize = _this.getSize();
  2076. _this.hasAlpha = _this._signedDistanceField === false;
  2077. // Recreate a new canvas with the final size: the one matching the texture (resizing the previous one doesn't work as one would expect...)
  2078. _this._canvas = document.createElement("canvas");
  2079. _this._canvas.width = textureSize.width;
  2080. _this._canvas.height = textureSize.height;
  2081. _this._context = _this._canvas.getContext("2d");
  2082. _this._context.textBaseline = "top";
  2083. _this._context.font = font;
  2084. _this._context.fillStyle = "white";
  2085. _this._context.imageSmoothingEnabled = false;
  2086. _this._context.clearRect(0, 0, textureSize.width, textureSize.height);
  2087. // Create a canvas for the signed distance field mode, we only have to store one char, the purpose is to render a char scaled _sdfScale times
  2088. // into this 2D context, then get the bitmap data, create the SDF char and push the result in the _context (which hold the whole Font Texture content)
  2089. // So you can see this context as an intermediate one, because it is.
  2090. if (_this._signedDistanceField) {
  2091. var sdfC = document.createElement("canvas");
  2092. var s = _this._sdfScale;
  2093. sdfC.width = (Math.ceil(maxCharWidth) + _this._xMargin * 2) * s;
  2094. sdfC.height = (Math.ceil(_this._lineHeightSuper) + _this._yMargin * 2) * s;
  2095. var sdfCtx = sdfC.getContext("2d");
  2096. sdfCtx.scale(s, s);
  2097. sdfCtx.textBaseline = "top";
  2098. sdfCtx.font = font;
  2099. sdfCtx.fillStyle = "white";
  2100. sdfCtx.imageSmoothingEnabled = false;
  2101. _this._sdfCanvas = sdfC;
  2102. _this._sdfContext = sdfCtx;
  2103. }
  2104. _this._currentFreePosition = BABYLON.Vector2.Zero();
  2105. // Add the basic ASCII based characters
  2106. for (var i = 0x20; i < 0x7F; i++) {
  2107. var c = String.fromCharCode(i);
  2108. _this.getChar(c);
  2109. }
  2110. _this.update();
  2111. return _this;
  2112. //this._saveToImage("");
  2113. }
  2114. Object.defineProperty(FontTexture.prototype, "isDynamicFontTexture", {
  2115. get: function () {
  2116. return true;
  2117. },
  2118. enumerable: true,
  2119. configurable: true
  2120. });
  2121. FontTexture.GetCachedFontTexture = function (scene, fontName, supersample, signedDistanceField, bilinearFiltering) {
  2122. if (supersample === void 0) { supersample = false; }
  2123. if (signedDistanceField === void 0) { signedDistanceField = false; }
  2124. if (bilinearFiltering === void 0) { bilinearFiltering = false; }
  2125. var dic = scene.getOrAddExternalDataWithFactory("FontTextureCache", function () { return new BABYLON.StringDictionary(); });
  2126. var lfn = fontName.toLocaleLowerCase() + (supersample ? "_+SS" : "_-SS") + (signedDistanceField ? "_+SDF" : "_-SDF") + (bilinearFiltering ? "_+BF" : "_-BF");
  2127. var ft = dic.get(lfn);
  2128. if (ft) {
  2129. ++ft._usedCounter;
  2130. return ft;
  2131. }
  2132. ft = new FontTexture(null, fontName, scene, supersample ? 100 : 200, (signedDistanceField || bilinearFiltering) ? BABYLON.Texture.BILINEAR_SAMPLINGMODE : BABYLON.Texture.NEAREST_SAMPLINGMODE, supersample, signedDistanceField);
  2133. ft._cachedFontId = lfn;
  2134. dic.add(lfn, ft);
  2135. return ft;
  2136. };
  2137. FontTexture.ReleaseCachedFontTexture = function (scene, fontName, supersample, signedDistanceField, bilinearFiltering) {
  2138. if (supersample === void 0) { supersample = false; }
  2139. if (signedDistanceField === void 0) { signedDistanceField = false; }
  2140. if (bilinearFiltering === void 0) { bilinearFiltering = false; }
  2141. var dic = scene.getExternalData("FontTextureCache");
  2142. if (!dic) {
  2143. return;
  2144. }
  2145. var lfn = fontName.toLocaleLowerCase() + (supersample ? "_+SS" : "_-SS") + (signedDistanceField ? "_+SDF" : "_-SDF") + (bilinearFiltering ? "_+BF" : "_-BF");
  2146. var font = dic.get(lfn);
  2147. if (--font._usedCounter === 0) {
  2148. dic.remove(lfn);
  2149. font.dispose();
  2150. }
  2151. };
  2152. FontTexture.prototype._saveToImage = function (url) {
  2153. var base64Image = this._canvas.toDataURL("image/png");
  2154. //Creating a link if the browser have the download attribute on the a tag, to automatically start download generated image.
  2155. if (("download" in document.createElement("a"))) {
  2156. var a = window.document.createElement("a");
  2157. a.href = base64Image;
  2158. var date = new Date();
  2159. var stringDate = (date.getFullYear() + "-" + (date.getMonth() + 1)).slice(-2) +
  2160. "-" +
  2161. date.getDate() +
  2162. "_" +
  2163. date.getHours() +
  2164. "-" +
  2165. ('0' + date.getMinutes()).slice(-2);
  2166. a.setAttribute("download", "screenshot_" + stringDate + ".png");
  2167. window.document.body.appendChild(a);
  2168. a.addEventListener("click", function () {
  2169. a.parentElement.removeChild(a);
  2170. });
  2171. a.click();
  2172. //Or opening a new tab with the image if it is not possible to automatically start download.
  2173. }
  2174. else {
  2175. var newWindow = window.open("");
  2176. var img = newWindow.document.createElement("img");
  2177. img.src = base64Image;
  2178. newWindow.document.body.appendChild(img);
  2179. }
  2180. };
  2181. /**
  2182. * Make sure the given char is present in the font map.
  2183. * @param char the character to get or add
  2184. * @return the CharInfo instance corresponding to the given character
  2185. */
  2186. FontTexture.prototype.getChar = function (char) {
  2187. var _this = this;
  2188. if (char.length !== 1) {
  2189. return null;
  2190. }
  2191. var info = this._charInfos.get(char);
  2192. if (info) {
  2193. return info;
  2194. }
  2195. info = new CharInfo();
  2196. var measure = this._context.measureText(char);
  2197. var textureSize = this.getSize();
  2198. // we reached the end of the current line?
  2199. var width = Math.ceil(measure.width + 0.5);
  2200. if (this._currentFreePosition.x + width + this._xMargin > textureSize.width) {
  2201. this._currentFreePosition.x = 0;
  2202. this._currentFreePosition.y += Math.ceil(this._lineHeightSuper + this._yMargin * 2);
  2203. // No more room?
  2204. if (this._currentFreePosition.y > textureSize.height) {
  2205. return this.getChar("!");
  2206. }
  2207. }
  2208. var curPosX = this._currentFreePosition.x + 0.5;
  2209. var curPosY = this._currentFreePosition.y + 0.5;
  2210. var curPosXMargin = curPosX + this._xMargin;
  2211. var curPosYMargin = curPosY + this._yMargin;
  2212. var drawDebug = function (ctx) {
  2213. ctx.strokeStyle = "green";
  2214. ctx.beginPath();
  2215. ctx.rect(curPosXMargin, curPosYMargin, width, _this._lineHeightSuper);
  2216. ctx.closePath();
  2217. ctx.stroke();
  2218. ctx.strokeStyle = "blue";
  2219. ctx.beginPath();
  2220. ctx.moveTo(curPosXMargin, curPosYMargin + Math.round(_this._baseLine));
  2221. ctx.lineTo(curPosXMargin + width, curPosYMargin + Math.round(_this._baseLine));
  2222. ctx.closePath();
  2223. ctx.stroke();
  2224. };
  2225. // In SDF mode we render the character in an intermediate 2D context which scale the character this._sdfScale times (which is required to compute the SDF map accurately)
  2226. if (this._signedDistanceField) {
  2227. var s = this._sdfScale;
  2228. this._sdfContext.clearRect(0, 0, this._sdfCanvas.width, this._sdfCanvas.height);
  2229. // Coordinates are subject to the context's scale
  2230. this._sdfContext.fillText(char, this._xMargin + 0.5, this._yMargin + 0.5 - this._offset);
  2231. // Canvas Pixel Coordinates, no scale
  2232. var data = this._sdfContext.getImageData(0, 0, (width + (this._xMargin * 2)) * s, this._sdfCanvas.height);
  2233. var res = this._computeSDFChar(data);
  2234. this._context.putImageData(res, curPosX, curPosY);
  2235. if (this.debugMode) {
  2236. drawDebug(this._context);
  2237. }
  2238. }
  2239. else {
  2240. if (this.debugMode) {
  2241. drawDebug(this._context);
  2242. }
  2243. // Draw the character in the HTML canvas
  2244. this._context.fillText(char, curPosXMargin, curPosYMargin - this._offset);
  2245. // Premul Alpha manually
  2246. var id = this._context.getImageData(curPosXMargin, curPosYMargin, width, this._lineHeightSuper);
  2247. for (var i = 0; i < id.data.length; i += 4) {
  2248. var v = id.data[i + 3];
  2249. if (v > 0 && v < 255) {
  2250. id.data[i + 0] = v;
  2251. id.data[i + 1] = v;
  2252. id.data[i + 2] = v;
  2253. id.data[i + 3] = v;
  2254. }
  2255. }
  2256. this._context.putImageData(id, curPosXMargin, curPosYMargin);
  2257. }
  2258. // Fill the CharInfo object
  2259. info.topLeftUV = new BABYLON.Vector2((curPosXMargin - 0.5) / textureSize.width, (this._currentFreePosition.y - 0.5 + this._yMargin) / textureSize.height);
  2260. info.bottomRightUV = new BABYLON.Vector2((curPosXMargin - 0.5 + width) / textureSize.width, info.topLeftUV.y + (this._lineHeightSuper / textureSize.height));
  2261. info.yOffset = info.xOffset = 0;
  2262. //console.log(`Char: ${char}, Offset: ${curPosX}, ${this._currentFreePosition.y + this._yMargin}, Size: ${width}, ${this._lineHeightSuper}, UV: ${info.topLeftUV}, ${info.bottomRightUV}`);
  2263. if (this._signedDistanceField) {
  2264. var off = 1 / textureSize.width;
  2265. info.topLeftUV.addInPlace(new BABYLON.Vector2(off, off));
  2266. info.bottomRightUV.addInPlace(new BABYLON.Vector2(off, off));
  2267. }
  2268. info.charWidth = this._superSample ? (width / 2) : width;
  2269. info.xAdvance = info.charWidth;
  2270. // Add the info structure
  2271. this._charInfos.add(char, info);
  2272. this._curCharCount++;
  2273. // Set the next position
  2274. this._currentFreePosition.x += Math.ceil(width + this._xMargin * 2);
  2275. return info;
  2276. };
  2277. FontTexture.prototype._computeSDFChar = function (source) {
  2278. var scl = this._sdfScale;
  2279. var sw = source.width;
  2280. var sh = source.height;
  2281. var dw = sw / scl;
  2282. var dh = sh / scl;
  2283. var roffx = 0;
  2284. var roffy = 0;
  2285. // We shouldn't look beyond half of the biggest between width and height
  2286. var radius = scl;
  2287. var br = radius - 1;
  2288. var lookupSrc = function (dx, dy, offX, offY, lookVis) {
  2289. var sx = dx * scl;
  2290. var sy = dy * scl;
  2291. // Looking out of the area? return true to make the test going on
  2292. if (((sx + offX) < 0) || ((sx + offX) >= sw) || ((sy + offY) < 0) || ((sy + offY) >= sh)) {
  2293. return true;
  2294. }
  2295. // Get the pixel we want
  2296. var val = source.data[(((sy + offY) * sw) + (sx + offX)) * 4];
  2297. var res = (val > 0) === lookVis;
  2298. if (!res) {
  2299. roffx = offX;
  2300. roffy = offY;
  2301. }
  2302. return res;
  2303. };
  2304. var lookupArea = function (dx, dy, lookVis) {
  2305. // Fast rejection test, if we have the same result in N, S, W, E at a distance which is the radius-1 then it means the data will be consistent in this area. That's because we've scale the rendering of the letter "radius" times, so a letter's pixel will be at least radius wide
  2306. if (lookupSrc(dx, dy, 0, br, lookVis) &&
  2307. lookupSrc(dx, dy, 0, -br, lookVis) &&
  2308. lookupSrc(dx, dy, -br, 0, lookVis) &&
  2309. lookupSrc(dx, dy, br, 0, lookVis)) {
  2310. return 0;
  2311. }
  2312. for (var i = 1; i <= radius; i++) {
  2313. // Quick test N, S, W, E
  2314. if (!lookupSrc(dx, dy, 0, i, lookVis) || !lookupSrc(dx, dy, 0, -i, lookVis) || !lookupSrc(dx, dy, -i, 0, lookVis) || !lookupSrc(dx, dy, i, 0, lookVis)) {
  2315. return i * i; // Squared Distance is simple to compute in this case
  2316. }
  2317. // Test the frame area (except the N, S, W, E spots) from the nearest point from the center to the further one
  2318. for (var j = 1; j <= i; j++) {
  2319. if (!lookupSrc(dx, dy, -j, i, lookVis) || !lookupSrc(dx, dy, j, i, lookVis) ||
  2320. !lookupSrc(dx, dy, i, -j, lookVis) || !lookupSrc(dx, dy, i, j, lookVis) ||
  2321. !lookupSrc(dx, dy, -j, -i, lookVis) || !lookupSrc(dx, dy, j, -i, lookVis) ||
  2322. !lookupSrc(dx, dy, -i, -j, lookVis) || !lookupSrc(dx, dy, -i, j, lookVis)) {
  2323. // We found the nearest texel having and opposite state, store the squared length
  2324. var res_1 = (i * i) + (j * j);
  2325. var count = 1;
  2326. // To improve quality we will sample the texels around this one, so it's 8 samples, we consider only the one having an opposite state, add them to the current res and will will compute the average at the end
  2327. if (!lookupSrc(dx, dy, roffx - 1, roffy, lookVis)) {
  2328. res_1 += (roffx - 1) * (roffx - 1) + roffy * roffy;
  2329. ++count;
  2330. }
  2331. if (!lookupSrc(dx, dy, roffx + 1, roffy, lookVis)) {
  2332. res_1 += (roffx + 1) * (roffx + 1) + roffy * roffy;
  2333. ++count;
  2334. }
  2335. if (!lookupSrc(dx, dy, roffx, roffy - 1, lookVis)) {
  2336. res_1 += roffx * roffx + (roffy - 1) * (roffy - 1);
  2337. ++count;
  2338. }
  2339. if (!lookupSrc(dx, dy, roffx, roffy + 1, lookVis)) {
  2340. res_1 += roffx * roffx + (roffy + 1) * (roffy + 1);
  2341. ++count;
  2342. }
  2343. if (!lookupSrc(dx, dy, roffx - 1, roffy - 1, lookVis)) {
  2344. res_1 += (roffx - 1) * (roffx - 1) + (roffy - 1) * (roffy - 1);
  2345. ++count;
  2346. }
  2347. if (!lookupSrc(dx, dy, roffx + 1, roffy + 1, lookVis)) {
  2348. res_1 += (roffx + 1) * (roffx + 1) + (roffy + 1) * (roffy + 1);
  2349. ++count;
  2350. }
  2351. if (!lookupSrc(dx, dy, roffx + 1, roffy - 1, lookVis)) {
  2352. res_1 += (roffx + 1) * (roffx + 1) + (roffy - 1) * (roffy - 1);
  2353. ++count;
  2354. }
  2355. if (!lookupSrc(dx, dy, roffx - 1, roffy + 1, lookVis)) {
  2356. res_1 += (roffx - 1) * (roffx - 1) + (roffy + 1) * (roffy + 1);
  2357. ++count;
  2358. }
  2359. // Compute the average based on the accumulated distance
  2360. return res_1 / count;
  2361. }
  2362. }
  2363. }
  2364. return 0;
  2365. };
  2366. var tmp = new Array(dw * dh);
  2367. for (var y = 0; y < dh; y++) {
  2368. for (var x = 0; x < dw; x++) {
  2369. var curState = lookupSrc(x, y, 0, 0, true);
  2370. var d = lookupArea(x, y, curState);
  2371. if (d === 0) {
  2372. d = radius * radius * 2;
  2373. }
  2374. tmp[(y * dw) + x] = curState ? d : -d;
  2375. }
  2376. }
  2377. var res = this._context.createImageData(dw, dh);
  2378. var size = dw * dh;
  2379. for (var j = 0; j < size; j++) {
  2380. var d = tmp[j];
  2381. var sign = (d < 0) ? -1 : 1;
  2382. d = Math.sqrt(Math.abs(d)) * sign;
  2383. d *= 127.5 / radius;
  2384. d += 127.5;
  2385. if (d < 0) {
  2386. d = 0;
  2387. }
  2388. else if (d > 255) {
  2389. d = 255;
  2390. }
  2391. d += 0.5;
  2392. res.data[j * 4 + 0] = d;
  2393. res.data[j * 4 + 1] = d;
  2394. res.data[j * 4 + 2] = d;
  2395. res.data[j * 4 + 3] = 255;
  2396. }
  2397. return res;
  2398. };
  2399. FontTexture.prototype.getSuperSampleFont = function (font) {
  2400. // Eternal thank to http://stackoverflow.com/a/10136041/802124
  2401. var regex = /^\s*(?=(?:(?:[-a-z]+\s*){0,2}(italic|oblique))?)(?=(?:(?:[-a-z]+\s*){0,2}(small-caps))?)(?=(?:(?:[-a-z]+\s*){0,2}(bold(?:er)?|lighter|[1-9]00))?)(?:(?:normal|\1|\2|\3)\s*){0,3}((?:xx?-)?(?:small|large)|medium|smaller|larger|[.\d]+(?:\%|in|[cem]m|ex|p[ctx]))(?:\s*\/\s*(normal|[.\d]+(?:\%|in|[cem]m|ex|p[ctx])))?\s*([-,\"\sa-z]+?)\s*$/;
  2402. var res = font.toLocaleLowerCase().match(regex);
  2403. if (res == null) {
  2404. return null;
  2405. }
  2406. var size = parseInt(res[4]);
  2407. res[4] = (size * 2).toString() + (res[4].match(/\D+/) || []).pop();
  2408. var newFont = "";
  2409. for (var j = 1; j < res.length; j++) {
  2410. if (res[j] != null) {
  2411. newFont += res[j] + " ";
  2412. }
  2413. }
  2414. return newFont;
  2415. };
  2416. // More info here: https://videlais.com/2014/03/16/the-many-and-varied-problems-with-measuring-font-height-for-html5-canvas/
  2417. FontTexture.prototype.getFontHeight = function (font, chars) {
  2418. var fontDraw = document.createElement("canvas");
  2419. fontDraw.width = 600;
  2420. fontDraw.height = 600;
  2421. var ctx = fontDraw.getContext('2d');
  2422. ctx.fillRect(0, 0, fontDraw.width, fontDraw.height);
  2423. ctx.textBaseline = 'top';
  2424. ctx.fillStyle = 'white';
  2425. ctx.font = font;
  2426. ctx.fillText(chars, 0, 0);
  2427. var pixels = ctx.getImageData(0, 0, fontDraw.width, fontDraw.height).data;
  2428. var start = -1;
  2429. var end = -1;
  2430. for (var row = 0; row < fontDraw.height; row++) {
  2431. for (var column = 0; column < fontDraw.width; column++) {
  2432. var index = (row * fontDraw.width + column) * 4;
  2433. var pix = pixels[index];
  2434. if (pix === 0) {
  2435. if (column === fontDraw.width - 1 && start !== -1) {
  2436. end = row;
  2437. row = fontDraw.height;
  2438. break;
  2439. }
  2440. continue;
  2441. }
  2442. else {
  2443. if (start === -1) {
  2444. start = row;
  2445. }
  2446. break;
  2447. }
  2448. }
  2449. }
  2450. return { height: (end - start) + 1, offset: start };
  2451. };
  2452. Object.defineProperty(FontTexture.prototype, "canRescale", {
  2453. get: function () {
  2454. return false;
  2455. },
  2456. enumerable: true,
  2457. configurable: true
  2458. });
  2459. FontTexture.prototype.getContext = function () {
  2460. return this._context;
  2461. };
  2462. /**
  2463. * Call this method when you've call getChar() at least one time, this will update the texture if needed.
  2464. * Don't be afraid to call it, if no new character was added, this method simply does nothing.
  2465. */
  2466. FontTexture.prototype.update = function () {
  2467. // Update only if there's new char added since the previous update
  2468. if (this._lastUpdateCharCount < this._curCharCount) {
  2469. this.getScene().getEngine().updateDynamicTexture(this._texture, this._canvas, false, true);
  2470. this._lastUpdateCharCount = this._curCharCount;
  2471. }
  2472. };
  2473. // cloning should be prohibited, there's no point to duplicate this texture at all
  2474. FontTexture.prototype.clone = function () {
  2475. return null;
  2476. };
  2477. /**
  2478. * For FontTexture retrieved using GetCachedFontTexture, use this method when you transfer this object's lifetime to another party in order to share this resource.
  2479. * When the other party is done with this object, decCachedFontTextureCounter must be called.
  2480. */
  2481. FontTexture.prototype.incCachedFontTextureCounter = function () {
  2482. ++this._usedCounter;
  2483. };
  2484. /**
  2485. * Use this method only in conjunction with incCachedFontTextureCounter, call it when you no longer need to use this shared resource.
  2486. */
  2487. FontTexture.prototype.decCachedFontTextureCounter = function () {
  2488. var dic = this.getScene().getExternalData("FontTextureCache");
  2489. if (!dic) {
  2490. return;
  2491. }
  2492. if (--this._usedCounter === 0) {
  2493. dic.remove(this._cachedFontId);
  2494. this.dispose();
  2495. }
  2496. };
  2497. return FontTexture;
  2498. }(BaseFontTexture));
  2499. BABYLON.FontTexture = FontTexture;
  2500. /**
  2501. * Orginial code from cocos2d-js, converted to TypeScript by Nockawa
  2502. * Load the Text version of the BMFont format, no XML or binary supported, just plain old text
  2503. */
  2504. var BMFontLoaderTxt = BMFontLoaderTxt_1 = (function () {
  2505. function BMFontLoaderTxt() {
  2506. }
  2507. BMFontLoaderTxt.prototype._parseStrToObj = function (str) {
  2508. var arr = str.match(BMFontLoaderTxt_1.ITEM_EXP);
  2509. if (!arr) {
  2510. return null;
  2511. }
  2512. var obj = {};
  2513. for (var i = 0, li = arr.length; i < li; i++) {
  2514. var tempStr = arr[i];
  2515. var index = tempStr.indexOf("=");
  2516. var key = tempStr.substring(0, index);
  2517. var value = tempStr.substring(index + 1);
  2518. if (value.match(BMFontLoaderTxt_1.INT_EXP))
  2519. value = parseInt(value);
  2520. else if (value[0] === '"')
  2521. value = value.substring(1, value.length - 1);
  2522. obj[key] = value;
  2523. }
  2524. return obj;
  2525. };
  2526. BMFontLoaderTxt.prototype._buildCharInfo = function (bfi, initialLine, obj, textureSize, invertY, chars) {
  2527. var char = null;
  2528. var x = null;
  2529. var y = null;
  2530. var width = null;
  2531. var height = null;
  2532. var xoffset = 0;
  2533. var yoffset = 0;
  2534. var xadvance = 0;
  2535. var ci = new CharInfo();
  2536. for (var key in obj) {
  2537. var value = obj[key];
  2538. switch (key) {
  2539. case "id":
  2540. char = String.fromCharCode(value);
  2541. break;
  2542. case "x":
  2543. x = value;
  2544. break;
  2545. case "y":
  2546. y = value;
  2547. break;
  2548. case "width":
  2549. width = value;
  2550. break;
  2551. case "height":
  2552. height = value;
  2553. break;
  2554. case "xadvance":
  2555. xadvance = value;
  2556. break;
  2557. case "xoffset":
  2558. xoffset = value;
  2559. break;
  2560. case "yoffset":
  2561. yoffset = value;
  2562. break;
  2563. }
  2564. }
  2565. if (x != null && y != null && width != null && height != null && char != null) {
  2566. ci.xAdvance = xadvance;
  2567. ci.xOffset = xoffset;
  2568. ci.yOffset = bfi.lineHeight - height - yoffset;
  2569. if (invertY) {
  2570. ci.topLeftUV = new BABYLON.Vector2(1 - (x / textureSize.width), 1 - (y / textureSize.height));
  2571. ci.bottomRightUV = new BABYLON.Vector2(1 - ((x + width) / textureSize.width), 1 - ((y + height) / textureSize.height));
  2572. }
  2573. else {
  2574. ci.topLeftUV = new BABYLON.Vector2(x / textureSize.width, y / textureSize.height);
  2575. ci.bottomRightUV = new BABYLON.Vector2((x + width) / textureSize.width, (y + height) / textureSize.height);
  2576. }
  2577. ci.charWidth = width;
  2578. chars.add(char, ci);
  2579. }
  2580. else {
  2581. console.log("Error while parsing line " + initialLine);
  2582. }
  2583. };
  2584. BMFontLoaderTxt.prototype.loadFont = function (fontContent, scene, invertY) {
  2585. var fontStr = fontContent;
  2586. var bfi = new BitmapFontInfo();
  2587. var errorCode = 0;
  2588. var errorMsg = "OK";
  2589. //padding
  2590. var info = fontStr.match(BMFontLoaderTxt_1.INFO_EXP);
  2591. var infoObj = this._parseStrToObj(info[0]);
  2592. if (!infoObj) {
  2593. return null;
  2594. }
  2595. var paddingArr = infoObj["padding"].split(",");
  2596. bfi.padding = new BABYLON.Vector4(parseInt(paddingArr[0]), parseInt(paddingArr[1]), parseInt(paddingArr[2]), parseInt(paddingArr[3]));
  2597. //common
  2598. var commonObj = this._parseStrToObj(fontStr.match(BMFontLoaderTxt_1.COMMON_EXP)[0]);
  2599. bfi.lineHeight = commonObj["lineHeight"];
  2600. bfi.baseLine = commonObj["base"];
  2601. bfi.textureSize = new BABYLON.Size(commonObj["scaleW"], commonObj["scaleH"]);
  2602. var maxTextureSize = scene.getEngine()._gl.getParameter(0xd33);
  2603. if (commonObj["scaleW"] > maxTextureSize.width || commonObj["scaleH"] > maxTextureSize.height) {
  2604. errorMsg = "FontMap texture's size is bigger than what WebGL supports";
  2605. errorCode = -1;
  2606. }
  2607. else {
  2608. if (commonObj["pages"] !== 1) {
  2609. errorMsg = "FontMap must contain one page only.";
  2610. errorCode = -1;
  2611. }
  2612. else {
  2613. //page
  2614. var pageObj = this._parseStrToObj(fontStr.match(BMFontLoaderTxt_1.PAGE_EXP)[0]);
  2615. if (pageObj["id"] !== 0) {
  2616. errorMsg = "Only one page of ID 0 is supported";
  2617. errorCode = -1;
  2618. }
  2619. else {
  2620. bfi.textureFile = pageObj["file"];
  2621. //char
  2622. var charLines = fontStr.match(BMFontLoaderTxt_1.CHAR_EXP);
  2623. for (var i = 0, li = charLines.length; i < li; i++) {
  2624. var charObj = this._parseStrToObj(charLines[i]);
  2625. this._buildCharInfo(bfi, charLines[i], charObj, bfi.textureSize, invertY, bfi.charDic);
  2626. }
  2627. //kerning
  2628. var kerningLines = fontStr.match(BMFontLoaderTxt_1.KERNING_EXP);
  2629. if (kerningLines) {
  2630. for (var i = 0, li = kerningLines.length; i < li; i++) {
  2631. var kerningObj = this._parseStrToObj(kerningLines[i]);
  2632. bfi.kerningDic.add(((kerningObj["first"] << 16) | (kerningObj["second"] & 0xffff)).toString(), kerningObj["amount"]);
  2633. }
  2634. }
  2635. }
  2636. }
  2637. }
  2638. return { bfi: bfi, errorCode: errorCode, errorMsg: errorMsg };
  2639. };
  2640. return BMFontLoaderTxt;
  2641. }());
  2642. BMFontLoaderTxt.INFO_EXP = /info [^\r\n]*(\r\n|$)/gi;
  2643. BMFontLoaderTxt.COMMON_EXP = /common [^\n]*(\n|$)/gi;
  2644. BMFontLoaderTxt.PAGE_EXP = /page [^\n]*(\n|$)/gi;
  2645. BMFontLoaderTxt.CHAR_EXP = /char [^\n]*(\n|$)/gi;
  2646. BMFontLoaderTxt.KERNING_EXP = /kerning [^\n]*(\n|$)/gi;
  2647. BMFontLoaderTxt.ITEM_EXP = /\w+=[^ \r\n]+/gi;
  2648. BMFontLoaderTxt.INT_EXP = /^[\-]?\d+$/;
  2649. BMFontLoaderTxt = BMFontLoaderTxt_1 = __decorate([
  2650. BitmapFontLoaderPlugin("fnt", new BMFontLoaderTxt_1())
  2651. ], BMFontLoaderTxt);
  2652. ;
  2653. function BitmapFontLoaderPlugin(fileExtension, plugin) {
  2654. return function () {
  2655. BitmapFontTexture.addLoader(fileExtension, plugin);
  2656. };
  2657. }
  2658. BABYLON.BitmapFontLoaderPlugin = BitmapFontLoaderPlugin;
  2659. var BMFontLoaderTxt_1;
  2660. })(BABYLON || (BABYLON = {}));
  2661. //# sourceMappingURL=babylon.fontTexture.js.map
  2662. var BABYLON;
  2663. (function (BABYLON) {
  2664. /**
  2665. * Stores 2D Bounding Information.
  2666. * This class handles a circle area and a bounding rectangle one.
  2667. */
  2668. var BoundingInfo2D = (function () {
  2669. function BoundingInfo2D() {
  2670. this.radius = 0;
  2671. this.center = BABYLON.Vector2.Zero();
  2672. this.extent = BABYLON.Vector2.Zero();
  2673. this._worldAABBDirty = false;
  2674. this._worldAABBDirtyObservable = null;
  2675. this._worldAABB = BABYLON.Vector4.Zero();
  2676. }
  2677. /**
  2678. * Create a BoundingInfo2D object from a given size
  2679. * @param size the size that will be used to set the extend, radius will be computed from it.
  2680. */
  2681. BoundingInfo2D.CreateFromSize = function (size) {
  2682. var r = new BoundingInfo2D();
  2683. BoundingInfo2D.CreateFromSizeToRef(size, r);
  2684. return r;
  2685. };
  2686. /**
  2687. * Create a BoundingInfo2D object from a given radius
  2688. * @param radius the radius to use, the extent will be computed from it.
  2689. */
  2690. BoundingInfo2D.CreateFromRadius = function (radius) {
  2691. var r = new BoundingInfo2D();
  2692. BoundingInfo2D.CreateFromRadiusToRef(radius, r);
  2693. return r;
  2694. };
  2695. /**
  2696. * Create a BoundingInfo2D object from a list of points.
  2697. * The resulted object will be the smallest bounding area that includes all the given points.
  2698. * @param points an array of points to compute the bounding object from.
  2699. */
  2700. BoundingInfo2D.CreateFromPoints = function (points) {
  2701. var r = new BoundingInfo2D();
  2702. BoundingInfo2D.CreateFromPointsToRef(points, r);
  2703. return r;
  2704. };
  2705. /**
  2706. * Update a BoundingInfo2D object using the given Size as input
  2707. * @param size the bounding data will be computed from this size.
  2708. * @param b must be a valid/allocated object, it will contain the result of the operation
  2709. */
  2710. BoundingInfo2D.CreateFromSizeToRef = function (size, b) {
  2711. if (!size) {
  2712. size = BABYLON.Size.Zero();
  2713. }
  2714. b.center.x = +size.width / 2;
  2715. b.center.y = +size.height / 2;
  2716. b.extent.x = b.center.x;
  2717. b.extent.y = b.center.y;
  2718. b.radius = b.extent.length();
  2719. b._worldAABBDirty = true;
  2720. };
  2721. /**
  2722. * Update a BoundingInfo2D object using the given radius as input
  2723. * @param radius the bounding data will be computed from this radius
  2724. * @param b must be a valid/allocated object, it will contain the result of the operation
  2725. */
  2726. BoundingInfo2D.CreateFromRadiusToRef = function (radius, b) {
  2727. b.center.x = b.center.y = 0;
  2728. var r = +radius;
  2729. b.extent.x = r;
  2730. b.extent.y = r;
  2731. b.radius = r;
  2732. b._worldAABBDirty = true;
  2733. };
  2734. /**
  2735. * Update a BoundingInfo2D object using the given points array as input
  2736. * @param points the point array to use to update the bounding data
  2737. * @param b must be a valid/allocated object, it will contain the result of the operation
  2738. */
  2739. BoundingInfo2D.CreateFromPointsToRef = function (points, b) {
  2740. var xmin = Number.MAX_VALUE, ymin = Number.MAX_VALUE, xmax = Number.MIN_VALUE, ymax = Number.MIN_VALUE;
  2741. for (var _i = 0, points_1 = points; _i < points_1.length; _i++) {
  2742. var p = points_1[_i];
  2743. xmin = Math.min(p.x, xmin);
  2744. xmax = Math.max(p.x, xmax);
  2745. ymin = Math.min(p.y, ymin);
  2746. ymax = Math.max(p.y, ymax);
  2747. }
  2748. BoundingInfo2D.CreateFromMinMaxToRef(xmin, xmax, ymin, ymax, b);
  2749. };
  2750. /**
  2751. * Update a BoundingInfo2D object using the given min/max values as input
  2752. * @param xmin the smallest x coordinate
  2753. * @param xmax the biggest x coordinate
  2754. * @param ymin the smallest y coordinate
  2755. * @param ymax the buggest y coordinate
  2756. * @param b must be a valid/allocated object, it will contain the result of the operation
  2757. */
  2758. BoundingInfo2D.CreateFromMinMaxToRef = function (xmin, xmax, ymin, ymax, b) {
  2759. var w = xmax - xmin;
  2760. var h = ymax - ymin;
  2761. b.center = new BABYLON.Vector2(xmin + w / 2, ymin + h / 2);
  2762. b.extent = new BABYLON.Vector2(xmax - b.center.x, ymax - b.center.y);
  2763. b.radius = b.extent.length();
  2764. b._worldAABBDirty = true;
  2765. };
  2766. BoundingInfo2D.prototype.toString = function () {
  2767. return "Center: " + this.center + ", Extent: " + this.extent + ", Radius: " + this.radius;
  2768. };
  2769. /**
  2770. * Duplicate this instance and return a new one
  2771. * @return the duplicated instance
  2772. */
  2773. BoundingInfo2D.prototype.clone = function () {
  2774. var r = new BoundingInfo2D();
  2775. r.center = this.center.clone();
  2776. r.radius = this.radius;
  2777. r.extent = this.extent.clone();
  2778. return r;
  2779. };
  2780. BoundingInfo2D.prototype.clear = function () {
  2781. this.center.copyFromFloats(0, 0);
  2782. this.radius = 0;
  2783. this.extent.copyFromFloats(0, 0);
  2784. this._worldAABBDirty = true;
  2785. };
  2786. BoundingInfo2D.prototype.copyFrom = function (src) {
  2787. this.center.copyFrom(src.center);
  2788. this.radius = src.radius;
  2789. this.extent.copyFrom(src.extent);
  2790. this._worldAABBDirty = true;
  2791. };
  2792. BoundingInfo2D.prototype.equals = function (other) {
  2793. if (!other) {
  2794. return false;
  2795. }
  2796. return other.center.equals(this.center) && other.extent.equals(this.extent);
  2797. };
  2798. /**
  2799. * return the max extend of the bounding info
  2800. */
  2801. BoundingInfo2D.prototype.max = function () {
  2802. var r = BABYLON.Vector2.Zero();
  2803. this.maxToRef(r);
  2804. return r;
  2805. };
  2806. /**
  2807. * return the min/max extend of the bounding info.
  2808. * x, y, z, w are left, bottom, right and top
  2809. */
  2810. BoundingInfo2D.prototype.minMax = function () {
  2811. var r = BABYLON.Vector4.Zero();
  2812. this.minMaxToRef(r);
  2813. return r;
  2814. };
  2815. /**
  2816. * Update a vector2 with the max extend of the bounding info
  2817. * @param result must be a valid/allocated vector2 that will contain the result of the operation
  2818. */
  2819. BoundingInfo2D.prototype.maxToRef = function (result) {
  2820. result.x = this.center.x + this.extent.x;
  2821. result.y = this.center.y + this.extent.y;
  2822. };
  2823. /**
  2824. * Update a vector4 with the min/max extend of the bounding info
  2825. * x, y, z, w are left, bottom, right and top
  2826. * @param result must be a valid/allocated vector4 that will contain the result of the operation
  2827. */
  2828. BoundingInfo2D.prototype.minMaxToRef = function (result) {
  2829. result.x = this.center.x - this.extent.x;
  2830. result.y = this.center.y - this.extent.y;
  2831. result.z = this.center.x + this.extent.x;
  2832. result.w = this.center.y + this.extent.y;
  2833. };
  2834. /**
  2835. * Return the size of the boundingInfo rect surface
  2836. */
  2837. BoundingInfo2D.prototype.size = function () {
  2838. var r = BABYLON.Size.Zero();
  2839. this.sizeToRef(r);
  2840. return r;
  2841. };
  2842. /**
  2843. * Stores in the result object the size of the boundingInfo rect surface
  2844. * @param result
  2845. */
  2846. BoundingInfo2D.prototype.sizeToRef = function (result) {
  2847. result.width = this.extent.x * 2;
  2848. result.height = this.extent.y * 2;
  2849. };
  2850. /**
  2851. * Inflate the boundingInfo with the given vector
  2852. * @param offset the extent will be incremented with offset and the radius will be computed again
  2853. */
  2854. BoundingInfo2D.prototype.inflate = function (offset) {
  2855. this.extent.addInPlace(offset);
  2856. this.radius = this.extent.length();
  2857. };
  2858. /**
  2859. * Apply a transformation matrix to this BoundingInfo2D and return a new instance containing the result
  2860. * @param matrix the transformation matrix to apply
  2861. * @return the new instance containing the result of the transformation applied on this BoundingInfo2D
  2862. */
  2863. BoundingInfo2D.prototype.transform = function (matrix) {
  2864. var r = new BoundingInfo2D();
  2865. this.transformToRef(matrix, r);
  2866. return r;
  2867. };
  2868. /**
  2869. * Compute the union of this BoundingInfo2D with a given one, returns a new BoundingInfo2D as a result
  2870. * @param other the second BoundingInfo2D to compute the union with this one
  2871. * @return a new instance containing the result of the union
  2872. */
  2873. BoundingInfo2D.prototype.union = function (other) {
  2874. var r = new BoundingInfo2D();
  2875. this.unionToRef(other, r);
  2876. return r;
  2877. };
  2878. BoundingInfo2D.prototype.worldAABBIntersectionTest = function (other) {
  2879. var a = this.worldAABB;
  2880. var b = other.worldAABB;
  2881. return b.z >= a.x && b.x <= a.z && b.w >= a.y && b.y <= a.w;
  2882. };
  2883. /**
  2884. * Transform this BoundingInfo2D with a given matrix and store the result in an existing BoundingInfo2D instance.
  2885. * This is a GC friendly version, try to use it as much as possible, specially if your transformation is inside a loop, allocate the result object once for good outside of the loop and use it every time.
  2886. * @param matrix The matrix to use to compute the transformation
  2887. * @param result A VALID (i.e. allocated) BoundingInfo2D object where the result will be stored
  2888. */
  2889. BoundingInfo2D.prototype.transformToRef = function (matrix, result) {
  2890. // Construct a bounding box based on the extent values
  2891. var p = BoundingInfo2D._transform;
  2892. p[0].x = this.center.x + this.extent.x;
  2893. p[0].y = this.center.y + this.extent.y;
  2894. p[1].x = this.center.x + this.extent.x;
  2895. p[1].y = this.center.y - this.extent.y;
  2896. p[2].x = this.center.x - this.extent.x;
  2897. p[2].y = this.center.y - this.extent.y;
  2898. p[3].x = this.center.x - this.extent.x;
  2899. p[3].y = this.center.y + this.extent.y;
  2900. // Transform the four points of the bounding box with the matrix
  2901. for (var i = 0; i < 4; i++) {
  2902. matrix.transformPointToRef(p[i], p[i]);
  2903. }
  2904. BoundingInfo2D.CreateFromPointsToRef(p, result);
  2905. };
  2906. BoundingInfo2D.prototype._updateWorldAABB = function (worldMatrix) {
  2907. // Construct a bounding box based on the extent values
  2908. var p = BoundingInfo2D._transform;
  2909. p[0].x = this.center.x + this.extent.x;
  2910. p[0].y = this.center.y + this.extent.y;
  2911. p[1].x = this.center.x + this.extent.x;
  2912. p[1].y = this.center.y - this.extent.y;
  2913. p[2].x = this.center.x - this.extent.x;
  2914. p[2].y = this.center.y - this.extent.y;
  2915. p[3].x = this.center.x - this.extent.x;
  2916. p[3].y = this.center.y + this.extent.y;
  2917. // Transform the four points of the bounding box with the matrix
  2918. for (var i = 0; i < 4; i++) {
  2919. worldMatrix.transformPointToRef(p[i], p[i]);
  2920. }
  2921. this._worldAABB.x = Math.min(Math.min(p[0].x, p[1].x), Math.min(p[2].x, p[3].x));
  2922. this._worldAABB.y = Math.min(Math.min(p[0].y, p[1].y), Math.min(p[2].y, p[3].y));
  2923. this._worldAABB.z = Math.max(Math.max(p[0].x, p[1].x), Math.max(p[2].x, p[3].x));
  2924. this._worldAABB.w = Math.max(Math.max(p[0].y, p[1].y), Math.max(p[2].y, p[3].y));
  2925. };
  2926. Object.defineProperty(BoundingInfo2D.prototype, "worldAABBDirtyObservable", {
  2927. get: function () {
  2928. if (!this._worldAABBDirtyObservable) {
  2929. this._worldAABBDirtyObservable = new BABYLON.Observable();
  2930. }
  2931. return this._worldAABBDirtyObservable;
  2932. },
  2933. enumerable: true,
  2934. configurable: true
  2935. });
  2936. Object.defineProperty(BoundingInfo2D.prototype, "isWorldAABBDirty", {
  2937. get: function () {
  2938. return this._worldAABBDirty;
  2939. },
  2940. enumerable: true,
  2941. configurable: true
  2942. });
  2943. BoundingInfo2D.prototype.dirtyWorldAABB = function () {
  2944. if (this._worldAABBDirty) {
  2945. return;
  2946. }
  2947. this._worldAABBDirty = true;
  2948. if (this._worldAABBDirtyObservable && this._worldAABBDirtyObservable.hasObservers()) {
  2949. this._worldAABBDirtyObservable.notifyObservers(this);
  2950. }
  2951. };
  2952. Object.defineProperty(BoundingInfo2D.prototype, "worldAABB", {
  2953. /**
  2954. * Retrieve the world AABB, the Vector4's data is x=xmin, y=ymin, z=xmax, w=ymax
  2955. */
  2956. get: function () {
  2957. if (this._worldAABBDirty) {
  2958. if (!this.worldMatrixAccess) {
  2959. throw new Error("you must set the worldMatrixAccess function first");
  2960. }
  2961. this._updateWorldAABB(this.worldMatrixAccess());
  2962. this._worldAABBDirty = false;
  2963. }
  2964. return this._worldAABB;
  2965. },
  2966. enumerable: true,
  2967. configurable: true
  2968. });
  2969. /**
  2970. * Compute the union of this BoundingInfo2D with another one and store the result in a third valid BoundingInfo2D object
  2971. * This is a GC friendly version, try to use it as much as possible, specially if your transformation is inside a loop, allocate the result object once for good outside of the loop and use it every time.
  2972. * @param other the second object used to compute the union
  2973. * @param result a VALID BoundingInfo2D instance (i.e. allocated) where the result will be stored
  2974. */
  2975. BoundingInfo2D.prototype.unionToRef = function (other, result) {
  2976. var xmax = Math.max(this.center.x + this.extent.x, other.center.x + other.extent.x);
  2977. var ymax = Math.max(this.center.y + this.extent.y, other.center.y + other.extent.y);
  2978. var xmin = Math.min(this.center.x - this.extent.x, other.center.x - other.extent.x);
  2979. var ymin = Math.min(this.center.y - this.extent.y, other.center.y - other.extent.y);
  2980. BoundingInfo2D.CreateFromMinMaxToRef(xmin, xmax, ymin, ymax, result);
  2981. };
  2982. /**
  2983. * Check if the given point is inside the BoundingInfo.
  2984. * The test is first made on the radius, then inside the rectangle described by the extent
  2985. * @param pickPosition the position to test
  2986. * @return true if the point is inside, false otherwise
  2987. */
  2988. BoundingInfo2D.prototype.doesIntersect = function (pickPosition) {
  2989. // is it inside the radius?
  2990. var pickLocal = pickPosition.subtract(this.center);
  2991. if (pickLocal.lengthSquared() <= (this.radius * this.radius)) {
  2992. // is it inside the rectangle?
  2993. return ((Math.abs(pickLocal.x) <= this.extent.x) && (Math.abs(pickLocal.y) <= this.extent.y));
  2994. }
  2995. return false;
  2996. };
  2997. return BoundingInfo2D;
  2998. }());
  2999. BoundingInfo2D._transform = new Array(BABYLON.Vector2.Zero(), BABYLON.Vector2.Zero(), BABYLON.Vector2.Zero(), BABYLON.Vector2.Zero());
  3000. BABYLON.BoundingInfo2D = BoundingInfo2D;
  3001. })(BABYLON || (BABYLON = {}));
  3002. //# sourceMappingURL=babylon.bounding2d.js.map
  3003. var __extends = (this && this.__extends) || (function () {
  3004. var extendStatics = Object.setPrototypeOf ||
  3005. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  3006. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  3007. return function (d, b) {
  3008. extendStatics(d, b);
  3009. function __() { this.constructor = d; }
  3010. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  3011. };
  3012. })();
  3013. var BABYLON;
  3014. (function (BABYLON) {
  3015. /**
  3016. * The base class for all implementation of a Primitive Collision Manager
  3017. */
  3018. var PrimitiveCollisionManagerBase = (function () {
  3019. function PrimitiveCollisionManagerBase(owner) {
  3020. this._owner = owner;
  3021. }
  3022. PrimitiveCollisionManagerBase.allocBasicPCM = function (owner, enableBorders) {
  3023. return new BasicPrimitiveCollisionManager(owner, enableBorders);
  3024. };
  3025. return PrimitiveCollisionManagerBase;
  3026. }());
  3027. BABYLON.PrimitiveCollisionManagerBase = PrimitiveCollisionManagerBase;
  3028. /**
  3029. * Base class of an Actor
  3030. */
  3031. var ActorInfoBase = (function () {
  3032. function ActorInfoBase() {
  3033. }
  3034. return ActorInfoBase;
  3035. }());
  3036. BABYLON.ActorInfoBase = ActorInfoBase;
  3037. var ActorInfo = (function (_super) {
  3038. __extends(ActorInfo, _super);
  3039. function ActorInfo(owner, actor, deep) {
  3040. var _this = _super.call(this) || this;
  3041. _this.owner = owner;
  3042. _this.prim = actor;
  3043. _this.flags = 0;
  3044. _this.presentInClusters = new BABYLON.StringDictionary();
  3045. _this.intersectWith = new BABYLON.ObservableStringDictionary(false);
  3046. _this.setFlags((deep ? ActorInfo.flagDeep : 0) | ActorInfo.flagDirty);
  3047. var bi = (deep ? actor.boundingInfo : actor.levelBoundingInfo);
  3048. // Dirty Actor if its WorldAABB changed
  3049. bi.worldAABBDirtyObservable.add(function (e, d) {
  3050. _this.owner.actorDirty(_this);
  3051. });
  3052. // Dirty Actor if it's getting enabled/disabled
  3053. actor.propertyChanged.add(function (e, d) {
  3054. if (d.mask === -1) {
  3055. return;
  3056. }
  3057. _this.setFlagsValue(ActorInfo.flagEnabled, e.newValue === true);
  3058. _this.owner.actorDirty(_this);
  3059. }, BABYLON.Prim2DBase.isVisibleProperty.flagId);
  3060. return _this;
  3061. }
  3062. ActorInfo.prototype.setFlags = function (flags) {
  3063. this.flags |= flags;
  3064. };
  3065. ActorInfo.prototype.clearFlags = function (flags) {
  3066. this.flags &= ~flags;
  3067. };
  3068. ActorInfo.prototype.isAllFlagsSet = function (flags) {
  3069. return (this.flags & flags) === flags;
  3070. };
  3071. ActorInfo.prototype.isSomeFlagsSet = function (flags) {
  3072. return (this.flags & flags) !== 0;
  3073. };
  3074. ActorInfo.prototype.setFlagsValue = function (flags, value) {
  3075. if (value) {
  3076. this.flags |= flags;
  3077. }
  3078. else {
  3079. this.flags &= ~flags;
  3080. }
  3081. };
  3082. Object.defineProperty(ActorInfo.prototype, "worldAABB", {
  3083. get: function () {
  3084. return (this.isSomeFlagsSet(ActorInfo.flagDeep) ? this.prim.boundingInfo : this.prim.levelBoundingInfo).worldAABB;
  3085. },
  3086. enumerable: true,
  3087. configurable: true
  3088. });
  3089. Object.defineProperty(ActorInfo.prototype, "isEnabled", {
  3090. get: function () {
  3091. return this.isSomeFlagsSet(ActorInfo.flagEnabled);
  3092. },
  3093. enumerable: true,
  3094. configurable: true
  3095. });
  3096. Object.defineProperty(ActorInfo.prototype, "isDeep", {
  3097. get: function () {
  3098. return this.isSomeFlagsSet(ActorInfo.flagDeep);
  3099. },
  3100. enumerable: true,
  3101. configurable: true
  3102. });
  3103. Object.defineProperty(ActorInfo.prototype, "isDirty", {
  3104. get: function () {
  3105. return this.isSomeFlagsSet(ActorInfo.flagDirty);
  3106. },
  3107. enumerable: true,
  3108. configurable: true
  3109. });
  3110. Object.defineProperty(ActorInfo.prototype, "isRemoved", {
  3111. get: function () {
  3112. return this.isSomeFlagsSet(ActorInfo.flagRemoved);
  3113. },
  3114. enumerable: true,
  3115. configurable: true
  3116. });
  3117. return ActorInfo;
  3118. }(ActorInfoBase));
  3119. ActorInfo.flagDeep = 0x0001; // set if the actor boundingInfo must be used instead of the levelBoundingInfo
  3120. ActorInfo.flagEnabled = 0x0002; // set if the actor is enabled and should be considered for intersection tests
  3121. ActorInfo.flagDirty = 0x0004; // set if the actor's AABB is dirty
  3122. ActorInfo.flagRemoved = 0x0008; // set if the actor was removed from the PCM
  3123. var ClusterInfo = (function () {
  3124. function ClusterInfo() {
  3125. this.actors = new BABYLON.StringDictionary();
  3126. }
  3127. ClusterInfo.prototype.clear = function () {
  3128. this.actors.clear();
  3129. };
  3130. return ClusterInfo;
  3131. }());
  3132. var BasicPrimitiveCollisionManager = (function (_super) {
  3133. __extends(BasicPrimitiveCollisionManager, _super);
  3134. function BasicPrimitiveCollisionManager(owner, enableBorders) {
  3135. var _this = _super.call(this, owner) || this;
  3136. _this._actors = new BABYLON.StringDictionary();
  3137. _this._dirtyActors = new BABYLON.StringDictionary();
  3138. _this._clusters = null;
  3139. _this._maxActorByCluster = 0;
  3140. _this._AABBRenderPrim = null;
  3141. _this._canvasSize = BABYLON.Size.Zero();
  3142. _this._ClusterRenderPrim = null;
  3143. _this._debugTextBackground = null;
  3144. _this._clusterDirty = true;
  3145. _this._clusterSize = new BABYLON.Size(2, 2);
  3146. _this._clusterStep = BABYLON.Vector2.Zero();
  3147. _this._lastClusterResizeCounter = 0;
  3148. _this._freeClusters = new Array();
  3149. _this._enableBorder = enableBorders;
  3150. _this._debugUpdateOpCount = new BABYLON.PerfCounter();
  3151. _this._debugUpdateTime = new BABYLON.PerfCounter();
  3152. _this._intersectedActors = new BABYLON.ObservableStringDictionary(false);
  3153. _this._borderIntersecteddActors = new Array(4);
  3154. for (var j = 0; j < 4; j++) {
  3155. _this._borderIntersecteddActors[j] = new BABYLON.ObservableStringDictionary(false);
  3156. }
  3157. var flagId = BABYLON.Canvas2D.actualSizeProperty.flagId;
  3158. if (!BasicPrimitiveCollisionManager.WAABBCorners) {
  3159. BasicPrimitiveCollisionManager.WAABBCorners = new Array(4);
  3160. for (var i = 0; i < 4; i++) {
  3161. BasicPrimitiveCollisionManager.WAABBCorners[i] = BABYLON.Vector2.Zero();
  3162. }
  3163. BasicPrimitiveCollisionManager.WAABBCornersCluster = new Array(4);
  3164. for (var i = 0; i < 4; i++) {
  3165. BasicPrimitiveCollisionManager.WAABBCornersCluster[i] = BABYLON.Vector2.Zero();
  3166. }
  3167. }
  3168. owner.propertyChanged.add(function (e, d) {
  3169. if (d.mask === -1) {
  3170. return;
  3171. }
  3172. _this._clusterDirty = true;
  3173. console.log("canvas size changed");
  3174. }, flagId);
  3175. _this.debugRenderAABB = false;
  3176. _this.debugRenderClusters = false;
  3177. _this.debugStats = false;
  3178. return _this;
  3179. }
  3180. BasicPrimitiveCollisionManager.prototype._addActor = function (actor, deep) {
  3181. var _this = this;
  3182. return this._actors.getOrAddWithFactory(actor.uid, function () {
  3183. var ai = new ActorInfo(_this, actor, deep);
  3184. _this.actorDirty(ai);
  3185. return ai;
  3186. });
  3187. };
  3188. BasicPrimitiveCollisionManager.prototype._removeActor = function (actor) {
  3189. var ai = this._actors.getAndRemove(actor.uid);
  3190. ai.setFlags(ActorInfo.flagRemoved);
  3191. this.actorDirty(ai);
  3192. };
  3193. BasicPrimitiveCollisionManager.prototype.actorDirty = function (actor) {
  3194. actor.setFlags(ActorInfo.flagDirty);
  3195. this._dirtyActors.add(actor.prim.uid, actor);
  3196. };
  3197. BasicPrimitiveCollisionManager.prototype._update = function () {
  3198. this._canvasSize.copyFrom(this._owner.actualSize);
  3199. // Should we update the WireFrame2D Primitive that displays the WorldAABB ?
  3200. if (this.debugRenderAABB) {
  3201. if (this._dirtyActors.count > 0 || this._debugRenderAABBDirty) {
  3202. this._updateAABBDisplay();
  3203. }
  3204. }
  3205. if (this._AABBRenderPrim) {
  3206. this._AABBRenderPrim.levelVisible = this.debugRenderAABB;
  3207. }
  3208. var cw = this._clusterSize.width;
  3209. var ch = this._clusterSize.height;
  3210. // Check for Cluster resize
  3211. if (((this._clusterSize.width < 16 && this._clusterSize.height < 16 && this._maxActorByCluster >= 10) ||
  3212. (this._clusterSize.width > 2 && this._clusterSize.height > 2 && this._maxActorByCluster <= 7)) &&
  3213. this._lastClusterResizeCounter > 100) {
  3214. if (this._maxActorByCluster >= 10) {
  3215. ++cw;
  3216. ++ch;
  3217. }
  3218. else {
  3219. --cw;
  3220. --ch;
  3221. }
  3222. console.log("Change cluster size to " + cw + ":" + ch + ", max actor " + this._maxActorByCluster);
  3223. this._clusterDirty = true;
  3224. }
  3225. // Should we update the WireFrame2D Primitive that displays the clusters
  3226. if (this.debugRenderClusters && this._clusterDirty) {
  3227. this._updateClusterDisplay(cw, ch);
  3228. }
  3229. if (this._ClusterRenderPrim) {
  3230. this._ClusterRenderPrim.levelVisible = this.debugRenderClusters;
  3231. }
  3232. var updateStats = this.debugStats && (this._dirtyActors.count > 0 || this._clusterDirty);
  3233. this._debugUpdateTime.beginMonitoring();
  3234. // If the Cluster Size changed: rebuild it and add all actors. Otherwise add only new (dirty) actors
  3235. if (this._clusterDirty) {
  3236. this._initializeCluster(cw, ch);
  3237. this._rebuildAllActors();
  3238. }
  3239. else {
  3240. this._rebuildDirtyActors();
  3241. ++this._lastClusterResizeCounter;
  3242. }
  3243. // Proceed to the collision detection between primitives
  3244. this._collisionDetection();
  3245. this._debugUpdateTime.endMonitoring();
  3246. if (updateStats) {
  3247. this._updateDebugStats();
  3248. }
  3249. if (this._debugTextBackground) {
  3250. this._debugTextBackground.levelVisible = updateStats;
  3251. }
  3252. // Reset the dirty actor list: everything is processed
  3253. this._dirtyActors.clear();
  3254. };
  3255. Object.defineProperty(BasicPrimitiveCollisionManager.prototype, "debugRenderAABB", {
  3256. /**
  3257. * Renders the World AABB of all Actors
  3258. */
  3259. get: function () {
  3260. return this._debugRenderAABB;
  3261. },
  3262. set: function (val) {
  3263. if (this._debugRenderAABB === val) {
  3264. return;
  3265. }
  3266. this._debugRenderAABB = val;
  3267. this._debugRenderAABBDirty = true;
  3268. },
  3269. enumerable: true,
  3270. configurable: true
  3271. });
  3272. Object.defineProperty(BasicPrimitiveCollisionManager.prototype, "intersectedActors", {
  3273. get: function () {
  3274. return this._intersectedActors;
  3275. },
  3276. enumerable: true,
  3277. configurable: true
  3278. });
  3279. Object.defineProperty(BasicPrimitiveCollisionManager.prototype, "leftBorderIntersectedActors", {
  3280. get: function () {
  3281. return this._borderIntersecteddActors[0];
  3282. },
  3283. enumerable: true,
  3284. configurable: true
  3285. });
  3286. Object.defineProperty(BasicPrimitiveCollisionManager.prototype, "bottomBorderIntersectedActors", {
  3287. get: function () {
  3288. return this._borderIntersecteddActors[1];
  3289. },
  3290. enumerable: true,
  3291. configurable: true
  3292. });
  3293. Object.defineProperty(BasicPrimitiveCollisionManager.prototype, "rightBorderIntersectedActors", {
  3294. get: function () {
  3295. return this._borderIntersecteddActors[2];
  3296. },
  3297. enumerable: true,
  3298. configurable: true
  3299. });
  3300. Object.defineProperty(BasicPrimitiveCollisionManager.prototype, "topBorderIntersectedActors", {
  3301. get: function () {
  3302. return this._borderIntersecteddActors[3];
  3303. },
  3304. enumerable: true,
  3305. configurable: true
  3306. });
  3307. BasicPrimitiveCollisionManager.prototype._initializeCluster = function (countW, countH) {
  3308. // Check for free
  3309. if (this._clusters) {
  3310. for (var w = 0; w < this._clusterSize.height; w++) {
  3311. for (var h = 0; h < this._clusterSize.width; h++) {
  3312. this._freeClusterInfo(this._clusters[w][h]);
  3313. }
  3314. }
  3315. }
  3316. // Allocate
  3317. this._clusterSize.copyFromFloats(countW, countH);
  3318. this._clusters = [];
  3319. for (var w = 0; w < this._clusterSize.height; w++) {
  3320. this._clusters[w] = [];
  3321. for (var h = 0; h < this._clusterSize.width; h++) {
  3322. var ci = this._allocClusterInfo();
  3323. this._clusters[w][h] = ci;
  3324. }
  3325. }
  3326. this._clusterStep.copyFromFloats(this._owner.actualWidth / countW, this._owner.actualHeight / countH);
  3327. this._maxActorByCluster = 0;
  3328. this._lastClusterResizeCounter = 0;
  3329. this._clusterDirty = false;
  3330. };
  3331. BasicPrimitiveCollisionManager.prototype._rebuildAllActors = function () {
  3332. var _this = this;
  3333. this._actors.forEach(function (k, ai) {
  3334. _this._processActor(ai);
  3335. });
  3336. };
  3337. BasicPrimitiveCollisionManager.prototype._rebuildDirtyActors = function () {
  3338. var _this = this;
  3339. this._dirtyActors.forEach(function (k, ai) {
  3340. _this._processActor(ai);
  3341. });
  3342. };
  3343. BasicPrimitiveCollisionManager.prototype._processActor = function (actor) {
  3344. var _this = this;
  3345. // Check if the actor is being disabled or removed
  3346. if (!actor.isEnabled || actor.isRemoved) {
  3347. actor.presentInClusters.forEach(function (k, ci) {
  3348. ci.actors.remove(actor.prim.uid);
  3349. });
  3350. actor.presentInClusters.clear();
  3351. return;
  3352. }
  3353. var wab = actor.worldAABB;
  3354. // Build the worldAABB corners
  3355. var wac = BasicPrimitiveCollisionManager.WAABBCorners;
  3356. wac[0].copyFromFloats(wab.x, wab.y); // Bottom/Left
  3357. wac[1].copyFromFloats(wab.z, wab.y); // Bottom/Right
  3358. wac[2].copyFromFloats(wab.z, wab.w); // Top/Right
  3359. wac[3].copyFromFloats(wab.x, wab.w); // Top/Left
  3360. var cs = this._clusterStep;
  3361. var wacc = BasicPrimitiveCollisionManager.WAABBCornersCluster;
  3362. for (var i = 0; i < 4; i++) {
  3363. var p = wac[i];
  3364. var cx = (p.x - (p.x % cs.x)) / cs.x;
  3365. var cy = (p.y - (p.y % cs.y)) / cs.y;
  3366. wacc[i].copyFromFloats(Math.floor(cx), Math.floor(cy));
  3367. }
  3368. var opCount = 0;
  3369. var totalClusters = 0;
  3370. var newCI = new Array();
  3371. var sx = Math.max(0, wacc[0].x); // Start Cluster X
  3372. var sy = Math.max(0, wacc[0].y); // Start Cluster Y
  3373. var ex = Math.min(this._clusterSize.width - 1, wacc[2].x); // End Cluster X
  3374. var ey = Math.min(this._clusterSize.height - 1, wacc[2].y); // End Cluster Y
  3375. if (this._enableBorder) {
  3376. if (wac[0].x < 0) {
  3377. this._borderIntersecteddActors[0].add(actor.prim.uid, actor.prim);
  3378. }
  3379. else {
  3380. this._borderIntersecteddActors[0].remove(actor.prim.uid);
  3381. }
  3382. if (wac[0].y < 0) {
  3383. this._borderIntersecteddActors[1].add(actor.prim.uid, actor.prim);
  3384. }
  3385. else {
  3386. this._borderIntersecteddActors[1].remove(actor.prim.uid);
  3387. }
  3388. if (wac[2].x >= this._canvasSize.width) {
  3389. this._borderIntersecteddActors[2].add(actor.prim.uid, actor.prim);
  3390. }
  3391. else {
  3392. this._borderIntersecteddActors[2].remove(actor.prim.uid);
  3393. }
  3394. if (wac[2].y >= this._canvasSize.height) {
  3395. this._borderIntersecteddActors[3].add(actor.prim.uid, actor.prim);
  3396. }
  3397. else {
  3398. this._borderIntersecteddActors[3].remove(actor.prim.uid);
  3399. }
  3400. }
  3401. for (var y = sy; y <= ey; y++) {
  3402. var _loop_1 = function (x) {
  3403. var k = x + ":" + y;
  3404. var cx = x, cy = y;
  3405. var ci = actor.presentInClusters.getOrAddWithFactory(k, function (k) {
  3406. var nci = _this._getCluster(cx, cy);
  3407. nci.actors.add(actor.prim.uid, actor);
  3408. _this._maxActorByCluster = Math.max(_this._maxActorByCluster, nci.actors.count);
  3409. ++opCount;
  3410. ++totalClusters;
  3411. return nci;
  3412. });
  3413. newCI.push(ci);
  3414. };
  3415. for (var x = sx; x <= ex; x++) {
  3416. _loop_1(x);
  3417. }
  3418. }
  3419. // Check if there were no change
  3420. if (opCount === 0 && actor.presentInClusters.count === totalClusters) {
  3421. return;
  3422. }
  3423. // Build the array of the cluster where the actor is no longer in
  3424. var clusterToRemove = new Array();
  3425. actor.presentInClusters.forEach(function (k, ci) {
  3426. if (newCI.indexOf(ci) === -1) {
  3427. clusterToRemove.push(k);
  3428. // remove the primitive from the Cluster Info object
  3429. ci.actors.remove(actor.prim.uid);
  3430. }
  3431. });
  3432. // Remove these clusters from the actor's dictionary
  3433. for (var _i = 0, clusterToRemove_1 = clusterToRemove; _i < clusterToRemove_1.length; _i++) {
  3434. var key = clusterToRemove_1[_i];
  3435. actor.presentInClusters.remove(key);
  3436. }
  3437. };
  3438. // The algorithm is simple, we have previously partitioned the Actors in the Clusters: each actor has a list of the Cluster(s) it's inside.
  3439. // Then for a given Actor that is dirty we evaluate the intersection with all the other actors present in the same Cluster(s)
  3440. // So it's basically O(n²), BUT only inside a Cluster and only for dirty Actors.
  3441. BasicPrimitiveCollisionManager.prototype._collisionDetection = function () {
  3442. var _this = this;
  3443. var hash = BasicPrimitiveCollisionManager.CandidatesActors;
  3444. var prev = BasicPrimitiveCollisionManager.PreviousIntersections;
  3445. var opCount = 0;
  3446. this._dirtyActors.forEach(function (k1, ai1) {
  3447. ++opCount;
  3448. // Build the list of candidates
  3449. hash.clear();
  3450. ai1.presentInClusters.forEach(function (k, ci) {
  3451. ++opCount;
  3452. ci.actors.forEach(function (k, v) { return hash.add(k, v); });
  3453. });
  3454. var wab1 = ai1.worldAABB;
  3455. // Save the previous intersections
  3456. prev.clear();
  3457. prev.copyFrom(ai1.intersectWith);
  3458. ai1.intersectWith.clear();
  3459. // For each candidate
  3460. hash.forEach(function (k2, ai2) {
  3461. ++opCount;
  3462. // Check if we're testing against itself
  3463. if (k1 === k2) {
  3464. return;
  3465. }
  3466. var wab2 = ai2.worldAABB;
  3467. if (wab2.z >= wab1.x && wab2.x <= wab1.z && wab2.w >= wab1.y && wab2.y <= wab1.w) {
  3468. if (ai1.prim.intersectOtherPrim(ai2.prim)) {
  3469. ++opCount;
  3470. ai1.intersectWith.add(k2, ai2);
  3471. if (k1 < k2) {
  3472. _this._intersectedActors.add(k1 + ";" + k2, { a: ai1.prim, b: ai2.prim });
  3473. }
  3474. else {
  3475. _this._intersectedActors.add(k2 + ";" + k1, { a: ai2.prim, b: ai1.prim });
  3476. }
  3477. }
  3478. }
  3479. });
  3480. // Check and remove the associations that no longer exist in the main intersection list
  3481. prev.forEach(function (k, ai) {
  3482. if (!ai1.intersectWith.contains(k)) {
  3483. ++opCount;
  3484. _this._intersectedActors.remove((k < k1 ? k : k1) + ";" + (k < k1 ? k1 : k));
  3485. }
  3486. });
  3487. });
  3488. this._debugUpdateOpCount.fetchNewFrame();
  3489. this._debugUpdateOpCount.addCount(opCount, true);
  3490. };
  3491. BasicPrimitiveCollisionManager.prototype._getCluster = function (x, y) {
  3492. return this._clusters[x][y];
  3493. };
  3494. BasicPrimitiveCollisionManager.prototype._updateDebugStats = function () {
  3495. var format = function (v) { return (Math.round(v * 100) / 100).toString(); };
  3496. var txt = "Primitive Collision Stats\n" +
  3497. (" - PCM Execution Time: " + format(this._debugUpdateTime.lastSecAverage) + "ms\n") +
  3498. (" - Operation Count: " + format(this._debugUpdateOpCount.current) + ", (avg:" + format(this._debugUpdateOpCount.lastSecAverage) + ", t:" + format(this._debugUpdateOpCount.total) + ")\n") +
  3499. (" - Max Actor per Cluster: " + this._maxActorByCluster + "\n") +
  3500. (" - Intersections count: " + this.intersectedActors.count);
  3501. if (!this._debugTextBackground) {
  3502. this._debugTextBackground = new BABYLON.Rectangle2D({
  3503. id: "###DEBUG PMC STATS###", parent: this._owner, marginAlignment: "h: left, v: top", fill: "#C0404080", padding: "10", margin: "10", roundRadius: 10, children: [
  3504. new BABYLON.Text2D(txt, { id: "###DEBUG PMC TEXT###", fontName: "12pt Lucida Console" })
  3505. ]
  3506. });
  3507. }
  3508. else {
  3509. this._debugTextBackground.levelVisible = true;
  3510. var text2d = this._debugTextBackground.children[0];
  3511. text2d.text = txt;
  3512. }
  3513. };
  3514. BasicPrimitiveCollisionManager.prototype._updateAABBDisplay = function () {
  3515. var g = new BABYLON.WireFrameGroup2D("main", new BABYLON.Color4(0.5, 0.8, 1.0, 1.0));
  3516. var v = BABYLON.Vector2.Zero();
  3517. this._actors.forEach(function (k, ai) {
  3518. if (ai.isEnabled) {
  3519. var ab = ai.worldAABB;
  3520. v.x = ab.x;
  3521. v.y = ab.y;
  3522. g.startLineStrip(v);
  3523. v.x = ab.z;
  3524. g.pushVertex(v);
  3525. v.y = ab.w;
  3526. g.pushVertex(v);
  3527. v.x = ab.x;
  3528. g.pushVertex(v);
  3529. v.y = ab.y;
  3530. g.endLineStrip(v);
  3531. }
  3532. });
  3533. if (!this._AABBRenderPrim) {
  3534. this._AABBRenderPrim = new BABYLON.WireFrame2D([g], { parent: this._owner, alignToPixel: true, id: "###DEBUG PCM AABB###" });
  3535. }
  3536. else {
  3537. this._AABBRenderPrim.wireFrameGroups.set("main", g);
  3538. this._AABBRenderPrim.wireFrameGroupsDirty();
  3539. }
  3540. this._debugRenderAABBDirty = false;
  3541. };
  3542. BasicPrimitiveCollisionManager.prototype._updateClusterDisplay = function (cw, ch) {
  3543. var g = new BABYLON.WireFrameGroup2D("main", new BABYLON.Color4(0.8, 0.1, 0.5, 1.0));
  3544. var v1 = BABYLON.Vector2.Zero();
  3545. var v2 = BABYLON.Vector2.Zero();
  3546. // Vertical lines
  3547. var step = (this._owner.actualWidth - 1) / cw;
  3548. v1.y = 0;
  3549. v2.y = this._owner.actualHeight;
  3550. for (var x = 0; x <= cw; x++) {
  3551. g.pushVertex(v1);
  3552. g.pushVertex(v2);
  3553. v1.x += step;
  3554. v2.x += step;
  3555. }
  3556. // Horizontal lines
  3557. step = (this._owner.actualHeight - 1) / ch;
  3558. v1.x = v1.y = v2.y = 0;
  3559. v2.x = this._owner.actualWidth;
  3560. for (var y = 0; y <= ch; y++) {
  3561. g.pushVertex(v1);
  3562. g.pushVertex(v2);
  3563. v1.y += step;
  3564. v2.y += step;
  3565. }
  3566. if (!this._ClusterRenderPrim) {
  3567. this._ClusterRenderPrim = new BABYLON.WireFrame2D([g], { parent: this._owner, alignToPixel: true, id: "###DEBUG PCM Clusters###" });
  3568. }
  3569. else {
  3570. this._ClusterRenderPrim.wireFrameGroups.set("main", g);
  3571. this._ClusterRenderPrim.wireFrameGroupsDirty();
  3572. }
  3573. };
  3574. // Basically: we don't want to spend our time playing with the GC each time the Cluster Array is rebuilt, so we keep a list of available
  3575. // ClusterInfo object and we have two method to allocate/free them. This way we always deal with the same objects.
  3576. // The free array never shrink, always grows...For the better...and the worst!
  3577. BasicPrimitiveCollisionManager.prototype._allocClusterInfo = function () {
  3578. if (this._freeClusters.length === 0) {
  3579. for (var i = 0; i < 8; i++) {
  3580. this._freeClusters.push(new ClusterInfo());
  3581. }
  3582. }
  3583. return this._freeClusters.pop();
  3584. };
  3585. BasicPrimitiveCollisionManager.prototype._freeClusterInfo = function (ci) {
  3586. ci.clear();
  3587. this._freeClusters.push(ci);
  3588. };
  3589. return BasicPrimitiveCollisionManager;
  3590. }(PrimitiveCollisionManagerBase));
  3591. BasicPrimitiveCollisionManager.WAABBCorners = null;
  3592. BasicPrimitiveCollisionManager.WAABBCornersCluster = null;
  3593. BasicPrimitiveCollisionManager.CandidatesActors = new BABYLON.StringDictionary();
  3594. BasicPrimitiveCollisionManager.PreviousIntersections = new BABYLON.StringDictionary();
  3595. })(BABYLON || (BABYLON = {}));
  3596. //# sourceMappingURL=babylon.primitiveCollisionManager.js.map
  3597. var __extends = (this && this.__extends) || (function () {
  3598. var extendStatics = Object.setPrototypeOf ||
  3599. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  3600. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  3601. return function (d, b) {
  3602. extendStatics(d, b);
  3603. function __() { this.constructor = d; }
  3604. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  3605. };
  3606. })();
  3607. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  3608. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  3609. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  3610. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  3611. return c > 3 && r && Object.defineProperty(target, key, r), r;
  3612. };
  3613. var BABYLON;
  3614. (function (BABYLON) {
  3615. var LayoutEngineBase = (function () {
  3616. function LayoutEngineBase() {
  3617. this.layoutDirtyOnPropertyChangedMask = 0;
  3618. }
  3619. LayoutEngineBase.prototype.updateLayout = function (prim) {
  3620. };
  3621. Object.defineProperty(LayoutEngineBase.prototype, "isChildPositionAllowed", {
  3622. get: function () {
  3623. return false;
  3624. },
  3625. enumerable: true,
  3626. configurable: true
  3627. });
  3628. LayoutEngineBase.prototype.isLocked = function () {
  3629. return this._isLocked;
  3630. };
  3631. LayoutEngineBase.prototype.lock = function () {
  3632. if (this._isLocked) {
  3633. return false;
  3634. }
  3635. this._isLocked = true;
  3636. return true;
  3637. };
  3638. return LayoutEngineBase;
  3639. }());
  3640. LayoutEngineBase = __decorate([
  3641. BABYLON.className("LayoutEngineBase", "BABYLON")
  3642. /**
  3643. * This is the base class you have to extend in order to implement your own Layout Engine.
  3644. * Note that for performance reason, each different Layout Engine type can be exposed as one/many singleton or must be instanced each time.
  3645. * If data has to be associated to a given primitive you can use the SmartPropertyPrim.addExternalData API to do it.
  3646. */
  3647. ], LayoutEngineBase);
  3648. BABYLON.LayoutEngineBase = LayoutEngineBase;
  3649. var CanvasLayoutEngine = CanvasLayoutEngine_1 = (function (_super) {
  3650. __extends(CanvasLayoutEngine, _super);
  3651. function CanvasLayoutEngine() {
  3652. var _this = _super.call(this) || this;
  3653. _this.layoutDirtyOnPropertyChangedMask = BABYLON.Prim2DBase.sizeProperty.flagId | BABYLON.Prim2DBase.actualSizeProperty.flagId;
  3654. return _this;
  3655. }
  3656. Object.defineProperty(CanvasLayoutEngine, "Singleton", {
  3657. get: function () {
  3658. if (!CanvasLayoutEngine_1._singleton) {
  3659. CanvasLayoutEngine_1._singleton = new CanvasLayoutEngine_1();
  3660. }
  3661. return CanvasLayoutEngine_1._singleton;
  3662. },
  3663. enumerable: true,
  3664. configurable: true
  3665. });
  3666. // A very simple (no) layout computing...
  3667. // The Canvas and its direct children gets the Canvas' size as Layout Area
  3668. // Indirect children have their Layout Area to the actualSize (margin area) of their parent
  3669. CanvasLayoutEngine.prototype.updateLayout = function (prim) {
  3670. // If this prim is layoutDiry we update its layoutArea and also the one of its direct children
  3671. if (prim._isFlagSet(BABYLON.SmartPropertyPrim.flagLayoutDirty)) {
  3672. prim._clearFlags(BABYLON.SmartPropertyPrim.flagLayoutDirty);
  3673. for (var _i = 0, _a = prim.children; _i < _a.length; _i++) {
  3674. var child = _a[_i];
  3675. this._doUpdate(child);
  3676. }
  3677. }
  3678. };
  3679. CanvasLayoutEngine.prototype._doUpdate = function (prim) {
  3680. // Canvas ?
  3681. if (prim instanceof BABYLON.Canvas2D) {
  3682. prim.layoutArea = prim.actualSize; //.multiplyByFloats(prim.scaleX, prim.scaleY);
  3683. }
  3684. else if (prim.parent instanceof BABYLON.Canvas2D) {
  3685. prim.layoutArea = prim.owner.actualSize; //.multiplyByFloats(prim.owner.scaleX, prim.owner.scaleY);
  3686. }
  3687. else {
  3688. var contentArea = prim.parent.contentArea;
  3689. // Can be null if the parent's content area depend of its children, the computation will be done in many passes
  3690. if (contentArea) {
  3691. prim.layoutArea = contentArea;
  3692. }
  3693. }
  3694. BABYLON.C2DLogging.setPostMessage(function () { return "Prim: " + prim.id + " has layoutArea: " + prim.layoutArea; });
  3695. };
  3696. Object.defineProperty(CanvasLayoutEngine.prototype, "isChildPositionAllowed", {
  3697. get: function () {
  3698. return true;
  3699. },
  3700. enumerable: true,
  3701. configurable: true
  3702. });
  3703. return CanvasLayoutEngine;
  3704. }(LayoutEngineBase));
  3705. CanvasLayoutEngine._singleton = null;
  3706. __decorate([
  3707. BABYLON.logMethod()
  3708. ], CanvasLayoutEngine.prototype, "updateLayout", null);
  3709. __decorate([
  3710. BABYLON.logMethod()
  3711. ], CanvasLayoutEngine.prototype, "_doUpdate", null);
  3712. CanvasLayoutEngine = CanvasLayoutEngine_1 = __decorate([
  3713. BABYLON.className("CanvasLayoutEngine", "BABYLON")
  3714. /**
  3715. * The default Layout Engine, primitive are positioning into a Canvas, using their x/y coordinates.
  3716. * This layout must be used as a Singleton through the CanvasLayoutEngine.Singleton property.
  3717. */
  3718. ], CanvasLayoutEngine);
  3719. BABYLON.CanvasLayoutEngine = CanvasLayoutEngine;
  3720. var StackPanelLayoutEngine = StackPanelLayoutEngine_1 = (function (_super) {
  3721. __extends(StackPanelLayoutEngine, _super);
  3722. function StackPanelLayoutEngine() {
  3723. var _this = _super.call(this) || this;
  3724. _this._isHorizontal = true;
  3725. _this.layoutDirtyOnPropertyChangedMask = BABYLON.Prim2DBase.sizeProperty.flagId | BABYLON.Prim2DBase.actualSizeProperty.flagId;
  3726. return _this;
  3727. }
  3728. Object.defineProperty(StackPanelLayoutEngine, "Horizontal", {
  3729. get: function () {
  3730. if (!StackPanelLayoutEngine_1._horizontal) {
  3731. StackPanelLayoutEngine_1._horizontal = new StackPanelLayoutEngine_1();
  3732. StackPanelLayoutEngine_1._horizontal.isHorizontal = true;
  3733. StackPanelLayoutEngine_1._horizontal.lock();
  3734. }
  3735. return StackPanelLayoutEngine_1._horizontal;
  3736. },
  3737. enumerable: true,
  3738. configurable: true
  3739. });
  3740. Object.defineProperty(StackPanelLayoutEngine, "Vertical", {
  3741. get: function () {
  3742. if (!StackPanelLayoutEngine_1._vertical) {
  3743. StackPanelLayoutEngine_1._vertical = new StackPanelLayoutEngine_1();
  3744. StackPanelLayoutEngine_1._vertical.isHorizontal = false;
  3745. StackPanelLayoutEngine_1._vertical.lock();
  3746. }
  3747. return StackPanelLayoutEngine_1._vertical;
  3748. },
  3749. enumerable: true,
  3750. configurable: true
  3751. });
  3752. Object.defineProperty(StackPanelLayoutEngine.prototype, "isHorizontal", {
  3753. get: function () {
  3754. return this._isHorizontal;
  3755. },
  3756. set: function (val) {
  3757. if (this.isLocked()) {
  3758. return;
  3759. }
  3760. this._isHorizontal = val;
  3761. },
  3762. enumerable: true,
  3763. configurable: true
  3764. });
  3765. StackPanelLayoutEngine.prototype.updateLayout = function (prim) {
  3766. if (prim._isFlagSet(BABYLON.SmartPropertyPrim.flagLayoutDirty)) {
  3767. var primLayoutArea = prim.layoutArea;
  3768. var isSizeAuto = prim.isSizeAuto;
  3769. // If we're not in autoSize the layoutArea of the prim having the stack panel must be computed in order for us to compute the children' position.
  3770. // If there's at least one auto size (Horizontal or Vertical) we will have to figure the layoutArea ourselves
  3771. if (!primLayoutArea && !isSizeAuto) {
  3772. return;
  3773. }
  3774. // console.log("Compute Stack Panel Layout " + ++StackPanelLayoutEngine.computeCounter);
  3775. var x = 0;
  3776. var y = 0;
  3777. var horizonStackPanel = this.isHorizontal;
  3778. // If the stack panel is horizontal we check if the primitive height is auto or not, if it's auto then we have to compute the required height, otherwise we just take the actualHeight. If the stack panel is vertical we do the same but with width
  3779. var max = 0;
  3780. var stackPanelLayoutArea = StackPanelLayoutEngine_1.stackPanelLayoutArea;
  3781. if (horizonStackPanel) {
  3782. if (prim.isVerticalSizeAuto) {
  3783. max = 0;
  3784. stackPanelLayoutArea.height = 0;
  3785. }
  3786. else {
  3787. max = prim.layoutArea.height;
  3788. stackPanelLayoutArea.height = prim.layoutArea.height;
  3789. stackPanelLayoutArea.width = 0;
  3790. }
  3791. }
  3792. else {
  3793. if (prim.isHorizontalSizeAuto) {
  3794. max = 0;
  3795. stackPanelLayoutArea.width = 0;
  3796. }
  3797. else {
  3798. max = prim.layoutArea.width;
  3799. stackPanelLayoutArea.width = prim.layoutArea.width;
  3800. stackPanelLayoutArea.height = 0;
  3801. }
  3802. }
  3803. for (var _i = 0, _a = prim.children; _i < _a.length; _i++) {
  3804. var child = _a[_i];
  3805. if (child._isFlagSet(BABYLON.SmartPropertyPrim.flagNoPartOfLayout)) {
  3806. continue;
  3807. }
  3808. if (child._hasMargin) {
  3809. // Calling computeWithAlignment will return us the area taken by "child" which is its layoutArea
  3810. // We also have the dstOffset which will give us the y position in horizontal mode or x position in vertical mode.
  3811. // The alignment offset on the other axis is simply ignored as it doesn't make any sense (e.g. horizontal alignment is ignored in horizontal mode)
  3812. child.margin.computeWithAlignment(stackPanelLayoutArea, child.actualSize, child.marginAlignment, child.actualScale, StackPanelLayoutEngine_1.dstOffset, StackPanelLayoutEngine_1.dstArea, true);
  3813. child.layoutArea = StackPanelLayoutEngine_1.dstArea;
  3814. }
  3815. else {
  3816. child.margin.computeArea(child.actualSize, child.actualScale, StackPanelLayoutEngine_1.dstArea);
  3817. child.layoutArea = StackPanelLayoutEngine_1.dstArea;
  3818. }
  3819. max = Math.max(max, horizonStackPanel ? StackPanelLayoutEngine_1.dstArea.height : StackPanelLayoutEngine_1.dstArea.width);
  3820. }
  3821. for (var _b = 0, _c = prim.children; _b < _c.length; _b++) {
  3822. var child = _c[_b];
  3823. if (child._isFlagSet(BABYLON.SmartPropertyPrim.flagNoPartOfLayout)) {
  3824. continue;
  3825. }
  3826. var layoutArea = child.layoutArea;
  3827. if (horizonStackPanel) {
  3828. child.layoutAreaPos = new BABYLON.Vector2(x, 0);
  3829. x += layoutArea.width;
  3830. child.layoutArea = new BABYLON.Size(layoutArea.width, max);
  3831. }
  3832. else {
  3833. child.layoutAreaPos = new BABYLON.Vector2(0, y);
  3834. y += layoutArea.height;
  3835. child.layoutArea = new BABYLON.Size(max, layoutArea.height);
  3836. }
  3837. }
  3838. prim._clearFlags(BABYLON.SmartPropertyPrim.flagLayoutDirty);
  3839. }
  3840. };
  3841. Object.defineProperty(StackPanelLayoutEngine.prototype, "isChildPositionAllowed", {
  3842. get: function () {
  3843. return false;
  3844. },
  3845. enumerable: true,
  3846. configurable: true
  3847. });
  3848. return StackPanelLayoutEngine;
  3849. }(LayoutEngineBase));
  3850. StackPanelLayoutEngine._horizontal = null;
  3851. StackPanelLayoutEngine._vertical = null;
  3852. StackPanelLayoutEngine.stackPanelLayoutArea = BABYLON.Size.Zero();
  3853. StackPanelLayoutEngine.dstOffset = BABYLON.Vector4.Zero();
  3854. StackPanelLayoutEngine.dstArea = BABYLON.Size.Zero();
  3855. StackPanelLayoutEngine.computeCounter = 0;
  3856. StackPanelLayoutEngine = StackPanelLayoutEngine_1 = __decorate([
  3857. BABYLON.className("StackPanelLayoutEngine", "BABYLON")
  3858. /**
  3859. * A stack panel layout. Primitive will be stack either horizontally or vertically.
  3860. * This Layout type must be used as a Singleton, use the StackPanelLayoutEngine.Horizontal for an horizontal stack panel or StackPanelLayoutEngine.Vertical for a vertical one.
  3861. */
  3862. ], StackPanelLayoutEngine);
  3863. BABYLON.StackPanelLayoutEngine = StackPanelLayoutEngine;
  3864. /**
  3865. * GridData is used specify what row(s) and column(s) a primitive is placed in when its parent is using a Grid Panel Layout.
  3866. */
  3867. var GridData = (function () {
  3868. /**
  3869. * Create a Grid Data that describes where a primitive will be placed in a Grid Panel Layout.
  3870. * @param row the row number of the grid
  3871. * @param column the column number of the grid
  3872. * @param rowSpan the number of rows a primitive will occupy
  3873. * @param columnSpan the number of columns a primitive will occupy
  3874. **/
  3875. function GridData(row, column, rowSpan, columnSpan) {
  3876. this.row = row;
  3877. this.column = column;
  3878. this.rowSpan = (rowSpan == null) ? 1 : rowSpan;
  3879. this.columnSpan = (columnSpan == null) ? 1 : columnSpan;
  3880. }
  3881. return GridData;
  3882. }());
  3883. BABYLON.GridData = GridData;
  3884. var GridDimensionDefinition = (function () {
  3885. function GridDimensionDefinition() {
  3886. }
  3887. GridDimensionDefinition.prototype._parse = function (value, res) {
  3888. var v = value.toLocaleLowerCase().trim();
  3889. if (v.indexOf("auto") === 0) {
  3890. res(null, null, GridDimensionDefinition.Auto);
  3891. }
  3892. else if (v.indexOf("*") !== -1) {
  3893. var i = v.indexOf("*");
  3894. var w = 1;
  3895. if (i > 0) {
  3896. w = parseFloat(v.substr(0, i));
  3897. }
  3898. res(w, null, GridDimensionDefinition.Stars);
  3899. }
  3900. else {
  3901. var w = parseFloat(v);
  3902. res(w, w, GridDimensionDefinition.Pixels);
  3903. }
  3904. };
  3905. return GridDimensionDefinition;
  3906. }());
  3907. GridDimensionDefinition.Pixels = 1;
  3908. GridDimensionDefinition.Stars = 2;
  3909. GridDimensionDefinition.Auto = 3;
  3910. var RowDefinition = (function (_super) {
  3911. __extends(RowDefinition, _super);
  3912. function RowDefinition() {
  3913. return _super !== null && _super.apply(this, arguments) || this;
  3914. }
  3915. return RowDefinition;
  3916. }(GridDimensionDefinition));
  3917. var ColumnDefinition = (function (_super) {
  3918. __extends(ColumnDefinition, _super);
  3919. function ColumnDefinition() {
  3920. return _super !== null && _super.apply(this, arguments) || this;
  3921. }
  3922. return ColumnDefinition;
  3923. }(GridDimensionDefinition));
  3924. var GridPanelLayoutEngine = GridPanelLayoutEngine_1 = (function (_super) {
  3925. __extends(GridPanelLayoutEngine, _super);
  3926. function GridPanelLayoutEngine(settings) {
  3927. var _this = _super.call(this) || this;
  3928. _this._children = [];
  3929. _this._rowBottoms = [];
  3930. _this._columnLefts = [];
  3931. _this._rowHeights = [];
  3932. _this._columnWidths = [];
  3933. _this.layoutDirtyOnPropertyChangedMask = BABYLON.Prim2DBase.sizeProperty.flagId | BABYLON.Prim2DBase.actualSizeProperty.flagId;
  3934. _this._rows = new Array();
  3935. _this._columns = new Array();
  3936. if (settings.rows) {
  3937. var _loop_1 = function (row) {
  3938. var r = new RowDefinition();
  3939. r._parse(row.height, function (v, vp, t) {
  3940. r.height = v;
  3941. r.heightPixels = vp;
  3942. r.heightType = t;
  3943. });
  3944. this_1._rows.push(r);
  3945. };
  3946. var this_1 = this;
  3947. for (var _i = 0, _a = settings.rows; _i < _a.length; _i++) {
  3948. var row = _a[_i];
  3949. _loop_1(row);
  3950. }
  3951. }
  3952. if (settings.columns) {
  3953. var _loop_2 = function (col) {
  3954. var r = new ColumnDefinition();
  3955. r._parse(col.width, function (v, vp, t) {
  3956. r.width = v;
  3957. r.widthPixels = vp;
  3958. r.widthType = t;
  3959. });
  3960. this_2._columns.push(r);
  3961. };
  3962. var this_2 = this;
  3963. for (var _b = 0, _c = settings.columns; _b < _c.length; _b++) {
  3964. var col = _c[_b];
  3965. _loop_2(col);
  3966. }
  3967. }
  3968. return _this;
  3969. }
  3970. GridPanelLayoutEngine.prototype.updateLayout = function (prim) {
  3971. if (prim._isFlagSet(BABYLON.SmartPropertyPrim.flagLayoutDirty)) {
  3972. if (!prim.layoutArea) {
  3973. return;
  3974. }
  3975. for (var _i = 0, _a = prim.children; _i < _a.length; _i++) {
  3976. var child = _a[_i];
  3977. if (child._isFlagSet(BABYLON.SmartPropertyPrim.flagNoPartOfLayout)) {
  3978. continue;
  3979. }
  3980. if (child._hasMargin) {
  3981. child.margin.computeWithAlignment(prim.layoutArea, child.actualSize, child.marginAlignment, child.actualScale, GridPanelLayoutEngine_1.dstOffset, GridPanelLayoutEngine_1.dstArea, true);
  3982. }
  3983. else {
  3984. child.margin.computeArea(child.actualSize, child.actualScale, GridPanelLayoutEngine_1.dstArea);
  3985. }
  3986. child.layoutArea = GridPanelLayoutEngine_1.dstArea;
  3987. }
  3988. this._updateGrid(prim);
  3989. var _children = this._children;
  3990. var rl = this._rows.length;
  3991. var cl = this._columns.length;
  3992. var columnWidth = 0;
  3993. var rowHeight = 0;
  3994. var dstArea = GridPanelLayoutEngine_1.dstArea;
  3995. var dstAreaPos = GridPanelLayoutEngine_1.dstAreaPos;
  3996. for (var i = 0; i < _children.length; i++) {
  3997. var children = _children[i];
  3998. if (children) {
  3999. var bottom = this._rowBottoms[i];
  4000. var rowHeight_1 = this._rowHeights[i];
  4001. var oBottom = bottom;
  4002. var oRowHeight = rowHeight_1;
  4003. for (var j = 0; j < children.length; j++) {
  4004. var left = this._columnLefts[j];
  4005. var columnWidth_1 = this._columnWidths[j];
  4006. var child = children[j];
  4007. if (child) {
  4008. var gd = child.layoutData;
  4009. if (gd.columnSpan > 1) {
  4010. for (var k = j + 1; k < gd.columnSpan + j && k < cl; k++) {
  4011. columnWidth_1 += this._columnWidths[k];
  4012. }
  4013. }
  4014. if (gd.rowSpan > 1) {
  4015. for (var k = i + 1; k < gd.rowSpan + i && k < rl; k++) {
  4016. rowHeight_1 += this._rowHeights[k];
  4017. bottom = this._rowBottoms[k];
  4018. }
  4019. }
  4020. dstArea.width = columnWidth_1;
  4021. dstArea.height = rowHeight_1;
  4022. child.layoutArea = dstArea;
  4023. dstAreaPos.x = left;
  4024. dstAreaPos.y = bottom;
  4025. child.layoutAreaPos = dstAreaPos;
  4026. bottom = oBottom;
  4027. rowHeight_1 = oRowHeight;
  4028. }
  4029. }
  4030. }
  4031. }
  4032. prim._clearFlags(BABYLON.SmartPropertyPrim.flagLayoutDirty);
  4033. }
  4034. };
  4035. Object.defineProperty(GridPanelLayoutEngine.prototype, "isChildPositionAllowed", {
  4036. get: function () {
  4037. return false;
  4038. },
  4039. enumerable: true,
  4040. configurable: true
  4041. });
  4042. GridPanelLayoutEngine.prototype._getMaxChildHeightInRow = function (rowNum) {
  4043. var rows = this._rows;
  4044. var cl = this._columns.length;
  4045. var rl = this._rows.length;
  4046. var children = this._children;
  4047. var row = rows[rowNum];
  4048. var maxHeight = 0;
  4049. if (children && children[rowNum]) {
  4050. for (var i = 0; i < cl; i++) {
  4051. var child = children[rowNum][i];
  4052. if (child) {
  4053. var span = child.layoutData.rowSpan;
  4054. if (maxHeight < child.layoutArea.height / span) {
  4055. maxHeight = child.layoutArea.height / span;
  4056. }
  4057. }
  4058. }
  4059. }
  4060. return maxHeight;
  4061. };
  4062. GridPanelLayoutEngine.prototype._getMaxChildWidthInColumn = function (colNum) {
  4063. var columns = this._columns;
  4064. var cl = this._columns.length;
  4065. var rl = this._rows.length;
  4066. var children = this._children;
  4067. var column = columns[colNum];
  4068. var maxWidth = 0;
  4069. if (children) {
  4070. for (var i = 0; i < rl; i++) {
  4071. if (children[i]) {
  4072. var child = children[i][colNum];
  4073. if (child) {
  4074. var span = child.layoutData.columnSpan;
  4075. if (maxWidth < child.layoutArea.width / span) {
  4076. maxWidth = child.layoutArea.width / span;
  4077. }
  4078. }
  4079. }
  4080. }
  4081. }
  4082. return maxWidth;
  4083. };
  4084. GridPanelLayoutEngine.prototype._updateGrid = function (prim) {
  4085. var _children = this._children;
  4086. //remove prim.children from _children
  4087. for (var i_1 = 0; i_1 < _children.length; i_1++) {
  4088. var children = _children[i_1];
  4089. if (children) {
  4090. children.length = 0;
  4091. }
  4092. }
  4093. var childrenThatSpan;
  4094. //add prim.children to _children
  4095. for (var _i = 0, _a = prim.children; _i < _a.length; _i++) {
  4096. var child = _a[_i];
  4097. if (!child.layoutData) {
  4098. continue;
  4099. }
  4100. var gd = child.layoutData;
  4101. if (!_children[gd.row]) {
  4102. _children[gd.row] = [];
  4103. }
  4104. if (gd.columnSpan == 1 && gd.rowSpan == 1) {
  4105. _children[gd.row][gd.column] = child;
  4106. }
  4107. else {
  4108. if (!childrenThatSpan) {
  4109. childrenThatSpan = [];
  4110. }
  4111. //when children span, we need to add them to _children whereever they span to so that
  4112. //_getMaxChildHeightInRow and _getMaxChildWidthInColumn will work correctly.
  4113. childrenThatSpan.push(child);
  4114. for (var i_2 = gd.row; i_2 < gd.row + gd.rowSpan; i_2++) {
  4115. for (var j = gd.column; j < gd.column + gd.columnSpan; j++) {
  4116. _children[i_2][j] = child;
  4117. }
  4118. }
  4119. }
  4120. }
  4121. var rows = this._rows;
  4122. var columns = this._columns;
  4123. var rl = this._rows.length;
  4124. var cl = this._columns.length;
  4125. //get fixed and auto row heights first
  4126. var starIndexes = [];
  4127. var totalStars = 0;
  4128. var rowHeights = 0;
  4129. var columnWidths = 0;
  4130. for (var i_3 = 0; i_3 < rl; i_3++) {
  4131. var row = this._rows[i_3];
  4132. if (row.heightType == GridDimensionDefinition.Auto) {
  4133. this._rowHeights[i_3] = this._getMaxChildHeightInRow(i_3);
  4134. rowHeights += this._rowHeights[i_3];
  4135. }
  4136. else if (row.heightType == GridDimensionDefinition.Pixels) {
  4137. var maxChildHeight = this._getMaxChildHeightInRow(i_3);
  4138. this._rowHeights[i_3] = Math.max(row.heightPixels, maxChildHeight);
  4139. rowHeights += this._rowHeights[i_3];
  4140. }
  4141. else if (row.heightType == GridDimensionDefinition.Stars) {
  4142. starIndexes.push(i_3);
  4143. totalStars += row.height;
  4144. }
  4145. }
  4146. //star row heights
  4147. if (starIndexes.length > 0) {
  4148. var remainingHeight = prim.contentArea.height - rowHeights;
  4149. for (var i_4 = 0; i_4 < starIndexes.length; i_4++) {
  4150. var rowIndex = starIndexes[i_4];
  4151. var starHeight = (this._rows[rowIndex].height / totalStars) * remainingHeight;
  4152. var maxChildHeight = this._getMaxChildHeightInRow(i_4);
  4153. this._rowHeights[rowIndex] = Math.max(starHeight, maxChildHeight);
  4154. }
  4155. }
  4156. //get fixed and auto column widths
  4157. starIndexes.length = 0;
  4158. totalStars = 0;
  4159. for (var i_5 = 0; i_5 < cl; i_5++) {
  4160. var column = this._columns[i_5];
  4161. if (column.widthType == GridDimensionDefinition.Auto) {
  4162. this._columnWidths[i_5] = this._getMaxChildWidthInColumn(i_5);
  4163. columnWidths += this._columnWidths[i_5];
  4164. }
  4165. else if (column.widthType == GridDimensionDefinition.Pixels) {
  4166. var maxChildWidth = this._getMaxChildWidthInColumn(i_5);
  4167. this._columnWidths[i_5] = Math.max(column.widthPixels, maxChildWidth);
  4168. columnWidths += this._columnWidths[i_5];
  4169. }
  4170. else if (column.widthType == GridDimensionDefinition.Stars) {
  4171. starIndexes.push(i_5);
  4172. totalStars += column.width;
  4173. }
  4174. }
  4175. //star column widths
  4176. if (starIndexes.length > 0) {
  4177. var remainingWidth = prim.contentArea.width - columnWidths;
  4178. for (var i_6 = 0; i_6 < starIndexes.length; i_6++) {
  4179. var columnIndex = starIndexes[i_6];
  4180. var starWidth = (this._columns[columnIndex].width / totalStars) * remainingWidth;
  4181. var maxChildWidth = this._getMaxChildWidthInColumn(i_6);
  4182. this._columnWidths[columnIndex] = Math.max(starWidth, maxChildWidth);
  4183. }
  4184. }
  4185. var y = 0;
  4186. this._rowBottoms[rl - 1] = y;
  4187. for (var i_7 = rl - 2; i_7 >= 0; i_7--) {
  4188. y += this._rowHeights[i_7 + 1];
  4189. this._rowBottoms[i_7] = y;
  4190. }
  4191. var x = 0;
  4192. this._columnLefts[0] = x;
  4193. for (var i_8 = 1; i_8 < cl; i_8++) {
  4194. x += this._columnWidths[i_8 - 1];
  4195. this._columnLefts[i_8] = x;
  4196. }
  4197. //remove duplicate references to children that span
  4198. if (childrenThatSpan) {
  4199. for (var i = 0; i < childrenThatSpan.length; i++) {
  4200. var child = childrenThatSpan[i];
  4201. var gd = child.layoutData;
  4202. for (var i_9 = gd.row; i_9 < gd.row + gd.rowSpan; i_9++) {
  4203. for (var j = gd.column; j < gd.column + gd.columnSpan; j++) {
  4204. if (i_9 == gd.row && j == gd.column) {
  4205. continue;
  4206. }
  4207. if (_children[i_9][j] == child) {
  4208. _children[i_9][j] = null;
  4209. }
  4210. }
  4211. }
  4212. }
  4213. }
  4214. };
  4215. return GridPanelLayoutEngine;
  4216. }(LayoutEngineBase));
  4217. GridPanelLayoutEngine.dstOffset = BABYLON.Vector4.Zero();
  4218. GridPanelLayoutEngine.dstArea = BABYLON.Size.Zero();
  4219. GridPanelLayoutEngine.dstAreaPos = BABYLON.Vector2.Zero();
  4220. GridPanelLayoutEngine = GridPanelLayoutEngine_1 = __decorate([
  4221. BABYLON.className("GridPanelLayoutEngine", "BABYLON")
  4222. /**
  4223. * A grid panel layout. Grid panel is a table that has rows and columns.
  4224. * When adding children to a primitive that is using grid panel layout, you must assign a GridData object to the child to indicate where the child will appear in the grid.
  4225. */
  4226. ], GridPanelLayoutEngine);
  4227. BABYLON.GridPanelLayoutEngine = GridPanelLayoutEngine;
  4228. var CanvasLayoutEngine_1, StackPanelLayoutEngine_1, GridPanelLayoutEngine_1;
  4229. })(BABYLON || (BABYLON = {}));
  4230. //# sourceMappingURL=babylon.canvas2dLayoutEngine.js.map
  4231. var __extends = (this && this.__extends) || (function () {
  4232. var extendStatics = Object.setPrototypeOf ||
  4233. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  4234. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  4235. return function (d, b) {
  4236. extendStatics(d, b);
  4237. function __() { this.constructor = d; }
  4238. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  4239. };
  4240. })();
  4241. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  4242. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  4243. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  4244. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  4245. return c > 3 && r && Object.defineProperty(target, key, r), r;
  4246. };
  4247. var BABYLON;
  4248. (function (BABYLON) {
  4249. /**
  4250. * Base class implementing the ILocable interface.
  4251. * The particularity of this class is to call the protected onLock() method when the instance is about to be locked for good.
  4252. */
  4253. var LockableBase = (function () {
  4254. function LockableBase() {
  4255. }
  4256. LockableBase.prototype.isLocked = function () {
  4257. return this._isLocked;
  4258. };
  4259. LockableBase.prototype.lock = function () {
  4260. if (this._isLocked) {
  4261. return true;
  4262. }
  4263. this.onLock();
  4264. this._isLocked = true;
  4265. return false;
  4266. };
  4267. /**
  4268. * Protected handler that will be called when the instance is about to be locked.
  4269. */
  4270. LockableBase.prototype.onLock = function () {
  4271. };
  4272. return LockableBase;
  4273. }());
  4274. BABYLON.LockableBase = LockableBase;
  4275. var SolidColorBrush2D = (function (_super) {
  4276. __extends(SolidColorBrush2D, _super);
  4277. function SolidColorBrush2D(color, lock) {
  4278. if (lock === void 0) { lock = false; }
  4279. var _this = _super.call(this) || this;
  4280. _this._color = color;
  4281. if (lock) {
  4282. {
  4283. _this.lock();
  4284. }
  4285. }
  4286. return _this;
  4287. }
  4288. /**
  4289. * Return true if the brush is transparent, false if it's totally opaque
  4290. */
  4291. SolidColorBrush2D.prototype.isTransparent = function () {
  4292. return this._color && this._color.a < 1.0;
  4293. };
  4294. Object.defineProperty(SolidColorBrush2D.prototype, "color", {
  4295. /**
  4296. * The color used by this instance to render
  4297. * @returns the color object. Note that it's not a clone of the actual object stored in the instance so you MUST NOT modify it, otherwise unexpected behavior might occurs.
  4298. */
  4299. get: function () {
  4300. return this._color;
  4301. },
  4302. set: function (value) {
  4303. if (this.isLocked()) {
  4304. return;
  4305. }
  4306. this._color = value;
  4307. },
  4308. enumerable: true,
  4309. configurable: true
  4310. });
  4311. /**
  4312. * Return a unique identifier of the instance, which is simply the hexadecimal representation (CSS Style) of the solid color.
  4313. */
  4314. SolidColorBrush2D.prototype.toString = function () {
  4315. return this._color.toHexString();
  4316. };
  4317. return SolidColorBrush2D;
  4318. }(LockableBase));
  4319. SolidColorBrush2D = __decorate([
  4320. BABYLON.className("SolidColorBrush2D", "BABYLON")
  4321. /**
  4322. * This class implements a Brush that will be drawn with a uniform solid color (i.e. the same color everywhere in the content where the brush is assigned to).
  4323. */
  4324. ], SolidColorBrush2D);
  4325. BABYLON.SolidColorBrush2D = SolidColorBrush2D;
  4326. var GradientColorBrush2D = (function (_super) {
  4327. __extends(GradientColorBrush2D, _super);
  4328. function GradientColorBrush2D(color1, color2, translation, rotation, scale, lock) {
  4329. if (translation === void 0) { translation = BABYLON.Vector2.Zero(); }
  4330. if (rotation === void 0) { rotation = 0; }
  4331. if (scale === void 0) { scale = 1; }
  4332. if (lock === void 0) { lock = false; }
  4333. var _this = _super.call(this) || this;
  4334. _this._color1 = color1;
  4335. _this._color2 = color2;
  4336. _this._translation = translation;
  4337. _this._rotation = rotation;
  4338. _this._scale = scale;
  4339. if (lock) {
  4340. _this.lock();
  4341. }
  4342. return _this;
  4343. }
  4344. /**
  4345. * Return true if the brush is transparent, false if it's totally opaque
  4346. */
  4347. GradientColorBrush2D.prototype.isTransparent = function () {
  4348. return (this._color1 && this._color1.a < 1.0) || (this._color2 && this._color2.a < 1.0);
  4349. };
  4350. Object.defineProperty(GradientColorBrush2D.prototype, "color1", {
  4351. /**
  4352. * First color, the blend will start from this color
  4353. */
  4354. get: function () {
  4355. return this._color1;
  4356. },
  4357. set: function (value) {
  4358. if (this.isLocked()) {
  4359. return;
  4360. }
  4361. this._color1 = value;
  4362. },
  4363. enumerable: true,
  4364. configurable: true
  4365. });
  4366. Object.defineProperty(GradientColorBrush2D.prototype, "color2", {
  4367. /**
  4368. * Second color, the blend will end to this color
  4369. */
  4370. get: function () {
  4371. return this._color2;
  4372. },
  4373. set: function (value) {
  4374. if (this.isLocked()) {
  4375. return;
  4376. }
  4377. this._color2 = value;
  4378. },
  4379. enumerable: true,
  4380. configurable: true
  4381. });
  4382. Object.defineProperty(GradientColorBrush2D.prototype, "translation", {
  4383. /**
  4384. * Translation vector to apply on the blend
  4385. * Default is [0;0]
  4386. */
  4387. get: function () {
  4388. return this._translation;
  4389. },
  4390. set: function (value) {
  4391. if (this.isLocked()) {
  4392. return;
  4393. }
  4394. this._translation = value;
  4395. },
  4396. enumerable: true,
  4397. configurable: true
  4398. });
  4399. Object.defineProperty(GradientColorBrush2D.prototype, "rotation", {
  4400. /**
  4401. * Rotation in radian to apply to the brush
  4402. * Default direction of the brush is vertical, you can change this using this property.
  4403. * Default is 0.
  4404. */
  4405. get: function () {
  4406. return this._rotation;
  4407. },
  4408. set: function (value) {
  4409. if (this.isLocked()) {
  4410. return;
  4411. }
  4412. this._rotation = value;
  4413. },
  4414. enumerable: true,
  4415. configurable: true
  4416. });
  4417. Object.defineProperty(GradientColorBrush2D.prototype, "scale", {
  4418. /**
  4419. * Scale factor to apply to the gradient.
  4420. * Default is 1: no scale.
  4421. */
  4422. get: function () {
  4423. return this._scale;
  4424. },
  4425. set: function (value) {
  4426. if (this.isLocked()) {
  4427. return;
  4428. }
  4429. this._scale = value;
  4430. },
  4431. enumerable: true,
  4432. configurable: true
  4433. });
  4434. /**
  4435. * Return a string describing the brush
  4436. */
  4437. GradientColorBrush2D.prototype.toString = function () {
  4438. return "C1:" + this._color1 + ";C2:" + this._color2 + ";T:" + this._translation.toString() + ";R:" + this._rotation + ";S:" + this._scale + ";";
  4439. };
  4440. /**
  4441. * Build a unique key string for the given parameters
  4442. */
  4443. GradientColorBrush2D.BuildKey = function (color1, color2, translation, rotation, scale) {
  4444. return "C1:" + color1 + ";C2:" + color2 + ";T:" + translation.toString() + ";R:" + rotation + ";S:" + scale + ";";
  4445. };
  4446. return GradientColorBrush2D;
  4447. }(LockableBase));
  4448. GradientColorBrush2D = __decorate([
  4449. BABYLON.className("GradientColorBrush2D", "BABYLON")
  4450. /**
  4451. * This class implements a Gradient Color Brush, the brush color will blend from a first given color to a second one.
  4452. */
  4453. ], GradientColorBrush2D);
  4454. BABYLON.GradientColorBrush2D = GradientColorBrush2D;
  4455. })(BABYLON || (BABYLON = {}));
  4456. //# sourceMappingURL=babylon.brushes2d.js.map
  4457. var __extends = (this && this.__extends) || (function () {
  4458. var extendStatics = Object.setPrototypeOf ||
  4459. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  4460. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  4461. return function (d, b) {
  4462. extendStatics(d, b);
  4463. function __() { this.constructor = d; }
  4464. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  4465. };
  4466. })();
  4467. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  4468. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  4469. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  4470. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  4471. return c > 3 && r && Object.defineProperty(target, key, r), r;
  4472. };
  4473. var BABYLON;
  4474. (function (BABYLON) {
  4475. var Prim2DClassInfo = (function () {
  4476. function Prim2DClassInfo() {
  4477. }
  4478. return Prim2DClassInfo;
  4479. }());
  4480. BABYLON.Prim2DClassInfo = Prim2DClassInfo;
  4481. var Prim2DPropInfo = (function () {
  4482. function Prim2DPropInfo() {
  4483. }
  4484. return Prim2DPropInfo;
  4485. }());
  4486. Prim2DPropInfo.PROPKIND_MODEL = 1;
  4487. Prim2DPropInfo.PROPKIND_INSTANCE = 2;
  4488. Prim2DPropInfo.PROPKIND_DYNAMIC = 3;
  4489. BABYLON.Prim2DPropInfo = Prim2DPropInfo;
  4490. var ClassTreeInfo = (function () {
  4491. function ClassTreeInfo(baseClass, type, classContentFactory) {
  4492. this._baseClass = baseClass;
  4493. this._type = type;
  4494. this._subClasses = new Array();
  4495. this._levelContent = new BABYLON.StringDictionary();
  4496. this._classContentFactory = classContentFactory;
  4497. }
  4498. Object.defineProperty(ClassTreeInfo.prototype, "classContent", {
  4499. get: function () {
  4500. if (!this._classContent) {
  4501. this._classContent = this._classContentFactory(this._baseClass ? this._baseClass.classContent : null);
  4502. }
  4503. return this._classContent;
  4504. },
  4505. enumerable: true,
  4506. configurable: true
  4507. });
  4508. Object.defineProperty(ClassTreeInfo.prototype, "type", {
  4509. get: function () {
  4510. return this._type;
  4511. },
  4512. enumerable: true,
  4513. configurable: true
  4514. });
  4515. Object.defineProperty(ClassTreeInfo.prototype, "levelContent", {
  4516. get: function () {
  4517. return this._levelContent;
  4518. },
  4519. enumerable: true,
  4520. configurable: true
  4521. });
  4522. Object.defineProperty(ClassTreeInfo.prototype, "fullContent", {
  4523. get: function () {
  4524. if (!this._fullContent) {
  4525. var dic_1 = new BABYLON.StringDictionary();
  4526. var curLevel = this;
  4527. while (curLevel) {
  4528. curLevel.levelContent.forEach(function (k, v) { return dic_1.add(k, v); });
  4529. curLevel = curLevel._baseClass;
  4530. }
  4531. this._fullContent = dic_1;
  4532. }
  4533. return this._fullContent;
  4534. },
  4535. enumerable: true,
  4536. configurable: true
  4537. });
  4538. ClassTreeInfo.prototype.getLevelOf = function (type) {
  4539. // Are we already there?
  4540. if (type === this._type) {
  4541. return this;
  4542. }
  4543. var baseProto = Object.getPrototypeOf(type);
  4544. var curProtoContent = this.getOrAddType(Object.getPrototypeOf(baseProto), baseProto);
  4545. if (!curProtoContent) {
  4546. this.getLevelOf(baseProto);
  4547. }
  4548. return this.getOrAddType(baseProto, type);
  4549. };
  4550. ClassTreeInfo.prototype.getOrAddType = function (baseType, type) {
  4551. // Are we at the level corresponding to the baseType?
  4552. // If so, get or add the level we're looking for
  4553. if (baseType === this._type) {
  4554. for (var _i = 0, _a = this._subClasses; _i < _a.length; _i++) {
  4555. var subType = _a[_i];
  4556. if (subType.type === type) {
  4557. return subType.node;
  4558. }
  4559. }
  4560. var node = new ClassTreeInfo(this, type, this._classContentFactory);
  4561. var info = { type: type, node: node };
  4562. this._subClasses.push(info);
  4563. return info.node;
  4564. }
  4565. // Recurse down to keep looking for the node corresponding to the baseTypeName
  4566. for (var _b = 0, _c = this._subClasses; _b < _c.length; _b++) {
  4567. var subType = _c[_b];
  4568. var info = subType.node.getOrAddType(baseType, type);
  4569. if (info) {
  4570. return info;
  4571. }
  4572. }
  4573. return null;
  4574. };
  4575. ClassTreeInfo.get = function (type) {
  4576. var dic = type["__classTreeInfo"];
  4577. if (!dic) {
  4578. return null;
  4579. }
  4580. return dic.getLevelOf(type);
  4581. };
  4582. ClassTreeInfo.getOrRegister = function (type, classContentFactory) {
  4583. var dic = type["__classTreeInfo"];
  4584. if (!dic) {
  4585. dic = new ClassTreeInfo(null, type, classContentFactory);
  4586. type["__classTreeInfo"] = dic;
  4587. }
  4588. return dic;
  4589. };
  4590. return ClassTreeInfo;
  4591. }());
  4592. BABYLON.ClassTreeInfo = ClassTreeInfo;
  4593. var DataBinding = DataBinding_1 = (function () {
  4594. function DataBinding() {
  4595. this._converter = null;
  4596. this._mode = DataBinding_1.MODE_DEFAULT;
  4597. this._uiElementId = null;
  4598. this._dataSource = null;
  4599. this._currentDataSource = null;
  4600. this._propertyPathName = null;
  4601. this._stringFormat = null;
  4602. this._updateSourceTrigger = DataBinding_1.UPDATESOURCETRIGGER_PROPERTYCHANGED;
  4603. this._boundTo = null;
  4604. this._owner = null;
  4605. this._updateCounter = 0;
  4606. }
  4607. Object.defineProperty(DataBinding.prototype, "converter", {
  4608. /**
  4609. * Provide a callback that will convert the value obtained by the Data Binding to the type of the SmartProperty it's bound to.
  4610. * If no value are set, then it's assumed that the sourceValue is of the same type as the SmartProperty's one.
  4611. * If the SmartProperty type is a basic data type (string, boolean or number) and no converter is specified but the sourceValue is of a different type, the conversion will be implicitly made, if possible.
  4612. * @param sourceValue the source object retrieve by the Data Binding mechanism
  4613. * @returns the object of a compatible type with the SmartProperty it's bound to
  4614. */
  4615. get: function () {
  4616. return this._converter;
  4617. },
  4618. set: function (value) {
  4619. if (this._converter === value) {
  4620. return;
  4621. }
  4622. this._converter = value;
  4623. },
  4624. enumerable: true,
  4625. configurable: true
  4626. });
  4627. Object.defineProperty(DataBinding.prototype, "mode", {
  4628. /**
  4629. * Set the mode to use for the data flow in the binding. Set one of the MODE_xxx static member of this class. If not specified then MODE_DEFAULT will be used
  4630. */
  4631. get: function () {
  4632. if (this._mode === DataBinding_1.MODE_DEFAULT) {
  4633. return this._boundTo.bindingMode;
  4634. }
  4635. return this._mode;
  4636. },
  4637. set: function (value) {
  4638. if (this._mode === value) {
  4639. return;
  4640. }
  4641. this._mode = value;
  4642. },
  4643. enumerable: true,
  4644. configurable: true
  4645. });
  4646. Object.defineProperty(DataBinding.prototype, "uiElementId", {
  4647. /**
  4648. * You can override the Data Source object with this member which is the Id of a uiElement existing in the UI Logical tree.
  4649. * If not set and source no set too, then the dataSource property will be used.
  4650. */
  4651. get: function () {
  4652. return this._uiElementId;
  4653. },
  4654. set: function (value) {
  4655. if (this._uiElementId === value) {
  4656. return;
  4657. }
  4658. this._uiElementId = value;
  4659. },
  4660. enumerable: true,
  4661. configurable: true
  4662. });
  4663. Object.defineProperty(DataBinding.prototype, "dataSource", {
  4664. /**
  4665. * You can override the Data Source object with this member which is the source object to use directly.
  4666. * If not set and uiElement no set too, then the dataSource property of the SmartPropertyBase object will be used.
  4667. */
  4668. get: function () {
  4669. return this._dataSource;
  4670. },
  4671. set: function (value) {
  4672. if (this._dataSource === value) {
  4673. return;
  4674. }
  4675. this._dataSource = value;
  4676. },
  4677. enumerable: true,
  4678. configurable: true
  4679. });
  4680. Object.defineProperty(DataBinding.prototype, "propertyPathName", {
  4681. /**
  4682. * The path & name of the property to get from the source object.
  4683. * Once the Source object is evaluated (it's either the one got from uiElementId, source or dataSource) you can specify which property of this object is the value to bind to the smartProperty.
  4684. * If nothing is set then the source object will be used.
  4685. * You can specify an indirect property using the format "firstProperty.indirectProperty" like "address.postalCode" if the source is a Customer object which contains an address property and the Address class contains a postalCode property.
  4686. * If the property is an Array and you want to address a particular element then use the 'arrayProperty[index]' notation. For example "phoneNumbers[0]" to get the first element of the phoneNumber property which is an array.
  4687. */
  4688. get: function () {
  4689. return this._propertyPathName;
  4690. },
  4691. set: function (value) {
  4692. if (this._propertyPathName === value) {
  4693. return;
  4694. }
  4695. if (this._owner) {
  4696. //BindingWatcher.unregisterBinding(this, null);
  4697. }
  4698. this._propertyPathName = value;
  4699. if (this._owner) {
  4700. //let watched = BindingWatcher._getDataSource(this._owner.dataSource, this);
  4701. //BindingWatcher.refreshBinding(watched, this._owner, this, true, null, true);
  4702. }
  4703. },
  4704. enumerable: true,
  4705. configurable: true
  4706. });
  4707. Object.defineProperty(DataBinding.prototype, "stringFormat", {
  4708. /**
  4709. * If the Smart Property is of the string type, you can use the string interpolation notation to provide how the sourceValue will be formatted, reference to the source value must be made via the token: ${value}. For instance `Customer Name: ${value}`
  4710. */
  4711. get: function () {
  4712. return this._stringFormat;
  4713. },
  4714. set: function (value) {
  4715. if (this._stringFormat === value) {
  4716. return;
  4717. }
  4718. this._stringFormat = value;
  4719. },
  4720. enumerable: true,
  4721. configurable: true
  4722. });
  4723. Object.defineProperty(DataBinding.prototype, "updateSourceTrigger", {
  4724. /**
  4725. * Specify how the source should be updated, use one of the UPDATESOURCETRIGGER_xxx member of this class, if not specified then UPDATESOURCETRIGGER_DEFAULT will be used.
  4726. */
  4727. get: function () {
  4728. return this._updateSourceTrigger;
  4729. },
  4730. set: function (value) {
  4731. if (this._updateSourceTrigger === value) {
  4732. return;
  4733. }
  4734. this._updateSourceTrigger = value;
  4735. },
  4736. enumerable: true,
  4737. configurable: true
  4738. });
  4739. DataBinding.prototype.canUpdateTarget = function (resetUpdateCounter) {
  4740. if (resetUpdateCounter) {
  4741. this._updateCounter = 0;
  4742. }
  4743. var mode = this.mode;
  4744. if (mode === DataBinding_1.MODE_ONETIME) {
  4745. return this._updateCounter === 0;
  4746. }
  4747. if (mode === DataBinding_1.MODE_ONEWAYTOSOURCE) {
  4748. return false;
  4749. }
  4750. return true;
  4751. };
  4752. DataBinding.prototype.updateTarget = function () {
  4753. var value = this._getActualDataSource();
  4754. var properties = this.propertyPathName.split(".");
  4755. for (var _i = 0, properties_1 = properties; _i < properties_1.length; _i++) {
  4756. var propertyName = properties_1[_i];
  4757. value = value[propertyName];
  4758. }
  4759. this._storeBoundValue(this._owner, value);
  4760. };
  4761. DataBinding.prototype._storeBoundValue = function (watcher, value) {
  4762. if ((++this._updateCounter > 1) && (this.mode === DataBinding_1.MODE_ONETIME)) {
  4763. return;
  4764. }
  4765. var newValue = value;
  4766. if (this._converter) {
  4767. newValue = this._converter(value);
  4768. }
  4769. if (this._stringFormat) {
  4770. newValue = this._stringFormat(newValue);
  4771. }
  4772. watcher[this._boundTo.name] = newValue;
  4773. };
  4774. DataBinding.prototype._getActualDataSource = function () {
  4775. if (this.dataSource) {
  4776. return this.dataSource;
  4777. }
  4778. if (this.uiElementId) {
  4779. // TODO Find UIElement
  4780. return null;
  4781. }
  4782. return this._owner.dataSource;
  4783. };
  4784. DataBinding.prototype._registerDataSource = function (updateTarget) {
  4785. var ds = this._getActualDataSource();
  4786. if (ds === this._currentDataSource) {
  4787. return;
  4788. }
  4789. if (this._currentDataSource) {
  4790. BindingHelper.unregisterDataSource(this._currentDataSource, this, 0);
  4791. }
  4792. if (ds) {
  4793. BindingHelper.registerDataSource(ds, this);
  4794. if (updateTarget && this.canUpdateTarget(true)) {
  4795. this.updateTarget();
  4796. }
  4797. }
  4798. this._currentDataSource = ds;
  4799. };
  4800. DataBinding.prototype._unregisterDataSource = function () {
  4801. var ds = this._getActualDataSource();
  4802. if (ds) {
  4803. BindingHelper.unregisterDataSource(ds, this, 0);
  4804. }
  4805. };
  4806. return DataBinding;
  4807. }());
  4808. /**
  4809. * Use the mode specified in the SmartProperty declaration
  4810. */
  4811. DataBinding.MODE_DEFAULT = 1;
  4812. /**
  4813. * Update the binding target only once when the Smart Property's value is first accessed
  4814. */
  4815. DataBinding.MODE_ONETIME = 2;
  4816. /**
  4817. * Update the smart property when the source changes.
  4818. * The source won't be updated if the smart property value is set.
  4819. */
  4820. DataBinding.MODE_ONEWAY = 3;
  4821. /**
  4822. * Only update the source when the target's data is changing.
  4823. */
  4824. DataBinding.MODE_ONEWAYTOSOURCE = 4;
  4825. /**
  4826. * Update the bind target when the source changes and update the source when the Smart Property value is set.
  4827. */
  4828. DataBinding.MODE_TWOWAY = 5;
  4829. /**
  4830. * Use the Update Source Trigger defined in the SmartProperty declaration
  4831. */
  4832. DataBinding.UPDATESOURCETRIGGER_DEFAULT = 1;
  4833. /**
  4834. * Update the source as soon as the Smart Property has a value change
  4835. */
  4836. DataBinding.UPDATESOURCETRIGGER_PROPERTYCHANGED = 2;
  4837. /**
  4838. * Update the source when the binding target loses focus
  4839. */
  4840. DataBinding.UPDATESOURCETRIGGER_LOSTFOCUS = 3;
  4841. /**
  4842. * Update the source will be made by explicitly calling the UpdateFromDataSource method
  4843. */
  4844. DataBinding.UPDATESOURCETRIGGER_EXPLICIT = 4;
  4845. DataBinding = DataBinding_1 = __decorate([
  4846. BABYLON.className("DataBinding", "BABYLON")
  4847. ], DataBinding);
  4848. BABYLON.DataBinding = DataBinding;
  4849. var SmartPropertyBase = SmartPropertyBase_1 = (function (_super) {
  4850. __extends(SmartPropertyBase, _super);
  4851. function SmartPropertyBase() {
  4852. var _this = _super.call(this) || this;
  4853. _this._dataSource = null;
  4854. _this._dataSourceObserver = null;
  4855. _this._instanceDirtyFlags = 0;
  4856. _this._isDisposed = false;
  4857. _this._bindings = null;
  4858. _this._hasBinding = 0;
  4859. _this._bindingSourceChanged = 0;
  4860. _this._disposeObservable = null;
  4861. return _this;
  4862. }
  4863. Object.defineProperty(SmartPropertyBase.prototype, "disposeObservable", {
  4864. get: function () {
  4865. if (!this._disposeObservable) {
  4866. this._disposeObservable = new BABYLON.Observable();
  4867. }
  4868. return this._disposeObservable;
  4869. },
  4870. enumerable: true,
  4871. configurable: true
  4872. });
  4873. Object.defineProperty(SmartPropertyBase.prototype, "isDisposed", {
  4874. /**
  4875. * Check if the object is disposed or not.
  4876. * @returns true if the object is dispose, false otherwise.
  4877. */
  4878. get: function () {
  4879. return this._isDisposed;
  4880. },
  4881. enumerable: true,
  4882. configurable: true
  4883. });
  4884. /**
  4885. * Disposable pattern, this method must be overloaded by derived types in order to clean up hardware related resources.
  4886. * @returns false if the object is already dispose, true otherwise. Your implementation must call super.dispose() and check for a false return and return immediately if it's the case.
  4887. */
  4888. SmartPropertyBase.prototype.dispose = function () {
  4889. if (this.isDisposed) {
  4890. return false;
  4891. }
  4892. if (this._disposeObservable && this._disposeObservable.hasObservers()) {
  4893. this._disposeObservable.notifyObservers(this);
  4894. }
  4895. this._isDisposed = true;
  4896. return true;
  4897. };
  4898. /**
  4899. * Check if a given set of properties are dirty or not.
  4900. * @param flags a ORed combination of Prim2DPropInfo.flagId values
  4901. * @return true if at least one property is dirty, false if none of them are.
  4902. */
  4903. SmartPropertyBase.prototype.checkPropertiesDirty = function (flags) {
  4904. return (this._instanceDirtyFlags & flags) !== 0;
  4905. };
  4906. /**
  4907. * Clear a given set of properties.
  4908. * @param flags a ORed combination of Prim2DPropInfo.flagId values
  4909. * @return the new set of property still marked as dirty
  4910. */
  4911. SmartPropertyBase.prototype.clearPropertiesDirty = function (flags) {
  4912. this._instanceDirtyFlags &= ~flags;
  4913. return this._instanceDirtyFlags;
  4914. };
  4915. SmartPropertyBase.prototype._resetPropertiesDirty = function () {
  4916. this._instanceDirtyFlags = 0;
  4917. };
  4918. /**
  4919. * Add an externally attached data from its key.
  4920. * This method call will fail and return false, if such key already exists.
  4921. * If you don't care and just want to get the data no matter what, use the more convenient getOrAddExternalDataWithFactory() method.
  4922. * @param key the unique key that identifies the data
  4923. * @param data the data object to associate to the key for this Engine instance
  4924. * @return true if no such key were already present and the data was added successfully, false otherwise
  4925. */
  4926. SmartPropertyBase.prototype.addExternalData = function (key, data) {
  4927. if (!this._externalData) {
  4928. this._externalData = new BABYLON.StringDictionary();
  4929. }
  4930. return this._externalData.add(key, data);
  4931. };
  4932. /**
  4933. * Get an externally attached data from its key
  4934. * @param key the unique key that identifies the data
  4935. * @return the associated data, if present (can be null), or undefined if not present
  4936. */
  4937. SmartPropertyBase.prototype.getExternalData = function (key) {
  4938. if (!this._externalData) {
  4939. return null;
  4940. }
  4941. return this._externalData.get(key);
  4942. };
  4943. /**
  4944. * Get an externally attached data from its key, create it using a factory if it's not already present
  4945. * @param key the unique key that identifies the data
  4946. * @param factory the factory that will be called to create the instance if and only if it doesn't exists
  4947. * @return the associated data, can be null if the factory returned null.
  4948. */
  4949. SmartPropertyBase.prototype.getOrAddExternalDataWithFactory = function (key, factory) {
  4950. if (!this._externalData) {
  4951. this._externalData = new BABYLON.StringDictionary();
  4952. }
  4953. return this._externalData.getOrAddWithFactory(key, factory);
  4954. };
  4955. /**
  4956. * Remove an externally attached data from the Engine instance
  4957. * @param key the unique key that identifies the data
  4958. * @return true if the data was successfully removed, false if it doesn't exist
  4959. */
  4960. SmartPropertyBase.prototype.removeExternalData = function (key) {
  4961. if (!this._externalData) {
  4962. return false;
  4963. }
  4964. return this._externalData.remove(key);
  4965. };
  4966. SmartPropertyBase._hookProperty = function (propId, piStore, kind, settings) {
  4967. return function (target, propName, descriptor) {
  4968. if (!settings) {
  4969. settings = {};
  4970. }
  4971. var propInfo = SmartPropertyBase_1._createPropInfo(target, propName, propId, kind, settings);
  4972. if (piStore) {
  4973. piStore(propInfo);
  4974. }
  4975. var getter = descriptor.get, setter = descriptor.set;
  4976. var typeLevelCompare = (settings.typeLevelCompare !== undefined) ? settings.typeLevelCompare : false;
  4977. // Overload the property setter implementation to add our own logic
  4978. descriptor.set = function (val) {
  4979. if (!setter) {
  4980. throw Error("Property '" + propInfo.name + "' of type '" + BABYLON.Tools.getFullClassName(this) + "' has no setter defined but was invoked as if it had one.");
  4981. }
  4982. // check for disposed first, do nothing
  4983. if (this.isDisposed) {
  4984. return;
  4985. }
  4986. var curVal = getter.call(this);
  4987. if (SmartPropertyBase_1._checkUnchanged(curVal, val)) {
  4988. return;
  4989. }
  4990. // Cast the object we're working one
  4991. var prim = this;
  4992. // Change the value
  4993. setter.call(this, val);
  4994. // Notify change, dirty flags update
  4995. prim._handlePropChanged(curVal, val, propName, propInfo, typeLevelCompare);
  4996. };
  4997. };
  4998. };
  4999. SmartPropertyBase._createPropInfo = function (target, propName, propId, kind, settings) {
  5000. var dic = ClassTreeInfo.getOrRegister(target, function () { return new Prim2DClassInfo(); });
  5001. var node = dic.getLevelOf(target);
  5002. var propInfo = node.levelContent.get(propId.toString());
  5003. if (propInfo) {
  5004. throw new Error("The ID " + propId + " is already taken by another property declaration named: " + propInfo.name);
  5005. }
  5006. // Create, setup and add the PropInfo object to our prop dictionary
  5007. propInfo = new Prim2DPropInfo();
  5008. propInfo.id = propId;
  5009. propInfo.flagId = Math.pow(2, propId);
  5010. propInfo.kind = kind;
  5011. propInfo.name = propName;
  5012. propInfo.bindingMode = (settings.bindingMode !== undefined) ? settings.bindingMode : DataBinding.MODE_TWOWAY;
  5013. propInfo.bindingUpdateSourceTrigger = (settings.bindingUpdateSourceTrigger !== undefined) ? settings.bindingUpdateSourceTrigger : DataBinding.UPDATESOURCETRIGGER_PROPERTYCHANGED;
  5014. propInfo.dirtyBoundingInfo = (settings.dirtyBoundingInfo !== undefined) ? settings.dirtyBoundingInfo : false;
  5015. propInfo.dirtyParentBoundingInfo = (settings.dirtyParentBoundingBox !== undefined) ? settings.dirtyParentBoundingBox : false;
  5016. propInfo.typeLevelCompare = (settings.typeLevelCompare !== undefined) ? settings.typeLevelCompare : false;
  5017. node.levelContent.add(propName, propInfo);
  5018. return propInfo;
  5019. };
  5020. Object.defineProperty(SmartPropertyBase.prototype, "propDic", {
  5021. /**
  5022. * Access the dictionary of properties metadata. Only properties decorated with XXXXLevelProperty are concerned
  5023. * @returns the dictionary, the key is the property name as declared in Javascript, the value is the metadata object
  5024. */
  5025. get: function () {
  5026. if (!this._propInfo) {
  5027. var cti = ClassTreeInfo.get(Object.getPrototypeOf(this));
  5028. if (!cti) {
  5029. throw new Error("Can't access the propDic member in class definition, is this class SmartPropertyPrim based?");
  5030. }
  5031. this._propInfo = cti.fullContent;
  5032. }
  5033. return this._propInfo;
  5034. },
  5035. enumerable: true,
  5036. configurable: true
  5037. });
  5038. SmartPropertyBase._checkUnchanged = function (curValue, newValue) {
  5039. // Nothing to nothing: nothing to do!
  5040. if ((curValue === null && newValue === null) || (curValue === undefined && newValue === undefined)) {
  5041. return true;
  5042. }
  5043. // Check value unchanged
  5044. if ((curValue != null) && (newValue != null)) {
  5045. if (typeof (curValue.equals) == "function") {
  5046. if (curValue.equals(newValue)) {
  5047. return true;
  5048. }
  5049. }
  5050. else {
  5051. if (curValue === newValue) {
  5052. return true;
  5053. }
  5054. }
  5055. }
  5056. return false;
  5057. };
  5058. SmartPropertyBase.prototype._handlePropChanged = function (curValue, newValue, propName, propInfo, typeLevelCompare) {
  5059. // Trigger property changed
  5060. var info = SmartPropertyBase_1.propChangeGuarding ? new BABYLON.PropertyChangedInfo() : SmartPropertyPrim.propChangedInfo;
  5061. info.oldValue = curValue;
  5062. info.newValue = newValue;
  5063. info.propertyName = propName;
  5064. var propMask = propInfo ? propInfo.flagId : -1;
  5065. try {
  5066. SmartPropertyBase_1.propChangeGuarding = true;
  5067. this.propertyChanged.notifyObservers(info, propMask);
  5068. }
  5069. finally {
  5070. SmartPropertyBase_1.propChangeGuarding = false;
  5071. }
  5072. };
  5073. SmartPropertyBase.prototype._triggerPropertyChanged = function (propInfo, newValue) {
  5074. if (this.isDisposed) {
  5075. return;
  5076. }
  5077. if (!propInfo) {
  5078. return;
  5079. }
  5080. this._handlePropChanged(undefined, newValue, propInfo.name, propInfo, propInfo.typeLevelCompare);
  5081. };
  5082. Object.defineProperty(SmartPropertyBase.prototype, "dataSource", {
  5083. /**
  5084. * Set the object from which Smart Properties using Binding will take/update their data from/to.
  5085. * When the object is part of a graph (with parent/children relationship) if the dataSource of a given instance is not specified, then the parent's one is used.
  5086. */
  5087. get: function () {
  5088. // Don't access to _dataSource directly but via a call to the _getDataSource method which can be overloaded in inherited classes
  5089. return this._getDataSource();
  5090. },
  5091. set: function (value) {
  5092. if (this._dataSource === value) {
  5093. return;
  5094. }
  5095. var oldValue = this._dataSource;
  5096. this._dataSource = value;
  5097. if (this._bindings && value != null) {
  5098. // Register the bindings
  5099. for (var _i = 0, _a = this._bindings; _i < _a.length; _i++) {
  5100. var binding = _a[_i];
  5101. if (binding != null) {
  5102. binding._registerDataSource(true);
  5103. }
  5104. }
  5105. }
  5106. this.onPropertyChanged("dataSource", oldValue, value);
  5107. },
  5108. enumerable: true,
  5109. configurable: true
  5110. });
  5111. // Inheriting classes can overload this method to provides additional logic for dataSource access
  5112. SmartPropertyBase.prototype._getDataSource = function () {
  5113. return this._dataSource;
  5114. };
  5115. SmartPropertyBase.prototype.createSimpleDataBinding = function (propInfo, propertyPathName, mode) {
  5116. if (mode === void 0) { mode = DataBinding.MODE_DEFAULT; }
  5117. var binding = new DataBinding();
  5118. binding.propertyPathName = propertyPathName;
  5119. binding.mode = mode;
  5120. return this.createDataBinding(propInfo, binding);
  5121. };
  5122. SmartPropertyBase.prototype.createDataBinding = function (propInfo, binding) {
  5123. if (!this._bindings) {
  5124. this._bindings = new Array();
  5125. }
  5126. if (!binding || binding._owner != null) {
  5127. throw Error("A valid/unused Binding must be passed.");
  5128. }
  5129. // Unregister a potentially existing binding for this property
  5130. this.removeDataBinding(propInfo);
  5131. // register the binding
  5132. binding._owner = this;
  5133. binding._boundTo = propInfo;
  5134. this._bindings[propInfo.id] = binding;
  5135. this._hasBinding |= propInfo.flagId;
  5136. binding._registerDataSource(true);
  5137. return binding;
  5138. };
  5139. SmartPropertyBase.prototype.removeDataBinding = function (propInfo) {
  5140. if ((this._hasBinding & propInfo.flagId) === 0) {
  5141. return false;
  5142. }
  5143. var curBinding = this._bindings[propInfo.id];
  5144. curBinding._unregisterDataSource();
  5145. this._bindings[propInfo.id] = null;
  5146. this._hasBinding &= ~propInfo.flagId;
  5147. return true;
  5148. };
  5149. SmartPropertyBase.prototype.updateFromDataSource = function () {
  5150. for (var _i = 0, _a = this._bindings; _i < _a.length; _i++) {
  5151. var binding = _a[_i];
  5152. if (binding) {
  5153. //BindingWatcher.updateFromDataSource(this, binding, false);
  5154. }
  5155. }
  5156. };
  5157. return SmartPropertyBase;
  5158. }(BABYLON.PropertyChangedBase));
  5159. SmartPropertyBase.propChangedInfo = new BABYLON.PropertyChangedInfo();
  5160. SmartPropertyBase.propChangeGuarding = false;
  5161. __decorate([
  5162. BABYLON.logProp()
  5163. ], SmartPropertyBase.prototype, "_triggerPropertyChanged", null);
  5164. SmartPropertyBase = SmartPropertyBase_1 = __decorate([
  5165. BABYLON.className("SmartPropertyBase", "BABYLON")
  5166. ], SmartPropertyBase);
  5167. BABYLON.SmartPropertyBase = SmartPropertyBase;
  5168. var BindingInfo = (function () {
  5169. function BindingInfo(binding, level, isLast) {
  5170. this.binding = binding;
  5171. this.level = level;
  5172. this.isLast = isLast;
  5173. }
  5174. return BindingInfo;
  5175. }());
  5176. var MonitoredObjectData = (function () {
  5177. function MonitoredObjectData(monitoredObject) {
  5178. var _this = this;
  5179. this.monitoredObject = monitoredObject;
  5180. this.monitoredIntermediateProperties = new BABYLON.StringDictionary();
  5181. this.observer = this.monitoredObject.propertyChanged.add(function (e, s) { _this.propertyChangedHandler(e.propertyName, e.oldValue, e.newValue); });
  5182. this.boundProperties = new BABYLON.StringDictionary();
  5183. this.monitoredIntermediateMask = 0;
  5184. this.boundPropertiesMask = 0;
  5185. }
  5186. MonitoredObjectData.prototype.propertyChangedHandler = function (propName, oldValue, newValue) {
  5187. var propId = BindingHelper._getPropertyID(this.monitoredObject, propName);
  5188. var propIdStr = propId.toString();
  5189. // Loop through all the registered bindings for this property that had a value change
  5190. if ((this.boundPropertiesMask & propId) !== 0) {
  5191. var bindingInfos = this.boundProperties.get(propIdStr);
  5192. for (var _i = 0, bindingInfos_1 = bindingInfos; _i < bindingInfos_1.length; _i++) {
  5193. var bi = bindingInfos_1[_i];
  5194. if (!bi.isLast) {
  5195. BindingHelper.unregisterDataSource(this.monitoredObject, bi.binding, bi.level);
  5196. BindingHelper.registerDataSource(bi.binding._currentDataSource, bi.binding);
  5197. }
  5198. if (bi.binding.canUpdateTarget(false)) {
  5199. bi.binding.updateTarget();
  5200. }
  5201. }
  5202. }
  5203. };
  5204. return MonitoredObjectData;
  5205. }());
  5206. var BindingHelper = (function () {
  5207. function BindingHelper() {
  5208. }
  5209. BindingHelper.registerDataSource = function (dataSource, binding) {
  5210. var properties = binding.propertyPathName.split(".");
  5211. var ownerMod = null;
  5212. var ownerInterPropId = 0;
  5213. var propertyOwner = dataSource;
  5214. var _loop_1 = function (i) {
  5215. var propName = properties[i];
  5216. var propId = BindingHelper._getPropertyID(propertyOwner, propName);
  5217. var propIdStr = propId.toString();
  5218. var mod = void 0;
  5219. if (ownerMod) {
  5220. var o_1 = ownerMod;
  5221. var po_1 = propertyOwner;
  5222. var oii_1 = ownerInterPropId;
  5223. mod = ownerMod.monitoredIntermediateProperties.getOrAddWithFactory(oii_1.toString(), function (k) {
  5224. o_1.monitoredIntermediateMask |= oii_1;
  5225. return BindingHelper._getMonitoredObjectData(po_1);
  5226. });
  5227. }
  5228. else {
  5229. mod = BindingHelper._getMonitoredObjectData(propertyOwner);
  5230. }
  5231. var m = mod;
  5232. var bindingInfos = mod.boundProperties.getOrAddWithFactory(propIdStr, function (k) {
  5233. m.boundPropertiesMask |= propId;
  5234. return new Array();
  5235. });
  5236. var bi = BABYLON.Tools.first(bindingInfos, function (cbi) { return cbi.binding === binding; });
  5237. if (!bi) {
  5238. bindingInfos.push(new BindingInfo(binding, i, (i + 1) === properties.length));
  5239. }
  5240. ownerMod = mod;
  5241. ownerInterPropId = propId;
  5242. propertyOwner = propertyOwner[propName];
  5243. };
  5244. for (var i = 0; i < properties.length; i++) {
  5245. _loop_1(i);
  5246. }
  5247. };
  5248. BindingHelper.unregisterDataSource = function (dataSource, binding, level) {
  5249. var properties = binding.propertyPathName.split(".");
  5250. var propertyOwner = dataSource;
  5251. var mod = BindingHelper._getMonitoredObjectData(propertyOwner);
  5252. for (var i = 0; i < properties.length; i++) {
  5253. var propName = properties[i];
  5254. var propId = BindingHelper._getPropertyID(propertyOwner, propName);
  5255. var propIdStr = propId.toString();
  5256. if (i >= level) {
  5257. mod = BindingHelper._unregisterBinding(mod, propId, binding);
  5258. }
  5259. else {
  5260. mod = mod.monitoredIntermediateProperties.get(propIdStr);
  5261. }
  5262. propertyOwner = propertyOwner[propName];
  5263. }
  5264. };
  5265. BindingHelper._unregisterBinding = function (mod, propertyID, binding) {
  5266. var propertyIDStr = propertyID.toString();
  5267. var res = null;
  5268. // Check if the property is registered as an intermediate and remove it
  5269. if ((mod.monitoredIntermediateMask & propertyID) !== 0) {
  5270. res = mod.monitoredIntermediateProperties.get(propertyIDStr);
  5271. mod.monitoredIntermediateProperties.remove(propertyIDStr);
  5272. // Update the mask
  5273. mod.monitoredIntermediateMask &= ~propertyID;
  5274. }
  5275. // Check if the property is registered as a final property and remove it
  5276. if ((mod.boundPropertiesMask & propertyID) !== 0) {
  5277. var bindingInfos = mod.boundProperties.get(propertyIDStr);
  5278. // Find the binding and remove it
  5279. var bi = BABYLON.Tools.first(bindingInfos, function (cbi) { return cbi.binding === binding; });
  5280. if (bi) {
  5281. var bii = bindingInfos.indexOf(bi);
  5282. bindingInfos.splice(bii, 1);
  5283. }
  5284. // If the array is empty, update the mask
  5285. if (bindingInfos.length === 0) {
  5286. mod.boundPropertiesMask &= ~propertyID;
  5287. }
  5288. }
  5289. // Check if the MOD is empty and unregister the observer and remove it from the list of MODs
  5290. if (mod.boundPropertiesMask === 0 && mod.monitoredIntermediateMask === 0) {
  5291. // Unregister the observer on Property Change
  5292. mod.monitoredObject.propertyChanged.remove(mod.observer);
  5293. // Remove the MOD from the dic
  5294. var objectId = BindingHelper._getObjectId(mod.monitoredObject);
  5295. BindingHelper._monitoredObjects.remove(objectId);
  5296. }
  5297. return res;
  5298. };
  5299. BindingHelper._getMonitoredObjectData = function (object) {
  5300. var objectId = BindingHelper._getObjectId(object);
  5301. var mod = BindingHelper._monitoredObjects.getOrAddWithFactory(objectId, function (k) { return new MonitoredObjectData(object); });
  5302. return mod;
  5303. };
  5304. BindingHelper._getObjectId = function (obj) {
  5305. var id = obj["__bindingHelperObjectId__"];
  5306. if (id == null) {
  5307. id = BABYLON.Tools.RandomId();
  5308. obj["__bindingHelperObjectId__"] = id;
  5309. return id;
  5310. }
  5311. return id;
  5312. };
  5313. BindingHelper._getObjectTypePropertyIDs = function (obj) {
  5314. var fullName = BABYLON.Tools.getFullClassName(obj);
  5315. if (!fullName) {
  5316. throw Error("Types involved in Data Binding must be decorated with the @className decorator");
  5317. }
  5318. var d = BindingHelper._propertiesID.getOrAddWithFactory(fullName, function () { return new BABYLON.StringDictionary(); });
  5319. return d;
  5320. };
  5321. BindingHelper._getPropertyID = function (object, propName) {
  5322. var otd = BindingHelper._getObjectTypePropertyIDs(object);
  5323. // Make sure we have a WatchedPropertyData for this property of this object type. This will contains the flagIg of the watched property.
  5324. // We use this flagId to flag for each watched instance which properties are watched, as final or intermediate and which directions are used
  5325. var propData = otd.getOrAddWithFactory(propName, function (k) { return 1 << otd.count; });
  5326. return propData;
  5327. };
  5328. return BindingHelper;
  5329. }());
  5330. BindingHelper._propertiesID = new BABYLON.StringDictionary();
  5331. BindingHelper._monitoredObjects = new BABYLON.StringDictionary();
  5332. var SmartPropertyPrim = SmartPropertyPrim_1 = (function (_super) {
  5333. __extends(SmartPropertyPrim, _super);
  5334. function SmartPropertyPrim() {
  5335. var _this = _super.call(this) || this;
  5336. _this._flags = 0;
  5337. _this._uid = null;
  5338. _this._modelKey = null;
  5339. _this._levelBoundingInfo = new BABYLON.BoundingInfo2D();
  5340. _this._boundingInfo = new BABYLON.BoundingInfo2D();
  5341. _this.animations = new Array();
  5342. return _this;
  5343. }
  5344. /**
  5345. * Disposable pattern, this method must be overloaded by derived types in order to clean up hardware related resources.
  5346. * @returns false if the object is already dispose, true otherwise. Your implementation must call super.dispose() and check for a false return and return immediately if it's the case.
  5347. */
  5348. SmartPropertyPrim.prototype.dispose = function () {
  5349. if (this.isDisposed) {
  5350. return false;
  5351. }
  5352. _super.prototype.dispose.call(this);
  5353. // Don't set to null, it may upset somebody...
  5354. this.animations.splice(0);
  5355. return true;
  5356. };
  5357. Object.defineProperty(SmartPropertyPrim.prototype, "uid", {
  5358. /**
  5359. * return a unique identifier for the Canvas2D
  5360. */
  5361. get: function () {
  5362. if (!this._uid) {
  5363. this._uid = BABYLON.Tools.RandomId();
  5364. }
  5365. return this._uid;
  5366. },
  5367. enumerable: true,
  5368. configurable: true
  5369. });
  5370. /**
  5371. * Returns as a new array populated with the Animatable used by the primitive. Must be overloaded by derived primitives.
  5372. * Look at Sprite2D for more information
  5373. */
  5374. SmartPropertyPrim.prototype.getAnimatables = function () {
  5375. return new Array();
  5376. };
  5377. Object.defineProperty(SmartPropertyPrim.prototype, "modelKey", {
  5378. /**
  5379. * Property giving the Model Key associated to the property.
  5380. * This value is constructed from the type of the primitive and all the name/value of its properties declared with the modelLevelProperty decorator
  5381. * @returns the model key string.
  5382. */
  5383. get: function () {
  5384. var _this = this;
  5385. // No need to compute it?
  5386. if (!this._isFlagSet(SmartPropertyPrim_1.flagModelDirty) && this._modelKey) {
  5387. return this._modelKey;
  5388. }
  5389. var modelKey = "Class:" + BABYLON.Tools.getClassName(this) + ";";
  5390. var propDic = this.propDic;
  5391. propDic.forEach(function (k, v) {
  5392. if (v.kind === Prim2DPropInfo.PROPKIND_MODEL) {
  5393. var propVal = _this[v.name];
  5394. // Special case, array, this WON'T WORK IN ALL CASES, all entries have to be of the same type and it must be a BJS well known one
  5395. if (propVal && propVal.constructor === Array) {
  5396. var firstVal = propVal[0];
  5397. if (!firstVal) {
  5398. propVal = 0;
  5399. }
  5400. else {
  5401. propVal = BABYLON.Tools.hashCodeFromStream(BABYLON.Tools.arrayOrStringFeeder(propVal));
  5402. }
  5403. }
  5404. var value = "[null]";
  5405. if (propVal != null) {
  5406. if (v.typeLevelCompare) {
  5407. value = BABYLON.Tools.getClassName(propVal);
  5408. }
  5409. else {
  5410. // String Dictionaries' content are too complex, with use a Random GUID to make the model unique
  5411. if (propVal instanceof BABYLON.StringDictionary) {
  5412. value = BABYLON.Tools.RandomId();
  5413. }
  5414. else if (propVal instanceof BABYLON.BaseTexture) {
  5415. value = propVal.uid;
  5416. }
  5417. else {
  5418. value = propVal.toString();
  5419. }
  5420. }
  5421. }
  5422. modelKey += v.name + ":" + value + ";";
  5423. }
  5424. });
  5425. this._clearFlags(SmartPropertyPrim_1.flagModelDirty);
  5426. this._modelKey = modelKey;
  5427. return modelKey;
  5428. },
  5429. enumerable: true,
  5430. configurable: true
  5431. });
  5432. Object.defineProperty(SmartPropertyPrim.prototype, "isDirty", {
  5433. /**
  5434. * States if the Primitive is dirty and should be rendered again next time.
  5435. * @returns true is dirty, false otherwise
  5436. */
  5437. get: function () {
  5438. return (this._instanceDirtyFlags !== 0) || this._areSomeFlagsSet(SmartPropertyPrim_1.flagModelDirty | SmartPropertyPrim_1.flagModelUpdate | SmartPropertyPrim_1.flagPositioningDirty | SmartPropertyPrim_1.flagLayoutDirty);
  5439. },
  5440. enumerable: true,
  5441. configurable: true
  5442. });
  5443. SmartPropertyPrim.prototype._boundingBoxDirty = function () {
  5444. this._setFlags(SmartPropertyPrim_1.flagLevelBoundingInfoDirty | SmartPropertyPrim_1.flagLayoutBoundingInfoDirty);
  5445. // Escalate the dirty flag in the instance hierarchy, stop when a renderable group is found or at the end
  5446. if (this instanceof BABYLON.Prim2DBase) {
  5447. var curprim = this;
  5448. while (curprim) {
  5449. curprim._setFlags(SmartPropertyPrim_1.flagBoundingInfoDirty | SmartPropertyPrim_1.flagLayoutBoundingInfoDirty);
  5450. if (curprim.isSizeAuto) {
  5451. curprim.onPrimitivePropertyDirty(BABYLON.Prim2DBase.sizeProperty.flagId);
  5452. if (curprim._isFlagSet(SmartPropertyPrim_1.flagUsePositioning)) {
  5453. curprim._setFlags(SmartPropertyPrim_1.flagPositioningDirty);
  5454. }
  5455. }
  5456. if (curprim instanceof BABYLON.Group2D) {
  5457. if (curprim.isRenderableGroup) {
  5458. break;
  5459. }
  5460. }
  5461. curprim = curprim.parent;
  5462. }
  5463. }
  5464. };
  5465. SmartPropertyPrim.prototype._handlePropChanged = function (curValue, newValue, propName, propInfo, typeLevelCompare) {
  5466. _super.prototype._handlePropChanged.call(this, curValue, newValue, propName, propInfo, typeLevelCompare);
  5467. // If the property change also dirty the boundingInfo, update the boundingInfo dirty flags
  5468. if (propInfo.dirtyBoundingInfo) {
  5469. this._boundingBoxDirty();
  5470. }
  5471. else if (propInfo.dirtyParentBoundingInfo) {
  5472. var p = this._parent;
  5473. if (p != null) {
  5474. p._boundingBoxDirty();
  5475. }
  5476. }
  5477. // If the property belong to a group, check if it's a cached one, and dirty its render sprite accordingly
  5478. if (this instanceof BABYLON.Group2D && this._renderableData) {
  5479. this.handleGroupChanged(propInfo);
  5480. }
  5481. // Check for parent layout dirty
  5482. if (this instanceof BABYLON.Prim2DBase) {
  5483. var p = this._parent;
  5484. if (p != null && p.layoutEngine && (p.layoutEngine.layoutDirtyOnPropertyChangedMask & propInfo.flagId) !== 0) {
  5485. p._setLayoutDirty();
  5486. }
  5487. var that = this;
  5488. if (that.layoutEngine && (that.layoutEngine.layoutDirtyOnPropertyChangedMask & propInfo.flagId) !== 0) {
  5489. this._setLayoutDirty();
  5490. }
  5491. }
  5492. // For type level compare, if there's a change of type it's a change of model, otherwise we issue an instance change
  5493. var instanceDirty = false;
  5494. if (typeLevelCompare && curValue != null && newValue != null) {
  5495. var cvProto = curValue.__proto__;
  5496. var nvProto = newValue.__proto__;
  5497. instanceDirty = (cvProto === nvProto);
  5498. }
  5499. // Set the dirty flags
  5500. if (!instanceDirty && (propInfo.kind === Prim2DPropInfo.PROPKIND_MODEL)) {
  5501. if (!this.isDirty) {
  5502. this.onPrimBecomesDirty();
  5503. this._setFlags(SmartPropertyPrim_1.flagModelDirty);
  5504. }
  5505. }
  5506. else if (instanceDirty || (propInfo.kind === Prim2DPropInfo.PROPKIND_INSTANCE) || (propInfo.kind === Prim2DPropInfo.PROPKIND_DYNAMIC)) {
  5507. var propMask = propInfo.flagId;
  5508. this.onPrimitivePropertyDirty(propMask);
  5509. }
  5510. };
  5511. SmartPropertyPrim.prototype.onPrimitivePropertyDirty = function (propFlagId) {
  5512. this.onPrimBecomesDirty();
  5513. this._instanceDirtyFlags |= propFlagId;
  5514. };
  5515. SmartPropertyPrim.prototype.handleGroupChanged = function (prop) {
  5516. };
  5517. SmartPropertyPrim.prototype._resetPropertiesDirty = function () {
  5518. _super.prototype._resetPropertiesDirty.call(this);
  5519. this._clearFlags(SmartPropertyPrim_1.flagPrimInDirtyList | SmartPropertyPrim_1.flagNeedRefresh);
  5520. };
  5521. Object.defineProperty(SmartPropertyPrim.prototype, "levelBoundingInfo", {
  5522. /**
  5523. * Retrieve the boundingInfo for this Primitive, computed based on the primitive itself and NOT its children
  5524. */
  5525. get: function () {
  5526. if (this._isFlagSet(SmartPropertyPrim_1.flagLevelBoundingInfoDirty)) {
  5527. if (this.updateLevelBoundingInfo()) {
  5528. this._boundingInfo.dirtyWorldAABB();
  5529. this._clearFlags(SmartPropertyPrim_1.flagLevelBoundingInfoDirty);
  5530. }
  5531. else {
  5532. this._levelBoundingInfo.clear();
  5533. }
  5534. }
  5535. return this._levelBoundingInfo;
  5536. },
  5537. enumerable: true,
  5538. configurable: true
  5539. });
  5540. /**
  5541. * This method must be overridden by a given Primitive implementation to compute its boundingInfo
  5542. */
  5543. SmartPropertyPrim.prototype.updateLevelBoundingInfo = function () {
  5544. return false;
  5545. };
  5546. /**
  5547. * Property method called when the Primitive becomes dirty
  5548. */
  5549. SmartPropertyPrim.prototype.onPrimBecomesDirty = function () {
  5550. };
  5551. /**
  5552. * Check if a given flag is set
  5553. * @param flag the flag value
  5554. * @return true if set, false otherwise
  5555. */
  5556. SmartPropertyPrim.prototype._isFlagSet = function (flag) {
  5557. return (this._flags & flag) !== 0;
  5558. };
  5559. /**
  5560. * Check if all given flags are set
  5561. * @param flags the flags ORed
  5562. * @return true if all the flags are set, false otherwise
  5563. */
  5564. SmartPropertyPrim.prototype._areAllFlagsSet = function (flags) {
  5565. return (this._flags & flags) === flags;
  5566. };
  5567. /**
  5568. * Check if at least one flag of the given flags is set
  5569. * @param flags the flags ORed
  5570. * @return true if at least one flag is set, false otherwise
  5571. */
  5572. SmartPropertyPrim.prototype._areSomeFlagsSet = function (flags) {
  5573. return (this._flags & flags) !== 0;
  5574. };
  5575. /**
  5576. * Clear the given flags
  5577. * @param flags the flags to clear
  5578. */
  5579. SmartPropertyPrim.prototype._clearFlags = function (flags) {
  5580. this._flags &= ~flags;
  5581. };
  5582. /**
  5583. * Set the given flags to true state
  5584. * @param flags the flags ORed to set
  5585. * @return the flags state before this call
  5586. */
  5587. SmartPropertyPrim.prototype._setFlags = function (flags) {
  5588. var cur = this._flags;
  5589. this._flags |= flags;
  5590. return cur;
  5591. };
  5592. /**
  5593. * Change the state of the given flags
  5594. * @param flags the flags ORed to change
  5595. * @param state true to set them, false to clear them
  5596. */
  5597. SmartPropertyPrim.prototype._changeFlags = function (flags, state) {
  5598. if (state) {
  5599. this._flags |= flags;
  5600. }
  5601. else {
  5602. this._flags &= ~flags;
  5603. }
  5604. };
  5605. SmartPropertyPrim.prototype._getFlagsDebug = function (flags) {
  5606. var res = "";
  5607. if (flags & SmartPropertyPrim_1.flagNoPartOfLayout)
  5608. res += "NoPartOfLayout, ";
  5609. if (flags & SmartPropertyPrim_1.flagLevelBoundingInfoDirty)
  5610. res += "LevelBoundingInfoDirty, ";
  5611. if (flags & SmartPropertyPrim_1.flagModelDirty)
  5612. res += "ModelDirty, ";
  5613. if (flags & SmartPropertyPrim_1.flagLayoutDirty)
  5614. res += "LayoutDirty, ";
  5615. if (flags & SmartPropertyPrim_1.flagLevelVisible)
  5616. res += "LevelVisible, ";
  5617. if (flags & SmartPropertyPrim_1.flagBoundingInfoDirty)
  5618. res += "BoundingInfoDirty, ";
  5619. if (flags & SmartPropertyPrim_1.flagIsPickable)
  5620. res += "IsPickable, ";
  5621. if (flags & SmartPropertyPrim_1.flagIsVisible)
  5622. res += "IsVisible, ";
  5623. if (flags & SmartPropertyPrim_1.flagVisibilityChanged)
  5624. res += "VisibilityChanged, ";
  5625. if (flags & SmartPropertyPrim_1.flagPositioningDirty)
  5626. res += "PositioningDirty, ";
  5627. if (flags & SmartPropertyPrim_1.flagTrackedGroup)
  5628. res += "TrackedGroup, ";
  5629. if (flags & SmartPropertyPrim_1.flagWorldCacheChanged)
  5630. res += "WorldCacheChanged, ";
  5631. if (flags & SmartPropertyPrim_1.flagChildrenFlatZOrder)
  5632. res += "ChildrenFlatZOrder, ";
  5633. if (flags & SmartPropertyPrim_1.flagZOrderDirty)
  5634. res += "ZOrderDirty, ";
  5635. if (flags & SmartPropertyPrim_1.flagActualOpacityDirty)
  5636. res += "ActualOpacityDirty, ";
  5637. if (flags & SmartPropertyPrim_1.flagPrimInDirtyList)
  5638. res += "PrimInDirtyList, ";
  5639. if (flags & SmartPropertyPrim_1.flagIsContainer)
  5640. res += "IsContainer, ";
  5641. if (flags & SmartPropertyPrim_1.flagNeedRefresh)
  5642. res += "NeedRefresh, ";
  5643. if (flags & SmartPropertyPrim_1.flagActualScaleDirty)
  5644. res += "ActualScaleDirty, ";
  5645. if (flags & SmartPropertyPrim_1.flagDontInheritParentScale)
  5646. res += "DontInheritParentScale, ";
  5647. if (flags & SmartPropertyPrim_1.flagGlobalTransformDirty)
  5648. res += "GlobalTransformDirty, ";
  5649. if (flags & SmartPropertyPrim_1.flagLayoutBoundingInfoDirty)
  5650. res += "LayoutBoundingInfoDirty, ";
  5651. if (flags & SmartPropertyPrim_1.flagCollisionActor)
  5652. res += "CollisionActor, ";
  5653. if (flags & SmartPropertyPrim_1.flagModelUpdate)
  5654. res += "ModelUpdate, ";
  5655. if (flags & SmartPropertyPrim_1.flagLocalTransformDirty)
  5656. res += "LocalTransformDirty, ";
  5657. if (flags & SmartPropertyPrim_1.flagUsePositioning)
  5658. res += "UsePositioning, ";
  5659. if (flags & SmartPropertyPrim_1.flagComputingPositioning)
  5660. res += "ComputingPositioning, ";
  5661. return res.slice(0, res.length - 2);
  5662. };
  5663. return SmartPropertyPrim;
  5664. }(SmartPropertyBase));
  5665. SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT = 0;
  5666. SmartPropertyPrim.flagNoPartOfLayout = 0x0000001; // set if the primitive's position/size must not be computed by Layout Engine
  5667. SmartPropertyPrim.flagLevelBoundingInfoDirty = 0x0000002; // set if the primitive's level bounding box (not including children) is dirty
  5668. SmartPropertyPrim.flagModelDirty = 0x0000004; // set if the model must be changed
  5669. SmartPropertyPrim.flagLayoutDirty = 0x0000008; // set if the layout must be computed
  5670. SmartPropertyPrim.flagLevelVisible = 0x0000010; // set if the primitive is set as visible for its level only
  5671. SmartPropertyPrim.flagBoundingInfoDirty = 0x0000020; // set if the primitive's overall bounding box (including children) is dirty
  5672. SmartPropertyPrim.flagIsPickable = 0x0000040; // set if the primitive can be picked during interaction
  5673. SmartPropertyPrim.flagIsVisible = 0x0000080; // set if the primitive is concretely visible (use the levelVisible of parents)
  5674. SmartPropertyPrim.flagVisibilityChanged = 0x0000100; // set if there was a transition between visible/hidden status
  5675. SmartPropertyPrim.flagPositioningDirty = 0x0000200; // set if the primitive positioning must be computed
  5676. SmartPropertyPrim.flagTrackedGroup = 0x0000400; // set if the group2D is tracking a scene node
  5677. SmartPropertyPrim.flagWorldCacheChanged = 0x0000800; // set if the cached bitmap of a world space canvas changed
  5678. SmartPropertyPrim.flagChildrenFlatZOrder = 0x0001000; // set if all the children (direct and indirect) will share the same Z-Order
  5679. SmartPropertyPrim.flagZOrderDirty = 0x0002000; // set if the Z-Order for this prim and its children must be recomputed
  5680. SmartPropertyPrim.flagActualOpacityDirty = 0x0004000; // set if the actualOpactity should be recomputed
  5681. SmartPropertyPrim.flagPrimInDirtyList = 0x0008000; // set if the primitive is in the primDirtyList
  5682. SmartPropertyPrim.flagIsContainer = 0x0010000; // set if the primitive is a container
  5683. SmartPropertyPrim.flagNeedRefresh = 0x0020000; // set if the primitive wasn't successful at refresh
  5684. SmartPropertyPrim.flagActualScaleDirty = 0x0040000; // set if the actualScale property needs to be recomputed
  5685. SmartPropertyPrim.flagDontInheritParentScale = 0x0080000; // set if the actualScale must not use its parent's scale to be computed
  5686. SmartPropertyPrim.flagGlobalTransformDirty = 0x0100000; // set if the global transform must be recomputed due to a local transform change
  5687. SmartPropertyPrim.flagLayoutBoundingInfoDirty = 0x0200000; // set if the layout bounding info is dirty
  5688. SmartPropertyPrim.flagCollisionActor = 0x0400000; // set if the primitive is part of the collision engine
  5689. SmartPropertyPrim.flagModelUpdate = 0x0800000; // set if the primitive's model data is to update
  5690. SmartPropertyPrim.flagLocalTransformDirty = 0x1000000; // set if the local transformation matrix must be recomputed
  5691. SmartPropertyPrim.flagUsePositioning = 0x2000000; // set if the primitive rely on the positioning engine (padding or margin is used)
  5692. SmartPropertyPrim.flagComputingPositioning = 0x4000000; // set if the positioning engine is computing the primitive, used to avoid re entrance
  5693. SmartPropertyPrim.flagAlignPrimitive = 0x8000000; // set if the primitive should be pixel aligned to the render target
  5694. __decorate([
  5695. BABYLON.logProp()
  5696. ], SmartPropertyPrim.prototype, "levelBoundingInfo", null);
  5697. SmartPropertyPrim = SmartPropertyPrim_1 = __decorate([
  5698. BABYLON.className("SmartPropertyPrim", "BABYLON")
  5699. /**
  5700. * Base class of the primitives, implementing core crosscutting features
  5701. */
  5702. ], SmartPropertyPrim);
  5703. BABYLON.SmartPropertyPrim = SmartPropertyPrim;
  5704. function dependencyProperty(propId, piStore, mode, updateSourceTrigger) {
  5705. if (mode === void 0) { mode = DataBinding.MODE_TWOWAY; }
  5706. if (updateSourceTrigger === void 0) { updateSourceTrigger = DataBinding.UPDATESOURCETRIGGER_PROPERTYCHANGED; }
  5707. return SmartPropertyBase._hookProperty(propId, piStore, Prim2DPropInfo.PROPKIND_DYNAMIC, { bindingMode: mode, bindingUpdateSourceTrigger: updateSourceTrigger });
  5708. }
  5709. BABYLON.dependencyProperty = dependencyProperty;
  5710. function modelLevelProperty(propId, piStore, typeLevelCompare, dirtyBoundingInfo, dirtyParentBoundingBox) {
  5711. if (typeLevelCompare === void 0) { typeLevelCompare = false; }
  5712. if (dirtyBoundingInfo === void 0) { dirtyBoundingInfo = false; }
  5713. if (dirtyParentBoundingBox === void 0) { dirtyParentBoundingBox = false; }
  5714. return SmartPropertyBase._hookProperty(propId, piStore, Prim2DPropInfo.PROPKIND_MODEL, { typeLevelCompare: typeLevelCompare, dirtyBoundingInfo: dirtyBoundingInfo, dirtyParentBoundingBox: dirtyParentBoundingBox });
  5715. }
  5716. BABYLON.modelLevelProperty = modelLevelProperty;
  5717. function instanceLevelProperty(propId, piStore, typeLevelCompare, dirtyBoundingInfo, dirtyParentBoundingBox) {
  5718. if (typeLevelCompare === void 0) { typeLevelCompare = false; }
  5719. if (dirtyBoundingInfo === void 0) { dirtyBoundingInfo = false; }
  5720. if (dirtyParentBoundingBox === void 0) { dirtyParentBoundingBox = false; }
  5721. return SmartPropertyBase._hookProperty(propId, piStore, Prim2DPropInfo.PROPKIND_INSTANCE, { typeLevelCompare: typeLevelCompare, dirtyBoundingInfo: dirtyBoundingInfo, dirtyParentBoundingBox: dirtyParentBoundingBox });
  5722. }
  5723. BABYLON.instanceLevelProperty = instanceLevelProperty;
  5724. function dynamicLevelProperty(propId, piStore, typeLevelCompare, dirtyBoundingInfo, dirtyParentBoundingBox) {
  5725. if (typeLevelCompare === void 0) { typeLevelCompare = false; }
  5726. if (dirtyBoundingInfo === void 0) { dirtyBoundingInfo = false; }
  5727. if (dirtyParentBoundingBox === void 0) { dirtyParentBoundingBox = false; }
  5728. return SmartPropertyBase._hookProperty(propId, piStore, Prim2DPropInfo.PROPKIND_DYNAMIC, { typeLevelCompare: typeLevelCompare, dirtyBoundingInfo: dirtyBoundingInfo, dirtyParentBoundingBox: dirtyParentBoundingBox });
  5729. }
  5730. BABYLON.dynamicLevelProperty = dynamicLevelProperty;
  5731. var DataBinding_1, SmartPropertyBase_1, SmartPropertyPrim_1;
  5732. })(BABYLON || (BABYLON = {}));
  5733. //# sourceMappingURL=babylon.smartPropertyPrim.js.map
  5734. var __extends = (this && this.__extends) || (function () {
  5735. var extendStatics = Object.setPrototypeOf ||
  5736. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  5737. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  5738. return function (d, b) {
  5739. extendStatics(d, b);
  5740. function __() { this.constructor = d; }
  5741. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  5742. };
  5743. })();
  5744. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  5745. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  5746. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  5747. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  5748. return c > 3 && r && Object.defineProperty(target, key, r), r;
  5749. };
  5750. var BABYLON;
  5751. (function (BABYLON) {
  5752. var PrepareRender2DContext = (function () {
  5753. function PrepareRender2DContext() {
  5754. this.forceRefreshPrimitive = false;
  5755. }
  5756. return PrepareRender2DContext;
  5757. }());
  5758. BABYLON.PrepareRender2DContext = PrepareRender2DContext;
  5759. var Render2DContext = (function () {
  5760. function Render2DContext(renderMode) {
  5761. this._renderMode = renderMode;
  5762. this.useInstancing = false;
  5763. this.groupInfoPartData = null;
  5764. this.partDataStartIndex = this.partDataEndIndex = null;
  5765. this.instancedBuffers = null;
  5766. }
  5767. Object.defineProperty(Render2DContext.prototype, "renderMode", {
  5768. /**
  5769. * Define which render Mode should be used to render the primitive: one of Render2DContext.RenderModeXxxx property
  5770. */
  5771. get: function () {
  5772. return this._renderMode;
  5773. },
  5774. enumerable: true,
  5775. configurable: true
  5776. });
  5777. Object.defineProperty(Render2DContext, "RenderModeOpaque", {
  5778. /**
  5779. * The set of primitives to render is opaque.
  5780. * This is the first rendering pass. All Opaque primitives are rendered. Depth Compare and Write are both enabled.
  5781. */
  5782. get: function () {
  5783. return Render2DContext._renderModeOpaque;
  5784. },
  5785. enumerable: true,
  5786. configurable: true
  5787. });
  5788. Object.defineProperty(Render2DContext, "RenderModeAlphaTest", {
  5789. /**
  5790. * The set of primitives to render is using Alpha Test (aka masking).
  5791. * Alpha Blend is enabled, the AlphaMode must be manually set, the render occurs after the RenderModeOpaque and is depth independent (i.e. primitives are not sorted by depth). Depth Compare and Write are both enabled.
  5792. */
  5793. get: function () {
  5794. return Render2DContext._renderModeAlphaTest;
  5795. },
  5796. enumerable: true,
  5797. configurable: true
  5798. });
  5799. Object.defineProperty(Render2DContext, "RenderModeTransparent", {
  5800. /**
  5801. * The set of primitives to render is transparent.
  5802. * Alpha Blend is enabled, the AlphaMode must be manually set, the render occurs after the RenderModeAlphaTest and is depth dependent (i.e. primitives are stored by depth and rendered back to front). Depth Compare is on, but Depth write is Off.
  5803. */
  5804. get: function () {
  5805. return Render2DContext._renderModeTransparent;
  5806. },
  5807. enumerable: true,
  5808. configurable: true
  5809. });
  5810. return Render2DContext;
  5811. }());
  5812. Render2DContext._renderModeOpaque = 1;
  5813. Render2DContext._renderModeAlphaTest = 2;
  5814. Render2DContext._renderModeTransparent = 3;
  5815. BABYLON.Render2DContext = Render2DContext;
  5816. /**
  5817. * This class store information for the pointerEventObservable Observable.
  5818. * The Observable is divided into many sub events (using the Mask feature of the Observable pattern): PointerOver, PointerEnter, PointerDown, PointerMouseWheel, PointerMove, PointerUp, PointerDown, PointerLeave, PointerGotCapture and PointerLostCapture.
  5819. */
  5820. var PrimitivePointerInfo = (function () {
  5821. function PrimitivePointerInfo() {
  5822. this.primitivePointerPos = BABYLON.Vector2.Zero();
  5823. this.tilt = BABYLON.Vector2.Zero();
  5824. this.cancelBubble = false;
  5825. }
  5826. Object.defineProperty(PrimitivePointerInfo, "PointerOver", {
  5827. // The behavior is based on the HTML specifications of the Pointer Events (https://www.w3.org/TR/pointerevents/#list-of-pointer-events). This is not 100% compliant and not meant to be, but still, it's based on these specs for most use cases to be programmed the same way (as closest as possible) as it would have been in HTML.
  5828. /**
  5829. * This event type is raised when a pointing device is moved into the hit test boundaries of a primitive.
  5830. * Bubbles: yes
  5831. */
  5832. get: function () {
  5833. return PrimitivePointerInfo._pointerOver;
  5834. },
  5835. enumerable: true,
  5836. configurable: true
  5837. });
  5838. Object.defineProperty(PrimitivePointerInfo, "PointerEnter", {
  5839. /**
  5840. * This event type is raised when a pointing device is moved into the hit test boundaries of a primitive or one of its descendants.
  5841. * Bubbles: no
  5842. */
  5843. get: function () {
  5844. return PrimitivePointerInfo._pointerEnter;
  5845. },
  5846. enumerable: true,
  5847. configurable: true
  5848. });
  5849. Object.defineProperty(PrimitivePointerInfo, "PointerDown", {
  5850. /**
  5851. * This event type is raised when a pointer enters the active button state (non-zero value in the buttons property). For mouse it's when the device transitions from no buttons depressed to at least one button depressed. For touch/pen this is when a physical contact is made.
  5852. * Bubbles: yes
  5853. */
  5854. get: function () {
  5855. return PrimitivePointerInfo._pointerDown;
  5856. },
  5857. enumerable: true,
  5858. configurable: true
  5859. });
  5860. Object.defineProperty(PrimitivePointerInfo, "PointerMouseWheel", {
  5861. /**
  5862. * This event type is raised when the pointer is a mouse and it's wheel is rolling
  5863. * Bubbles: yes
  5864. */
  5865. get: function () {
  5866. return PrimitivePointerInfo._pointerMouseWheel;
  5867. },
  5868. enumerable: true,
  5869. configurable: true
  5870. });
  5871. Object.defineProperty(PrimitivePointerInfo, "PointerMove", {
  5872. /**
  5873. * This event type is raised when a pointer change coordinates or when a pointer changes button state, pressure, tilt, or contact geometry and the circumstances produce no other pointers events.
  5874. * Bubbles: yes
  5875. */
  5876. get: function () {
  5877. return PrimitivePointerInfo._pointerMove;
  5878. },
  5879. enumerable: true,
  5880. configurable: true
  5881. });
  5882. Object.defineProperty(PrimitivePointerInfo, "PointerUp", {
  5883. /**
  5884. * This event type is raised when the pointer leaves the active buttons states (zero value in the buttons property). For mouse, this is when the device transitions from at least one button depressed to no buttons depressed. For touch/pen, this is when physical contact is removed.
  5885. * Bubbles: yes
  5886. */
  5887. get: function () {
  5888. return PrimitivePointerInfo._pointerUp;
  5889. },
  5890. enumerable: true,
  5891. configurable: true
  5892. });
  5893. Object.defineProperty(PrimitivePointerInfo, "PointerOut", {
  5894. /**
  5895. * This event type is raised when a pointing device is moved out of the hit test the boundaries of a primitive.
  5896. * Bubbles: yes
  5897. */
  5898. get: function () {
  5899. return PrimitivePointerInfo._pointerOut;
  5900. },
  5901. enumerable: true,
  5902. configurable: true
  5903. });
  5904. Object.defineProperty(PrimitivePointerInfo, "PointerLeave", {
  5905. /**
  5906. * This event type is raised when a pointing device is moved out of the hit test boundaries of a primitive and all its descendants.
  5907. * Bubbles: no
  5908. */
  5909. get: function () {
  5910. return PrimitivePointerInfo._pointerLeave;
  5911. },
  5912. enumerable: true,
  5913. configurable: true
  5914. });
  5915. Object.defineProperty(PrimitivePointerInfo, "PointerGotCapture", {
  5916. /**
  5917. * This event type is raised when a primitive receives the pointer capture. This event is fired at the element that is receiving pointer capture. Subsequent events for that pointer will be fired at this element.
  5918. * Bubbles: yes
  5919. */
  5920. get: function () {
  5921. return PrimitivePointerInfo._pointerGotCapture;
  5922. },
  5923. enumerable: true,
  5924. configurable: true
  5925. });
  5926. Object.defineProperty(PrimitivePointerInfo, "PointerLostCapture", {
  5927. /**
  5928. * This event type is raised after pointer capture is released for a pointer.
  5929. * Bubbles: yes
  5930. */
  5931. get: function () {
  5932. return PrimitivePointerInfo._pointerLostCapture;
  5933. },
  5934. enumerable: true,
  5935. configurable: true
  5936. });
  5937. Object.defineProperty(PrimitivePointerInfo, "MouseWheelPrecision", {
  5938. get: function () {
  5939. return PrimitivePointerInfo._mouseWheelPrecision;
  5940. },
  5941. enumerable: true,
  5942. configurable: true
  5943. });
  5944. PrimitivePointerInfo.prototype.updateRelatedTarget = function (prim, primPointerPos) {
  5945. this.relatedTarget = prim;
  5946. this.relatedTargetPointerPos = primPointerPos;
  5947. };
  5948. PrimitivePointerInfo.getEventTypeName = function (mask) {
  5949. switch (mask) {
  5950. case PrimitivePointerInfo.PointerOver: return "PointerOver";
  5951. case PrimitivePointerInfo.PointerEnter: return "PointerEnter";
  5952. case PrimitivePointerInfo.PointerDown: return "PointerDown";
  5953. case PrimitivePointerInfo.PointerMouseWheel: return "PointerMouseWheel";
  5954. case PrimitivePointerInfo.PointerMove: return "PointerMove";
  5955. case PrimitivePointerInfo.PointerUp: return "PointerUp";
  5956. case PrimitivePointerInfo.PointerOut: return "PointerOut";
  5957. case PrimitivePointerInfo.PointerLeave: return "PointerLeave";
  5958. case PrimitivePointerInfo.PointerGotCapture: return "PointerGotCapture";
  5959. case PrimitivePointerInfo.PointerLostCapture: return "PointerLostCapture";
  5960. }
  5961. };
  5962. return PrimitivePointerInfo;
  5963. }());
  5964. PrimitivePointerInfo._pointerOver = 0x0001;
  5965. PrimitivePointerInfo._pointerEnter = 0x0002;
  5966. PrimitivePointerInfo._pointerDown = 0x0004;
  5967. PrimitivePointerInfo._pointerMouseWheel = 0x0008;
  5968. PrimitivePointerInfo._pointerMove = 0x0010;
  5969. PrimitivePointerInfo._pointerUp = 0x0020;
  5970. PrimitivePointerInfo._pointerOut = 0x0040;
  5971. PrimitivePointerInfo._pointerLeave = 0x0080;
  5972. PrimitivePointerInfo._pointerGotCapture = 0x0100;
  5973. PrimitivePointerInfo._pointerLostCapture = 0x0200;
  5974. PrimitivePointerInfo._mouseWheelPrecision = 3.0;
  5975. BABYLON.PrimitivePointerInfo = PrimitivePointerInfo;
  5976. /**
  5977. * Defines the horizontal and vertical alignment information for a Primitive.
  5978. */
  5979. var PrimitiveAlignment = PrimitiveAlignment_1 = (function () {
  5980. function PrimitiveAlignment(changeCallback) {
  5981. this._changedCallback = changeCallback;
  5982. this._horizontal = PrimitiveAlignment_1.AlignLeft;
  5983. this._vertical = PrimitiveAlignment_1.AlignBottom;
  5984. }
  5985. Object.defineProperty(PrimitiveAlignment, "AlignLeft", {
  5986. /**
  5987. * Alignment is made relative to the left edge of the Primitive. Valid for horizontal alignment only.
  5988. */
  5989. get: function () { return PrimitiveAlignment_1._AlignLeft; },
  5990. enumerable: true,
  5991. configurable: true
  5992. });
  5993. Object.defineProperty(PrimitiveAlignment, "AlignTop", {
  5994. /**
  5995. * Alignment is made relative to the top edge of the Primitive. Valid for vertical alignment only.
  5996. */
  5997. get: function () { return PrimitiveAlignment_1._AlignTop; },
  5998. enumerable: true,
  5999. configurable: true
  6000. });
  6001. Object.defineProperty(PrimitiveAlignment, "AlignRight", {
  6002. /**
  6003. * Alignment is made relative to the right edge of the Primitive. Valid for horizontal alignment only.
  6004. */
  6005. get: function () { return PrimitiveAlignment_1._AlignRight; },
  6006. enumerable: true,
  6007. configurable: true
  6008. });
  6009. Object.defineProperty(PrimitiveAlignment, "AlignBottom", {
  6010. /**
  6011. * Alignment is made relative to the bottom edge of the Primitive. Valid for vertical alignment only.
  6012. */
  6013. get: function () { return PrimitiveAlignment_1._AlignBottom; },
  6014. enumerable: true,
  6015. configurable: true
  6016. });
  6017. Object.defineProperty(PrimitiveAlignment, "AlignCenter", {
  6018. /**
  6019. * Alignment is made to center the content from equal distance to the opposite edges of the Primitive
  6020. */
  6021. get: function () { return PrimitiveAlignment_1._AlignCenter; },
  6022. enumerable: true,
  6023. configurable: true
  6024. });
  6025. Object.defineProperty(PrimitiveAlignment, "AlignStretch", {
  6026. /**
  6027. * The content is stretched toward the opposite edges of the Primitive
  6028. */
  6029. get: function () { return PrimitiveAlignment_1._AlignStretch; },
  6030. enumerable: true,
  6031. configurable: true
  6032. });
  6033. Object.defineProperty(PrimitiveAlignment.prototype, "horizontal", {
  6034. /**
  6035. * Get/set the horizontal alignment. Use one of the AlignXXX static properties of this class
  6036. */
  6037. get: function () {
  6038. return this._horizontal;
  6039. },
  6040. set: function (value) {
  6041. if (this._horizontal === value) {
  6042. return;
  6043. }
  6044. this._horizontal = value;
  6045. this.onChangeCallback();
  6046. },
  6047. enumerable: true,
  6048. configurable: true
  6049. });
  6050. Object.defineProperty(PrimitiveAlignment.prototype, "vertical", {
  6051. /**
  6052. * Get/set the vertical alignment. Use one of the AlignXXX static properties of this class
  6053. */
  6054. get: function () {
  6055. return this._vertical;
  6056. },
  6057. set: function (value) {
  6058. if (this._vertical === value) {
  6059. return;
  6060. }
  6061. this._vertical = value;
  6062. this.onChangeCallback();
  6063. },
  6064. enumerable: true,
  6065. configurable: true
  6066. });
  6067. PrimitiveAlignment.prototype.onChangeCallback = function () {
  6068. if (this._changedCallback) {
  6069. this._changedCallback();
  6070. }
  6071. };
  6072. /**
  6073. * Set the horizontal alignment from a string value.
  6074. * @param text can be either: 'left','right','center','stretch'
  6075. */
  6076. PrimitiveAlignment.prototype.setHorizontal = function (text) {
  6077. var v = text.trim().toLocaleLowerCase();
  6078. switch (v) {
  6079. case "left":
  6080. this.horizontal = PrimitiveAlignment_1.AlignLeft;
  6081. return;
  6082. case "right":
  6083. this.horizontal = PrimitiveAlignment_1.AlignRight;
  6084. return;
  6085. case "center":
  6086. this.horizontal = PrimitiveAlignment_1.AlignCenter;
  6087. return;
  6088. case "stretch":
  6089. this.horizontal = PrimitiveAlignment_1.AlignStretch;
  6090. return;
  6091. }
  6092. };
  6093. /**
  6094. * Set the vertical alignment from a string value.
  6095. * @param text can be either: 'top','bottom','center','stretch'
  6096. */
  6097. PrimitiveAlignment.prototype.setVertical = function (text) {
  6098. var v = text.trim().toLocaleLowerCase();
  6099. switch (v) {
  6100. case "top":
  6101. this.vertical = PrimitiveAlignment_1.AlignTop;
  6102. return;
  6103. case "bottom":
  6104. this.vertical = PrimitiveAlignment_1.AlignBottom;
  6105. return;
  6106. case "center":
  6107. this.vertical = PrimitiveAlignment_1.AlignCenter;
  6108. return;
  6109. case "stretch":
  6110. this.vertical = PrimitiveAlignment_1.AlignStretch;
  6111. return;
  6112. }
  6113. };
  6114. /**
  6115. * Set the horizontal and or vertical alignments from a string value.
  6116. * @param text can be: [<h:|horizontal:><left|right|center|stretch>], [<v:|vertical:><top|bottom|center|stretch>]
  6117. */
  6118. PrimitiveAlignment.prototype.fromString = function (value) {
  6119. var m = value.trim().split(",");
  6120. var hset = false;
  6121. var vset = false;
  6122. for (var _i = 0, m_1 = m; _i < m_1.length; _i++) {
  6123. var v = m_1[_i];
  6124. v = v.toLocaleLowerCase().trim();
  6125. // Horizontal
  6126. var i = v.indexOf("h:");
  6127. if (i === -1) {
  6128. i = v.indexOf("horizontal:");
  6129. }
  6130. if (i !== -1) {
  6131. v = v.substr(v.indexOf(":") + 1);
  6132. this.setHorizontal(v);
  6133. hset = true;
  6134. continue;
  6135. }
  6136. // Vertical
  6137. i = v.indexOf("v:");
  6138. if (i === -1) {
  6139. i = v.indexOf("vertical:");
  6140. }
  6141. if (i !== -1) {
  6142. v = v.substr(v.indexOf(":") + 1);
  6143. this.setVertical(v);
  6144. vset = true;
  6145. continue;
  6146. }
  6147. }
  6148. if (!hset && !vset && m.length === 1) {
  6149. this.setHorizontal(m[0]);
  6150. this.setVertical(m[0]);
  6151. }
  6152. };
  6153. PrimitiveAlignment.prototype.copyFrom = function (pa) {
  6154. this._horizontal = pa._horizontal;
  6155. this._vertical = pa._vertical;
  6156. this.onChangeCallback();
  6157. };
  6158. PrimitiveAlignment.prototype.clone = function () {
  6159. var pa = new PrimitiveAlignment_1();
  6160. pa._horizontal = this._horizontal;
  6161. pa._vertical = this._vertical;
  6162. return pa;
  6163. };
  6164. Object.defineProperty(PrimitiveAlignment.prototype, "isDefault", {
  6165. get: function () {
  6166. return this.horizontal === PrimitiveAlignment_1.AlignLeft && this.vertical === PrimitiveAlignment_1.AlignBottom;
  6167. },
  6168. enumerable: true,
  6169. configurable: true
  6170. });
  6171. return PrimitiveAlignment;
  6172. }());
  6173. PrimitiveAlignment._AlignLeft = 1;
  6174. PrimitiveAlignment._AlignTop = 1; // Same as left
  6175. PrimitiveAlignment._AlignRight = 2;
  6176. PrimitiveAlignment._AlignBottom = 2; // Same as right
  6177. PrimitiveAlignment._AlignCenter = 3;
  6178. PrimitiveAlignment._AlignStretch = 4;
  6179. PrimitiveAlignment = PrimitiveAlignment_1 = __decorate([
  6180. BABYLON.className("PrimitiveAlignment", "BABYLON")
  6181. ], PrimitiveAlignment);
  6182. BABYLON.PrimitiveAlignment = PrimitiveAlignment;
  6183. /**
  6184. * Stores information about a Primitive that was intersected
  6185. */
  6186. var PrimitiveIntersectedInfo = (function () {
  6187. function PrimitiveIntersectedInfo(prim, intersectionLocation) {
  6188. this.prim = prim;
  6189. this.intersectionLocation = intersectionLocation;
  6190. }
  6191. return PrimitiveIntersectedInfo;
  6192. }());
  6193. BABYLON.PrimitiveIntersectedInfo = PrimitiveIntersectedInfo;
  6194. /**
  6195. * Define a thickness toward every edges of a Primitive to allow margin and padding.
  6196. * The thickness can be expressed as pixels, percentages, inherit the value of the parent primitive or be auto.
  6197. */
  6198. var PrimitiveThickness = PrimitiveThickness_1 = (function () {
  6199. function PrimitiveThickness(parentAccess, changedCallback) {
  6200. this._parentAccess = parentAccess;
  6201. this._changedCallback = changedCallback;
  6202. this._pixels = new Array(4);
  6203. this._percentages = new Array(4);
  6204. this._setType(0, PrimitiveThickness_1.Auto);
  6205. this._setType(1, PrimitiveThickness_1.Auto);
  6206. this._setType(2, PrimitiveThickness_1.Auto);
  6207. this._setType(3, PrimitiveThickness_1.Auto);
  6208. this._pixels[0] = 0;
  6209. this._pixels[1] = 0;
  6210. this._pixels[2] = 0;
  6211. this._pixels[3] = 0;
  6212. }
  6213. /**
  6214. * Set the thickness from a string value
  6215. * @param thickness format is "top: <value>, left:<value>, right:<value>, bottom:<value>" or "<value>" (same for all edges) each are optional, auto will be set if it's omitted.
  6216. * Values are: 'auto', 'inherit', 'XX%' for percentage, 'XXpx' or 'XX' for pixels.
  6217. */
  6218. PrimitiveThickness.prototype.fromString = function (thickness) {
  6219. this._clear();
  6220. var m = thickness.trim().split(",");
  6221. // Special case, one value to apply to all edges
  6222. if (m.length === 1 && thickness.indexOf(":") === -1) {
  6223. this._setStringValue(m[0], 0, false);
  6224. this._setStringValue(m[0], 1, false);
  6225. this._setStringValue(m[0], 2, false);
  6226. this._setStringValue(m[0], 3, false);
  6227. this.onChangeCallback();
  6228. return;
  6229. }
  6230. var res = false;
  6231. for (var _i = 0, m_2 = m; _i < m_2.length; _i++) {
  6232. var cm = m_2[_i];
  6233. res = this._extractString(cm, false) || res;
  6234. }
  6235. if (!res) {
  6236. throw new Error("Can't parse the string to create a PrimitiveMargin object, format must be: 'top: <value>, left:<value>, right:<value>, bottom:<value>");
  6237. }
  6238. // Check the margin that weren't set and set them in auto
  6239. if ((this._flags & 0x000F) === 0)
  6240. this._flags |= PrimitiveThickness_1.Pixel << 0;
  6241. if ((this._flags & 0x00F0) === 0)
  6242. this._flags |= PrimitiveThickness_1.Pixel << 4;
  6243. if ((this._flags & 0x0F00) === 0)
  6244. this._flags |= PrimitiveThickness_1.Pixel << 8;
  6245. if ((this._flags & 0xF000) === 0)
  6246. this._flags |= PrimitiveThickness_1.Pixel << 12;
  6247. this.onChangeCallback();
  6248. };
  6249. /**
  6250. * Set the thickness from multiple string
  6251. * Possible values are: 'auto', 'inherit', 'XX%' for percentage, 'XXpx' or 'XX' for pixels.
  6252. * @param top the top thickness to set
  6253. * @param left the left thickness to set
  6254. * @param right the right thickness to set
  6255. * @param bottom the bottom thickness to set
  6256. */
  6257. PrimitiveThickness.prototype.fromStrings = function (top, left, right, bottom) {
  6258. this._clear();
  6259. this._setStringValue(top, 0, false);
  6260. this._setStringValue(left, 1, false);
  6261. this._setStringValue(right, 2, false);
  6262. this._setStringValue(bottom, 3, false);
  6263. this.onChangeCallback();
  6264. return this;
  6265. };
  6266. /**
  6267. * Set the thickness from pixel values
  6268. * @param top the top thickness in pixels to set
  6269. * @param left the left thickness in pixels to set
  6270. * @param right the right thickness in pixels to set
  6271. * @param bottom the bottom thickness in pixels to set
  6272. */
  6273. PrimitiveThickness.prototype.fromPixels = function (top, left, right, bottom) {
  6274. this._clear();
  6275. this._pixels[0] = top;
  6276. this._pixels[1] = left;
  6277. this._pixels[2] = right;
  6278. this._pixels[3] = bottom;
  6279. this.onChangeCallback();
  6280. return this;
  6281. };
  6282. /**
  6283. * Apply the same pixel value to all edges
  6284. * @param margin the value to set, in pixels.
  6285. */
  6286. PrimitiveThickness.prototype.fromUniformPixels = function (margin) {
  6287. this._clear();
  6288. this._pixels[0] = margin;
  6289. this._pixels[1] = margin;
  6290. this._pixels[2] = margin;
  6291. this._pixels[3] = margin;
  6292. this.onChangeCallback();
  6293. return this;
  6294. };
  6295. PrimitiveThickness.prototype.copyFrom = function (pt) {
  6296. this._clear();
  6297. for (var i = 0; i < 4; i++) {
  6298. this._pixels[i] = pt._pixels[i];
  6299. this._percentages[i] = pt._percentages[i];
  6300. }
  6301. this._flags = pt._flags;
  6302. this.onChangeCallback();
  6303. };
  6304. /**
  6305. * Set all edges in auto
  6306. */
  6307. PrimitiveThickness.prototype.auto = function () {
  6308. this._clear();
  6309. this._flags = (PrimitiveThickness_1.Auto << 0) | (PrimitiveThickness_1.Auto << 4) | (PrimitiveThickness_1.Auto << 8) | (PrimitiveThickness_1.Auto << 12);
  6310. this._pixels[0] = 0;
  6311. this._pixels[1] = 0;
  6312. this._pixels[2] = 0;
  6313. this._pixels[3] = 0;
  6314. this.onChangeCallback();
  6315. return this;
  6316. };
  6317. PrimitiveThickness.prototype._clear = function () {
  6318. this._flags = 0;
  6319. this._pixels[0] = 0;
  6320. this._pixels[1] = 0;
  6321. this._pixels[2] = 0;
  6322. this._pixels[3] = 0;
  6323. this._percentages[0] = null;
  6324. this._percentages[1] = null;
  6325. this._percentages[2] = null;
  6326. this._percentages[3] = null;
  6327. };
  6328. PrimitiveThickness.prototype._extractString = function (value, emitChanged) {
  6329. var v = value.trim().toLocaleLowerCase();
  6330. if (v.indexOf("top:") === 0) {
  6331. v = v.substr(4).trim();
  6332. return this._setStringValue(v, 0, emitChanged);
  6333. }
  6334. if (v.indexOf("left:") === 0) {
  6335. v = v.substr(5).trim();
  6336. return this._setStringValue(v, 1, emitChanged);
  6337. }
  6338. if (v.indexOf("right:") === 0) {
  6339. v = v.substr(6).trim();
  6340. return this._setStringValue(v, 2, emitChanged);
  6341. }
  6342. if (v.indexOf("bottom:") === 0) {
  6343. v = v.substr(7).trim();
  6344. return this._setStringValue(v, 3, emitChanged);
  6345. }
  6346. return false;
  6347. };
  6348. PrimitiveThickness.prototype._setStringValue = function (value, index, emitChanged) {
  6349. // Check for auto
  6350. var v = value.trim().toLocaleLowerCase();
  6351. if (v === "auto") {
  6352. if (this._isType(index, PrimitiveThickness_1.Auto)) {
  6353. return true;
  6354. }
  6355. this._setType(index, PrimitiveThickness_1.Auto);
  6356. this._pixels[index] = 0;
  6357. if (emitChanged) {
  6358. this.onChangeCallback();
  6359. }
  6360. }
  6361. else if (v === "inherit") {
  6362. if (this._isType(index, PrimitiveThickness_1.Inherit)) {
  6363. return true;
  6364. }
  6365. this._setType(index, PrimitiveThickness_1.Inherit);
  6366. this._pixels[index] = null;
  6367. if (emitChanged) {
  6368. this.onChangeCallback();
  6369. }
  6370. }
  6371. else {
  6372. var pI = v.indexOf("%");
  6373. // Check for percentage
  6374. if (pI !== -1) {
  6375. var n_1 = v.substr(0, pI);
  6376. var number_1 = Math.round(Number(n_1)) / 100; // Normalize the percentage to [0;1] with a 0.01 precision
  6377. if (this._isType(index, PrimitiveThickness_1.Percentage) && (this._percentages[index] === number_1)) {
  6378. return true;
  6379. }
  6380. this._setType(index, PrimitiveThickness_1.Percentage);
  6381. if (isNaN(number_1)) {
  6382. return false;
  6383. }
  6384. this._percentages[index] = number_1;
  6385. if (emitChanged) {
  6386. this.onChangeCallback();
  6387. }
  6388. return true;
  6389. }
  6390. // Check for pixel
  6391. var n = void 0;
  6392. pI = v.indexOf("px");
  6393. if (pI !== -1) {
  6394. n = v.substr(0, pI).trim();
  6395. }
  6396. else {
  6397. n = v;
  6398. }
  6399. var number = Number(n);
  6400. if (this._isType(index, PrimitiveThickness_1.Pixel) && (this._pixels[index] === number)) {
  6401. return true;
  6402. }
  6403. if (isNaN(number)) {
  6404. return false;
  6405. }
  6406. this._pixels[index] = number;
  6407. this._setType(index, PrimitiveThickness_1.Pixel);
  6408. if (emitChanged) {
  6409. this.onChangeCallback();
  6410. }
  6411. return true;
  6412. }
  6413. };
  6414. PrimitiveThickness.prototype._setPixels = function (value, index, emitChanged) {
  6415. // Round the value because, well, it's the thing to do! Otherwise we'll have sub-pixel stuff, and the no change comparison just below will almost never work for PrimitiveThickness values inside a hierarchy of Primitives
  6416. value = Math.round(value);
  6417. if (this._isType(index, PrimitiveThickness_1.Pixel) && this._pixels[index] === value) {
  6418. return;
  6419. }
  6420. this._setType(index, PrimitiveThickness_1.Pixel);
  6421. this._pixels[index] = value;
  6422. if (emitChanged) {
  6423. this.onChangeCallback();
  6424. }
  6425. };
  6426. PrimitiveThickness.prototype._setPercentage = function (value, index, emitChanged) {
  6427. // Clip Value to bounds
  6428. value = Math.min(1, value);
  6429. value = Math.max(0, value);
  6430. value = Math.round(value * 100) / 100; // 0.01 precision
  6431. if (this._isType(index, PrimitiveThickness_1.Percentage) && this._percentages[index] === value) {
  6432. return;
  6433. }
  6434. this._setType(index, PrimitiveThickness_1.Percentage);
  6435. this._percentages[index] = value;
  6436. if (emitChanged) {
  6437. this.onChangeCallback();
  6438. }
  6439. };
  6440. PrimitiveThickness.prototype._getStringValue = function (index) {
  6441. var f = (this._flags >> (index * 4)) & 0xF;
  6442. switch (f) {
  6443. case PrimitiveThickness_1.Auto:
  6444. return "auto";
  6445. case PrimitiveThickness_1.Pixel:
  6446. return this._pixels[index] + "px";
  6447. case PrimitiveThickness_1.Percentage:
  6448. return this._percentages[index] * 100 + "%";
  6449. case PrimitiveThickness_1.Inherit:
  6450. return "inherit";
  6451. }
  6452. return "";
  6453. };
  6454. PrimitiveThickness.prototype._isType = function (index, type) {
  6455. var f = (this._flags >> (index * 4)) & 0xF;
  6456. return f === type;
  6457. };
  6458. PrimitiveThickness.prototype._getType = function (index, processInherit) {
  6459. var t = (this._flags >> (index * 4)) & 0xF;
  6460. if (processInherit && (t === PrimitiveThickness_1.Inherit)) {
  6461. var p = this._parentAccess();
  6462. if (p) {
  6463. return p._getType(index, true);
  6464. }
  6465. return PrimitiveThickness_1.Auto;
  6466. }
  6467. return t;
  6468. };
  6469. PrimitiveThickness.prototype._setType = function (index, type) {
  6470. this._flags &= ~(0xF << (index * 4));
  6471. this._flags |= type << (index * 4);
  6472. };
  6473. PrimitiveThickness.prototype.setTop = function (value) {
  6474. if (typeof value === "string") {
  6475. this._setStringValue(value, 0, true);
  6476. }
  6477. else {
  6478. this.topPixels = value;
  6479. }
  6480. };
  6481. PrimitiveThickness.prototype.setLeft = function (value) {
  6482. if (typeof value === "string") {
  6483. this._setStringValue(value, 1, true);
  6484. }
  6485. else {
  6486. this.leftPixels = value;
  6487. }
  6488. };
  6489. PrimitiveThickness.prototype.setRight = function (value) {
  6490. if (typeof value === "string") {
  6491. this._setStringValue(value, 2, true);
  6492. }
  6493. else {
  6494. this.rightPixels = value;
  6495. }
  6496. };
  6497. PrimitiveThickness.prototype.setBottom = function (value) {
  6498. if (typeof value === "string") {
  6499. this._setStringValue(value, 3, true);
  6500. }
  6501. else {
  6502. this.bottomPixels = value;
  6503. }
  6504. };
  6505. Object.defineProperty(PrimitiveThickness.prototype, "top", {
  6506. /**
  6507. * Get/set the top thickness. Possible values are: 'auto', 'inherit', 'XX%' for percentage, 'XXpx' or 'XX' for pixels.
  6508. */
  6509. get: function () {
  6510. return this._getStringValue(0);
  6511. },
  6512. set: function (value) {
  6513. this._setStringValue(value, 0, true);
  6514. },
  6515. enumerable: true,
  6516. configurable: true
  6517. });
  6518. Object.defineProperty(PrimitiveThickness.prototype, "left", {
  6519. /**
  6520. * Get/set the left thickness. Possible values are: 'auto', 'inherit', 'XX%' for percentage, 'XXpx' or 'XX' for pixels.
  6521. */
  6522. get: function () {
  6523. return this._getStringValue(1);
  6524. },
  6525. set: function (value) {
  6526. this._setStringValue(value, 1, true);
  6527. },
  6528. enumerable: true,
  6529. configurable: true
  6530. });
  6531. Object.defineProperty(PrimitiveThickness.prototype, "right", {
  6532. /**
  6533. * Get/set the right thickness. Possible values are: 'auto', 'inherit', 'XX%' for percentage, 'XXpx' or 'XX' for pixels.
  6534. */
  6535. get: function () {
  6536. return this._getStringValue(2);
  6537. },
  6538. set: function (value) {
  6539. this._setStringValue(value, 2, true);
  6540. },
  6541. enumerable: true,
  6542. configurable: true
  6543. });
  6544. Object.defineProperty(PrimitiveThickness.prototype, "bottom", {
  6545. /**
  6546. * Get/set the bottom thickness. Possible values are: 'auto', 'inherit', 'XX%' for percentage, 'XXpx' or 'XX' for pixels.
  6547. */
  6548. get: function () {
  6549. return this._getStringValue(3);
  6550. },
  6551. set: function (value) {
  6552. this._setStringValue(value, 3, true);
  6553. },
  6554. enumerable: true,
  6555. configurable: true
  6556. });
  6557. Object.defineProperty(PrimitiveThickness.prototype, "topPixels", {
  6558. /**
  6559. * Get/set the top thickness in pixel.
  6560. */
  6561. get: function () {
  6562. return this._pixels[0];
  6563. },
  6564. set: function (value) {
  6565. this._setPixels(value, 0, true);
  6566. },
  6567. enumerable: true,
  6568. configurable: true
  6569. });
  6570. Object.defineProperty(PrimitiveThickness.prototype, "leftPixels", {
  6571. /**
  6572. * Get/set the left thickness in pixel.
  6573. */
  6574. get: function () {
  6575. return this._pixels[1];
  6576. },
  6577. set: function (value) {
  6578. this._setPixels(value, 1, true);
  6579. },
  6580. enumerable: true,
  6581. configurable: true
  6582. });
  6583. Object.defineProperty(PrimitiveThickness.prototype, "rightPixels", {
  6584. /**
  6585. * Get/set the right thickness in pixel.
  6586. */
  6587. get: function () {
  6588. return this._pixels[2];
  6589. },
  6590. set: function (value) {
  6591. this._setPixels(value, 2, true);
  6592. },
  6593. enumerable: true,
  6594. configurable: true
  6595. });
  6596. Object.defineProperty(PrimitiveThickness.prototype, "bottomPixels", {
  6597. /**
  6598. * Get/set the bottom thickness in pixel.
  6599. */
  6600. get: function () {
  6601. return this._pixels[3];
  6602. },
  6603. set: function (value) {
  6604. this._setPixels(value, 3, true);
  6605. },
  6606. enumerable: true,
  6607. configurable: true
  6608. });
  6609. Object.defineProperty(PrimitiveThickness.prototype, "topPercentage", {
  6610. /**
  6611. * Get/set the top thickness in percentage.
  6612. * The get will return a valid value only if the edge type is percentage.
  6613. * The Set will change the edge mode if needed
  6614. */
  6615. get: function () {
  6616. return this._percentages[0];
  6617. },
  6618. set: function (value) {
  6619. this._setPercentage(value, 0, true);
  6620. },
  6621. enumerable: true,
  6622. configurable: true
  6623. });
  6624. Object.defineProperty(PrimitiveThickness.prototype, "leftPercentage", {
  6625. /**
  6626. * Get/set the left thickness in percentage.
  6627. * The get will return a valid value only if the edge mode is percentage.
  6628. * The Set will change the edge mode if needed
  6629. */
  6630. get: function () {
  6631. return this._percentages[1];
  6632. },
  6633. set: function (value) {
  6634. this._setPercentage(value, 1, true);
  6635. },
  6636. enumerable: true,
  6637. configurable: true
  6638. });
  6639. Object.defineProperty(PrimitiveThickness.prototype, "rightPercentage", {
  6640. /**
  6641. * Get/set the right thickness in percentage.
  6642. * The get will return a valid value only if the edge mode is percentage.
  6643. * The Set will change the edge mode if needed
  6644. */
  6645. get: function () {
  6646. return this._percentages[2];
  6647. },
  6648. set: function (value) {
  6649. this._setPercentage(value, 2, true);
  6650. },
  6651. enumerable: true,
  6652. configurable: true
  6653. });
  6654. Object.defineProperty(PrimitiveThickness.prototype, "bottomPercentage", {
  6655. /**
  6656. * Get/set the bottom thickness in percentage.
  6657. * The get will return a valid value only if the edge mode is percentage.
  6658. * The Set will change the edge mode if needed
  6659. */
  6660. get: function () {
  6661. return this._percentages[3];
  6662. },
  6663. set: function (value) {
  6664. this._setPercentage(value, 3, true);
  6665. },
  6666. enumerable: true,
  6667. configurable: true
  6668. });
  6669. Object.defineProperty(PrimitiveThickness.prototype, "topMode", {
  6670. /**
  6671. * Get/set the top mode. The setter shouldn't be used, other setters with value should be preferred
  6672. */
  6673. get: function () {
  6674. return this._getType(0, false);
  6675. },
  6676. set: function (mode) {
  6677. this._setType(0, mode);
  6678. },
  6679. enumerable: true,
  6680. configurable: true
  6681. });
  6682. Object.defineProperty(PrimitiveThickness.prototype, "leftMode", {
  6683. /**
  6684. * Get/set the left mode. The setter shouldn't be used, other setters with value should be preferred
  6685. */
  6686. get: function () {
  6687. return this._getType(1, false);
  6688. },
  6689. set: function (mode) {
  6690. this._setType(1, mode);
  6691. },
  6692. enumerable: true,
  6693. configurable: true
  6694. });
  6695. Object.defineProperty(PrimitiveThickness.prototype, "rightMode", {
  6696. /**
  6697. * Get/set the right mode. The setter shouldn't be used, other setters with value should be preferred
  6698. */
  6699. get: function () {
  6700. return this._getType(2, false);
  6701. },
  6702. set: function (mode) {
  6703. this._setType(2, mode);
  6704. },
  6705. enumerable: true,
  6706. configurable: true
  6707. });
  6708. Object.defineProperty(PrimitiveThickness.prototype, "bottomMode", {
  6709. /**
  6710. * Get/set the bottom mode. The setter shouldn't be used, other setters with value should be preferred
  6711. */
  6712. get: function () {
  6713. return this._getType(3, false);
  6714. },
  6715. set: function (mode) {
  6716. this._setType(3, mode);
  6717. },
  6718. enumerable: true,
  6719. configurable: true
  6720. });
  6721. Object.defineProperty(PrimitiveThickness.prototype, "isDefault", {
  6722. get: function () {
  6723. return this._flags === 0x1111;
  6724. },
  6725. enumerable: true,
  6726. configurable: true
  6727. });
  6728. PrimitiveThickness.prototype._computePixels = function (index, sourceArea, emitChanged) {
  6729. var type = this._getType(index, false);
  6730. if (type === PrimitiveThickness_1.Inherit) {
  6731. this._parentAccess()._computePixels(index, sourceArea, emitChanged);
  6732. return;
  6733. }
  6734. if (type !== PrimitiveThickness_1.Percentage) {
  6735. return;
  6736. }
  6737. var pixels = ((index === 0 || index === 3) ? sourceArea.height : sourceArea.width) * this._percentages[index];
  6738. this._pixels[index] = pixels;
  6739. if (emitChanged) {
  6740. this.onChangeCallback();
  6741. }
  6742. };
  6743. PrimitiveThickness.prototype.onChangeCallback = function () {
  6744. if (this._changedCallback) {
  6745. this._changedCallback();
  6746. }
  6747. };
  6748. /**
  6749. * Compute the positioning/size of an area considering the thickness of this object and a given alignment
  6750. * @param sourceArea the source area where the content must be sized/positioned
  6751. * @param contentSize the content size to position/resize
  6752. * @param alignment the alignment setting
  6753. * @param dstOffset the position of the content, x, y, z, w are left, bottom, right, top
  6754. * @param dstArea the new size of the content
  6755. */
  6756. PrimitiveThickness.prototype.computeWithAlignment = function (sourceArea, contentSize, alignment, contentScale, dstOffset, dstArea, computeLayoutArea, computeAxis) {
  6757. if (computeLayoutArea === void 0) { computeLayoutArea = false; }
  6758. if (computeAxis === void 0) { computeAxis = PrimitiveThickness_1.ComputeAll; }
  6759. // Fetch some data
  6760. var topType = this._getType(0, true);
  6761. var leftType = this._getType(1, true);
  6762. var rightType = this._getType(2, true);
  6763. var bottomType = this._getType(3, true);
  6764. var hasWidth = contentSize && (contentSize.width != null);
  6765. var hasHeight = contentSize && (contentSize.height != null);
  6766. var sx = contentScale.x;
  6767. var sy = contentScale.y;
  6768. var isx = 1 / sx;
  6769. var isy = 1 / sy;
  6770. var width = hasWidth ? contentSize.width : 0;
  6771. var height = hasHeight ? contentSize.height : 0;
  6772. var isTopAuto = topType === PrimitiveThickness_1.Auto;
  6773. var isLeftAuto = leftType === PrimitiveThickness_1.Auto;
  6774. var isRightAuto = rightType === PrimitiveThickness_1.Auto;
  6775. var isBottomAuto = bottomType === PrimitiveThickness_1.Auto;
  6776. if (computeAxis & PrimitiveThickness_1.ComputeH) {
  6777. switch (alignment.horizontal) {
  6778. case PrimitiveAlignment.AlignLeft:
  6779. {
  6780. var leftPixels = 0;
  6781. if (!isLeftAuto) {
  6782. this._computePixels(1, sourceArea, true);
  6783. leftPixels = this.leftPixels;
  6784. }
  6785. dstOffset.x = leftPixels;
  6786. dstArea.width = width * isx;
  6787. dstOffset.z = sourceArea.width - (width * sx + leftPixels);
  6788. if (computeLayoutArea) {
  6789. var rightPixels = 0;
  6790. if (!isRightAuto) {
  6791. this._computePixels(2, sourceArea, true);
  6792. rightPixels = this.rightPixels;
  6793. }
  6794. dstArea.width += (leftPixels + rightPixels) * isx;
  6795. }
  6796. break;
  6797. }
  6798. case PrimitiveAlignment.AlignRight:
  6799. {
  6800. var rightPixels = 0;
  6801. if (!isRightAuto) {
  6802. this._computePixels(2, sourceArea, true);
  6803. rightPixels = this.rightPixels;
  6804. }
  6805. dstOffset.x = sourceArea.width - (width * sx + rightPixels);
  6806. dstArea.width = width * isx;
  6807. dstOffset.z = rightPixels;
  6808. if (computeLayoutArea) {
  6809. var leftPixels = 0;
  6810. if (!isLeftAuto) {
  6811. this._computePixels(1, sourceArea, true);
  6812. leftPixels = this.leftPixels;
  6813. }
  6814. dstArea.width += (leftPixels + rightPixels) * isx;
  6815. }
  6816. break;
  6817. }
  6818. case PrimitiveAlignment.AlignStretch:
  6819. {
  6820. if (isLeftAuto) {
  6821. dstOffset.x = 0;
  6822. }
  6823. else {
  6824. this._computePixels(1, sourceArea, true);
  6825. dstOffset.x = this.leftPixels;
  6826. }
  6827. var rightPixels = 0;
  6828. if (!isRightAuto) {
  6829. this._computePixels(2, sourceArea, true);
  6830. rightPixels = this.rightPixels;
  6831. }
  6832. if (computeLayoutArea) {
  6833. dstArea.width = sourceArea.width * isx;
  6834. }
  6835. else {
  6836. dstArea.width = (sourceArea.width * isx) - (dstOffset.x + rightPixels) * isx;
  6837. }
  6838. dstOffset.z = this.rightPixels;
  6839. break;
  6840. }
  6841. case PrimitiveAlignment.AlignCenter:
  6842. {
  6843. var leftPixels = 0;
  6844. if (!isLeftAuto) {
  6845. this._computePixels(1, sourceArea, true);
  6846. leftPixels = this.leftPixels;
  6847. }
  6848. var rightPixels = 0;
  6849. if (!isRightAuto) {
  6850. this._computePixels(2, sourceArea, true);
  6851. rightPixels = this.rightPixels;
  6852. }
  6853. var center = ((sourceArea.width - (width * sx)) / 2);
  6854. dstOffset.x = center + (leftPixels - rightPixels);
  6855. if (computeLayoutArea) {
  6856. dstArea.width = (width * isx) + (this.leftPixels + this.rightPixels) * isx;
  6857. }
  6858. else {
  6859. dstArea.width = (width * isx);
  6860. }
  6861. dstOffset.z = rightPixels + center;
  6862. break;
  6863. }
  6864. }
  6865. }
  6866. if (computeAxis & PrimitiveThickness_1.ComputeV) {
  6867. switch (alignment.vertical) {
  6868. case PrimitiveAlignment.AlignBottom:
  6869. {
  6870. var bottomPixels = 0;
  6871. if (!isBottomAuto) {
  6872. this._computePixels(3, sourceArea, true);
  6873. bottomPixels = this.bottomPixels;
  6874. }
  6875. dstOffset.y = bottomPixels;
  6876. dstArea.height = height * isy;
  6877. dstOffset.w = sourceArea.height - (height * sy + bottomPixels);
  6878. if (computeLayoutArea) {
  6879. var topPixels = 0;
  6880. if (!isTopAuto) {
  6881. this._computePixels(0, sourceArea, true);
  6882. topPixels = this.topPixels;
  6883. }
  6884. dstArea.height += (bottomPixels + topPixels) * isy;
  6885. }
  6886. break;
  6887. }
  6888. case PrimitiveAlignment.AlignTop:
  6889. {
  6890. var topPixels = 0;
  6891. if (!isTopAuto) {
  6892. this._computePixels(0, sourceArea, true);
  6893. topPixels = this.topPixels;
  6894. }
  6895. dstOffset.y = sourceArea.height - ((height * sy) + topPixels);
  6896. dstArea.height = height * isy;
  6897. dstOffset.w = topPixels;
  6898. if (computeLayoutArea) {
  6899. var bottomPixels = 0;
  6900. if (!isBottomAuto) {
  6901. this._computePixels(3, sourceArea, true);
  6902. bottomPixels = this.bottomPixels;
  6903. }
  6904. dstArea.height += (bottomPixels + topPixels) * isy;
  6905. }
  6906. break;
  6907. }
  6908. case PrimitiveAlignment.AlignStretch:
  6909. {
  6910. var bottom = 0;
  6911. if (!isBottomAuto) {
  6912. this._computePixels(3, sourceArea, true);
  6913. bottom = this.bottomPixels;
  6914. }
  6915. dstOffset.y = bottom;
  6916. var top_1 = 0;
  6917. if (!isTopAuto) {
  6918. this._computePixels(0, sourceArea, true);
  6919. top_1 = this.topPixels;
  6920. }
  6921. dstOffset.w = top_1;
  6922. if (computeLayoutArea) {
  6923. dstArea.height = sourceArea.height * isy;
  6924. }
  6925. else {
  6926. dstArea.height = (sourceArea.height * isy) - (top_1 + bottom) * isy;
  6927. }
  6928. break;
  6929. }
  6930. case PrimitiveAlignment.AlignCenter:
  6931. {
  6932. var bottomPixels = 0;
  6933. if (!isBottomAuto) {
  6934. this._computePixels(3, sourceArea, true);
  6935. bottomPixels = this.bottomPixels;
  6936. }
  6937. var topPixels = 0;
  6938. if (!isTopAuto) {
  6939. this._computePixels(0, sourceArea, true);
  6940. topPixels = this.topPixels;
  6941. }
  6942. var center = ((sourceArea.height - (height * sy)) / 2);
  6943. dstOffset.y = center + (bottomPixels - topPixels);
  6944. if (computeLayoutArea) {
  6945. dstArea.height = (height * isy) + (bottomPixels + topPixels) * isy;
  6946. }
  6947. else {
  6948. dstArea.height = (height * isy);
  6949. }
  6950. dstOffset.w = topPixels + center;
  6951. break;
  6952. }
  6953. }
  6954. }
  6955. };
  6956. /**
  6957. * Compute an area and its position considering this thickness properties based on a given source area
  6958. * @param sourceArea the source area
  6959. * @param dstOffset the position of the resulting area
  6960. * @param dstArea the size of the resulting area
  6961. */
  6962. PrimitiveThickness.prototype.compute = function (sourceArea, dstOffset, dstArea, computeLayoutArea) {
  6963. if (computeLayoutArea === void 0) { computeLayoutArea = false; }
  6964. this._computePixels(0, sourceArea, true);
  6965. this._computePixels(1, sourceArea, true);
  6966. this._computePixels(2, sourceArea, true);
  6967. this._computePixels(3, sourceArea, true);
  6968. dstOffset.x = this.leftPixels;
  6969. if (computeLayoutArea) {
  6970. dstArea.width = (sourceArea.width) + (dstOffset.x + this.rightPixels);
  6971. }
  6972. else {
  6973. dstArea.width = (sourceArea.width) - (dstOffset.x + this.rightPixels);
  6974. }
  6975. dstOffset.y = this.bottomPixels;
  6976. if (computeLayoutArea) {
  6977. dstArea.height = (sourceArea.height) + (dstOffset.y + this.topPixels);
  6978. }
  6979. else {
  6980. dstArea.height = (sourceArea.height) - (dstOffset.y + this.topPixels);
  6981. }
  6982. dstOffset.z = this.rightPixels;
  6983. dstOffset.w = this.topPixels;
  6984. };
  6985. /**
  6986. * Compute an area considering this thickness properties based on a given source area
  6987. * @param sourceArea the source area
  6988. * @param result the resulting area
  6989. */
  6990. PrimitiveThickness.prototype.computeArea = function (sourceArea, sourceScale, result) {
  6991. this._computePixels(0, sourceArea, true);
  6992. this._computePixels(1, sourceArea, true);
  6993. this._computePixels(2, sourceArea, true);
  6994. this._computePixels(3, sourceArea, true);
  6995. result.width = this.leftPixels + (sourceArea.width * sourceScale.x) + this.rightPixels;
  6996. result.height = this.bottomPixels + (sourceArea.height * sourceScale.y) + this.topPixels;
  6997. };
  6998. PrimitiveThickness.prototype.enlarge = function (sourceArea, sourceScale, dstOffset, enlargedArea) {
  6999. this._computePixels(0, sourceArea, true);
  7000. this._computePixels(1, sourceArea, true);
  7001. this._computePixels(2, sourceArea, true);
  7002. this._computePixels(3, sourceArea, true);
  7003. dstOffset.x = this.leftPixels;
  7004. enlargedArea.width = (sourceArea.width * sourceScale.x) + (dstOffset.x + this.rightPixels);
  7005. dstOffset.y = this.bottomPixels;
  7006. enlargedArea.height = (sourceArea.height * sourceScale.y) + (dstOffset.y + this.topPixels);
  7007. dstOffset.z = this.rightPixels;
  7008. dstOffset.w = this.topPixels;
  7009. };
  7010. return PrimitiveThickness;
  7011. }());
  7012. PrimitiveThickness.Auto = 0x1;
  7013. PrimitiveThickness.Inherit = 0x2;
  7014. PrimitiveThickness.Percentage = 0x4;
  7015. PrimitiveThickness.Pixel = 0x8;
  7016. PrimitiveThickness.ComputeH = 0x1;
  7017. PrimitiveThickness.ComputeV = 0x2;
  7018. PrimitiveThickness.ComputeAll = 0x03;
  7019. PrimitiveThickness = PrimitiveThickness_1 = __decorate([
  7020. BABYLON.className("PrimitiveThickness", "BABYLON")
  7021. ], PrimitiveThickness);
  7022. BABYLON.PrimitiveThickness = PrimitiveThickness;
  7023. /**
  7024. * Main class used for the Primitive Intersection API
  7025. */
  7026. var IntersectInfo2D = (function () {
  7027. function IntersectInfo2D() {
  7028. this.findFirstOnly = false;
  7029. this.intersectHidden = false;
  7030. this.pickPosition = BABYLON.Vector2.Zero();
  7031. }
  7032. Object.defineProperty(IntersectInfo2D.prototype, "isIntersected", {
  7033. /**
  7034. * true if at least one primitive intersected during the test
  7035. */
  7036. get: function () {
  7037. return this.intersectedPrimitives && this.intersectedPrimitives.length > 0;
  7038. },
  7039. enumerable: true,
  7040. configurable: true
  7041. });
  7042. IntersectInfo2D.prototype.isPrimIntersected = function (prim) {
  7043. for (var _i = 0, _a = this.intersectedPrimitives; _i < _a.length; _i++) {
  7044. var cur = _a[_i];
  7045. if (cur.prim === prim) {
  7046. return cur.intersectionLocation;
  7047. }
  7048. }
  7049. return null;
  7050. };
  7051. // Internals, don't use
  7052. IntersectInfo2D.prototype._exit = function (firstLevel) {
  7053. if (firstLevel) {
  7054. this._globalPickPosition = null;
  7055. }
  7056. };
  7057. return IntersectInfo2D;
  7058. }());
  7059. BABYLON.IntersectInfo2D = IntersectInfo2D;
  7060. var Prim2DBase = Prim2DBase_1 = (function (_super) {
  7061. __extends(Prim2DBase, _super);
  7062. function Prim2DBase(settings) {
  7063. var _this = this;
  7064. // Avoid checking every time if the object exists
  7065. if (settings == null) {
  7066. settings = {};
  7067. }
  7068. // BASE CLASS CALL
  7069. _this = _super.call(this) || this;
  7070. // Fetch the owner, parent. There're many ways to do it and we can end up with nothing for both
  7071. var owner;
  7072. var parent;
  7073. if (Prim2DBase_1._isCanvasInit) {
  7074. owner = _this;
  7075. parent = null;
  7076. _this._canvasPreInit(settings);
  7077. }
  7078. else {
  7079. if (settings.parent != null) {
  7080. parent = settings.parent;
  7081. owner = settings.parent.owner;
  7082. if (!owner) {
  7083. throw new Error("Parent " + parent.id + " of " + settings.id + " doesn't have a valid owner!");
  7084. }
  7085. if (!(_this instanceof BABYLON.Group2D) && !(_this instanceof BABYLON.Sprite2D && settings.id != null && settings.id.indexOf("__cachedSpriteOfGroup__") === 0) && (owner.cachingStrategy === BABYLON.Canvas2D.CACHESTRATEGY_TOPLEVELGROUPS) && (parent === owner)) {
  7086. throw new Error("Can't create a primitive with the canvas as direct parent when the caching strategy is TOPLEVELGROUPS. You need to create a Group below the canvas and use it as the parent for the primitive");
  7087. }
  7088. }
  7089. }
  7090. // Fields initialization
  7091. _this._layoutEngine = BABYLON.CanvasLayoutEngine.Singleton;
  7092. _this._size = null; //Size.Zero();
  7093. _this._scale = new BABYLON.Vector2(1, 1);
  7094. _this._postScale = new BABYLON.Vector2(1, 1);
  7095. _this._actualSize = null;
  7096. _this._internalSize = BABYLON.Size.Zero();
  7097. _this._layoutArea = null;
  7098. _this._layoutAreaPos = null;
  7099. _this._layoutBoundingInfo = null;
  7100. _this._marginOffset = BABYLON.Vector4.Zero();
  7101. _this._paddingOffset = BABYLON.Vector4.Zero();
  7102. _this._parentPaddingOffset = BABYLON.Vector2.Zero();
  7103. _this._parentContentArea = BABYLON.Size.Zero();
  7104. _this._lastAutoSizeArea = BABYLON.Size.Zero();
  7105. _this._contentArea = BABYLON.Size.Zero();
  7106. _this._pointerEventObservable = new BABYLON.Observable();
  7107. _this._owner = owner;
  7108. _this._parent = null;
  7109. _this._margin = null;
  7110. _this._padding = null;
  7111. _this._marginAlignment = null;
  7112. _this._id = settings.id;
  7113. _this._children = new Array();
  7114. _this._localTransform = new BABYLON.Matrix2D();
  7115. _this._localLayoutTransform = new BABYLON.Matrix2D();
  7116. _this._globalTransform = null;
  7117. _this._invGlobalTransform = null;
  7118. _this._globalTransformProcessStep = 0;
  7119. _this._globalTransformStep = 0;
  7120. _this._prepareProcessStep = 0;
  7121. _this._updateCachesProcessStep = 0;
  7122. _this._renderGroup = null;
  7123. _this._primLinearPosition = 0;
  7124. _this._manualZOrder = null;
  7125. _this._zOrder = 0;
  7126. _this._zMax = 0;
  7127. _this._firstZDirtyIndex = Prim2DBase_1._bigInt;
  7128. _this._actualOpacity = 0;
  7129. _this._actualScale = BABYLON.Vector2.Zero();
  7130. _this._displayDebugAreas = false;
  7131. _this._debugAreaGroup = null;
  7132. _this._primTriArray = null;
  7133. _this._primTriArrayDirty = true;
  7134. if (owner) {
  7135. _this.onSetOwner();
  7136. }
  7137. _this._levelBoundingInfo.worldMatrixAccess = function () { return _this.globalTransform; };
  7138. _this._boundingInfo.worldMatrixAccess = function () { return _this.globalTransform; };
  7139. var isPickable = true;
  7140. var isContainer = true;
  7141. if (settings.isPickable !== undefined) {
  7142. isPickable = settings.isPickable;
  7143. }
  7144. if (settings.isContainer !== undefined) {
  7145. isContainer = settings.isContainer;
  7146. }
  7147. if (settings.dontInheritParentScale) {
  7148. _this._setFlags(BABYLON.SmartPropertyPrim.flagDontInheritParentScale);
  7149. }
  7150. if (settings.alignToPixel) {
  7151. _this.alignToPixel = true;
  7152. }
  7153. _this._setFlags((isPickable ? BABYLON.SmartPropertyPrim.flagIsPickable : 0) | BABYLON.SmartPropertyPrim.flagBoundingInfoDirty | BABYLON.SmartPropertyPrim.flagActualOpacityDirty | (isContainer ? BABYLON.SmartPropertyPrim.flagIsContainer : 0) | BABYLON.SmartPropertyPrim.flagActualScaleDirty | BABYLON.SmartPropertyPrim.flagLayoutBoundingInfoDirty);
  7154. if (settings.opacity != null) {
  7155. _this._opacity = settings.opacity;
  7156. }
  7157. else {
  7158. _this._opacity = 1;
  7159. }
  7160. _this._updateRenderMode();
  7161. if (settings.childrenFlatZOrder) {
  7162. _this._setFlags(BABYLON.SmartPropertyPrim.flagChildrenFlatZOrder);
  7163. }
  7164. // If the parent is given, initialize the hierarchy/owner related data
  7165. if (parent != null) {
  7166. parent.addChild(_this);
  7167. _this._hierarchyDepth = parent._hierarchyDepth + 1;
  7168. _this._patchHierarchy(parent.owner);
  7169. }
  7170. // If it's a group, detect its own states
  7171. if (_this.owner && _this instanceof BABYLON.Group2D) {
  7172. var group = _this;
  7173. group.detectGroupStates();
  7174. }
  7175. // Time to insert children if some are specified
  7176. if (settings.children != null) {
  7177. for (var _i = 0, _a = settings.children; _i < _a.length; _i++) {
  7178. var child = _a[_i];
  7179. _this.addChild(child);
  7180. // Good time to patch the hierarchy, it won't go very far if there's no need to
  7181. if (_this.owner != null && _this._hierarchyDepth != null) {
  7182. child._patchHierarchy(_this.owner);
  7183. }
  7184. }
  7185. }
  7186. if (settings.zOrder != null) {
  7187. _this.zOrder = settings.zOrder;
  7188. }
  7189. // Set the model related properties
  7190. if (settings.position != null) {
  7191. _this.position = settings.position;
  7192. }
  7193. else if (settings.x != null || settings.y != null) {
  7194. _this.position = new BABYLON.Vector2(settings.x || 0, settings.y || 0);
  7195. }
  7196. else {
  7197. _this._position = null;
  7198. }
  7199. _this.rotation = (settings.rotation == null) ? 0 : settings.rotation;
  7200. if (settings.scale != null) {
  7201. _this.scale = settings.scale;
  7202. }
  7203. else {
  7204. if (settings.scaleX != null) {
  7205. _this.scaleX = settings.scaleX;
  7206. }
  7207. if (settings.scaleY != null) {
  7208. _this.scaleY = settings.scaleY;
  7209. }
  7210. }
  7211. _this.levelVisible = (settings.isVisible == null) ? true : settings.isVisible;
  7212. _this.origin = settings.origin || new BABYLON.Vector2(0.5, 0.5);
  7213. // Layout Engine
  7214. if (settings.layoutEngine != null) {
  7215. if (typeof settings.layoutEngine === "string") {
  7216. var name_1 = settings.layoutEngine.toLocaleLowerCase().trim();
  7217. if (name_1 === "canvas" || name_1 === "canvaslayoutengine") {
  7218. _this.layoutEngine = BABYLON.CanvasLayoutEngine.Singleton;
  7219. }
  7220. else if (name_1.indexOf("stackpanel") === 0 || name_1.indexOf("horizontalstackpanel") === 0) {
  7221. _this.layoutEngine = BABYLON.StackPanelLayoutEngine.Horizontal;
  7222. }
  7223. else if (name_1.indexOf("verticalstackpanel") === 0) {
  7224. _this.layoutEngine = BABYLON.StackPanelLayoutEngine.Vertical;
  7225. }
  7226. }
  7227. else if (settings.layoutEngine instanceof BABYLON.LayoutEngineBase) {
  7228. _this.layoutEngine = settings.layoutEngine;
  7229. }
  7230. }
  7231. // Set the layout/margin stuffs
  7232. if (settings.marginTop) {
  7233. _this.margin.setTop(settings.marginTop);
  7234. }
  7235. if (settings.marginLeft) {
  7236. _this.margin.setLeft(settings.marginLeft);
  7237. }
  7238. if (settings.marginRight) {
  7239. _this.margin.setRight(settings.marginRight);
  7240. }
  7241. if (settings.marginBottom) {
  7242. _this.margin.setBottom(settings.marginBottom);
  7243. }
  7244. if (settings.margin) {
  7245. if (typeof settings.margin === "string") {
  7246. _this.margin.fromString(settings.margin);
  7247. }
  7248. else {
  7249. _this.margin.fromUniformPixels(settings.margin);
  7250. }
  7251. }
  7252. if (settings.marginHAlignment) {
  7253. _this.marginAlignment.horizontal = settings.marginHAlignment;
  7254. }
  7255. if (settings.marginVAlignment) {
  7256. _this.marginAlignment.vertical = settings.marginVAlignment;
  7257. }
  7258. if (settings.marginAlignment) {
  7259. _this.marginAlignment.fromString(settings.marginAlignment);
  7260. }
  7261. if (settings.paddingTop) {
  7262. _this.padding.setTop(settings.paddingTop);
  7263. }
  7264. if (settings.paddingLeft) {
  7265. _this.padding.setLeft(settings.paddingLeft);
  7266. }
  7267. if (settings.paddingRight) {
  7268. _this.padding.setRight(settings.paddingRight);
  7269. }
  7270. if (settings.paddingBottom) {
  7271. _this.padding.setBottom(settings.paddingBottom);
  7272. }
  7273. if (settings.padding) {
  7274. if (typeof settings.padding === "string") {
  7275. _this.padding.fromString(settings.padding);
  7276. }
  7277. else {
  7278. _this.padding.fromUniformPixels(settings.padding);
  7279. }
  7280. }
  7281. if (settings.layoutData) {
  7282. _this.layoutData = settings.layoutData;
  7283. }
  7284. _this._updatePositioningState();
  7285. // Dirty layout and positioning
  7286. _this._parentLayoutDirty();
  7287. _this._positioningDirty();
  7288. // Add in the PCM
  7289. if (settings.levelCollision || settings.deepCollision) {
  7290. _this._actorInfo = _this.owner._primitiveCollisionManager._addActor(_this, settings.deepCollision === true);
  7291. _this._setFlags(BABYLON.SmartPropertyPrim.flagCollisionActor);
  7292. }
  7293. else {
  7294. _this._actorInfo = null;
  7295. }
  7296. return _this;
  7297. }
  7298. Object.defineProperty(Prim2DBase.prototype, "intersectWithObservable", {
  7299. /**
  7300. * Return the ChangedDictionary observable of the StringDictionary containing the primitives intersecting with this one
  7301. */
  7302. get: function () {
  7303. if (!this._actorInfo) {
  7304. return null;
  7305. }
  7306. return this._actorInfo.intersectWith.dictionaryChanged;
  7307. },
  7308. enumerable: true,
  7309. configurable: true
  7310. });
  7311. Object.defineProperty(Prim2DBase.prototype, "intersectWith", {
  7312. /**
  7313. * Return the ObservableStringDictionary containing all the primitives intersecting with this one.
  7314. * The key is the primitive uid, the value is the ActorInfo object
  7315. * @returns {}
  7316. */
  7317. get: function () {
  7318. if (!this._actorInfo) {
  7319. return null;
  7320. }
  7321. return this._actorInfo.intersectWith;
  7322. },
  7323. enumerable: true,
  7324. configurable: true
  7325. });
  7326. Object.defineProperty(Prim2DBase.prototype, "actionManager", {
  7327. get: function () {
  7328. if (!this._actionManager) {
  7329. this._actionManager = new BABYLON.ActionManager(this.owner.scene);
  7330. }
  7331. return this._actionManager;
  7332. },
  7333. enumerable: true,
  7334. configurable: true
  7335. });
  7336. /**
  7337. * From 'this' primitive, traverse up (from parent to parent) until the given predicate is true
  7338. * @param predicate the predicate to test on each parent
  7339. * @return the first primitive where the predicate was successful
  7340. */
  7341. Prim2DBase.prototype.traverseUp = function (predicate) {
  7342. var p = this;
  7343. while (p != null) {
  7344. if (predicate(p)) {
  7345. return p;
  7346. }
  7347. p = p._parent;
  7348. }
  7349. return null;
  7350. };
  7351. Object.defineProperty(Prim2DBase.prototype, "owner", {
  7352. /**
  7353. * Retrieve the owner Canvas2D
  7354. */
  7355. get: function () {
  7356. return this._owner;
  7357. },
  7358. enumerable: true,
  7359. configurable: true
  7360. });
  7361. Object.defineProperty(Prim2DBase.prototype, "parent", {
  7362. /**
  7363. * Get the parent primitive (can be the Canvas, only the Canvas has no parent)
  7364. */
  7365. get: function () {
  7366. return this._parent;
  7367. },
  7368. enumerable: true,
  7369. configurable: true
  7370. });
  7371. Object.defineProperty(Prim2DBase.prototype, "children", {
  7372. /**
  7373. * The array of direct children primitives
  7374. */
  7375. get: function () {
  7376. return this._children;
  7377. },
  7378. enumerable: true,
  7379. configurable: true
  7380. });
  7381. Object.defineProperty(Prim2DBase.prototype, "id", {
  7382. /**
  7383. * The identifier of this primitive, may not be unique, it's for information purpose only
  7384. */
  7385. get: function () {
  7386. return this._id;
  7387. },
  7388. set: function (value) {
  7389. if (this._id === value) {
  7390. return;
  7391. }
  7392. var oldValue = this._id;
  7393. this.onPropertyChanged("id", oldValue, this._id);
  7394. },
  7395. enumerable: true,
  7396. configurable: true
  7397. });
  7398. Object.defineProperty(Prim2DBase.prototype, "actualPosition", {
  7399. get: function () {
  7400. // If we don't use positioning engine the actual position is the position
  7401. if (!this._isFlagSet(BABYLON.SmartPropertyPrim.flagUsePositioning)) {
  7402. return this.position;
  7403. }
  7404. // We use the positioning engine, if the variable is fetched, it's up to date, return it
  7405. if (this._actualPosition != null) {
  7406. return this._actualPosition;
  7407. }
  7408. this._updatePositioning();
  7409. return this._actualPosition;
  7410. },
  7411. /**
  7412. * DO NOT INVOKE for internal purpose only
  7413. */
  7414. set: function (val) {
  7415. if (!this._actualPosition) {
  7416. this._actualPosition = val.clone();
  7417. }
  7418. else {
  7419. this._actualPosition.copyFrom(val);
  7420. }
  7421. },
  7422. enumerable: true,
  7423. configurable: true
  7424. });
  7425. Object.defineProperty(Prim2DBase.prototype, "actualX", {
  7426. /**
  7427. * Shortcut to actualPosition.x
  7428. */
  7429. get: function () {
  7430. return this.actualPosition.x;
  7431. },
  7432. /**
  7433. * DO NOT INVOKE for internal purpose only
  7434. */
  7435. set: function (val) {
  7436. this._actualPosition.x = val;
  7437. this._triggerPropertyChanged(Prim2DBase_1.actualPositionProperty, this._actualPosition);
  7438. },
  7439. enumerable: true,
  7440. configurable: true
  7441. });
  7442. Object.defineProperty(Prim2DBase.prototype, "actualY", {
  7443. /**
  7444. * Shortcut to actualPosition.y
  7445. */
  7446. get: function () {
  7447. return this.actualPosition.y;
  7448. },
  7449. /**
  7450. * DO NOT INVOKE for internal purpose only
  7451. */
  7452. set: function (val) {
  7453. this._actualPosition.y = val;
  7454. this._triggerPropertyChanged(Prim2DBase_1.actualPositionProperty, this._actualPosition);
  7455. },
  7456. enumerable: true,
  7457. configurable: true
  7458. });
  7459. Object.defineProperty(Prim2DBase.prototype, "position", {
  7460. /**
  7461. * Position of the primitive, relative to its parent.
  7462. * BEWARE: if you change only position.x or y it won't trigger a property change and you won't have the expected behavior.
  7463. * Use this property to set a new Vector2 object, otherwise to change only the x/y use Prim2DBase.x or y properties.
  7464. * Setting this property may have no effect is specific alignment are in effect.
  7465. */
  7466. get: function () {
  7467. if (!this._position) {
  7468. this._position = BABYLON.Vector2.Zero();
  7469. }
  7470. return this._position;
  7471. },
  7472. set: function (value) {
  7473. //if (!this._checkPositionChange()) {
  7474. // return;
  7475. //}
  7476. if (this._checkUseMargin()) {
  7477. switch (this.marginAlignment.horizontal) {
  7478. case PrimitiveAlignment.AlignLeft:
  7479. case PrimitiveAlignment.AlignStretch:
  7480. case PrimitiveAlignment.AlignCenter:
  7481. this.margin.leftPixels = value.x;
  7482. break;
  7483. case PrimitiveAlignment.AlignRight:
  7484. this.margin.rightPixels = value.x;
  7485. break;
  7486. }
  7487. switch (this.marginAlignment.vertical) {
  7488. case PrimitiveAlignment.AlignBottom:
  7489. case PrimitiveAlignment.AlignStretch:
  7490. case PrimitiveAlignment.AlignCenter:
  7491. this.margin.bottomPixels = value.y;
  7492. break;
  7493. case PrimitiveAlignment.AlignTop:
  7494. this.margin.topPixels = value.y;
  7495. break;
  7496. }
  7497. return;
  7498. }
  7499. else {
  7500. if (!value) {
  7501. this._position = null;
  7502. }
  7503. else {
  7504. if (!this._position) {
  7505. this._position = value.clone();
  7506. }
  7507. else {
  7508. this._position.copyFrom(value);
  7509. }
  7510. }
  7511. this._actualPosition = null;
  7512. this._triggerPropertyChanged(Prim2DBase_1.actualPositionProperty, value);
  7513. }
  7514. },
  7515. enumerable: true,
  7516. configurable: true
  7517. });
  7518. Object.defineProperty(Prim2DBase.prototype, "x", {
  7519. /**
  7520. * Direct access to the position.x value of the primitive
  7521. * Use this property when you only want to change one component of the position property
  7522. */
  7523. get: function () {
  7524. if (!this._position) {
  7525. return null;
  7526. }
  7527. return this._position.x;
  7528. },
  7529. set: function (value) {
  7530. //if (!this._checkPositionChange()) {
  7531. // return;
  7532. //}
  7533. if (value == null) {
  7534. throw new Error("Can't set a null x in primitive " + this.id + ", only the position can be turned to null");
  7535. }
  7536. if (this._checkUseMargin()) {
  7537. switch (this.marginAlignment.horizontal) {
  7538. case PrimitiveAlignment.AlignLeft:
  7539. case PrimitiveAlignment.AlignStretch:
  7540. case PrimitiveAlignment.AlignCenter:
  7541. this.margin.leftPixels = value;
  7542. break;
  7543. case PrimitiveAlignment.AlignRight:
  7544. this.margin.rightPixels = value;
  7545. break;
  7546. }
  7547. return;
  7548. }
  7549. else {
  7550. if (!this._position) {
  7551. this._position = BABYLON.Vector2.Zero();
  7552. }
  7553. if (this._position.x === value) {
  7554. return;
  7555. }
  7556. this._position.x = value;
  7557. this._actualPosition = null;
  7558. this._triggerPropertyChanged(Prim2DBase_1.positionProperty, value);
  7559. this._triggerPropertyChanged(Prim2DBase_1.actualPositionProperty, value);
  7560. }
  7561. },
  7562. enumerable: true,
  7563. configurable: true
  7564. });
  7565. Object.defineProperty(Prim2DBase.prototype, "y", {
  7566. /**
  7567. * Direct access to the position.y value of the primitive
  7568. * Use this property when you only want to change one component of the position property
  7569. */
  7570. get: function () {
  7571. if (!this._position) {
  7572. return null;
  7573. }
  7574. return this._position.y;
  7575. },
  7576. set: function (value) {
  7577. //if (!this._checkPositionChange()) {
  7578. // return;
  7579. //}
  7580. if (value == null) {
  7581. throw new Error("Can't set a null y in primitive " + this.id + ", only the position can be turned to null");
  7582. }
  7583. if (this._checkUseMargin()) {
  7584. switch (this.marginAlignment.vertical) {
  7585. case PrimitiveAlignment.AlignBottom:
  7586. case PrimitiveAlignment.AlignStretch:
  7587. case PrimitiveAlignment.AlignCenter:
  7588. this.margin.bottomPixels = value;
  7589. break;
  7590. case PrimitiveAlignment.AlignTop:
  7591. this.margin.topPixels = value;
  7592. break;
  7593. }
  7594. return;
  7595. }
  7596. else {
  7597. if (!this._position) {
  7598. this._position = BABYLON.Vector2.Zero();
  7599. }
  7600. if (this._position.y === value) {
  7601. return;
  7602. }
  7603. this._position.y = value;
  7604. this._actualPosition = null;
  7605. this._triggerPropertyChanged(Prim2DBase_1.positionProperty, value);
  7606. this._triggerPropertyChanged(Prim2DBase_1.actualPositionProperty, value);
  7607. }
  7608. },
  7609. enumerable: true,
  7610. configurable: true
  7611. });
  7612. Object.defineProperty(Prim2DBase.prototype, "size", {
  7613. get: function () {
  7614. return this.internalGetSize();
  7615. },
  7616. set: function (value) {
  7617. this.internalSetSize(value);
  7618. },
  7619. enumerable: true,
  7620. configurable: true
  7621. });
  7622. Prim2DBase.prototype.internalGetSize = function () {
  7623. if (!this._size || this._size.width == null || this._size.height == null) {
  7624. var bbr = Prim2DBase_1.boundinbBoxReentrency;
  7625. if (bbr !== -1 && bbr <= (this.hierarchyDepth || 0)) {
  7626. BABYLON.C2DLogging.setPostMessage(function () { return "re entrancy detected"; });
  7627. return Prim2DBase_1.nullSize;
  7628. }
  7629. if (!this._isFlagSet(BABYLON.SmartPropertyPrim.flagLayoutBoundingInfoDirty)) {
  7630. BABYLON.C2DLogging.setPostMessage(function () { return "cache hit"; });
  7631. return this._internalSize;
  7632. }
  7633. BABYLON.C2DLogging.setPostMessage(function () { return "cache miss"; });
  7634. Prim2DBase_1.boundinbBoxReentrency = this.hierarchyDepth || 0;
  7635. var b = this.boundingInfo;
  7636. Prim2DBase_1.boundinbBoxReentrency = -1;
  7637. Prim2DBase_1._size.copyFrom(this._internalSize);
  7638. b.sizeToRef(this._internalSize);
  7639. if (!this._internalSize.equals(Prim2DBase_1._size)) {
  7640. this._triggerPropertyChanged(Prim2DBase_1.sizeProperty, this._internalSize);
  7641. this._positioningDirty();
  7642. }
  7643. return this._internalSize || Prim2DBase_1._nullSize;
  7644. }
  7645. else {
  7646. BABYLON.C2DLogging.setPostMessage(function () { return "user set size"; });
  7647. }
  7648. return this._size || Prim2DBase_1._nullSize;
  7649. };
  7650. Prim2DBase.prototype.internalSetSize = function (value) {
  7651. if (!value) {
  7652. this._size = null;
  7653. }
  7654. else {
  7655. if (!this._size) {
  7656. this._size = value.clone();
  7657. }
  7658. else {
  7659. this._size.copyFrom(value);
  7660. }
  7661. }
  7662. this._actualSize = null;
  7663. this._updatePositioningState();
  7664. this._positioningDirty();
  7665. };
  7666. Object.defineProperty(Prim2DBase.prototype, "width", {
  7667. get: function () {
  7668. if (!this.size) {
  7669. return null;
  7670. }
  7671. return this.size.width;
  7672. },
  7673. set: function (value) {
  7674. if (this.size && this.size.width === value) {
  7675. return;
  7676. }
  7677. if (!this.size) {
  7678. this.size = new BABYLON.Size(value, 0);
  7679. }
  7680. else {
  7681. this.size.width = value;
  7682. }
  7683. this._actualSize = null;
  7684. this._triggerPropertyChanged(Prim2DBase_1.sizeProperty, value);
  7685. this._positioningDirty();
  7686. },
  7687. enumerable: true,
  7688. configurable: true
  7689. });
  7690. Object.defineProperty(Prim2DBase.prototype, "height", {
  7691. get: function () {
  7692. if (!this.size) {
  7693. return null;
  7694. }
  7695. return this.size.height;
  7696. },
  7697. set: function (value) {
  7698. if (this.size && this.size.height === value) {
  7699. return;
  7700. }
  7701. if (!this.size) {
  7702. this.size = new BABYLON.Size(0, value);
  7703. }
  7704. else {
  7705. this.size.height = value;
  7706. }
  7707. this._actualSize = null;
  7708. this._triggerPropertyChanged(Prim2DBase_1.sizeProperty, value);
  7709. this._positioningDirty();
  7710. },
  7711. enumerable: true,
  7712. configurable: true
  7713. });
  7714. Object.defineProperty(Prim2DBase.prototype, "rotation", {
  7715. get: function () {
  7716. return this._rotation;
  7717. },
  7718. set: function (value) {
  7719. this._rotation = value;
  7720. if (this._hasMargin) {
  7721. this._positioningDirty();
  7722. }
  7723. },
  7724. enumerable: true,
  7725. configurable: true
  7726. });
  7727. Object.defineProperty(Prim2DBase.prototype, "scale", {
  7728. get: function () {
  7729. return this._scale.x;
  7730. },
  7731. set: function (value) {
  7732. if (value <= 0) {
  7733. throw new Error("You can't set the scale to less or equal to 0");
  7734. }
  7735. this._scale.x = this._scale.y = value;
  7736. this._setFlags(BABYLON.SmartPropertyPrim.flagActualScaleDirty);
  7737. this._spreadActualScaleDirty();
  7738. this._positioningDirty();
  7739. },
  7740. enumerable: true,
  7741. configurable: true
  7742. });
  7743. Object.defineProperty(Prim2DBase.prototype, "actualSize", {
  7744. get: function () {
  7745. // If we don't use positioning engine the actual size is the size
  7746. if (!this._isFlagSet(BABYLON.SmartPropertyPrim.flagUsePositioning)) {
  7747. return this.size;
  7748. }
  7749. // We use the positioning engine, if the variable is fetched, it's up to date, return it
  7750. if (this._actualSize) {
  7751. return this._actualSize;
  7752. }
  7753. this._updatePositioning();
  7754. return this._actualSize;
  7755. },
  7756. set: function (value) {
  7757. if (this._actualSize && this._actualSize.equals(value)) {
  7758. return;
  7759. }
  7760. if (!this._actualSize) {
  7761. this._actualSize = value.clone();
  7762. }
  7763. else {
  7764. this._actualSize.copyFrom(value);
  7765. }
  7766. },
  7767. enumerable: true,
  7768. configurable: true
  7769. });
  7770. Object.defineProperty(Prim2DBase.prototype, "actualWidth", {
  7771. get: function () {
  7772. return this.actualSize.width;
  7773. },
  7774. set: function (val) {
  7775. this._actualSize.width = val;
  7776. this._triggerPropertyChanged(Prim2DBase_1.actualSizeProperty, this._actualSize);
  7777. },
  7778. enumerable: true,
  7779. configurable: true
  7780. });
  7781. Object.defineProperty(Prim2DBase.prototype, "actualHeight", {
  7782. get: function () {
  7783. return this.actualSize.height;
  7784. },
  7785. set: function (val) {
  7786. this._actualSize.height = val;
  7787. this._triggerPropertyChanged(Prim2DBase_1.actualPositionProperty, this._actualSize);
  7788. },
  7789. enumerable: true,
  7790. configurable: true
  7791. });
  7792. Object.defineProperty(Prim2DBase.prototype, "actualZOffset", {
  7793. get: function () {
  7794. if (this._manualZOrder != null) {
  7795. return this._manualZOrder;
  7796. }
  7797. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagZOrderDirty)) {
  7798. this._updateZOrder();
  7799. }
  7800. return (1 - this._zOrder);
  7801. },
  7802. enumerable: true,
  7803. configurable: true
  7804. });
  7805. Object.defineProperty(Prim2DBase.prototype, "minSize", {
  7806. /**
  7807. * Get or set the minimal size the Layout Engine should respect when computing the primitive's actualSize.
  7808. * The Primitive's size won't be less than specified.
  7809. * The default value depends of the Primitive type
  7810. */
  7811. get: function () {
  7812. return this._minSize;
  7813. },
  7814. set: function (value) {
  7815. if (this._minSize && value && this._minSize.equals(value)) {
  7816. return;
  7817. }
  7818. if (!this._minSize) {
  7819. this._minSize = value.clone();
  7820. }
  7821. else {
  7822. this._minSize.copyFrom(value);
  7823. }
  7824. this._parentLayoutDirty();
  7825. },
  7826. enumerable: true,
  7827. configurable: true
  7828. });
  7829. Object.defineProperty(Prim2DBase.prototype, "maxSize", {
  7830. /**
  7831. * Get or set the maximal size the Layout Engine should respect when computing the primitive's actualSize.
  7832. * The Primitive's size won't be more than specified.
  7833. * The default value depends of the Primitive type
  7834. */
  7835. get: function () {
  7836. return this._maxSize;
  7837. },
  7838. set: function (value) {
  7839. if (this._maxSize && value && this._maxSize.equals(value)) {
  7840. return;
  7841. }
  7842. if (!this._maxSize) {
  7843. this._maxSize = value.clone();
  7844. }
  7845. else {
  7846. this._maxSize.copyFrom(value);
  7847. }
  7848. this._parentLayoutDirty();
  7849. },
  7850. enumerable: true,
  7851. configurable: true
  7852. });
  7853. Object.defineProperty(Prim2DBase.prototype, "origin", {
  7854. /**
  7855. * The origin defines the normalized coordinate of the center of the primitive, from the bottom/left corner.
  7856. * The origin is used only to compute transformation of the primitive, it has no meaning in the primitive local frame of reference
  7857. * For instance:
  7858. * 0,0 means the center is bottom/left. Which is the default for Canvas2D instances
  7859. * 0.5,0.5 means the center is at the center of the primitive, which is default of all types of Primitives
  7860. * 0,1 means the center is top/left
  7861. * @returns The normalized center.
  7862. */
  7863. get: function () {
  7864. return this._origin;
  7865. },
  7866. set: function (value) {
  7867. if (!this._origin) {
  7868. this._origin = value.clone();
  7869. }
  7870. else {
  7871. this._origin.copyFrom(value);
  7872. }
  7873. },
  7874. enumerable: true,
  7875. configurable: true
  7876. });
  7877. Object.defineProperty(Prim2DBase.prototype, "levelVisible", {
  7878. get: function () {
  7879. return this._isFlagSet(BABYLON.SmartPropertyPrim.flagLevelVisible);
  7880. },
  7881. set: function (value) {
  7882. this._changeFlags(BABYLON.SmartPropertyPrim.flagLevelVisible, value);
  7883. },
  7884. enumerable: true,
  7885. configurable: true
  7886. });
  7887. Object.defineProperty(Prim2DBase.prototype, "isVisible", {
  7888. get: function () {
  7889. return this._isFlagSet(BABYLON.SmartPropertyPrim.flagIsVisible);
  7890. },
  7891. set: function (value) {
  7892. this._changeFlags(BABYLON.SmartPropertyPrim.flagIsVisible, value);
  7893. },
  7894. enumerable: true,
  7895. configurable: true
  7896. });
  7897. Object.defineProperty(Prim2DBase.prototype, "zOrder", {
  7898. get: function () {
  7899. return this._manualZOrder;
  7900. },
  7901. set: function (value) {
  7902. if (this._manualZOrder === value) {
  7903. return;
  7904. }
  7905. this._manualZOrder = value;
  7906. this.onZOrderChanged();
  7907. if (this._actualZOrderChangedObservable && this._actualZOrderChangedObservable.hasObservers()) {
  7908. this._actualZOrderChangedObservable.notifyObservers(value);
  7909. }
  7910. },
  7911. enumerable: true,
  7912. configurable: true
  7913. });
  7914. Object.defineProperty(Prim2DBase.prototype, "isManualZOrder", {
  7915. get: function () {
  7916. return this._manualZOrder != null;
  7917. },
  7918. enumerable: true,
  7919. configurable: true
  7920. });
  7921. Object.defineProperty(Prim2DBase.prototype, "margin", {
  7922. get: function () {
  7923. var _this = this;
  7924. if (!this._margin) {
  7925. this._margin = new PrimitiveThickness(function () {
  7926. if (!_this.parent) {
  7927. return null;
  7928. }
  7929. return _this.parent.margin;
  7930. }, function () {
  7931. _this._positioningDirty();
  7932. _this._updatePositioningState();
  7933. });
  7934. this._updatePositioningState();
  7935. }
  7936. return this._margin;
  7937. },
  7938. set: function (value) {
  7939. if (!value) {
  7940. this._margin = null;
  7941. }
  7942. else {
  7943. this.margin.copyFrom(value);
  7944. }
  7945. this._updatePositioningState();
  7946. },
  7947. enumerable: true,
  7948. configurable: true
  7949. });
  7950. /**
  7951. * Set the margin from a string value
  7952. * @param value is "top: <value>, left:<value>, right:<value>, bottom:<value>" or "<value>" (same for all edges) each are optional, auto will be set if it's omitted.
  7953. * Values are: 'auto', 'inherit', 'XX%' for percentage, 'XXpx' or 'XX' for pixels.
  7954. */
  7955. Prim2DBase.prototype.setMargin = function (value) {
  7956. this.margin.fromString(value);
  7957. this._updatePositioningState();
  7958. };
  7959. Object.defineProperty(Prim2DBase.prototype, "_hasMargin", {
  7960. /**
  7961. * Check for both margin and marginAlignment, return true if at least one of them is specified with a non default value
  7962. */
  7963. get: function () {
  7964. return (this._margin !== null && !this._margin.isDefault) || (this._marginAlignment !== null && !this._marginAlignment.isDefault);
  7965. },
  7966. enumerable: true,
  7967. configurable: true
  7968. });
  7969. Object.defineProperty(Prim2DBase.prototype, "padding", {
  7970. get: function () {
  7971. var _this = this;
  7972. if (!this._padding) {
  7973. this._padding = new PrimitiveThickness(function () {
  7974. if (!_this.parent) {
  7975. return null;
  7976. }
  7977. return _this.parent.padding;
  7978. }, function () { return _this._positioningDirty(); });
  7979. this._updatePositioningState();
  7980. }
  7981. return this._padding;
  7982. },
  7983. set: function (value) {
  7984. if (!value) {
  7985. this._padding = null;
  7986. }
  7987. else {
  7988. this.padding.copyFrom(value);
  7989. }
  7990. this._updatePositioningState();
  7991. },
  7992. enumerable: true,
  7993. configurable: true
  7994. });
  7995. /**
  7996. * Set the padding from a string value
  7997. * @param value is "top: <value>, left:<value>, right:<value>, bottom:<value>" or "<value>" (same for all edges) each are optional, auto will be set if it's omitted.
  7998. * Values are: 'auto', 'inherit', 'XX%' for percentage, 'XXpx' or 'XX' for pixels. */
  7999. Prim2DBase.prototype.setPadding = function (value) {
  8000. this.padding.fromString(value);
  8001. this._updatePositioningState();
  8002. };
  8003. Object.defineProperty(Prim2DBase.prototype, "_hasPadding", {
  8004. get: function () {
  8005. return this._padding !== null && !this._padding.isDefault;
  8006. },
  8007. enumerable: true,
  8008. configurable: true
  8009. });
  8010. Object.defineProperty(Prim2DBase.prototype, "marginAlignment", {
  8011. get: function () {
  8012. var _this = this;
  8013. if (!this._marginAlignment) {
  8014. this._marginAlignment = new PrimitiveAlignment(function () {
  8015. _this._positioningDirty();
  8016. _this._updatePositioningState();
  8017. });
  8018. this._updatePositioningState();
  8019. }
  8020. return this._marginAlignment;
  8021. },
  8022. set: function (value) {
  8023. if (!value) {
  8024. this._marginAlignment = null;
  8025. }
  8026. else {
  8027. this.marginAlignment.copyFrom(value);
  8028. }
  8029. this._updatePositioningState();
  8030. },
  8031. enumerable: true,
  8032. configurable: true
  8033. });
  8034. /**
  8035. * Set the margin's horizontal and or vertical alignments from a string value.
  8036. * @param value can be: [<h:|horizontal:><left|right|center|stretch>], [<v:|vertical:><top|bottom|center|stretch>]
  8037. */
  8038. Prim2DBase.prototype.setMarginalignment = function (value) {
  8039. this.marginAlignment.fromString(value);
  8040. this._updatePositioningState();
  8041. };
  8042. Object.defineProperty(Prim2DBase.prototype, "_hasMarginAlignment", {
  8043. /**
  8044. * Check if there a marginAlignment specified (non null and not default)
  8045. */
  8046. get: function () {
  8047. return (this._marginAlignment !== null && !this._marginAlignment.isDefault);
  8048. },
  8049. enumerable: true,
  8050. configurable: true
  8051. });
  8052. Prim2DBase.prototype._updatePositioningState = function () {
  8053. var value = this._hasMargin || this._hasPadding || this.isSizeAuto;
  8054. // console.log(`${this.id} with parent ${this._parent ? this._parent.id : "[none]"} state: ${value} `);
  8055. this._changeFlags(BABYLON.SmartPropertyPrim.flagUsePositioning, value);
  8056. };
  8057. Object.defineProperty(Prim2DBase.prototype, "opacity", {
  8058. get: function () {
  8059. return this._opacity;
  8060. },
  8061. set: function (value) {
  8062. if (value < 0) {
  8063. value = 0;
  8064. }
  8065. else if (value > 1) {
  8066. value = 1;
  8067. }
  8068. if (this._opacity === value) {
  8069. return;
  8070. }
  8071. this._opacity = value;
  8072. this._setFlags(BABYLON.SmartPropertyPrim.flagActualOpacityDirty);
  8073. this._spreadActualOpacityChanged();
  8074. this._updateRenderMode();
  8075. },
  8076. enumerable: true,
  8077. configurable: true
  8078. });
  8079. Object.defineProperty(Prim2DBase.prototype, "scaleX", {
  8080. get: function () {
  8081. return this._scale.x;
  8082. },
  8083. set: function (value) {
  8084. if (value <= 0) {
  8085. throw new Error("You can't set the scaleX to less or equal to 0");
  8086. }
  8087. this._scale.x = value;
  8088. this._setFlags(BABYLON.SmartPropertyPrim.flagActualScaleDirty);
  8089. this._spreadActualScaleDirty();
  8090. this._positioningDirty();
  8091. },
  8092. enumerable: true,
  8093. configurable: true
  8094. });
  8095. Object.defineProperty(Prim2DBase.prototype, "scaleY", {
  8096. get: function () {
  8097. return this._scale.y;
  8098. },
  8099. set: function (value) {
  8100. if (value <= 0) {
  8101. throw new Error("You can't set the scaleY to less or equal to 0");
  8102. }
  8103. this._scale.y = value;
  8104. this._setFlags(BABYLON.SmartPropertyPrim.flagActualScaleDirty);
  8105. this._spreadActualScaleDirty();
  8106. this._positioningDirty();
  8107. },
  8108. enumerable: true,
  8109. configurable: true
  8110. });
  8111. Prim2DBase.prototype._spreadActualScaleDirty = function () {
  8112. for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
  8113. var child = _a[_i];
  8114. child._setFlags(BABYLON.SmartPropertyPrim.flagActualScaleDirty);
  8115. child._spreadActualScaleDirty();
  8116. }
  8117. };
  8118. Object.defineProperty(Prim2DBase.prototype, "actualScale", {
  8119. /**
  8120. * Returns the actual scale of this Primitive, the value is computed from the scale property of this primitive, multiplied by the actualScale of its parent one (if any). The Vector2 object returned contains the scale for both X and Y axis
  8121. */
  8122. get: function () {
  8123. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagActualScaleDirty)) {
  8124. var cur = this._isFlagSet(BABYLON.SmartPropertyPrim.flagDontInheritParentScale) ? null : this.parent;
  8125. var sx = this.scaleX;
  8126. var sy = this.scaleY;
  8127. while (cur) {
  8128. sx *= cur.scaleX;
  8129. sy *= cur.scaleY;
  8130. cur = cur._isFlagSet(BABYLON.SmartPropertyPrim.flagDontInheritParentScale) ? null : cur.parent;
  8131. }
  8132. this._actualScale.copyFromFloats(sx, sy);
  8133. this._clearFlags(BABYLON.SmartPropertyPrim.flagActualScaleDirty);
  8134. }
  8135. return this._actualScale;
  8136. },
  8137. enumerable: true,
  8138. configurable: true
  8139. });
  8140. Object.defineProperty(Prim2DBase.prototype, "actualScaleX", {
  8141. /**
  8142. * Get the actual Scale of the X axis, shortcut for this.actualScale.x
  8143. */
  8144. get: function () {
  8145. return this.actualScale.x;
  8146. },
  8147. enumerable: true,
  8148. configurable: true
  8149. });
  8150. /**
  8151. * This method stores the actual global scale (including DesignMode and DPR related scales) in the given Vector2
  8152. * @param res the object that will receive the actual global scale: this is actualScale * DPRScale * DesignModeScale
  8153. */
  8154. Prim2DBase.prototype.getActualGlobalScaleToRef = function (res) {
  8155. var as = this.actualScale;
  8156. var cls = this.owner._canvasLevelScale || Prim2DBase_1._iv2;
  8157. res.x = as.x * cls.x;
  8158. res.y = as.y * cls.y;
  8159. };
  8160. Object.defineProperty(Prim2DBase.prototype, "actualScaleY", {
  8161. /**
  8162. * Get the actual Scale of the Y axis, shortcut for this.actualScale.y
  8163. */
  8164. get: function () {
  8165. return this.actualScale.y;
  8166. },
  8167. enumerable: true,
  8168. configurable: true
  8169. });
  8170. Object.defineProperty(Prim2DBase.prototype, "actualOpacity", {
  8171. /**
  8172. * Get the actual opacity level, this property is computed from the opacity property, multiplied by the actualOpacity of its parent (if any)
  8173. */
  8174. get: function () {
  8175. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagActualOpacityDirty)) {
  8176. var cur = this.parent;
  8177. var op = this.opacity;
  8178. while (cur) {
  8179. op *= cur.opacity;
  8180. cur = cur.parent;
  8181. }
  8182. this._actualOpacity = op;
  8183. this._clearFlags(BABYLON.SmartPropertyPrim.flagActualOpacityDirty);
  8184. }
  8185. return this._actualOpacity;
  8186. },
  8187. enumerable: true,
  8188. configurable: true
  8189. });
  8190. Object.defineProperty(Prim2DBase.prototype, "layoutEngine", {
  8191. /**
  8192. * Get/set the layout engine to use for this primitive.
  8193. * The default layout engine is the CanvasLayoutEngine.
  8194. */
  8195. get: function () {
  8196. if (!this._layoutEngine) {
  8197. this._layoutEngine = BABYLON.CanvasLayoutEngine.Singleton;
  8198. }
  8199. return this._layoutEngine;
  8200. },
  8201. set: function (value) {
  8202. if (this._layoutEngine === value) {
  8203. return;
  8204. }
  8205. this._changeLayoutEngine(value);
  8206. },
  8207. enumerable: true,
  8208. configurable: true
  8209. });
  8210. Object.defineProperty(Prim2DBase.prototype, "layoutArea", {
  8211. /**
  8212. * Get/set the layout are of this primitive.
  8213. * The Layout area is the zone allocated by the Layout Engine for this particular primitive. Margins/Alignment will be computed based on this area.
  8214. * The setter should only be called by a Layout Engine class.
  8215. */
  8216. get: function () {
  8217. return this._layoutArea;
  8218. },
  8219. set: function (val) {
  8220. if (this._layoutArea && this._layoutArea.equals(val)) {
  8221. return;
  8222. }
  8223. this._positioningDirty();
  8224. this._setFlags(BABYLON.SmartPropertyPrim.flagLayoutBoundingInfoDirty);
  8225. if (this.parent) {
  8226. this.parent._setFlags(BABYLON.SmartPropertyPrim.flagLayoutBoundingInfoDirty | BABYLON.SmartPropertyPrim.flagGlobalTransformDirty);
  8227. }
  8228. if (!this._layoutArea) {
  8229. this._layoutArea = val.clone();
  8230. }
  8231. else {
  8232. this._layoutArea.copyFrom(val);
  8233. }
  8234. },
  8235. enumerable: true,
  8236. configurable: true
  8237. });
  8238. Object.defineProperty(Prim2DBase.prototype, "layoutAreaPos", {
  8239. /**
  8240. * Get/set the layout area position (relative to the parent primitive).
  8241. * The setter should only be called by a Layout Engine class.
  8242. */
  8243. get: function () {
  8244. return this._layoutAreaPos;
  8245. },
  8246. set: function (val) {
  8247. if (this._layoutAreaPos && this._layoutAreaPos.equals(val)) {
  8248. return;
  8249. }
  8250. if (this.parent) {
  8251. this.parent._setFlags(BABYLON.SmartPropertyPrim.flagLayoutBoundingInfoDirty | BABYLON.SmartPropertyPrim.flagGlobalTransformDirty);
  8252. }
  8253. this._positioningDirty();
  8254. if (!this._layoutAreaPos) {
  8255. this._layoutAreaPos = val.clone();
  8256. }
  8257. else {
  8258. this._layoutAreaPos.copyFrom(val);
  8259. }
  8260. this._setFlags(BABYLON.SmartPropertyPrim.flagLocalTransformDirty);
  8261. },
  8262. enumerable: true,
  8263. configurable: true
  8264. });
  8265. Object.defineProperty(Prim2DBase.prototype, "isPickable", {
  8266. /**
  8267. * Define if the Primitive can be subject to intersection test or not (default is true)
  8268. */
  8269. get: function () {
  8270. return this._isFlagSet(BABYLON.SmartPropertyPrim.flagIsPickable);
  8271. },
  8272. set: function (value) {
  8273. this._changeFlags(BABYLON.SmartPropertyPrim.flagIsPickable, value);
  8274. },
  8275. enumerable: true,
  8276. configurable: true
  8277. });
  8278. Object.defineProperty(Prim2DBase.prototype, "isContainer", {
  8279. /**
  8280. * Define if the Primitive acts as a container or not
  8281. * A container will encapsulate its children for interaction event.
  8282. * If it's not a container events will be process down to children if the primitive is not pickable.
  8283. * Default value is true
  8284. */
  8285. get: function () {
  8286. return this._isFlagSet(BABYLON.SmartPropertyPrim.flagIsContainer);
  8287. },
  8288. set: function (value) {
  8289. this._changeFlags(BABYLON.SmartPropertyPrim.flagIsContainer, value);
  8290. },
  8291. enumerable: true,
  8292. configurable: true
  8293. });
  8294. Object.defineProperty(Prim2DBase.prototype, "hierarchyDepth", {
  8295. /**
  8296. * Return the depth level of the Primitive into the Canvas' Graph. A Canvas will be 0, its direct children 1, and so on.
  8297. */
  8298. get: function () {
  8299. return this._hierarchyDepth;
  8300. },
  8301. enumerable: true,
  8302. configurable: true
  8303. });
  8304. Object.defineProperty(Prim2DBase.prototype, "renderGroup", {
  8305. /**
  8306. * Retrieve the Group that is responsible to render this primitive
  8307. */
  8308. get: function () {
  8309. return this._renderGroup;
  8310. },
  8311. enumerable: true,
  8312. configurable: true
  8313. });
  8314. Object.defineProperty(Prim2DBase.prototype, "globalTransform", {
  8315. /**
  8316. * Get the global transformation matrix of the primitive
  8317. */
  8318. get: function () {
  8319. if (!this._globalTransform || (this._globalTransformProcessStep !== this.owner._globalTransformProcessStep)) {
  8320. this.updateCachedStates(false);
  8321. }
  8322. return this._globalTransform;
  8323. },
  8324. enumerable: true,
  8325. configurable: true
  8326. });
  8327. /**
  8328. * return the global position of the primitive, relative to its canvas
  8329. */
  8330. Prim2DBase.prototype.getGlobalPosition = function () {
  8331. var v = new BABYLON.Vector2(0, 0);
  8332. this.getGlobalPositionByRef(v);
  8333. return v;
  8334. };
  8335. /**
  8336. * return the global position of the primitive, relative to its canvas
  8337. * @param v the valid Vector2 object where the global position will be stored
  8338. */
  8339. Prim2DBase.prototype.getGlobalPositionByRef = function (v) {
  8340. v.x = this.globalTransform.m[4];
  8341. v.y = this.globalTransform.m[5];
  8342. };
  8343. Object.defineProperty(Prim2DBase.prototype, "invGlobalTransform", {
  8344. /**
  8345. * Get invert of the global transformation matrix of the primitive
  8346. */
  8347. get: function () {
  8348. this._updateLocalTransform();
  8349. return this._invGlobalTransform;
  8350. },
  8351. enumerable: true,
  8352. configurable: true
  8353. });
  8354. Object.defineProperty(Prim2DBase.prototype, "localTransform", {
  8355. /**
  8356. * Get the local transformation of the primitive
  8357. */
  8358. get: function () {
  8359. this._updateLocalTransform();
  8360. return this._localTransform;
  8361. },
  8362. enumerable: true,
  8363. configurable: true
  8364. });
  8365. Object.defineProperty(Prim2DBase.prototype, "localLayoutTransform", {
  8366. get: function () {
  8367. this._updateLocalTransform();
  8368. return this._localLayoutTransform;
  8369. },
  8370. enumerable: true,
  8371. configurable: true
  8372. });
  8373. Object.defineProperty(Prim2DBase.prototype, "alignToPixel", {
  8374. /**
  8375. * Get/set if the sprite rendering should be aligned to the target rendering device pixel or not
  8376. */
  8377. get: function () {
  8378. return this._isFlagSet(BABYLON.SmartPropertyPrim.flagAlignPrimitive);
  8379. },
  8380. set: function (value) {
  8381. this._changeFlags(BABYLON.SmartPropertyPrim.flagAlignPrimitive, value);
  8382. },
  8383. enumerable: true,
  8384. configurable: true
  8385. });
  8386. Object.defineProperty(Prim2DBase.prototype, "boundingInfo", {
  8387. /**
  8388. * Get the boundingInfo associated to the primitive and its children.
  8389. */
  8390. get: function () {
  8391. // Check if we must update the boundingInfo
  8392. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagBoundingInfoDirty)) {
  8393. if (this.owner) {
  8394. this.owner.boundingInfoRecomputeCounter.addCount(1, false);
  8395. }
  8396. BABYLON.C2DLogging.setPostMessage(function () { return "cache miss"; });
  8397. var sizedByContent = this.isSizedByContent;
  8398. if (sizedByContent) {
  8399. this._boundingInfo.clear();
  8400. }
  8401. else {
  8402. this._boundingInfo.copyFrom(this.levelBoundingInfo);
  8403. }
  8404. if (this._children.length > 0) {
  8405. var contentBI = new BABYLON.BoundingInfo2D();
  8406. var tps = Prim2DBase_1._tpsBB2;
  8407. for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
  8408. var curChild = _a[_i];
  8409. if (curChild._isFlagSet(BABYLON.SmartPropertyPrim.flagNoPartOfLayout)) {
  8410. continue;
  8411. }
  8412. var bb = curChild.layoutBoundingInfo;
  8413. bb.transformToRef(curChild.localLayoutTransform, tps);
  8414. contentBI.unionToRef(tps, contentBI);
  8415. }
  8416. // Apply padding
  8417. if (this._hasPadding) {
  8418. var padding = this.padding;
  8419. var minmax = Prim2DBase_1._bMinMax;
  8420. contentBI.minMaxToRef(minmax);
  8421. this._paddingOffset.copyFromFloats(padding.leftPixels, padding.bottomPixels, padding.rightPixels, padding.topPixels);
  8422. var size = Prim2DBase_1._size2;
  8423. contentBI.sizeToRef(size);
  8424. this._getActualSizeFromContentToRef(size, this._paddingOffset, size);
  8425. minmax.z += this._paddingOffset.z + this._paddingOffset.x;
  8426. minmax.w += this._paddingOffset.w + this._paddingOffset.y;
  8427. BABYLON.BoundingInfo2D.CreateFromMinMaxToRef(minmax.x, minmax.z, minmax.y, minmax.w, contentBI);
  8428. }
  8429. else {
  8430. this._paddingOffset.copyFromFloats(0, 0, 0, 0);
  8431. }
  8432. this._boundingInfo.unionToRef(contentBI, this._boundingInfo);
  8433. }
  8434. if (sizedByContent || !this._isFlagSet(BABYLON.SmartPropertyPrim.flagLevelBoundingInfoDirty)) {
  8435. this._clearFlags(BABYLON.SmartPropertyPrim.flagBoundingInfoDirty);
  8436. }
  8437. }
  8438. else {
  8439. BABYLON.C2DLogging.setPostMessage(function () { return "cache hit"; });
  8440. }
  8441. return this._boundingInfo;
  8442. },
  8443. enumerable: true,
  8444. configurable: true
  8445. });
  8446. Object.defineProperty(Prim2DBase.prototype, "layoutBoundingInfo", {
  8447. /**
  8448. * Get the boundingInfo of the primitive's content arranged by a layout Engine
  8449. * If a particular child is not arranged by layout, it's boundingInfo is used instead to produce something as accurate as possible
  8450. */
  8451. get: function () {
  8452. var usePositioning = this._isFlagSet(BABYLON.SmartPropertyPrim.flagUsePositioning);
  8453. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagLayoutBoundingInfoDirty)) {
  8454. BABYLON.C2DLogging.setPostMessage(function () { return "cache miss"; });
  8455. if (this._owner) {
  8456. this._owner.addLayoutBoundingInfoUpdateCounter(1);
  8457. }
  8458. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagLayoutDirty)) {
  8459. if (this._owner) {
  8460. this._owner.addUpdateLayoutCounter(1);
  8461. }
  8462. this._layoutEngine.updateLayout(this);
  8463. this._clearFlags(BABYLON.SmartPropertyPrim.flagLayoutDirty);
  8464. }
  8465. if (usePositioning) {
  8466. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagPositioningDirty)) {
  8467. this._updatePositioning();
  8468. }
  8469. // Safety check, code re entrance is a PITA in this part of the code
  8470. if (!this._layoutBoundingInfo) {
  8471. BABYLON.C2DLogging.setPostMessage(function () { return "re entrance detected, boundingInfo returned"; });
  8472. return this.boundingInfo;
  8473. }
  8474. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagPositioningDirty)) {
  8475. BABYLON.C2DLogging.setPostMessage(function () { return "couldn't compute positioning, boundingInfo returned"; });
  8476. return this.boundingInfo;
  8477. }
  8478. }
  8479. if (!usePositioning) {
  8480. var bi = this.boundingInfo;
  8481. if (!this._isFlagSet(BABYLON.SmartPropertyPrim.flagBoundingInfoDirty)) {
  8482. this._clearFlags(BABYLON.SmartPropertyPrim.flagLayoutBoundingInfoDirty);
  8483. }
  8484. return bi;
  8485. }
  8486. this._clearFlags(BABYLON.SmartPropertyPrim.flagLayoutBoundingInfoDirty);
  8487. }
  8488. else {
  8489. BABYLON.C2DLogging.setPostMessage(function () { return "cache hit"; });
  8490. }
  8491. return usePositioning ? this._layoutBoundingInfo : this.boundingInfo;
  8492. },
  8493. enumerable: true,
  8494. configurable: true
  8495. });
  8496. Object.defineProperty(Prim2DBase.prototype, "isSizeAuto", {
  8497. /**
  8498. * Determine if the size is automatically computed or fixed because manually specified.
  8499. * Use the actualSize property to get the final/real size of the primitive
  8500. * @returns true if the size is automatically computed, false if it were manually specified.
  8501. */
  8502. get: function () {
  8503. var size = this._size;
  8504. return size == null || (size.width == null && size.height == null);
  8505. },
  8506. enumerable: true,
  8507. configurable: true
  8508. });
  8509. Object.defineProperty(Prim2DBase.prototype, "isHorizontalSizeAuto", {
  8510. /**
  8511. * Determine if the horizontal size is automatically computed or fixed because manually specified.
  8512. * Use the actualSize property to get the final/real size of the primitive
  8513. * @returns true if the horizontal size is automatically computed, false if it were manually specified.
  8514. */
  8515. get: function () {
  8516. var size = this._size;
  8517. return size == null || size.width == null;
  8518. },
  8519. enumerable: true,
  8520. configurable: true
  8521. });
  8522. Object.defineProperty(Prim2DBase.prototype, "isVerticalSizeAuto", {
  8523. /**
  8524. * Determine if the vertical size is automatically computed or fixed because manually specified.
  8525. * Use the actualSize property to get the final/real size of the primitive
  8526. * @returns true if the vertical size is automatically computed, false if it were manually specified.
  8527. */
  8528. get: function () {
  8529. var size = this._size;
  8530. return size == null || size.height == null;
  8531. },
  8532. enumerable: true,
  8533. configurable: true
  8534. });
  8535. Object.defineProperty(Prim2DBase.prototype, "isSizedByContent", {
  8536. /**
  8537. * Return true if this prim has an auto size which is set by the children's global bounding box
  8538. */
  8539. get: function () {
  8540. return (this._size == null) && (this._children.length > 0);
  8541. },
  8542. enumerable: true,
  8543. configurable: true
  8544. });
  8545. Object.defineProperty(Prim2DBase.prototype, "isPositionAuto", {
  8546. /**
  8547. * Determine if the position is automatically computed or fixed because manually specified.
  8548. * Use the actualPosition property to get the final/real position of the primitive
  8549. * @returns true if the position is automatically computed, false if it were manually specified.
  8550. */
  8551. get: function () {
  8552. return this._position == null;
  8553. },
  8554. enumerable: true,
  8555. configurable: true
  8556. });
  8557. Object.defineProperty(Prim2DBase.prototype, "pointerEventObservable", {
  8558. /**
  8559. * Interaction with the primitive can be create using this Observable. See the PrimitivePointerInfo class for more information
  8560. */
  8561. get: function () {
  8562. return this._pointerEventObservable;
  8563. },
  8564. enumerable: true,
  8565. configurable: true
  8566. });
  8567. Object.defineProperty(Prim2DBase.prototype, "zActualOrderChangedObservable", {
  8568. get: function () {
  8569. if (!this._actualZOrderChangedObservable) {
  8570. this._actualZOrderChangedObservable = new BABYLON.Observable();
  8571. }
  8572. return this._actualZOrderChangedObservable;
  8573. },
  8574. enumerable: true,
  8575. configurable: true
  8576. });
  8577. Object.defineProperty(Prim2DBase.prototype, "displayDebugAreas", {
  8578. get: function () {
  8579. return this._displayDebugAreas;
  8580. },
  8581. set: function (value) {
  8582. if (this._displayDebugAreas === value) {
  8583. return;
  8584. }
  8585. if (value === false) {
  8586. this._debugAreaGroup.dispose();
  8587. this._debugAreaGroup = null;
  8588. }
  8589. else {
  8590. var layoutFill = "#F0808040"; // Red - Layout area
  8591. var layoutBorder = "#F08080FF";
  8592. var marginFill = "#F0F04040"; // Yellow - Margin area
  8593. var marginBorder = "#F0F040FF";
  8594. var paddingFill = "#F040F040"; // Magenta - Padding Area
  8595. var paddingBorder = "#F040F0FF";
  8596. var contentFill = "#40F0F040"; // Cyan - Content area
  8597. var contentBorder = "#40F0F0FF";
  8598. var s = new BABYLON.Size(10, 10);
  8599. var p = BABYLON.Vector2.Zero();
  8600. this._debugAreaGroup = new BABYLON.Group2D({
  8601. parent: (this.parent != null) ? this.parent : this, id: "###DEBUG AREA GROUP###", children: [
  8602. new BABYLON.Group2D({
  8603. id: "###Layout Area###", position: p, size: s, children: [
  8604. new BABYLON.Rectangle2D({ id: "###Layout Frame###", position: BABYLON.Vector2.Zero(), size: s, fill: null, border: layoutBorder }),
  8605. new BABYLON.Rectangle2D({ id: "###Layout Top###", position: BABYLON.Vector2.Zero(), size: s, fill: layoutFill }),
  8606. new BABYLON.Rectangle2D({ id: "###Layout Left###", position: BABYLON.Vector2.Zero(), size: s, fill: layoutFill }),
  8607. new BABYLON.Rectangle2D({ id: "###Layout Right###", position: BABYLON.Vector2.Zero(), size: s, fill: layoutFill }),
  8608. new BABYLON.Rectangle2D({ id: "###Layout Bottom###", position: BABYLON.Vector2.Zero(), size: s, fill: layoutFill })
  8609. ]
  8610. }),
  8611. new BABYLON.Group2D({
  8612. id: "###Margin Area###", position: p, size: s, children: [
  8613. new BABYLON.Rectangle2D({ id: "###Margin Frame###", position: BABYLON.Vector2.Zero(), size: s, fill: null, border: marginBorder }),
  8614. new BABYLON.Rectangle2D({ id: "###Margin Top###", position: BABYLON.Vector2.Zero(), size: s, fill: marginFill }),
  8615. new BABYLON.Rectangle2D({ id: "###Margin Left###", position: BABYLON.Vector2.Zero(), size: s, fill: marginFill }),
  8616. new BABYLON.Rectangle2D({ id: "###Margin Right###", position: BABYLON.Vector2.Zero(), size: s, fill: marginFill }),
  8617. new BABYLON.Rectangle2D({ id: "###Margin Bottom###", position: BABYLON.Vector2.Zero(), size: s, fill: marginFill })
  8618. ]
  8619. }),
  8620. new BABYLON.Group2D({
  8621. id: "###Padding Area###", position: p, size: s, children: [
  8622. new BABYLON.Rectangle2D({ id: "###Padding Frame###", position: BABYLON.Vector2.Zero(), size: s, fill: null, border: paddingBorder }),
  8623. new BABYLON.Rectangle2D({ id: "###Padding Top###", position: BABYLON.Vector2.Zero(), size: s, fill: paddingFill }),
  8624. new BABYLON.Rectangle2D({ id: "###Padding Left###", position: BABYLON.Vector2.Zero(), size: s, fill: paddingFill }),
  8625. new BABYLON.Rectangle2D({ id: "###Padding Right###", position: BABYLON.Vector2.Zero(), size: s, fill: paddingFill }),
  8626. new BABYLON.Rectangle2D({ id: "###Padding Bottom###", position: BABYLON.Vector2.Zero(), size: s, fill: paddingFill })
  8627. ]
  8628. }),
  8629. new BABYLON.Group2D({
  8630. id: "###Content Area###", position: p, size: s, children: [
  8631. new BABYLON.Rectangle2D({ id: "###Content Frame###", position: BABYLON.Vector2.Zero(), size: s, fill: null, border: contentBorder }),
  8632. new BABYLON.Rectangle2D({ id: "###Content Top###", position: BABYLON.Vector2.Zero(), size: s, fill: contentFill }),
  8633. new BABYLON.Rectangle2D({ id: "###Content Left###", position: BABYLON.Vector2.Zero(), size: s, fill: contentFill }),
  8634. new BABYLON.Rectangle2D({ id: "###Content Right###", position: BABYLON.Vector2.Zero(), size: s, fill: contentFill }),
  8635. new BABYLON.Rectangle2D({ id: "###Content Bottom###", position: BABYLON.Vector2.Zero(), size: s, fill: contentFill })
  8636. ]
  8637. })
  8638. ]
  8639. });
  8640. this._debugAreaGroup._setFlags(BABYLON.SmartPropertyPrim.flagNoPartOfLayout);
  8641. this._updateDebugArea();
  8642. }
  8643. this._displayDebugAreas = value;
  8644. },
  8645. enumerable: true,
  8646. configurable: true
  8647. });
  8648. Prim2DBase.prototype._updateDebugArea = function () {
  8649. if (Prim2DBase_1._updatingDebugArea === true) {
  8650. return;
  8651. }
  8652. Prim2DBase_1._updatingDebugArea = true;
  8653. var areaNames = ["Layout", "Margin", "Padding", "Content"];
  8654. var areaZones = ["Area", "Frame", "Top", "Left", "Right", "Bottom"];
  8655. var prims = new Array(4);
  8656. // Get all the primitives used to display the areas
  8657. for (var i = 0; i < 4; i++) {
  8658. prims[i] = new Array(6);
  8659. for (var j = 0; j < 6; j++) {
  8660. prims[i][j] = this._debugAreaGroup.findById("###" + areaNames[i] + " " + areaZones[j] + "###");
  8661. if (j > 1) {
  8662. prims[i][j].levelVisible = false;
  8663. }
  8664. }
  8665. }
  8666. // Update the visibility status of layout/margin/padding
  8667. var hasLayout = this._layoutAreaPos != null;
  8668. var hasPos = (this.actualPosition.x !== 0) || (this.actualPosition.y !== 0);
  8669. var hasMargin = this._hasMargin;
  8670. var hasPadding = this._hasPadding;
  8671. prims[0][0].levelVisible = hasLayout;
  8672. prims[1][0].levelVisible = hasMargin;
  8673. prims[2][0].levelVisible = hasPadding;
  8674. prims[3][0].levelVisible = true;
  8675. // Current offset
  8676. var curOffset = BABYLON.Vector2.Zero();
  8677. // Store the area info of the layout area
  8678. var curAreaIndex = 0;
  8679. // Store data about each area
  8680. var areaInfo = new Array(4);
  8681. var storeAreaInfo = function (pos, size) {
  8682. var min = pos.clone();
  8683. var max = pos.clone();
  8684. if (size.width > 0) {
  8685. max.x += size.width;
  8686. }
  8687. if (size.height > 0) {
  8688. max.y += size.height;
  8689. }
  8690. areaInfo[curAreaIndex++] = { off: pos, size: size, min: min, max: max };
  8691. };
  8692. var isCanvas = this instanceof BABYLON.Canvas2D;
  8693. var marginH = this._marginOffset.x + this._marginOffset.z;
  8694. var marginV = this._marginOffset.y + this._marginOffset.w;
  8695. var actualSize = this.actualSize.multiplyByFloats(isCanvas ? 1 : this.scaleX, isCanvas ? 1 : this.scaleY);
  8696. var w = hasLayout ? (this.layoutAreaPos.x + this.layoutArea.width) : (marginH + actualSize.width);
  8697. var h = hasLayout ? (this.layoutAreaPos.y + this.layoutArea.height) : (marginV + actualSize.height);
  8698. var pos = (!hasLayout && !hasMargin && !hasPadding && hasPos) ? this.actualPosition : BABYLON.Vector2.Zero();
  8699. storeAreaInfo(pos, new BABYLON.Size(w, h));
  8700. // Compute the layout related data
  8701. if (hasLayout) {
  8702. var layoutOffset = this.layoutAreaPos.clone();
  8703. storeAreaInfo(layoutOffset, (hasMargin || hasPadding) ? this.layoutArea.clone() : actualSize.clone());
  8704. curOffset = layoutOffset.clone();
  8705. }
  8706. // Compute margin data
  8707. if (hasMargin) {
  8708. var marginOffset = curOffset.clone();
  8709. marginOffset.x += this._marginOffset.x;
  8710. marginOffset.y += this._marginOffset.y;
  8711. var marginArea = actualSize;
  8712. storeAreaInfo(marginOffset, marginArea);
  8713. curOffset = marginOffset.clone();
  8714. }
  8715. if (hasPadding) {
  8716. var contentOffset = curOffset.clone();
  8717. contentOffset.x += this._paddingOffset.x;
  8718. contentOffset.y += this._paddingOffset.y;
  8719. var contentArea = this.contentArea;
  8720. storeAreaInfo(contentOffset, contentArea);
  8721. curOffset = curOffset.add(contentOffset);
  8722. }
  8723. // Helper function that set the pos and size of a given prim
  8724. var setArea = function (i, j, pos, size) {
  8725. prims[i][j].position = pos;
  8726. prims[i][j].size = size;
  8727. };
  8728. var setFullRect = function (i, pos, size) {
  8729. var plist = prims[i];
  8730. plist[2].levelVisible = true;
  8731. plist[3].levelVisible = false;
  8732. plist[4].levelVisible = false;
  8733. plist[5].levelVisible = false;
  8734. setArea(i, 1, pos, size);
  8735. setArea(i, 2, pos, size);
  8736. };
  8737. var setQuadRect = function (i, areaIndex) {
  8738. var plist = prims[i];
  8739. plist[2].levelVisible = true;
  8740. plist[3].levelVisible = true;
  8741. plist[4].levelVisible = true;
  8742. plist[5].levelVisible = true;
  8743. var ca = areaInfo[areaIndex];
  8744. var na = areaInfo[areaIndex + 1];
  8745. var tp = new BABYLON.Vector2(ca.min.x, na.max.y);
  8746. var ts = new BABYLON.Size(ca.size.width, ca.max.y - tp.y);
  8747. var lp = new BABYLON.Vector2(ca.min.x, na.min.y);
  8748. var ls = new BABYLON.Size(na.min.x - ca.min.x, na.max.y - na.min.y);
  8749. var rp = new BABYLON.Vector2(na.max.x, na.min.y);
  8750. var rs = new BABYLON.Size(ca.max.x - na.max.x, na.max.y - na.min.y);
  8751. var bp = new BABYLON.Vector2(ca.min.x, ca.min.y);
  8752. var bs = new BABYLON.Size(ca.size.width, na.min.y - ca.min.y);
  8753. // Frame
  8754. plist[1].position = ca.off;
  8755. plist[1].size = ca.size;
  8756. // Top rect
  8757. plist[2].position = tp;
  8758. plist[2].size = ts;
  8759. // Left rect
  8760. plist[3].position = lp;
  8761. plist[3].size = ls;
  8762. // Right rect
  8763. plist[4].position = rp;
  8764. plist[4].size = rs;
  8765. // Bottom rect
  8766. plist[5].position = bp;
  8767. plist[5].size = bs;
  8768. };
  8769. var areaCount = curAreaIndex;
  8770. curAreaIndex = 0;
  8771. // Available zones
  8772. var availableZones = [false, hasLayout, hasMargin, hasPadding, true];
  8773. for (var k = 1; k < 5; k++) {
  8774. if (availableZones[k]) {
  8775. var ai = areaInfo[curAreaIndex];
  8776. setArea(k - 1, 0, BABYLON.Vector2.Zero(), ai.size);
  8777. // setArea(k-1, 1, Vector2.Zero(), ai.size);
  8778. if (k === 4) {
  8779. setFullRect(k - 1, ai.off, ai.size);
  8780. }
  8781. else {
  8782. setQuadRect(k - 1, curAreaIndex);
  8783. }
  8784. ++curAreaIndex;
  8785. }
  8786. }
  8787. Prim2DBase_1._updatingDebugArea = false;
  8788. };
  8789. Prim2DBase.prototype.findById = function (id) {
  8790. if (this._id === id) {
  8791. return this;
  8792. }
  8793. for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
  8794. var child = _a[_i];
  8795. var r = child.findById(id);
  8796. if (r != null) {
  8797. return r;
  8798. }
  8799. }
  8800. };
  8801. Prim2DBase.prototype.onZOrderChanged = function () {
  8802. };
  8803. Prim2DBase.prototype.levelIntersect = function (intersectInfo) {
  8804. return false;
  8805. };
  8806. /**
  8807. * Capture all the Events of the given PointerId for this primitive.
  8808. * Don't forget to call releasePointerEventsCapture when done.
  8809. * @param pointerId the Id of the pointer to capture the events from.
  8810. */
  8811. Prim2DBase.prototype.setPointerEventCapture = function (pointerId) {
  8812. return this.owner._setPointerCapture(pointerId, this);
  8813. };
  8814. /**
  8815. * Release a captured pointer made with setPointerEventCapture.
  8816. * @param pointerId the Id of the pointer to release the capture from.
  8817. */
  8818. Prim2DBase.prototype.releasePointerEventsCapture = function (pointerId) {
  8819. return this.owner._releasePointerCapture(pointerId, this);
  8820. };
  8821. /**
  8822. * Make an intersection test with the primitive, all inputs/outputs are stored in the IntersectInfo2D class, see its documentation for more information.
  8823. * @param intersectInfo contains the settings of the intersection to perform, to setup before calling this method as well as the result, available after a call to this method.
  8824. */
  8825. Prim2DBase.prototype.intersect = function (intersectInfo) {
  8826. if (!intersectInfo) {
  8827. return false;
  8828. }
  8829. // If this is null it means this method is call for the first level, initialize stuffs
  8830. var firstLevel = !intersectInfo._globalPickPosition;
  8831. if (firstLevel) {
  8832. // Compute the pickPosition in global space and use it to find the local position for each level down, always relative from the world to get the maximum accuracy (and speed). The other way would have been to compute in local every level down relative to its parent's local, which wouldn't be as accurate (even if javascript number is 80bits accurate).
  8833. intersectInfo._globalPickPosition = BABYLON.Vector2.Zero();
  8834. this.globalTransform.transformPointToRef(intersectInfo.pickPosition, intersectInfo._globalPickPosition);
  8835. intersectInfo._localPickPosition = intersectInfo.pickPosition.clone();
  8836. intersectInfo.intersectedPrimitives = new Array();
  8837. intersectInfo.topMostIntersectedPrimitive = null;
  8838. }
  8839. if (!Prim2DBase_1._bypassGroup2DExclusion && this instanceof BABYLON.Group2D && this.isCachedGroup && !this.isRenderableGroup) {
  8840. // Important to call this before each return to allow a good recursion next time this intersectInfo is reused
  8841. intersectInfo._exit(firstLevel);
  8842. return false;
  8843. }
  8844. if (!intersectInfo.intersectHidden && !this.isVisible) {
  8845. // Important to call this before each return to allow a good recursion next time this intersectInfo is reused
  8846. intersectInfo._exit(firstLevel);
  8847. return false;
  8848. }
  8849. var id = this.id;
  8850. if (id != null && id.indexOf("__cachedSpriteOfGroup__") === 0) {
  8851. try {
  8852. Prim2DBase_1._bypassGroup2DExclusion = true;
  8853. var ownerGroup = this.getExternalData("__cachedGroup__");
  8854. if (!ownerGroup) {
  8855. return false;
  8856. }
  8857. return ownerGroup.intersect(intersectInfo);
  8858. }
  8859. finally {
  8860. Prim2DBase_1._bypassGroup2DExclusion = false;
  8861. }
  8862. }
  8863. // If we're testing a cachedGroup, we must reject pointer outside its levelBoundingInfo because children primitives could be partially clipped outside so we must not accept them as intersected when it's the case (because they're not visually visible).
  8864. var isIntersectionTest = false;
  8865. if (this instanceof BABYLON.Group2D) {
  8866. var g = this;
  8867. isIntersectionTest = g.isCachedGroup;
  8868. }
  8869. if (isIntersectionTest && !this.levelBoundingInfo.doesIntersect(intersectInfo._localPickPosition)) {
  8870. // Important to call this before each return to allow a good recursion next time this intersectInfo is reused
  8871. intersectInfo._exit(firstLevel);
  8872. return false;
  8873. }
  8874. // Fast rejection test with boundingInfo
  8875. var boundingIntersected = true;
  8876. if (this.isPickable && !this.boundingInfo.doesIntersect(intersectInfo._localPickPosition)) {
  8877. if (this.isContainer) {
  8878. // Important to call this before each return to allow a good recursion next time this intersectInfo is reused
  8879. intersectInfo._exit(firstLevel);
  8880. return false;
  8881. }
  8882. boundingIntersected = false;
  8883. }
  8884. // We hit the boundingInfo that bounds this primitive and its children, now we have to test on the primitive of this level
  8885. var levelIntersectRes = false;
  8886. if (this.isPickable) {
  8887. levelIntersectRes = boundingIntersected && this.levelIntersect(intersectInfo);
  8888. if (levelIntersectRes) {
  8889. var pii = new PrimitiveIntersectedInfo(this, intersectInfo._localPickPosition.clone());
  8890. intersectInfo.intersectedPrimitives.push(pii);
  8891. if (!intersectInfo.topMostIntersectedPrimitive || (intersectInfo.topMostIntersectedPrimitive.prim.actualZOffset > pii.prim.actualZOffset)) {
  8892. intersectInfo.topMostIntersectedPrimitive = pii;
  8893. }
  8894. // If we must stop at the first intersection, we're done, quit!
  8895. if (intersectInfo.findFirstOnly) {
  8896. intersectInfo._exit(firstLevel);
  8897. return true;
  8898. }
  8899. }
  8900. }
  8901. // Recurse to children if needed
  8902. if (!levelIntersectRes || !intersectInfo.findFirstOnly) {
  8903. for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
  8904. var curChild = _a[_i];
  8905. // Don't test primitive not pick able or if it's hidden and we don't test hidden ones
  8906. if ((!curChild.isPickable && curChild.isContainer) || (!intersectInfo.intersectHidden && !curChild.isVisible)) {
  8907. continue;
  8908. }
  8909. // Must compute the localPickLocation for the children level
  8910. curChild.invGlobalTransform.transformPointToRef(intersectInfo._globalPickPosition, intersectInfo._localPickPosition);
  8911. // If we got an intersection with the child and we only need to find the first one, quit!
  8912. if (curChild.intersect(intersectInfo) && intersectInfo.findFirstOnly) {
  8913. intersectInfo._exit(firstLevel);
  8914. return true;
  8915. }
  8916. }
  8917. }
  8918. intersectInfo._exit(firstLevel);
  8919. return intersectInfo.isIntersected;
  8920. };
  8921. Prim2DBase.prototype.intersectOtherPrim = function (other) {
  8922. var setA = this.triList;
  8923. var setB = other.triList;
  8924. return BABYLON.Tri2DArray.doesIntersect(setA, setB, other.globalTransform.multiply(this.globalTransform.clone().invert()));
  8925. };
  8926. Object.defineProperty(Prim2DBase.prototype, "triList", {
  8927. get: function () {
  8928. if (this._primTriArrayDirty) {
  8929. this.updateTriArray();
  8930. this._primTriArrayDirty = false;
  8931. }
  8932. return this._primTriArray;
  8933. },
  8934. enumerable: true,
  8935. configurable: true
  8936. });
  8937. // This is the worst implementation, if the top level primitive doesn't override this method we will just store a quad that defines the bounding rect of the prim
  8938. Prim2DBase.prototype.updateTriArray = function () {
  8939. if (this._primTriArray == null) {
  8940. this._primTriArray = new BABYLON.Tri2DArray(2);
  8941. }
  8942. else {
  8943. this._primTriArray.clear(2);
  8944. }
  8945. var size = this.actualSize;
  8946. var lb = new BABYLON.Vector2(0, 0);
  8947. var rt = new BABYLON.Vector2(size.width, size.height);
  8948. var lt = new BABYLON.Vector2(0, size.height);
  8949. var rb = new BABYLON.Vector2(size.width, 0);
  8950. this._primTriArray.storeTriangle(0, lb, lt, rt);
  8951. this._primTriArray.storeTriangle(1, lb, rt, rb);
  8952. };
  8953. /**
  8954. * Move a child object into a new position regarding its siblings to change its rendering order.
  8955. * You can also use the shortcut methods to move top/bottom: moveChildToTop, moveChildToBottom, moveToTop, moveToBottom.
  8956. * @param child the object to move
  8957. * @param previous the object which will be before "child", if child has to be the first among sibling, set "previous" to null.
  8958. */
  8959. Prim2DBase.prototype.moveChild = function (child, previous) {
  8960. if (child.parent !== this) {
  8961. return false;
  8962. }
  8963. var childIndex = this._children.indexOf(child);
  8964. var prevIndex = previous ? this._children.indexOf(previous) : -1;
  8965. if (!this._isFlagSet(BABYLON.SmartPropertyPrim.flagChildrenFlatZOrder)) {
  8966. this._setFlags(BABYLON.SmartPropertyPrim.flagZOrderDirty);
  8967. this._firstZDirtyIndex = Math.min(this._firstZDirtyIndex, prevIndex + 1);
  8968. }
  8969. this._children.splice(prevIndex + 1, 0, this._children.splice(childIndex, 1)[0]);
  8970. return true;
  8971. };
  8972. /**
  8973. * Move the given child so it's displayed on the top of all its siblings
  8974. * @param child the primitive to move to the top
  8975. */
  8976. Prim2DBase.prototype.moveChildToTop = function (child) {
  8977. return this.moveChild(child, this._children[this._children.length - 1]);
  8978. };
  8979. /**
  8980. * Move the given child so it's displayed on the bottom of all its siblings
  8981. * @param child the primitive to move to the top
  8982. */
  8983. Prim2DBase.prototype.moveChildToBottom = function (child) {
  8984. return this.moveChild(child, null);
  8985. };
  8986. /**
  8987. * Move this primitive to be at the top among all its sibling
  8988. */
  8989. Prim2DBase.prototype.moveToTop = function () {
  8990. if (this.parent == null) {
  8991. return false;
  8992. }
  8993. return this.parent.moveChildToTop(this);
  8994. };
  8995. /**
  8996. * Move this primitive to be at the bottom among all its sibling
  8997. */
  8998. Prim2DBase.prototype.moveToBottom = function () {
  8999. if (this.parent == null) {
  9000. return false;
  9001. }
  9002. return this.parent.moveChildToBottom(this);
  9003. };
  9004. Prim2DBase.prototype.addChild = function (child) {
  9005. child._parent = this;
  9006. this._boundingBoxDirty();
  9007. var flat = this._isFlagSet(BABYLON.SmartPropertyPrim.flagChildrenFlatZOrder);
  9008. if (flat) {
  9009. child._setFlags(BABYLON.SmartPropertyPrim.flagChildrenFlatZOrder);
  9010. child._setZOrder(this._zOrder, true);
  9011. child._zMax = this._zOrder;
  9012. }
  9013. else {
  9014. this._setFlags(BABYLON.SmartPropertyPrim.flagZOrderDirty);
  9015. }
  9016. var length = this._children.push(child);
  9017. this._firstZDirtyIndex = Math.min(this._firstZDirtyIndex, length - 1);
  9018. child._setFlags(BABYLON.SmartPropertyPrim.flagActualOpacityDirty);
  9019. };
  9020. /**
  9021. * Dispose the primitive, remove it from its parent.
  9022. */
  9023. Prim2DBase.prototype.dispose = function () {
  9024. if (!_super.prototype.dispose.call(this)) {
  9025. return false;
  9026. }
  9027. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagCollisionActor)) {
  9028. this.owner._primitiveCollisionManager._removeActor(this);
  9029. this._actorInfo = null;
  9030. }
  9031. if (this._pointerEventObservable) {
  9032. this._pointerEventObservable.clear();
  9033. this._pointerEventObservable = null;
  9034. }
  9035. if (this._actionManager) {
  9036. this._actionManager.dispose();
  9037. this._actionManager = null;
  9038. }
  9039. this.owner.scene.stopAnimation(this);
  9040. // If there's a parent, remove this object from its parent list
  9041. if (this._parent) {
  9042. if (this instanceof BABYLON.Group2D) {
  9043. var g = this;
  9044. if (g.isRenderableGroup) {
  9045. var parentRenderable = this.parent.traverseUp(function (p) { return (p instanceof BABYLON.Group2D && p.isRenderableGroup); });
  9046. if (parentRenderable != null) {
  9047. var l = parentRenderable._renderableData._childrenRenderableGroups;
  9048. var i_1 = l.indexOf(g);
  9049. if (i_1 !== -1) {
  9050. l.splice(i_1, 1);
  9051. }
  9052. }
  9053. }
  9054. }
  9055. var i = this._parent._children.indexOf(this);
  9056. if (i !== undefined) {
  9057. this._parent._children.splice(i, 1);
  9058. }
  9059. this._parent = null;
  9060. }
  9061. // Recurse dispose to children
  9062. if (this._children) {
  9063. while (this._children.length > 0) {
  9064. this._children[this._children.length - 1].dispose();
  9065. }
  9066. }
  9067. return true;
  9068. };
  9069. Prim2DBase.prototype.onPrimBecomesDirty = function () {
  9070. if (this._renderGroup && !this._isFlagSet(BABYLON.SmartPropertyPrim.flagPrimInDirtyList)) {
  9071. this._renderGroup._addPrimToDirtyList(this);
  9072. this._setFlags(BABYLON.SmartPropertyPrim.flagPrimInDirtyList);
  9073. }
  9074. };
  9075. Prim2DBase.prototype._needPrepare = function () {
  9076. return this._areSomeFlagsSet(BABYLON.SmartPropertyPrim.flagVisibilityChanged | BABYLON.SmartPropertyPrim.flagModelDirty | BABYLON.SmartPropertyPrim.flagModelUpdate | BABYLON.SmartPropertyPrim.flagNeedRefresh) || (this._instanceDirtyFlags !== 0) || (this._globalTransformProcessStep !== this._globalTransformStep);
  9077. };
  9078. Prim2DBase.prototype._prepareRender = function (context) {
  9079. var globalTransformStep = this.owner._globalTransformStep;
  9080. if (this._prepareProcessStep < globalTransformStep) {
  9081. this._prepareRenderPre(context);
  9082. this._prepareRenderPost(context);
  9083. this._prepareProcessStep = globalTransformStep;
  9084. }
  9085. };
  9086. Prim2DBase.prototype._prepareRenderPre = function (context) {
  9087. };
  9088. Prim2DBase.prototype._prepareRenderPost = function (context) {
  9089. // Don't recurse if it's a renderable group, the content will be processed by the group itself
  9090. if (this instanceof BABYLON.Group2D) {
  9091. var self = this;
  9092. if (self.isRenderableGroup) {
  9093. return;
  9094. }
  9095. }
  9096. // Check if we need to recurse the prepare to children primitives
  9097. // - must have children
  9098. // - the global transform of this level have changed, or
  9099. // - the visible state of primitive has changed
  9100. if (this._children.length > 0 && ((this._globalTransformProcessStep !== this._globalTransformStep) ||
  9101. this.checkPropertiesDirty(Prim2DBase_1.isVisibleProperty.flagId))) {
  9102. this._children.forEach(function (c) {
  9103. // As usual stop the recursion if we meet a renderable group
  9104. if (!(c instanceof BABYLON.Group2D && c.isRenderableGroup)) {
  9105. c._prepareRender(context);
  9106. }
  9107. });
  9108. }
  9109. // Finally reset the dirty flags as we've processed everything
  9110. this._clearFlags(BABYLON.SmartPropertyPrim.flagModelDirty);
  9111. this._instanceDirtyFlags = 0;
  9112. };
  9113. Prim2DBase.prototype._canvasPreInit = function (settings) {
  9114. };
  9115. Prim2DBase.CheckParent = function (parent) {
  9116. //if (!Prim2DBase._isCanvasInit && !parent) {
  9117. // throw new Error("A Primitive needs a valid Parent, it can be any kind of Primitives based types, even the Canvas (with the exception that only Group2D can be direct child of a Canvas if the cache strategy used is TOPLEVELGROUPS)");
  9118. //}
  9119. };
  9120. Prim2DBase.prototype.updateCachedStatesOf = function (list, recurse) {
  9121. for (var _i = 0, list_1 = list; _i < list_1.length; _i++) {
  9122. var cur = list_1[_i];
  9123. cur.updateCachedStates(recurse);
  9124. }
  9125. };
  9126. Prim2DBase.prototype._parentLayoutDirty = function () {
  9127. if (!this._parent || this._parent.isDisposed) {
  9128. return;
  9129. }
  9130. this._parent._setLayoutDirty();
  9131. };
  9132. Prim2DBase.prototype._setLayoutDirty = function () {
  9133. this.onPrimBecomesDirty();
  9134. this._setFlags(BABYLON.SmartPropertyPrim.flagLayoutDirty);
  9135. };
  9136. //private _checkPositionChange(): boolean {
  9137. // if (this.parent && this.parent.layoutEngine.isChildPositionAllowed === false) {
  9138. // console.log(`Can't manually set the position of ${this.id}, the Layout Engine of its parent doesn't allow it`);
  9139. // return false;
  9140. // }
  9141. // if (this._isFlagSet(SmartPropertyPrim.flagUsePositioning)) {
  9142. // if (<any>this instanceof Group2D && (<Group2D><any>this).trackedNode == null) {
  9143. // console.log(`You can't set the position/x/y of ${this.id} properties while positioning engine is used (margin, margin alignment and/or padding are set`);
  9144. // return false;
  9145. // }
  9146. // }
  9147. // return true;
  9148. //}
  9149. Prim2DBase.prototype._checkUseMargin = function () {
  9150. // Special cae: tracked node
  9151. if (this instanceof BABYLON.Group2D && this.trackedNode != null) {
  9152. return false;
  9153. }
  9154. return this._isFlagSet(BABYLON.SmartPropertyPrim.flagUsePositioning);
  9155. };
  9156. Prim2DBase.prototype._positioningDirty = function () {
  9157. if (!this._isFlagSet(BABYLON.SmartPropertyPrim.flagUsePositioning)) {
  9158. return;
  9159. }
  9160. this.onPrimBecomesDirty();
  9161. this._setFlags(BABYLON.SmartPropertyPrim.flagPositioningDirty);
  9162. };
  9163. Prim2DBase.prototype._spreadActualOpacityChanged = function () {
  9164. for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
  9165. var child = _a[_i];
  9166. child._setFlags(BABYLON.SmartPropertyPrim.flagActualOpacityDirty);
  9167. child._updateRenderMode();
  9168. child.onPrimBecomesDirty();
  9169. child._spreadActualOpacityChanged();
  9170. }
  9171. };
  9172. Prim2DBase.prototype._changeLayoutEngine = function (engine) {
  9173. this._layoutEngine = engine;
  9174. };
  9175. Prim2DBase.prototype._updateLocalTransform = function () {
  9176. var tflags = Prim2DBase_1.actualPositionProperty.flagId | Prim2DBase_1.rotationProperty.flagId | Prim2DBase_1.scaleProperty.flagId | Prim2DBase_1.scaleXProperty.flagId | Prim2DBase_1.scaleYProperty.flagId | Prim2DBase_1.originProperty.flagId;
  9177. if (this.checkPropertiesDirty(tflags) || this._areSomeFlagsSet(BABYLON.SmartPropertyPrim.flagLocalTransformDirty | BABYLON.SmartPropertyPrim.flagPositioningDirty)) {
  9178. if (this.owner) {
  9179. this.owner.addupdateLocalTransformCounter(1);
  9180. }
  9181. // Check for positioning update
  9182. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagPositioningDirty)) {
  9183. this._updatePositioning();
  9184. }
  9185. var rot = this._rotation;
  9186. var local;
  9187. var pos = this._position ? this.position : (this.layoutAreaPos || Prim2DBase_1._v0);
  9188. var postScale = this._postScale;
  9189. var canvasScale = Prim2DBase_1._iv2;
  9190. //let hasCanvasScale = false;
  9191. //if (this._parent instanceof Canvas2D) {
  9192. // hasCanvasScale = true;
  9193. // canvasScale = (this._parent as Canvas2D)._canvasLevelScale || Prim2DBase._iv2;
  9194. //}
  9195. var globalScale = this._scale.multiplyByFloats(/*postScale.x**/ canvasScale.x, /*postScale.y**/ canvasScale.y);
  9196. if ((this._origin.x === 0 && this._origin.y === 0) || this._hasMargin) {
  9197. local = BABYLON.Matrix2D.Compose(globalScale, rot, new BABYLON.Vector2(pos.x + this._marginOffset.x, pos.y + this._marginOffset.y));
  9198. this._localTransform = local;
  9199. this._localLayoutTransform = BABYLON.Matrix2D.Compose(globalScale, rot, new BABYLON.Vector2(pos.x, pos.y));
  9200. }
  9201. else {
  9202. // -Origin offset
  9203. var t0 = Prim2DBase_1._t0;
  9204. var t1 = Prim2DBase_1._t1;
  9205. var t2 = Prim2DBase_1._t2;
  9206. var as = Prim2DBase_1._ts0;
  9207. as.copyFrom(this.actualSize);
  9208. //as.width /= postScale.x;
  9209. //as.height /= postScale.y;
  9210. BABYLON.Matrix2D.TranslationToRef((-as.width * this._origin.x), (-as.height * this._origin.y), t0);
  9211. // -Origin * rotation
  9212. BABYLON.Matrix2D.RotationToRef(rot, t1);
  9213. t0.multiplyToRef(t1, t2);
  9214. BABYLON.Matrix2D.ScalingToRef(this._scale.x, this._scale.y, t0);
  9215. t2.multiplyToRef(t0, t1);
  9216. BABYLON.Matrix2D.TranslationToRef((as.width * this._origin.x), (as.height * this._origin.y), t2);
  9217. t1.multiplyToRef(t2, t0);
  9218. BABYLON.Matrix2D.ScalingToRef(postScale.x, postScale.y, t1);
  9219. t0.multiplyToRef(t1, t2);
  9220. BABYLON.Matrix2D.TranslationToRef(pos.x + this._marginOffset.x, pos.y + this._marginOffset.y, t0);
  9221. t2.multiplyToRef(t0, this._localTransform);
  9222. //if (hasCanvasScale) {
  9223. // Matrix2D.ScalingToRef(canvasScale.x, canvasScale.y, Prim2DBase._t1);
  9224. // this._localTransform.multiplyToRef(Prim2DBase._t1, this._localTransform);
  9225. //}
  9226. this._localLayoutTransform = BABYLON.Matrix2D.Compose(globalScale, rot, pos);
  9227. }
  9228. this.clearPropertiesDirty(tflags);
  9229. this._setFlags(BABYLON.SmartPropertyPrim.flagGlobalTransformDirty);
  9230. this._clearFlags(BABYLON.SmartPropertyPrim.flagLocalTransformDirty);
  9231. return true;
  9232. }
  9233. return false;
  9234. };
  9235. Prim2DBase.prototype.updateCachedStates = function (recurse) {
  9236. if (this.isDisposed) {
  9237. BABYLON.C2DLogging.setPostMessage(function () { return "disposed"; });
  9238. return;
  9239. }
  9240. var ownerProcessStep = this.owner._globalTransformProcessStep;
  9241. if (this._updateCachesProcessStep === ownerProcessStep) {
  9242. return;
  9243. }
  9244. this._updateCachesProcessStep = ownerProcessStep;
  9245. this.owner.addUpdateCachedStateCounter(1);
  9246. // Check if the parent is synced
  9247. if (this._parent && ((this._parent._globalTransformProcessStep !== this.owner._globalTransformProcessStep) || this._parent._areSomeFlagsSet(BABYLON.SmartPropertyPrim.flagLayoutDirty | BABYLON.SmartPropertyPrim.flagPositioningDirty | BABYLON.SmartPropertyPrim.flagZOrderDirty))) {
  9248. this._parent.updateCachedStates(false);
  9249. }
  9250. // Update Z-Order if needed
  9251. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagZOrderDirty)) {
  9252. this._updateZOrder();
  9253. }
  9254. // Update actualSize only if there' not positioning to recompute and the size changed
  9255. // Otherwise positioning will take care of it.
  9256. var sizeDirty = this.checkPropertiesDirty(Prim2DBase_1.sizeProperty.flagId);
  9257. if (!this._isFlagSet(BABYLON.SmartPropertyPrim.flagLayoutDirty) && !this._isFlagSet(BABYLON.SmartPropertyPrim.flagPositioningDirty) && sizeDirty) {
  9258. var size = this.size;
  9259. this.onPropertyChanged("actualSize", size, size, Prim2DBase_1.actualSizeProperty.flagId);
  9260. this.clearPropertiesDirty(Prim2DBase_1.sizeProperty.flagId);
  9261. }
  9262. var positioningDirty = this._isFlagSet(BABYLON.SmartPropertyPrim.flagPositioningDirty);
  9263. var positioningComputed = positioningDirty && !this._isFlagSet(BABYLON.SmartPropertyPrim.flagPositioningDirty);
  9264. // Check for layout update
  9265. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagLayoutDirty)) {
  9266. this.owner.addUpdateLayoutCounter(1);
  9267. this._layoutEngine.updateLayout(this);
  9268. this._clearFlags(BABYLON.SmartPropertyPrim.flagLayoutDirty);
  9269. }
  9270. var autoContentChanged = false;
  9271. if (this.isSizeAuto) {
  9272. if (!this._lastAutoSizeArea) {
  9273. autoContentChanged = this.actualSize !== null;
  9274. }
  9275. else {
  9276. autoContentChanged = (!this._lastAutoSizeArea.equals(this.actualSize));
  9277. }
  9278. }
  9279. // Check for positioning update
  9280. if (!positioningComputed && (autoContentChanged || sizeDirty || this._isFlagSet(BABYLON.SmartPropertyPrim.flagPositioningDirty) || (this._parent && !this._parent.contentArea.equals(this._parentContentArea)))) {
  9281. this._updatePositioning();
  9282. if (sizeDirty) {
  9283. this.clearPropertiesDirty(Prim2DBase_1.sizeProperty.flagId);
  9284. }
  9285. positioningComputed = true;
  9286. }
  9287. if (positioningComputed && this._parent) {
  9288. this._parentContentArea.copyFrom(this._parent.contentArea);
  9289. }
  9290. // Check if we must update this prim
  9291. if (!this._globalTransform || (this._globalTransformProcessStep !== this.owner._globalTransformProcessStep) || (this._areSomeFlagsSet(BABYLON.SmartPropertyPrim.flagGlobalTransformDirty))) {
  9292. this.owner.addUpdateGlobalTransformCounter(1);
  9293. var curVisibleState = this.isVisible;
  9294. this.isVisible = (!this._parent || this._parent.isVisible) && this.levelVisible;
  9295. // Detect a change of visibility
  9296. this._changeFlags(BABYLON.SmartPropertyPrim.flagVisibilityChanged, curVisibleState !== this.isVisible);
  9297. // Get/compute the localTransform
  9298. var localDirty = this._updateLocalTransform();
  9299. var parentPaddingChanged = false;
  9300. var parentPaddingOffset = Prim2DBase_1._v0;
  9301. if (this._parent) {
  9302. parentPaddingOffset = new BABYLON.Vector2(this._parent._paddingOffset.x, this._parent._paddingOffset.y);
  9303. parentPaddingChanged = !parentPaddingOffset.equals(this._parentPaddingOffset);
  9304. }
  9305. // Check if there are changes in the parent that will force us to update the global matrix
  9306. var parentDirty = (this._parent != null) ? (this._parent._globalTransformStep !== this._parentTransformStep) : false;
  9307. // Check if we have to update the globalTransform
  9308. if (!this._globalTransform || localDirty || parentDirty || parentPaddingChanged || this._areSomeFlagsSet(BABYLON.SmartPropertyPrim.flagGlobalTransformDirty)) {
  9309. var globalTransform = this._parent ? this._parent._globalTransform : null;
  9310. var localTransform = void 0;
  9311. Prim2DBase_1._transMtx.copyFrom(this._localTransform);
  9312. Prim2DBase_1._transMtx.m[4] += parentPaddingOffset.x;
  9313. Prim2DBase_1._transMtx.m[5] += parentPaddingOffset.y;
  9314. localTransform = Prim2DBase_1._transMtx;
  9315. this._globalTransform = this._parent ? localTransform.multiply(globalTransform) : localTransform.clone();
  9316. this._invGlobalTransform = BABYLON.Matrix2D.Invert(this._globalTransform);
  9317. this._levelBoundingInfo.dirtyWorldAABB();
  9318. this._boundingInfo.dirtyWorldAABB();
  9319. this._globalTransformStep = this.owner._globalTransformProcessStep + 1;
  9320. this._parentTransformStep = this._parent ? this._parent._globalTransformStep : 0;
  9321. this._clearFlags(BABYLON.SmartPropertyPrim.flagGlobalTransformDirty);
  9322. }
  9323. this._globalTransformProcessStep = this.owner._globalTransformProcessStep;
  9324. }
  9325. if (recurse) {
  9326. for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
  9327. var child = _a[_i];
  9328. // Stop the recursion if we meet a renderable group
  9329. child.updateCachedStates(!(child instanceof BABYLON.Group2D && child.isRenderableGroup));
  9330. }
  9331. }
  9332. };
  9333. Prim2DBase.prototype._updatePositioning = function () {
  9334. if (!this._isFlagSet(BABYLON.SmartPropertyPrim.flagUsePositioning)) {
  9335. BABYLON.C2DLogging.setPostMessage(function () { return "Not using positioning engine"; });
  9336. // Just in case, if may happen and if we don't clear some computation will keep going on forever
  9337. this._clearFlags(BABYLON.SmartPropertyPrim.flagPositioningDirty);
  9338. return;
  9339. }
  9340. var success = true;
  9341. // Check if re-entrance is occurring
  9342. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagComputingPositioning) /* || (hasMargin && !this._layoutArea)*/) {
  9343. if (!this._actualSize) {
  9344. this._actualSize = this.size.clone() || BABYLON.Size.Zero();
  9345. this._contentArea.copyFrom(this._actualSize);
  9346. }
  9347. if (!this._actualPosition) {
  9348. this._actualPosition = BABYLON.Vector2.Zero();
  9349. }
  9350. BABYLON.C2DLogging.setPostMessage(function () { return "Re entrance detected"; });
  9351. return;
  9352. }
  9353. if (this.owner) {
  9354. this.owner.addUpdatePositioningCounter(1);
  9355. }
  9356. // Set the flag to avoid re-entrance
  9357. this._setFlags(BABYLON.SmartPropertyPrim.flagComputingPositioning);
  9358. try {
  9359. var isSizeAuto = this.isSizeAuto;
  9360. var isVSizeAuto = this.isVerticalSizeAuto;
  9361. var isHSizeAuto = this.isHorizontalSizeAuto;
  9362. var ma = this._marginAlignment ? this._marginAlignment.clone() : new PrimitiveAlignment();
  9363. var levelScale = this._scale;
  9364. var primSize = this.size;
  9365. // If the primitive has no size and is autoSized without margin, then set a Stretch/Stretch margin alignment for the primitive to take all the available space
  9366. if (!this._hasMarginAlignment && (isSizeAuto && (primSize === Prim2DBase_1.nullSize || (primSize === this._internalSize && primSize.width === 0 && primSize.height === 0)))) {
  9367. if (isSizeAuto || this.actualSize.width == null) {
  9368. ma.horizontal = PrimitiveAlignment.AlignStretch;
  9369. }
  9370. if (isSizeAuto || this.actualSize.height == null) {
  9371. ma.vertical = PrimitiveAlignment.AlignStretch;
  9372. }
  9373. }
  9374. var transformedBSize = Prim2DBase_1._size3;
  9375. var bSize = Prim2DBase_1._size4;
  9376. var bi = this.boundingInfo;
  9377. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagBoundingInfoDirty)) {
  9378. success = false;
  9379. }
  9380. var tbi = Prim2DBase_1._tbi;
  9381. bi.transformToRef(BABYLON.Matrix2D.Rotation(this.rotation), tbi);
  9382. tbi.sizeToRef(transformedBSize);
  9383. bi.sizeToRef(bSize);
  9384. bi.extent.subtractToRef(bi.center, Prim2DBase_1._pv1);
  9385. tbi.center.subtractToRef(tbi.extent, Prim2DBase_1._pv2);
  9386. var transbi = Prim2DBase_1._pv2.add(Prim2DBase_1._pv1);
  9387. var setSize = false;
  9388. var hasMargin = (this._margin !== null && !this._margin.isDefault) || (ma !== null && !ma.isDefault);
  9389. var primNewSize = Prim2DBase_1._size;
  9390. var hasH = false;
  9391. var hasV = false;
  9392. //let paddingApplied = false;
  9393. var hasPadding = this._hasPadding;
  9394. // Compute the size
  9395. // The size is the size of the prim or the computed one if there's a marginAlignment of Stretch
  9396. if (hasMargin) {
  9397. var layoutArea = this.layoutArea;
  9398. if (layoutArea /*&& layoutArea.width >= size.width */ && ma.horizontal === PrimitiveAlignment.AlignStretch) {
  9399. this.margin.computeWithAlignment(layoutArea, primSize, ma, levelScale, this._marginOffset, primNewSize, false, PrimitiveThickness.ComputeH);
  9400. hasH = true;
  9401. setSize = true;
  9402. }
  9403. if (layoutArea /*&& layoutArea.height >= size.height */ && ma.vertical === PrimitiveAlignment.AlignStretch) {
  9404. this.margin.computeWithAlignment(layoutArea, primSize, ma, levelScale, this._marginOffset, primNewSize, false, PrimitiveThickness.ComputeV);
  9405. hasV = true;
  9406. setSize = true;
  9407. }
  9408. }
  9409. if (!hasH) {
  9410. // If the Horizontal size is Auto, we have to compute it from its content and padding
  9411. if (isHSizeAuto) {
  9412. primNewSize.width = bSize.width;
  9413. setSize = true;
  9414. }
  9415. else {
  9416. primNewSize.width = primSize.width;
  9417. }
  9418. }
  9419. if (!hasV) {
  9420. // If the Vertical size is Auto, we have to compute it from its content and padding
  9421. if (isVSizeAuto) {
  9422. primNewSize.height = bSize.height;
  9423. setSize = true;
  9424. }
  9425. else {
  9426. primNewSize.height = primSize.height;
  9427. }
  9428. }
  9429. Prim2DBase_1._curContentArea.copyFrom(this._contentArea);
  9430. if (hasPadding) {
  9431. var area = Prim2DBase_1._icArea;
  9432. var zone = Prim2DBase_1._icZone;
  9433. this._getInitialContentAreaToRef(primNewSize, zone, area);
  9434. area.width = Math.max(0, area.width);
  9435. area.height = Math.max(0, area.height);
  9436. this.padding.compute(area, this._paddingOffset, Prim2DBase_1._size2);
  9437. if (!isHSizeAuto) {
  9438. this._paddingOffset.x += zone.x;
  9439. this._paddingOffset.z -= zone.z;
  9440. this._contentArea.width = Prim2DBase_1._size2.width;
  9441. }
  9442. if (!isVSizeAuto) {
  9443. this._paddingOffset.y += zone.y;
  9444. this._paddingOffset.w -= zone.w;
  9445. this._contentArea.height = Prim2DBase_1._size2.height;
  9446. }
  9447. }
  9448. else {
  9449. this._contentArea.copyFrom(primNewSize);
  9450. }
  9451. if (!Prim2DBase_1._curContentArea.equals(this._contentArea)) {
  9452. this._setLayoutDirty();
  9453. }
  9454. // Finally we apply margin to determine the position
  9455. if (hasMargin) {
  9456. var layoutArea = this.layoutArea;
  9457. var mo = this._marginOffset;
  9458. var margin = this.margin;
  9459. // We compute margin only if the layoutArea is "real": a valid object with dimensions greater than 0
  9460. // otherwise sometimes this code would be triggered with and invalid layoutArea, resulting to an invalid positioning
  9461. // So we make sure with compute alignment only if the layoutArea is good
  9462. if (layoutArea && layoutArea.width > 0 && layoutArea.height > 0) {
  9463. margin.computeWithAlignment(layoutArea, transformedBSize, ma, levelScale, mo, Prim2DBase_1._size2);
  9464. }
  9465. else {
  9466. mo.copyFromFloats(0, 0, 0, 0);
  9467. }
  9468. var tbi_1 = Prim2DBase_1._tpsBB;
  9469. tbi_1.copyFrom(bi);
  9470. var minmax = Prim2DBase_1._bMinMax;
  9471. tbi_1.minMaxToRef(minmax);
  9472. minmax.z += margin.leftPixels + margin.rightPixels;
  9473. minmax.w += margin.topPixels + margin.bottomPixels;
  9474. BABYLON.BoundingInfo2D.CreateFromMinMaxToRef(minmax.x, minmax.z, minmax.y, minmax.w, tbi_1);
  9475. // Check if the layoutBoundingInfo changed
  9476. var changed = false;
  9477. if (!this._layoutBoundingInfo) {
  9478. this._layoutBoundingInfo = tbi_1.clone();
  9479. changed = true;
  9480. }
  9481. else if (!this._layoutBoundingInfo.equals(tbi_1)) {
  9482. this._layoutBoundingInfo.copyFrom(tbi_1);
  9483. changed = true;
  9484. }
  9485. if (changed) {
  9486. var p = this._parent;
  9487. while (p) {
  9488. if (p.isSizedByContent) {
  9489. p._setFlags(BABYLON.SmartPropertyPrim.flagLayoutBoundingInfoDirty);
  9490. p.onPrimitivePropertyDirty(Prim2DBase_1.actualSizeProperty.flagId);
  9491. }
  9492. else {
  9493. break;
  9494. }
  9495. p = p._parent;
  9496. }
  9497. this.onPrimitivePropertyDirty(Prim2DBase_1.actualSizeProperty.flagId);
  9498. }
  9499. this._marginOffset.x -= transbi.x * levelScale.x;
  9500. this._marginOffset.y -= transbi.y * levelScale.y;
  9501. }
  9502. var lap = this.layoutAreaPos;
  9503. this.actualPosition = new BABYLON.Vector2(this._marginOffset.x + (lap ? lap.x : 0), this._marginOffset.y + (lap ? lap.y : 0));
  9504. // if (setSize) {
  9505. this.actualSize = primNewSize.clone();
  9506. // }
  9507. this._setFlags(BABYLON.SmartPropertyPrim.flagLocalTransformDirty);
  9508. if (isSizeAuto) {
  9509. this._lastAutoSizeArea = this.actualSize;
  9510. }
  9511. if (this.displayDebugAreas) {
  9512. this._updateDebugArea();
  9513. }
  9514. }
  9515. finally {
  9516. BABYLON.C2DLogging.setPostMessage(function () { return "Succeeded"; });
  9517. this._clearFlags(BABYLON.SmartPropertyPrim.flagComputingPositioning);
  9518. // Remove dirty flag
  9519. if (success) {
  9520. this._clearFlags(BABYLON.SmartPropertyPrim.flagPositioningDirty);
  9521. }
  9522. }
  9523. };
  9524. Object.defineProperty(Prim2DBase.prototype, "contentArea", {
  9525. /**
  9526. * Get the content are of this primitive, this area is computed the primitive size and using the padding property.
  9527. * Children of this primitive will be positioned relative to the bottom/left corner of this area.
  9528. */
  9529. get: function () {
  9530. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagUsePositioning)) {
  9531. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagPositioningDirty)) {
  9532. this._updatePositioning();
  9533. }
  9534. return this._contentArea;
  9535. }
  9536. else {
  9537. return this.size;
  9538. }
  9539. },
  9540. enumerable: true,
  9541. configurable: true
  9542. });
  9543. Prim2DBase.prototype._patchHierarchy = function (owner) {
  9544. if (this._owner == null) {
  9545. this._owner = owner;
  9546. this.onSetOwner();
  9547. this._setFlags(BABYLON.SmartPropertyPrim.flagLayoutBoundingInfoDirty);
  9548. }
  9549. // The only place we initialize the _renderGroup is this method, if it's set, we already been there, no need to execute more
  9550. if (this._renderGroup != null) {
  9551. return;
  9552. }
  9553. if (this instanceof BABYLON.Group2D) {
  9554. var group = this;
  9555. group.detectGroupStates();
  9556. if (group._trackedNode && !group._isFlagSet(BABYLON.SmartPropertyPrim.flagTrackedGroup)) {
  9557. group.owner._registerTrackedNode(this);
  9558. }
  9559. }
  9560. this._renderGroup = this.traverseUp(function (p) { return p instanceof BABYLON.Group2D && p.isRenderableGroup; });
  9561. if (this._parent) {
  9562. this._parentLayoutDirty();
  9563. }
  9564. // Make sure the prim is in the dirtyList if it should be
  9565. if (this._renderGroup && this.isDirty) {
  9566. var list = this._renderGroup._renderableData._primDirtyList;
  9567. var i = list.indexOf(this);
  9568. if (i === -1) {
  9569. this._setFlags(BABYLON.SmartPropertyPrim.flagPrimInDirtyList);
  9570. list.push(this);
  9571. }
  9572. }
  9573. // Recurse
  9574. for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
  9575. var child = _a[_i];
  9576. child._hierarchyDepth = this._hierarchyDepth + 1;
  9577. child._patchHierarchy(owner);
  9578. }
  9579. };
  9580. Prim2DBase.prototype.onSetOwner = function () {
  9581. };
  9582. Prim2DBase.prototype._updateZOrder = function () {
  9583. var prevLinPos = this._primLinearPosition;
  9584. var startI = 0;
  9585. var startZ = this._zOrder;
  9586. // We must start rebuilding Z-Order from the Prim before the first one that changed, because we know its Z-Order is correct, so are its children, but it's better to recompute everything from this point instead of finding the last valid children
  9587. var childrenCount = this._children.length;
  9588. if (this._firstZDirtyIndex > 0) {
  9589. if ((this._firstZDirtyIndex - 1) < childrenCount) {
  9590. var prevPrim = this._children[this._firstZDirtyIndex - 1];
  9591. prevLinPos = prevPrim._primLinearPosition;
  9592. startI = this._firstZDirtyIndex - 1;
  9593. startZ = prevPrim._zOrder;
  9594. }
  9595. }
  9596. var startPos = prevLinPos;
  9597. // Update the linear position of the primitive from the first one to the last inside this primitive, compute the total number of prim traversed
  9598. Prim2DBase_1._totalCount = 0;
  9599. for (var i = startI; i < childrenCount; i++) {
  9600. var child = this._children[i];
  9601. prevLinPos = child._updatePrimitiveLinearPosition(prevLinPos);
  9602. }
  9603. // Compute the new Z-Order for all the primitives
  9604. // Add 20% to the current total count to reserve space for future insertions, except if we're rebuilding due to a zMinDelta reached
  9605. var zDelta = (this._zMax - startZ) / (Prim2DBase_1._totalCount * (Prim2DBase_1._zRebuildReentrency ? 1 : 1.2));
  9606. // If the computed delta is less than the smallest allowed by the depth buffer, we rebuild the Z-Order from the very beginning of the primitive's children (that is, the first) to redistribute uniformly the Z.
  9607. if (zDelta < BABYLON.Canvas2D._zMinDelta) {
  9608. // Check for re-entrance, if the flag is true we already attempted a rebuild but couldn't get a better zDelta, go up in the hierarchy to rebuilt one level up, hoping to get this time a decent delta, otherwise, recurse until we got it or when no parent is reached, which would mean the canvas would have more than 16 millions of primitives...
  9609. if (Prim2DBase_1._zRebuildReentrency) {
  9610. var p = this._parent;
  9611. if (p == null) {
  9612. // Can't find a good Z delta and we're in the canvas, which mean we're dealing with too many objects (which should never happen, but well...)
  9613. console.log("Can't compute Z-Order for " + this.id + "'s children, zDelta is too small, Z-Order is now in an unstable state");
  9614. Prim2DBase_1._zRebuildReentrency = false;
  9615. return;
  9616. }
  9617. p._firstZDirtyIndex = 0;
  9618. return p._updateZOrder();
  9619. }
  9620. Prim2DBase_1._zRebuildReentrency = true;
  9621. this._firstZDirtyIndex = 0;
  9622. this._updateZOrder();
  9623. Prim2DBase_1._zRebuildReentrency = false;
  9624. }
  9625. for (var i = startI; i < childrenCount; i++) {
  9626. var child = this._children[i];
  9627. child._updatePrimitiveZOrder(startPos, startZ, zDelta);
  9628. }
  9629. // Notify the Observers that we found during the Z change (we do it after to avoid any kind of re-entrance)
  9630. for (var _i = 0, _a = Prim2DBase_1._zOrderChangedNotifList; _i < _a.length; _i++) {
  9631. var p = _a[_i];
  9632. p._actualZOrderChangedObservable.notifyObservers(p.actualZOffset);
  9633. }
  9634. Prim2DBase_1._zOrderChangedNotifList.splice(0);
  9635. this._firstZDirtyIndex = Prim2DBase_1._bigInt;
  9636. this._clearFlags(BABYLON.SmartPropertyPrim.flagZOrderDirty);
  9637. };
  9638. Prim2DBase.prototype._updatePrimitiveLinearPosition = function (prevLinPos) {
  9639. if (this.isManualZOrder) {
  9640. return prevLinPos;
  9641. }
  9642. this._primLinearPosition = ++prevLinPos;
  9643. Prim2DBase_1._totalCount++;
  9644. // Check for the FlatZOrder, which means the children won't have a dedicated Z-Order but will all share the same (unique) one.
  9645. if (!this._isFlagSet(BABYLON.SmartPropertyPrim.flagChildrenFlatZOrder)) {
  9646. for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
  9647. var child = _a[_i];
  9648. prevLinPos = child._updatePrimitiveLinearPosition(prevLinPos);
  9649. }
  9650. }
  9651. return prevLinPos;
  9652. };
  9653. Prim2DBase.prototype._updatePrimitiveZOrder = function (startPos, startZ, deltaZ) {
  9654. if (this.isManualZOrder) {
  9655. return null;
  9656. }
  9657. var newZ = startZ + ((this._primLinearPosition - startPos) * deltaZ);
  9658. var isFlat = this._isFlagSet(BABYLON.SmartPropertyPrim.flagChildrenFlatZOrder);
  9659. this._setZOrder(newZ, false);
  9660. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagZOrderDirty)) {
  9661. this._firstZDirtyIndex = Prim2DBase_1._bigInt;
  9662. this._clearFlags(BABYLON.SmartPropertyPrim.flagZOrderDirty);
  9663. }
  9664. var curZ = newZ;
  9665. // Check for the FlatZOrder, which means the children won't have a dedicated Z-Order but will all share the same (unique) one.
  9666. if (isFlat) {
  9667. if (this._children.length > 0) {
  9668. //let childrenZOrder = startZ + ((this._children[0]._primLinearPosition - startPos) * deltaZ);
  9669. for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
  9670. var child = _a[_i];
  9671. child._updatePrimitiveFlatZOrder(this._zOrder);
  9672. }
  9673. }
  9674. }
  9675. else {
  9676. for (var _b = 0, _c = this._children; _b < _c.length; _b++) {
  9677. var child = _c[_b];
  9678. var r = child._updatePrimitiveZOrder(startPos, startZ, deltaZ);
  9679. if (r != null) {
  9680. curZ = r;
  9681. }
  9682. }
  9683. }
  9684. this._zMax = isFlat ? newZ : (curZ + deltaZ);
  9685. return curZ;
  9686. };
  9687. Prim2DBase.prototype._updatePrimitiveFlatZOrder = function (newZ) {
  9688. if (this.isManualZOrder) {
  9689. return;
  9690. }
  9691. this._setZOrder(newZ, false);
  9692. this._zMax = newZ;
  9693. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagZOrderDirty)) {
  9694. this._firstZDirtyIndex = Prim2DBase_1._bigInt;
  9695. this._clearFlags(BABYLON.SmartPropertyPrim.flagZOrderDirty);
  9696. }
  9697. for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
  9698. var child = _a[_i];
  9699. child._updatePrimitiveFlatZOrder(newZ);
  9700. }
  9701. };
  9702. Prim2DBase.prototype._setZOrder = function (newZ, directEmit) {
  9703. if (newZ !== this._zOrder) {
  9704. this._zOrder = newZ;
  9705. this.onPrimBecomesDirty();
  9706. this.onZOrderChanged();
  9707. if (this._actualZOrderChangedObservable && this._actualZOrderChangedObservable.hasObservers()) {
  9708. if (directEmit) {
  9709. this._actualZOrderChangedObservable.notifyObservers(newZ);
  9710. }
  9711. else {
  9712. Prim2DBase_1._zOrderChangedNotifList.push(this);
  9713. }
  9714. }
  9715. }
  9716. };
  9717. Prim2DBase.prototype._updateRenderMode = function () {
  9718. };
  9719. /**
  9720. * This method is used to alter the contentArea of the Primitive before margin is applied.
  9721. * In most of the case you won't need to override this method, but it can prove some usefulness, check the Rectangle2D class for a concrete application.
  9722. * @param primSize the current size of the primitive
  9723. * @param initialContentPosition the position of the initial content area to compute, a valid object is passed, you have to set its properties. PLEASE ROUND the values, we're talking about pixels and fraction of them is not a good thing! x, y, z, w area left, bottom, right, top
  9724. * @param initialContentArea the size of the initial content area to compute, a valid object is passed, you have to set its properties. PLEASE ROUND the values, we're talking about pixels and fraction of them is not a good thing!
  9725. */
  9726. Prim2DBase.prototype._getInitialContentAreaToRef = function (primSize, initialContentPosition, initialContentArea) {
  9727. initialContentArea.copyFrom(primSize);
  9728. initialContentPosition.x = initialContentPosition.y = initialContentPosition.z = initialContentPosition.w = 0;
  9729. };
  9730. /**
  9731. * This method is used to calculate the new size of the primitive based on the content which must stay the same
  9732. * Check the Rectangle2D implementation for a concrete application.
  9733. * @param primSize the current size of the primitive
  9734. * @param newPrimSize the new size of the primitive. PLEASE ROUND THE values, we're talking about pixels and fraction of them are not our friends!
  9735. */
  9736. Prim2DBase.prototype._getActualSizeFromContentToRef = function (primSize, paddingOffset, newPrimSize) {
  9737. newPrimSize.copyFrom(primSize);
  9738. };
  9739. Object.defineProperty(Prim2DBase.prototype, "layoutData", {
  9740. /**
  9741. * Get/set the layout data to use for this primitive.
  9742. */
  9743. get: function () {
  9744. return this._layoutData;
  9745. },
  9746. set: function (value) {
  9747. if (this._layoutData === value) {
  9748. return;
  9749. }
  9750. this._layoutData = value;
  9751. },
  9752. enumerable: true,
  9753. configurable: true
  9754. });
  9755. return Prim2DBase;
  9756. }(BABYLON.SmartPropertyPrim));
  9757. Prim2DBase.PRIM2DBASE_PROPCOUNT = 25;
  9758. Prim2DBase._bigInt = Math.pow(2, 30);
  9759. Prim2DBase._nullPosition = BABYLON.Vector2.Zero();
  9760. Prim2DBase._nullSize = BABYLON.Size.Zero();
  9761. Prim2DBase.boundinbBoxReentrency = -1;
  9762. Prim2DBase.nullSize = BABYLON.Size.Zero();
  9763. Prim2DBase._bMinMax = BABYLON.Vector4.Zero();
  9764. Prim2DBase._bMax = BABYLON.Vector2.Zero();
  9765. Prim2DBase._bSize = BABYLON.Size.Zero();
  9766. Prim2DBase._tpsBB = new BABYLON.BoundingInfo2D();
  9767. Prim2DBase._tpsBB2 = new BABYLON.BoundingInfo2D();
  9768. Prim2DBase._updatingDebugArea = false;
  9769. Prim2DBase._bypassGroup2DExclusion = false;
  9770. Prim2DBase._isCanvasInit = false;
  9771. Prim2DBase._t0 = new BABYLON.Matrix2D();
  9772. Prim2DBase._t1 = new BABYLON.Matrix2D();
  9773. Prim2DBase._t2 = new BABYLON.Matrix2D();
  9774. Prim2DBase._v0 = BABYLON.Vector2.Zero(); // Must stay with the value 0,0
  9775. Prim2DBase._v30 = BABYLON.Vector3.Zero(); // Must stay with the value 0,0,0
  9776. Prim2DBase._iv2 = new BABYLON.Vector2(1, 1); // Must stay identity vector
  9777. Prim2DBase._ts0 = BABYLON.Size.Zero();
  9778. Prim2DBase._transMtx = BABYLON.Matrix2D.Zero();
  9779. Prim2DBase._icPos = BABYLON.Vector2.Zero();
  9780. Prim2DBase._icZone = BABYLON.Vector4.Zero();
  9781. Prim2DBase._icArea = BABYLON.Size.Zero();
  9782. Prim2DBase._size = BABYLON.Size.Zero();
  9783. Prim2DBase._size2 = BABYLON.Size.Zero();
  9784. Prim2DBase._size3 = BABYLON.Size.Zero();
  9785. Prim2DBase._size4 = BABYLON.Size.Zero();
  9786. Prim2DBase._pv0 = BABYLON.Vector2.Zero();
  9787. Prim2DBase._curContentArea = BABYLON.Size.Zero();
  9788. Prim2DBase._piv = new BABYLON.Vector2(1, 1);
  9789. Prim2DBase._tbi = new BABYLON.BoundingInfo2D();
  9790. Prim2DBase._pv1 = BABYLON.Vector2.Zero();
  9791. Prim2DBase._pv2 = BABYLON.Vector2.Zero();
  9792. Prim2DBase._zOrderChangedNotifList = new Array();
  9793. Prim2DBase._zRebuildReentrency = false;
  9794. Prim2DBase._totalCount = 0;
  9795. __decorate([
  9796. BABYLON.logProp(null, false, false, false),
  9797. BABYLON.instanceLevelProperty(1, function (pi) { return Prim2DBase_1.actualPositionProperty = pi; }, false, false, true)
  9798. /**
  9799. * Return the position where the primitive is rendered in the Canvas, this position may be different than the one returned by the position property due to layout/alignment/margin/padding computing.
  9800. * BEWARE: don't change this value, it's read-only!
  9801. */
  9802. ], Prim2DBase.prototype, "actualPosition", null);
  9803. __decorate([
  9804. BABYLON.instanceLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 1, function (pi) { return Prim2DBase_1.actualXProperty = pi; }, false, false, true)
  9805. ], Prim2DBase.prototype, "actualX", null);
  9806. __decorate([
  9807. BABYLON.instanceLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 2, function (pi) { return Prim2DBase_1.actualYProperty = pi; }, false, false, true)
  9808. ], Prim2DBase.prototype, "actualY", null);
  9809. __decorate([
  9810. BABYLON.dynamicLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 3, function (pi) { return Prim2DBase_1.positionProperty = pi; }, false, false, true)
  9811. ], Prim2DBase.prototype, "position", null);
  9812. __decorate([
  9813. BABYLON.dynamicLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 4, function (pi) { return Prim2DBase_1.xProperty = pi; }, false, false, true)
  9814. ], Prim2DBase.prototype, "x", null);
  9815. __decorate([
  9816. BABYLON.dynamicLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 5, function (pi) { return Prim2DBase_1.yProperty = pi; }, false, false, true)
  9817. ], Prim2DBase.prototype, "y", null);
  9818. __decorate([
  9819. BABYLON.logProp(),
  9820. BABYLON.dynamicLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 6, function (pi) { return Prim2DBase_1.sizeProperty = pi; }, false, true)
  9821. /**
  9822. * Size of the primitive or its bounding area
  9823. * BEWARE: if you change only size.width or height it won't trigger a property change and you won't have the expected behavior.
  9824. * Use this property to set a new Size object, otherwise to change only the width/height use Prim2DBase.width or height properties.
  9825. */
  9826. ], Prim2DBase.prototype, "size", null);
  9827. __decorate([
  9828. BABYLON.logMethod()
  9829. ], Prim2DBase.prototype, "internalGetSize", null);
  9830. __decorate([
  9831. BABYLON.logMethod()
  9832. ], Prim2DBase.prototype, "internalSetSize", null);
  9833. __decorate([
  9834. BABYLON.logProp(),
  9835. BABYLON.dynamicLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 7, function (pi) { return Prim2DBase_1.widthProperty = pi; }, false, true)
  9836. /**
  9837. * Direct access to the size.width value of the primitive
  9838. * Use this property when you only want to change one component of the size property
  9839. */
  9840. ], Prim2DBase.prototype, "width", null);
  9841. __decorate([
  9842. BABYLON.logProp(),
  9843. BABYLON.dynamicLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 8, function (pi) { return Prim2DBase_1.heightProperty = pi; }, false, true)
  9844. /**
  9845. * Direct access to the size.height value of the primitive
  9846. * Use this property when you only want to change one component of the size property
  9847. */
  9848. ], Prim2DBase.prototype, "height", null);
  9849. __decorate([
  9850. BABYLON.logProp(),
  9851. BABYLON.instanceLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 9, function (pi) { return Prim2DBase_1.rotationProperty = pi; }, false, true)
  9852. /**
  9853. * Rotation of the primitive, in radian, along the Z axis
  9854. */
  9855. ], Prim2DBase.prototype, "rotation", null);
  9856. __decorate([
  9857. BABYLON.logProp(),
  9858. BABYLON.instanceLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 10, function (pi) { return Prim2DBase_1.scaleProperty = pi; }, false, true)
  9859. /**
  9860. * Uniform scale applied on the primitive. If a non-uniform scale is applied through scaleX/scaleY property the getter of this property will return scaleX.
  9861. */
  9862. ], Prim2DBase.prototype, "scale", null);
  9863. __decorate([
  9864. BABYLON.logProp(),
  9865. BABYLON.dynamicLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 11, function (pi) { return Prim2DBase_1.actualSizeProperty = pi; }, false, true)
  9866. /**
  9867. * Return the size of the primitive as it's being rendered into the target.
  9868. * This value may be different of the size property when layout/alignment is used or specific primitive types can implement a custom logic through this property.
  9869. * BEWARE: don't use the setter, it's for internal purpose only
  9870. * Note to implementers: you have to override this property and declare if necessary a @xxxxInstanceLevel decorator
  9871. */
  9872. ], Prim2DBase.prototype, "actualSize", null);
  9873. __decorate([
  9874. BABYLON.dynamicLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 12, function (pi) { return Prim2DBase_1.actualWidthProperty = pi; }, false, true)
  9875. /**
  9876. * Shortcut to actualSize.width
  9877. */
  9878. ], Prim2DBase.prototype, "actualWidth", null);
  9879. __decorate([
  9880. BABYLON.dynamicLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 13, function (pi) { return Prim2DBase_1.actualHeightProperty = pi; }, false, true)
  9881. /**
  9882. * Shortcut to actualPosition.height
  9883. */
  9884. ], Prim2DBase.prototype, "actualHeight", null);
  9885. __decorate([
  9886. BABYLON.dynamicLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 14, function (pi) { return Prim2DBase_1.originProperty = pi; }, false, true)
  9887. ], Prim2DBase.prototype, "origin", null);
  9888. __decorate([
  9889. BABYLON.dynamicLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 15, function (pi) { return Prim2DBase_1.levelVisibleProperty = pi; })
  9890. /**
  9891. * Let the user defines if the Primitive is hidden or not at its level. As Primitives inherit the hidden status from their parent, only the isVisible property give properly the real visible state.
  9892. * Default is true, setting to false will hide this primitive and its children.
  9893. */
  9894. ], Prim2DBase.prototype, "levelVisible", null);
  9895. __decorate([
  9896. BABYLON.instanceLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 16, function (pi) { return Prim2DBase_1.isVisibleProperty = pi; })
  9897. /**
  9898. * Use ONLY THE GETTER to determine if the primitive is visible or not.
  9899. * The Setter is for internal purpose only!
  9900. */
  9901. ], Prim2DBase.prototype, "isVisible", null);
  9902. __decorate([
  9903. BABYLON.instanceLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 17, function (pi) { return Prim2DBase_1.zOrderProperty = pi; })
  9904. /**
  9905. * You can override the default Z Order through this property, but most of the time the default behavior is acceptable
  9906. */
  9907. ], Prim2DBase.prototype, "zOrder", null);
  9908. __decorate([
  9909. BABYLON.dynamicLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 18, function (pi) { return Prim2DBase_1.marginProperty = pi; })
  9910. /**
  9911. * You can get/set a margin on the primitive through this property
  9912. * @returns the margin object, if there was none, a default one is created and returned
  9913. */
  9914. ], Prim2DBase.prototype, "margin", null);
  9915. __decorate([
  9916. BABYLON.dynamicLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 19, function (pi) { return Prim2DBase_1.paddingProperty = pi; })
  9917. /**
  9918. * You can get/set a margin on the primitive through this property
  9919. * @returns the margin object, if there was none, a default one is created and returned
  9920. */
  9921. ], Prim2DBase.prototype, "padding", null);
  9922. __decorate([
  9923. BABYLON.dynamicLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 20, function (pi) { return Prim2DBase_1.marginAlignmentProperty = pi; })
  9924. /**
  9925. * You can get/set the margin alignment through this property
  9926. */
  9927. ], Prim2DBase.prototype, "marginAlignment", null);
  9928. __decorate([
  9929. BABYLON.instanceLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 21, function (pi) { return Prim2DBase_1.opacityProperty = pi; })
  9930. /**
  9931. * Get/set the opacity of the whole primitive
  9932. */
  9933. ], Prim2DBase.prototype, "opacity", null);
  9934. __decorate([
  9935. BABYLON.instanceLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 22, function (pi) { return Prim2DBase_1.scaleXProperty = pi; }, false, true)
  9936. /**
  9937. * Scale applied on the X axis of the primitive
  9938. */
  9939. ], Prim2DBase.prototype, "scaleX", null);
  9940. __decorate([
  9941. BABYLON.instanceLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 23, function (pi) { return Prim2DBase_1.scaleYProperty = pi; }, false, true)
  9942. /**
  9943. * Scale applied on the Y axis of the primitive
  9944. */
  9945. ], Prim2DBase.prototype, "scaleY", null);
  9946. __decorate([
  9947. BABYLON.instanceLevelProperty(BABYLON.SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 24, function (pi) { return Prim2DBase_1.actualScaleProperty = pi; }, false, true)
  9948. ], Prim2DBase.prototype, "actualScale", null);
  9949. __decorate([
  9950. BABYLON.logProp("", true)
  9951. ], Prim2DBase.prototype, "boundingInfo", null);
  9952. __decorate([
  9953. BABYLON.logProp("", true)
  9954. ], Prim2DBase.prototype, "layoutBoundingInfo", null);
  9955. __decorate([
  9956. BABYLON.logMethod("", true)
  9957. ], Prim2DBase.prototype, "_setLayoutDirty", null);
  9958. __decorate([
  9959. BABYLON.logMethod("", true)
  9960. ], Prim2DBase.prototype, "_positioningDirty", null);
  9961. __decorate([
  9962. BABYLON.logMethod()
  9963. ], Prim2DBase.prototype, "updateCachedStates", null);
  9964. __decorate([
  9965. BABYLON.logMethod()
  9966. ], Prim2DBase.prototype, "_updatePositioning", null);
  9967. Prim2DBase = Prim2DBase_1 = __decorate([
  9968. BABYLON.className("Prim2DBase", "BABYLON")
  9969. /**
  9970. * Base class for a Primitive of the Canvas2D feature
  9971. */
  9972. ], Prim2DBase);
  9973. BABYLON.Prim2DBase = Prim2DBase;
  9974. var PrimitiveAlignment_1, PrimitiveThickness_1, Prim2DBase_1;
  9975. })(BABYLON || (BABYLON = {}));
  9976. //# sourceMappingURL=babylon.prim2dBase.js.map
  9977. var __extends = (this && this.__extends) || (function () {
  9978. var extendStatics = Object.setPrototypeOf ||
  9979. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  9980. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  9981. return function (d, b) {
  9982. extendStatics(d, b);
  9983. function __() { this.constructor = d; }
  9984. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  9985. };
  9986. })();
  9987. var BABYLON;
  9988. (function (BABYLON) {
  9989. var GroupInstanceInfo = (function () {
  9990. function GroupInstanceInfo(owner, mrc, partCount) {
  9991. this._partCount = partCount;
  9992. this._primCount = 0;
  9993. this.owner = owner;
  9994. this.modelRenderCache = mrc;
  9995. this.modelRenderCache.addRef();
  9996. this.partIndexFromId = new BABYLON.StringDictionary();
  9997. this._usedShaderCategories = new Array(partCount);
  9998. this._strides = new Array(partCount);
  9999. this._opaqueData = null;
  10000. this._alphaTestData = null;
  10001. this._transparentData = null;
  10002. this.opaqueDirty = this.alphaTestDirty = this.transparentDirty = this.transparentOrderDirty = false;
  10003. }
  10004. GroupInstanceInfo.prototype.incPrimCount = function () {
  10005. ++this._primCount;
  10006. };
  10007. GroupInstanceInfo.prototype.dispose = function () {
  10008. if (this._isDisposed) {
  10009. return false;
  10010. }
  10011. // Disposed is called when a primitive instance is disposed, so we decrement the counter
  10012. --this._primCount;
  10013. // If the counter is still greater than 0 there's still other primitives using this GII
  10014. if (this._primCount > 0) {
  10015. return false;
  10016. }
  10017. // We're going to dispose this GII, first remove it from the dictionary
  10018. this.owner._renderableData._renderGroupInstancesInfo.remove(this.modelRenderCache.modelKey);
  10019. if (this.modelRenderCache) {
  10020. this.modelRenderCache.dispose();
  10021. this.modelRenderCache = null;
  10022. }
  10023. var engine = this.owner.owner.engine;
  10024. if (this._opaqueData) {
  10025. this._opaqueData.forEach(function (d) { return d.dispose(engine); });
  10026. this._opaqueData = null;
  10027. }
  10028. if (this._alphaTestData) {
  10029. this._alphaTestData.forEach(function (d) { return d.dispose(engine); });
  10030. this._alphaTestData = null;
  10031. }
  10032. if (this._transparentData) {
  10033. this._transparentData.forEach(function (d) { return d.dispose(engine); });
  10034. this._transparentData = null;
  10035. }
  10036. this.partIndexFromId = null;
  10037. this._isDisposed = true;
  10038. return true;
  10039. };
  10040. Object.defineProperty(GroupInstanceInfo.prototype, "isDisposed", {
  10041. get: function () {
  10042. return this._isDisposed;
  10043. },
  10044. enumerable: true,
  10045. configurable: true
  10046. });
  10047. Object.defineProperty(GroupInstanceInfo.prototype, "hasOpaqueData", {
  10048. get: function () {
  10049. return this._opaqueData != null;
  10050. },
  10051. enumerable: true,
  10052. configurable: true
  10053. });
  10054. Object.defineProperty(GroupInstanceInfo.prototype, "hasAlphaTestData", {
  10055. get: function () {
  10056. return this._alphaTestData != null;
  10057. },
  10058. enumerable: true,
  10059. configurable: true
  10060. });
  10061. Object.defineProperty(GroupInstanceInfo.prototype, "hasTransparentData", {
  10062. get: function () {
  10063. return this._transparentData != null;
  10064. },
  10065. enumerable: true,
  10066. configurable: true
  10067. });
  10068. Object.defineProperty(GroupInstanceInfo.prototype, "opaqueData", {
  10069. get: function () {
  10070. if (!this._opaqueData) {
  10071. this._opaqueData = new Array(this._partCount);
  10072. for (var i = 0; i < this._partCount; i++) {
  10073. this._opaqueData[i] = new GroupInfoPartData(this._strides[i]);
  10074. }
  10075. }
  10076. return this._opaqueData;
  10077. },
  10078. enumerable: true,
  10079. configurable: true
  10080. });
  10081. Object.defineProperty(GroupInstanceInfo.prototype, "alphaTestData", {
  10082. get: function () {
  10083. if (!this._alphaTestData) {
  10084. this._alphaTestData = new Array(this._partCount);
  10085. for (var i = 0; i < this._partCount; i++) {
  10086. this._alphaTestData[i] = new GroupInfoPartData(this._strides[i]);
  10087. }
  10088. }
  10089. return this._alphaTestData;
  10090. },
  10091. enumerable: true,
  10092. configurable: true
  10093. });
  10094. Object.defineProperty(GroupInstanceInfo.prototype, "transparentData", {
  10095. get: function () {
  10096. if (!this._transparentData) {
  10097. this._transparentData = new Array(this._partCount);
  10098. for (var i = 0; i < this._partCount; i++) {
  10099. var zoff = this.modelRenderCache._partData[i]._zBiasOffset;
  10100. this._transparentData[i] = new TransparentGroupInfoPartData(this._strides[i], zoff);
  10101. }
  10102. }
  10103. return this._transparentData;
  10104. },
  10105. enumerable: true,
  10106. configurable: true
  10107. });
  10108. GroupInstanceInfo.prototype.sortTransparentData = function () {
  10109. if (!this.transparentOrderDirty) {
  10110. return;
  10111. }
  10112. for (var i = 0; i < this._transparentData.length; i++) {
  10113. var td = this._transparentData[i];
  10114. td._partData.sort();
  10115. }
  10116. this.transparentOrderDirty = false;
  10117. };
  10118. Object.defineProperty(GroupInstanceInfo.prototype, "usedShaderCategories", {
  10119. get: function () {
  10120. return this._usedShaderCategories;
  10121. },
  10122. enumerable: true,
  10123. configurable: true
  10124. });
  10125. Object.defineProperty(GroupInstanceInfo.prototype, "strides", {
  10126. get: function () {
  10127. return this._strides;
  10128. },
  10129. enumerable: true,
  10130. configurable: true
  10131. });
  10132. return GroupInstanceInfo;
  10133. }());
  10134. BABYLON.GroupInstanceInfo = GroupInstanceInfo;
  10135. var TransparentSegment = (function () {
  10136. function TransparentSegment() {
  10137. this.groupInsanceInfo = null;
  10138. this.startZ = 0;
  10139. this.endZ = 0;
  10140. this.startDataIndex = BABYLON.Prim2DBase._bigInt;
  10141. this.endDataIndex = 0;
  10142. this.partBuffers = null;
  10143. }
  10144. TransparentSegment.prototype.dispose = function (engine) {
  10145. if (this.partBuffers) {
  10146. this.partBuffers.forEach(function (b) { return engine._releaseBuffer(b); });
  10147. this.partBuffers.splice(0);
  10148. this.partBuffers = null;
  10149. }
  10150. };
  10151. return TransparentSegment;
  10152. }());
  10153. BABYLON.TransparentSegment = TransparentSegment;
  10154. var GroupInfoPartData = (function () {
  10155. function GroupInfoPartData(stride) {
  10156. this._partData = null;
  10157. this._partBuffer = null;
  10158. this._partBufferSize = 0;
  10159. this._partData = new BABYLON.DynamicFloatArray(stride / 4, 50);
  10160. this._isDisposed = false;
  10161. }
  10162. GroupInfoPartData.prototype.dispose = function (engine) {
  10163. if (this._isDisposed) {
  10164. return false;
  10165. }
  10166. if (this._partBuffer) {
  10167. engine._releaseBuffer(this._partBuffer);
  10168. this._partBuffer = null;
  10169. }
  10170. this._partData = null;
  10171. this._isDisposed = true;
  10172. };
  10173. return GroupInfoPartData;
  10174. }());
  10175. BABYLON.GroupInfoPartData = GroupInfoPartData;
  10176. var TransparentGroupInfoPartData = (function (_super) {
  10177. __extends(TransparentGroupInfoPartData, _super);
  10178. function TransparentGroupInfoPartData(stride, zoff) {
  10179. var _this = _super.call(this, stride) || this;
  10180. _this._partData.compareValueOffset = zoff;
  10181. _this._partData.sortingAscending = false;
  10182. return _this;
  10183. }
  10184. return TransparentGroupInfoPartData;
  10185. }(GroupInfoPartData));
  10186. BABYLON.TransparentGroupInfoPartData = TransparentGroupInfoPartData;
  10187. var ModelRenderCache = (function () {
  10188. function ModelRenderCache(engine, modelKey) {
  10189. this._engine = engine;
  10190. this._modelKey = modelKey;
  10191. this._nextKey = 1;
  10192. this._refCounter = 1;
  10193. this._partData = null;
  10194. }
  10195. ModelRenderCache.prototype.dispose = function () {
  10196. if (--this._refCounter !== 0) {
  10197. return false;
  10198. }
  10199. // Remove the Model Render Cache from the global dictionary
  10200. var edata = this._engine.getExternalData("__BJSCANVAS2D__");
  10201. if (edata) {
  10202. edata.DisposeModelRenderCache(this);
  10203. }
  10204. return true;
  10205. };
  10206. Object.defineProperty(ModelRenderCache.prototype, "isDisposed", {
  10207. get: function () {
  10208. return this._refCounter <= 0;
  10209. },
  10210. enumerable: true,
  10211. configurable: true
  10212. });
  10213. ModelRenderCache.prototype.addRef = function () {
  10214. return ++this._refCounter;
  10215. };
  10216. Object.defineProperty(ModelRenderCache.prototype, "modelKey", {
  10217. get: function () {
  10218. return this._modelKey;
  10219. },
  10220. enumerable: true,
  10221. configurable: true
  10222. });
  10223. ModelRenderCache.prototype.updateModelRenderCache = function (prim) {
  10224. return false;
  10225. };
  10226. /**
  10227. * Render the model instances
  10228. * @param instanceInfo
  10229. * @param context
  10230. * @return must return true is the rendering succeed, false if the rendering couldn't be done (asset's not yet ready, like Effect)
  10231. */
  10232. ModelRenderCache.prototype.render = function (instanceInfo, context) {
  10233. return true;
  10234. };
  10235. ModelRenderCache.prototype.getPartIndexFromId = function (partId) {
  10236. for (var i = 0; i < this._partData.length; i++) {
  10237. if (this._partData[i]._partId === partId) {
  10238. return i;
  10239. }
  10240. }
  10241. return null;
  10242. };
  10243. ModelRenderCache.prototype.loadInstancingAttributes = function (partId, effect) {
  10244. var i = this.getPartIndexFromId(partId);
  10245. if (i === null) {
  10246. return null;
  10247. }
  10248. var ci = this._partsClassInfo[i];
  10249. var categories = this._partData[i]._partUsedCategories;
  10250. var res = ci.classContent.getInstancingAttributeInfos(effect, categories);
  10251. return res;
  10252. };
  10253. ModelRenderCache.prototype.setupUniforms = function (effect, partIndex, data, elementCount) {
  10254. var pd = this._partData[partIndex];
  10255. var offset = (pd._partDataStride / 4) * elementCount;
  10256. var pci = this._partsClassInfo[partIndex];
  10257. var self = this;
  10258. pci.fullContent.forEach(function (k, v) {
  10259. if (!v.category || pd._partUsedCategories.indexOf(v.category) !== -1) {
  10260. switch (v.dataType) {
  10261. case 3 /* float */:
  10262. {
  10263. var attribOffset = v.instanceOffset.get(pd._partJoinedUsedCategories);
  10264. effect.setFloat(v.attributeName, data.buffer[offset + attribOffset]);
  10265. break;
  10266. }
  10267. case 0 /* Vector2 */:
  10268. {
  10269. var attribOffset = v.instanceOffset.get(pd._partJoinedUsedCategories);
  10270. ModelRenderCache.v2.x = data.buffer[offset + attribOffset + 0];
  10271. ModelRenderCache.v2.y = data.buffer[offset + attribOffset + 1];
  10272. effect.setVector2(v.attributeName, ModelRenderCache.v2);
  10273. break;
  10274. }
  10275. case 4 /* Color3 */:
  10276. case 1 /* Vector3 */:
  10277. {
  10278. var attribOffset = v.instanceOffset.get(pd._partJoinedUsedCategories);
  10279. ModelRenderCache.v3.x = data.buffer[offset + attribOffset + 0];
  10280. ModelRenderCache.v3.y = data.buffer[offset + attribOffset + 1];
  10281. ModelRenderCache.v3.z = data.buffer[offset + attribOffset + 2];
  10282. effect.setVector3(v.attributeName, ModelRenderCache.v3);
  10283. break;
  10284. }
  10285. case 5 /* Color4 */:
  10286. case 2 /* Vector4 */:
  10287. {
  10288. var attribOffset = v.instanceOffset.get(pd._partJoinedUsedCategories);
  10289. ModelRenderCache.v4.x = data.buffer[offset + attribOffset + 0];
  10290. ModelRenderCache.v4.y = data.buffer[offset + attribOffset + 1];
  10291. ModelRenderCache.v4.z = data.buffer[offset + attribOffset + 2];
  10292. ModelRenderCache.v4.w = data.buffer[offset + attribOffset + 3];
  10293. effect.setVector4(v.attributeName, ModelRenderCache.v4);
  10294. break;
  10295. }
  10296. default:
  10297. }
  10298. }
  10299. });
  10300. };
  10301. return ModelRenderCache;
  10302. }());
  10303. //setupUniformsLocation(effect: Effect, uniforms: string[], partId: number) {
  10304. // let i = this.getPartIndexFromId(partId);
  10305. // if (i === null) {
  10306. // return null;
  10307. // }
  10308. // let pci = this._partsClassInfo[i];
  10309. // pci.fullContent.forEach((k, v) => {
  10310. // if (uniforms.indexOf(v.attributeName) !== -1) {
  10311. // v.uniformLocation = effect.getUniform(v.attributeName);
  10312. // }
  10313. // });
  10314. //}
  10315. ModelRenderCache.v2 = BABYLON.Vector2.Zero();
  10316. ModelRenderCache.v3 = BABYLON.Vector3.Zero();
  10317. ModelRenderCache.v4 = BABYLON.Vector4.Zero();
  10318. BABYLON.ModelRenderCache = ModelRenderCache;
  10319. var ModelRenderCachePartData = (function () {
  10320. function ModelRenderCachePartData() {
  10321. }
  10322. return ModelRenderCachePartData;
  10323. }());
  10324. BABYLON.ModelRenderCachePartData = ModelRenderCachePartData;
  10325. })(BABYLON || (BABYLON = {}));
  10326. //# sourceMappingURL=babylon.modelRenderCache.js.map
  10327. var __extends = (this && this.__extends) || (function () {
  10328. var extendStatics = Object.setPrototypeOf ||
  10329. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  10330. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  10331. return function (d, b) {
  10332. extendStatics(d, b);
  10333. function __() { this.constructor = d; }
  10334. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  10335. };
  10336. })();
  10337. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  10338. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  10339. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  10340. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  10341. return c > 3 && r && Object.defineProperty(target, key, r), r;
  10342. };
  10343. var BABYLON;
  10344. (function (BABYLON) {
  10345. var InstanceClassInfo = (function () {
  10346. function InstanceClassInfo(base) {
  10347. this._baseInfo = base;
  10348. this._nextOffset = new BABYLON.StringDictionary();
  10349. this._attributes = new Array();
  10350. }
  10351. InstanceClassInfo.prototype.mapProperty = function (propInfo, push) {
  10352. var curOff = this._nextOffset.getOrAdd(InstanceClassInfo._CurCategories, 0);
  10353. propInfo.instanceOffset.add(InstanceClassInfo._CurCategories, this._getBaseOffset(InstanceClassInfo._CurCategories) + curOff);
  10354. //console.log(`[${InstanceClassInfo._CurCategories}] New PropInfo. Category: ${propInfo.category}, Name: ${propInfo.attributeName}, Offset: ${propInfo.instanceOffset.get(InstanceClassInfo._CurCategories)}, Size: ${propInfo.size / 4}`);
  10355. this._nextOffset.set(InstanceClassInfo._CurCategories, curOff + (propInfo.size / 4));
  10356. if (push) {
  10357. this._attributes.push(propInfo);
  10358. }
  10359. };
  10360. InstanceClassInfo.prototype.getInstancingAttributeInfos = function (effect, categories) {
  10361. var catInline = ";" + categories.join(";") + ";";
  10362. var res = new Array();
  10363. var curInfo = this;
  10364. while (curInfo) {
  10365. for (var _i = 0, _a = curInfo._attributes; _i < _a.length; _i++) {
  10366. var attrib = _a[_i];
  10367. // Only map if there's no category assigned to the instance data or if there's a category and it's in the given list
  10368. if (!attrib.category || categories.indexOf(attrib.category) !== -1) {
  10369. var index = effect.getAttributeLocationByName(attrib.attributeName);
  10370. if (index === -1) {
  10371. throw new Error("Attribute " + attrib.attributeName + " was not found in Effect: " + effect.name + ". It's certainly no longer used in the Effect's Shaders");
  10372. }
  10373. var iai = new BABYLON.InstancingAttributeInfo();
  10374. iai.index = index;
  10375. iai.attributeSize = attrib.size / 4; // attrib.size is in byte and we need to store in "component" (i.e float is 1, vec3 is 3)
  10376. iai.offset = attrib.instanceOffset.get(catInline) * 4; // attrib.instanceOffset is in float, iai.offset must be in bytes
  10377. iai.attributeName = attrib.attributeName;
  10378. res.push(iai);
  10379. }
  10380. }
  10381. curInfo = curInfo._baseInfo;
  10382. }
  10383. return res;
  10384. };
  10385. InstanceClassInfo.prototype.getShaderAttributes = function (categories) {
  10386. var res = new Array();
  10387. var curInfo = this;
  10388. while (curInfo) {
  10389. for (var _i = 0, _a = curInfo._attributes; _i < _a.length; _i++) {
  10390. var attrib = _a[_i];
  10391. // Only map if there's no category assigned to the instance data or if there's a category and it's in the given list
  10392. if (!attrib.category || categories.indexOf(attrib.category) !== -1) {
  10393. res.push(attrib.attributeName);
  10394. }
  10395. }
  10396. curInfo = curInfo._baseInfo;
  10397. }
  10398. return res;
  10399. };
  10400. InstanceClassInfo.prototype._getBaseOffset = function (categories) {
  10401. var curOffset = 0;
  10402. var curBase = this._baseInfo;
  10403. while (curBase) {
  10404. curOffset += curBase._nextOffset.getOrAdd(categories, 0);
  10405. curBase = curBase._baseInfo;
  10406. }
  10407. return curOffset;
  10408. };
  10409. return InstanceClassInfo;
  10410. }());
  10411. BABYLON.InstanceClassInfo = InstanceClassInfo;
  10412. var InstancePropInfo = (function () {
  10413. function InstancePropInfo() {
  10414. this.attributeName = null;
  10415. this.category = null;
  10416. this.size = null;
  10417. this.instanceOffset = new BABYLON.StringDictionary();
  10418. this.dataType = 0;
  10419. this.curCategory = "";
  10420. this.curCategoryOffset = 0;
  10421. }
  10422. InstancePropInfo.prototype.setSize = function (val) {
  10423. if (val instanceof BABYLON.Vector2) {
  10424. this.size = 8;
  10425. this.dataType = 0 /* Vector2 */;
  10426. return;
  10427. }
  10428. if (val instanceof BABYLON.Vector3) {
  10429. this.size = 12;
  10430. this.dataType = 1 /* Vector3 */;
  10431. return;
  10432. }
  10433. if (val instanceof BABYLON.Vector4) {
  10434. this.size = 16;
  10435. this.dataType = 2 /* Vector4 */;
  10436. return;
  10437. }
  10438. if (val instanceof BABYLON.Matrix2D) {
  10439. throw new Error("Matrix2D type is not supported by WebGL Instance Buffer, you have to use four Vector4 properties instead");
  10440. }
  10441. if (typeof (val) === "number") {
  10442. this.size = 4;
  10443. this.dataType = 3 /* float */;
  10444. return;
  10445. }
  10446. if (val instanceof BABYLON.Color3) {
  10447. this.size = 12;
  10448. this.dataType = 4 /* Color3 */;
  10449. return;
  10450. }
  10451. if (val instanceof BABYLON.Color4) {
  10452. this.size = 16;
  10453. this.dataType = 5 /* Color4 */;
  10454. return;
  10455. }
  10456. if (val instanceof BABYLON.Size) {
  10457. this.size = 8;
  10458. this.dataType = 6 /* Size */;
  10459. return;
  10460. }
  10461. return;
  10462. };
  10463. InstancePropInfo.prototype.writeData = function (array, offset, val) {
  10464. switch (this.dataType) {
  10465. case 0 /* Vector2 */:
  10466. {
  10467. var v = val;
  10468. array[offset + 0] = v.x;
  10469. array[offset + 1] = v.y;
  10470. break;
  10471. }
  10472. case 1 /* Vector3 */:
  10473. {
  10474. var v = val;
  10475. array[offset + 0] = v.x;
  10476. array[offset + 1] = v.y;
  10477. array[offset + 2] = v.z;
  10478. break;
  10479. }
  10480. case 2 /* Vector4 */:
  10481. {
  10482. var v = val;
  10483. array[offset + 0] = v.x;
  10484. array[offset + 1] = v.y;
  10485. array[offset + 2] = v.z;
  10486. array[offset + 3] = v.w;
  10487. break;
  10488. }
  10489. case 4 /* Color3 */:
  10490. {
  10491. var v = val;
  10492. array[offset + 0] = v.r;
  10493. array[offset + 1] = v.g;
  10494. array[offset + 2] = v.b;
  10495. break;
  10496. }
  10497. case 5 /* Color4 */:
  10498. {
  10499. var v = val;
  10500. array[offset + 0] = v.r;
  10501. array[offset + 1] = v.g;
  10502. array[offset + 2] = v.b;
  10503. array[offset + 3] = v.a;
  10504. break;
  10505. }
  10506. case 3 /* float */:
  10507. {
  10508. var v = val;
  10509. array[offset] = v;
  10510. break;
  10511. }
  10512. case 6 /* Size */:
  10513. {
  10514. var s = val;
  10515. array[offset + 0] = s.width;
  10516. array[offset + 1] = s.height;
  10517. break;
  10518. }
  10519. }
  10520. };
  10521. return InstancePropInfo;
  10522. }());
  10523. BABYLON.InstancePropInfo = InstancePropInfo;
  10524. function instanceData(category, shaderAttributeName) {
  10525. return function (target, propName, descriptor) {
  10526. var dic = BABYLON.ClassTreeInfo.getOrRegister(target, function (base) { return new InstanceClassInfo(base); });
  10527. var node = dic.getLevelOf(target);
  10528. var instanceDataName = propName;
  10529. shaderAttributeName = shaderAttributeName || instanceDataName;
  10530. var info = node.levelContent.get(instanceDataName);
  10531. if (info) {
  10532. throw new Error("The ID " + instanceDataName + " is already taken by another instance data");
  10533. }
  10534. info = new InstancePropInfo();
  10535. info.attributeName = shaderAttributeName;
  10536. info.category = category || null;
  10537. if (info.category) {
  10538. info.delimitedCategory = ";" + info.category + ";";
  10539. }
  10540. node.levelContent.add(instanceDataName, info);
  10541. descriptor.get = function () {
  10542. return null;
  10543. };
  10544. descriptor.set = function (val) {
  10545. // Check that we're not trying to set a property that belongs to a category that is not allowed (current)
  10546. // Quit if it's the case, otherwise we could overwrite data somewhere...
  10547. if (info.category && InstanceClassInfo._CurCategories.indexOf(info.delimitedCategory) === -1) {
  10548. return;
  10549. }
  10550. var catOffset;
  10551. if (info.curCategory === InstanceClassInfo._CurCategories) {
  10552. catOffset = info.curCategoryOffset;
  10553. }
  10554. else {
  10555. if (!info.size) {
  10556. info.setSize(val);
  10557. node.classContent.mapProperty(info, true);
  10558. }
  10559. else if (!info.instanceOffset.contains(InstanceClassInfo._CurCategories)) {
  10560. node.classContent.mapProperty(info, false);
  10561. }
  10562. catOffset = info.instanceOffset.get(InstanceClassInfo._CurCategories);
  10563. info.curCategory = InstanceClassInfo._CurCategories;
  10564. info.curCategoryOffset = catOffset;
  10565. }
  10566. var obj = this;
  10567. if (obj.dataBuffer && obj.dataElements) {
  10568. var offset = obj.dataElements[obj.curElement].offset + catOffset;
  10569. info.writeData(obj.dataBuffer.buffer, offset, val);
  10570. }
  10571. };
  10572. };
  10573. }
  10574. BABYLON.instanceData = instanceData;
  10575. var InstanceDataBase = (function () {
  10576. function InstanceDataBase(partId, dataElementCount) {
  10577. this.id = partId;
  10578. this.curElement = 0;
  10579. this._dataElementCount = dataElementCount;
  10580. this.renderMode = 0;
  10581. this.arrayLengthChanged = false;
  10582. }
  10583. Object.defineProperty(InstanceDataBase.prototype, "zBias", {
  10584. get: function () {
  10585. return null;
  10586. },
  10587. set: function (value) {
  10588. },
  10589. enumerable: true,
  10590. configurable: true
  10591. });
  10592. Object.defineProperty(InstanceDataBase.prototype, "transformX", {
  10593. get: function () {
  10594. return null;
  10595. },
  10596. set: function (value) {
  10597. },
  10598. enumerable: true,
  10599. configurable: true
  10600. });
  10601. Object.defineProperty(InstanceDataBase.prototype, "transformY", {
  10602. get: function () {
  10603. return null;
  10604. },
  10605. set: function (value) {
  10606. },
  10607. enumerable: true,
  10608. configurable: true
  10609. });
  10610. Object.defineProperty(InstanceDataBase.prototype, "renderingInfo", {
  10611. // The vector3 is: rendering width, height and 1 if the primitive must be aligned to pixel or 0 otherwise
  10612. get: function () {
  10613. return null;
  10614. },
  10615. set: function (val) {
  10616. },
  10617. enumerable: true,
  10618. configurable: true
  10619. });
  10620. Object.defineProperty(InstanceDataBase.prototype, "opacity", {
  10621. get: function () {
  10622. return null;
  10623. },
  10624. set: function (value) {
  10625. },
  10626. enumerable: true,
  10627. configurable: true
  10628. });
  10629. InstanceDataBase.prototype.getClassTreeInfo = function () {
  10630. if (!this.typeInfo) {
  10631. this.typeInfo = BABYLON.ClassTreeInfo.get(Object.getPrototypeOf(this));
  10632. }
  10633. return this.typeInfo;
  10634. };
  10635. InstanceDataBase.prototype.allocElements = function () {
  10636. if (!this.dataBuffer || this.dataElements) {
  10637. return;
  10638. }
  10639. var res = new Array(this.dataElementCount);
  10640. for (var i = 0; i < this.dataElementCount; i++) {
  10641. res[i] = this.dataBuffer.allocElement();
  10642. }
  10643. this.dataElements = res;
  10644. };
  10645. InstanceDataBase.prototype.freeElements = function () {
  10646. if (!this.dataElements) {
  10647. return;
  10648. }
  10649. for (var _i = 0, _a = this.dataElements; _i < _a.length; _i++) {
  10650. var ei = _a[_i];
  10651. this.dataBuffer.freeElement(ei);
  10652. }
  10653. this.dataElements = null;
  10654. };
  10655. Object.defineProperty(InstanceDataBase.prototype, "dataElementCount", {
  10656. get: function () {
  10657. return this._dataElementCount;
  10658. },
  10659. set: function (value) {
  10660. if (value === this._dataElementCount) {
  10661. return;
  10662. }
  10663. this.arrayLengthChanged = true;
  10664. this.freeElements();
  10665. this._dataElementCount = value;
  10666. this.allocElements();
  10667. },
  10668. enumerable: true,
  10669. configurable: true
  10670. });
  10671. return InstanceDataBase;
  10672. }());
  10673. __decorate([
  10674. instanceData()
  10675. ], InstanceDataBase.prototype, "zBias", null);
  10676. __decorate([
  10677. instanceData()
  10678. ], InstanceDataBase.prototype, "transformX", null);
  10679. __decorate([
  10680. instanceData()
  10681. ], InstanceDataBase.prototype, "transformY", null);
  10682. __decorate([
  10683. instanceData()
  10684. ], InstanceDataBase.prototype, "renderingInfo", null);
  10685. __decorate([
  10686. instanceData()
  10687. ], InstanceDataBase.prototype, "opacity", null);
  10688. BABYLON.InstanceDataBase = InstanceDataBase;
  10689. var RenderablePrim2D = RenderablePrim2D_1 = (function (_super) {
  10690. __extends(RenderablePrim2D, _super);
  10691. function RenderablePrim2D(settings) {
  10692. var _this = _super.call(this, settings) || this;
  10693. _this._transparentPrimitiveInfo = null;
  10694. return _this;
  10695. }
  10696. Object.defineProperty(RenderablePrim2D.prototype, "isAlphaTest", {
  10697. get: function () {
  10698. return this._useTextureAlpha() || this._isPrimAlphaTest();
  10699. },
  10700. enumerable: true,
  10701. configurable: true
  10702. });
  10703. Object.defineProperty(RenderablePrim2D.prototype, "isTransparent", {
  10704. get: function () {
  10705. return (this.actualOpacity < 1) || this._shouldUseAlphaFromTexture() || this._isPrimTransparent();
  10706. },
  10707. enumerable: true,
  10708. configurable: true
  10709. });
  10710. Object.defineProperty(RenderablePrim2D.prototype, "renderMode", {
  10711. get: function () {
  10712. return this._renderMode;
  10713. },
  10714. enumerable: true,
  10715. configurable: true
  10716. });
  10717. /**
  10718. * Dispose the primitive and its resources, remove it from its parent
  10719. */
  10720. RenderablePrim2D.prototype.dispose = function () {
  10721. if (!_super.prototype.dispose.call(this)) {
  10722. return false;
  10723. }
  10724. if (this.renderGroup) {
  10725. this.renderGroup._setCacheGroupDirty();
  10726. }
  10727. if (this._transparentPrimitiveInfo) {
  10728. this.renderGroup._renderableData.removeTransparentPrimitiveInfo(this._transparentPrimitiveInfo);
  10729. this._transparentPrimitiveInfo = null;
  10730. }
  10731. if (this._instanceDataParts) {
  10732. this._cleanupInstanceDataParts();
  10733. }
  10734. if (this._modelRenderCache) {
  10735. this._modelRenderCache.dispose();
  10736. this._modelRenderCache = null;
  10737. }
  10738. if (this._instanceDataParts) {
  10739. this._instanceDataParts.forEach(function (p) {
  10740. p.freeElements();
  10741. });
  10742. this._instanceDataParts = null;
  10743. }
  10744. return true;
  10745. };
  10746. RenderablePrim2D.prototype._cleanupInstanceDataParts = function () {
  10747. var gii = null;
  10748. for (var _i = 0, _a = this._instanceDataParts; _i < _a.length; _i++) {
  10749. var part = _a[_i];
  10750. part.freeElements();
  10751. gii = part.groupInstanceInfo;
  10752. part.groupInstanceInfo = null;
  10753. }
  10754. if (gii) {
  10755. if (gii.hasOpaqueData) {
  10756. gii.opaqueDirty = true;
  10757. }
  10758. if (gii.hasAlphaTestData) {
  10759. gii.alphaTestDirty = true;
  10760. }
  10761. if (gii.hasTransparentData) {
  10762. gii.transparentDirty = true;
  10763. }
  10764. gii.dispose();
  10765. if (this._modelRenderCache) {
  10766. this._modelRenderCache.dispose();
  10767. this._modelRenderCache = null;
  10768. }
  10769. }
  10770. this._instanceDataParts = null;
  10771. };
  10772. RenderablePrim2D.prototype._prepareRenderPre = function (context) {
  10773. _super.prototype._prepareRenderPre.call(this, context);
  10774. // If the model changed and we have already an instance, we must remove this instance from the obsolete model
  10775. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagModelDirty) && this._instanceDataParts) {
  10776. this._cleanupInstanceDataParts();
  10777. }
  10778. // Need to create the model?
  10779. var setupModelRenderCache = false;
  10780. if (!this._modelRenderCache || this._isFlagSet(BABYLON.SmartPropertyPrim.flagModelDirty)) {
  10781. setupModelRenderCache = this._createModelRenderCache();
  10782. }
  10783. var gii = null;
  10784. var newInstance = false;
  10785. // Need to create the instance data parts?
  10786. if (!this._instanceDataParts) {
  10787. // Yes, flag it for later, more processing will have to be done
  10788. newInstance = true;
  10789. gii = this._createModelDataParts();
  10790. }
  10791. // If the ModelRenderCache is brand new, now is the time to call the implementation's specific setup method to create the rendering resources
  10792. if (setupModelRenderCache) {
  10793. this.setupModelRenderCache(this._modelRenderCache);
  10794. }
  10795. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagModelUpdate)) {
  10796. if (this._modelRenderCache.updateModelRenderCache(this)) {
  10797. this._clearFlags(BABYLON.SmartPropertyPrim.flagModelUpdate);
  10798. }
  10799. }
  10800. // At this stage we have everything correctly initialized, ModelRenderCache is setup, Model Instance data are good too, they have allocated elements in the Instanced DynamicFloatArray.
  10801. // The last thing to do is check if the instanced related data must be updated because a InstanceLevel property had changed or the primitive visibility changed.
  10802. if (this._areSomeFlagsSet(BABYLON.SmartPropertyPrim.flagVisibilityChanged | BABYLON.SmartPropertyPrim.flagNeedRefresh) || context.forceRefreshPrimitive || newInstance || (this._instanceDirtyFlags !== 0) || (this._globalTransformProcessStep !== this._globalTransformStep) || this._mustUpdateInstance()) {
  10803. this._updateInstanceDataParts(gii);
  10804. }
  10805. };
  10806. RenderablePrim2D.prototype._createModelRenderCache = function () {
  10807. var _this = this;
  10808. var setupModelRenderCache = false;
  10809. if (this._modelRenderCache) {
  10810. this._modelRenderCache.dispose();
  10811. }
  10812. this._modelRenderCache = this.owner._engineData.GetOrAddModelCache(this.modelKey, function (key) {
  10813. var mrc = _this.createModelRenderCache(key);
  10814. setupModelRenderCache = true;
  10815. return mrc;
  10816. });
  10817. this._clearFlags(BABYLON.SmartPropertyPrim.flagModelDirty);
  10818. // if this is still false it means the MRC already exists, so we add a reference to it
  10819. if (!setupModelRenderCache) {
  10820. this._modelRenderCache.addRef();
  10821. }
  10822. return setupModelRenderCache;
  10823. };
  10824. RenderablePrim2D.prototype._createModelDataParts = function () {
  10825. var _this = this;
  10826. // Create the instance data parts of the primitive and store them
  10827. var parts = this.createInstanceDataParts();
  10828. this._instanceDataParts = parts;
  10829. // Check if the ModelRenderCache for this particular instance is also brand new, initialize it if it's the case
  10830. if (!this._modelRenderCache._partData) {
  10831. this._setupModelRenderCache(parts);
  10832. }
  10833. // The Rendering resources (Effect, VB, IB, Textures) are stored in the ModelRenderCache
  10834. // But it's the RenderGroup that will store all the Instanced related data to render all the primitive it owns.
  10835. // So for a given ModelKey we getOrAdd a GroupInstanceInfo that will store all these data
  10836. var gii = this.renderGroup._renderableData._renderGroupInstancesInfo.getOrAddWithFactory(this.modelKey, function (k) {
  10837. var res = new BABYLON.GroupInstanceInfo(_this.renderGroup, _this._modelRenderCache, _this._modelRenderCache._partData.length);
  10838. for (var j = 0; j < _this._modelRenderCache._partData.length; j++) {
  10839. var part = _this._instanceDataParts[j];
  10840. res.partIndexFromId.add(part.id.toString(), j);
  10841. res.usedShaderCategories[j] = ";" + _this.getUsedShaderCategories(part).join(";") + ";";
  10842. res.strides[j] = _this._modelRenderCache._partData[j]._partDataStride;
  10843. }
  10844. return res;
  10845. });
  10846. // Get the GroupInfoDataPart corresponding to the render category of the part
  10847. var rm = 0;
  10848. var gipd = null;
  10849. if (this.isTransparent) {
  10850. gipd = gii.transparentData;
  10851. rm = BABYLON.Render2DContext.RenderModeTransparent;
  10852. }
  10853. else if (this.isAlphaTest) {
  10854. gipd = gii.alphaTestData;
  10855. rm = BABYLON.Render2DContext.RenderModeAlphaTest;
  10856. }
  10857. else {
  10858. gipd = gii.opaqueData;
  10859. rm = BABYLON.Render2DContext.RenderModeOpaque;
  10860. }
  10861. // For each instance data part of the primitive, allocate the instanced element it needs for render
  10862. for (var i = 0; i < parts.length; i++) {
  10863. var part = parts[i];
  10864. part.dataBuffer = gipd[i]._partData;
  10865. part.allocElements();
  10866. part.renderMode = rm;
  10867. part.groupInstanceInfo = gii;
  10868. }
  10869. // Increment the primitive count as one more primitive is using this GroupInstanceInfo
  10870. gii.incPrimCount();
  10871. return gii;
  10872. };
  10873. RenderablePrim2D.prototype._setupModelRenderCache = function (parts) {
  10874. var ctiArray = new Array();
  10875. this._modelRenderCache._partData = new Array();
  10876. for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) {
  10877. var dataPart = parts_1[_i];
  10878. var pd = new BABYLON.ModelRenderCachePartData();
  10879. this._modelRenderCache._partData.push(pd);
  10880. var cat = this.getUsedShaderCategories(dataPart);
  10881. var cti = dataPart.getClassTreeInfo();
  10882. // Make sure the instance is visible other the properties won't be set and their size/offset wont be computed
  10883. var curVisible = this.isVisible;
  10884. this.isVisible = true;
  10885. // We manually trigger refreshInstanceData for the only sake of evaluating each instance property size and offset in the instance data, this can only be made at runtime. Once it's done we have all the information to create the instance data buffer.
  10886. //console.log("Build Prop Layout for " + Tools.getClassName(this._instanceDataParts[0]));
  10887. var joinCat = ";" + cat.join(";") + ";";
  10888. pd._partJoinedUsedCategories = joinCat;
  10889. InstanceClassInfo._CurCategories = joinCat;
  10890. var obj = this.beforeRefreshForLayoutConstruction(dataPart);
  10891. if (!this.refreshInstanceDataPart(dataPart)) {
  10892. console.log("Layout construction for " + BABYLON.Tools.getClassName(this._instanceDataParts[0]) + " failed because refresh returned false");
  10893. }
  10894. this.afterRefreshForLayoutConstruction(dataPart, obj);
  10895. this.isVisible = curVisible;
  10896. var size = 0;
  10897. cti.fullContent.forEach(function (k, v) {
  10898. if (!v.category || cat.indexOf(v.category) !== -1) {
  10899. if (v.attributeName === "zBias") {
  10900. pd._zBiasOffset = v.instanceOffset.get(joinCat);
  10901. }
  10902. if (!v.size) {
  10903. console.log("ERROR: Couldn't detect the size of the Property " + v.attributeName + " from type " + BABYLON.Tools.getClassName(cti.type) + ". Property is ignored.");
  10904. }
  10905. else {
  10906. size += v.size;
  10907. }
  10908. }
  10909. });
  10910. pd._partDataStride = size;
  10911. pd._partUsedCategories = cat;
  10912. pd._partId = dataPart.id;
  10913. ctiArray.push(cti);
  10914. }
  10915. this._modelRenderCache._partsClassInfo = ctiArray;
  10916. };
  10917. RenderablePrim2D.prototype.onZOrderChanged = function () {
  10918. if (this.isTransparent && this._transparentPrimitiveInfo) {
  10919. this.renderGroup._renderableData.transparentPrimitiveZChanged(this._transparentPrimitiveInfo);
  10920. var gii = this.renderGroup._renderableData._renderGroupInstancesInfo.get(this.modelKey);
  10921. // Flag the transparentData dirty has will have to sort it again
  10922. gii.transparentOrderDirty = true;
  10923. }
  10924. };
  10925. RenderablePrim2D.prototype._mustUpdateInstance = function () {
  10926. return false;
  10927. };
  10928. RenderablePrim2D.prototype._useTextureAlpha = function () {
  10929. return false;
  10930. };
  10931. RenderablePrim2D.prototype._shouldUseAlphaFromTexture = function () {
  10932. return false;
  10933. };
  10934. RenderablePrim2D.prototype._isPrimAlphaTest = function () {
  10935. return false;
  10936. };
  10937. RenderablePrim2D.prototype._isPrimTransparent = function () {
  10938. return false;
  10939. };
  10940. RenderablePrim2D.prototype._updateInstanceDataParts = function (gii) {
  10941. // Fetch the GroupInstanceInfo if we don't already have it
  10942. var rd = this.renderGroup._renderableData;
  10943. if (!gii) {
  10944. gii = rd._renderGroupInstancesInfo.get(this.modelKey);
  10945. }
  10946. if (gii.isDisposed) {
  10947. return;
  10948. }
  10949. var isTransparent = this.isTransparent;
  10950. var isAlphaTest = this.isAlphaTest;
  10951. var wereTransparent = false;
  10952. // Check a render mode change
  10953. var rmChanged = false;
  10954. if (this._instanceDataParts.length > 0) {
  10955. var firstPart = this._instanceDataParts[0];
  10956. var partRM = firstPart.renderMode;
  10957. var curRM = this.renderMode;
  10958. if (partRM !== curRM) {
  10959. wereTransparent = partRM === BABYLON.Render2DContext.RenderModeTransparent;
  10960. rmChanged = true;
  10961. var gipd = void 0;
  10962. switch (curRM) {
  10963. case BABYLON.Render2DContext.RenderModeTransparent:
  10964. gipd = gii.transparentData;
  10965. break;
  10966. case BABYLON.Render2DContext.RenderModeAlphaTest:
  10967. gipd = gii.alphaTestData;
  10968. break;
  10969. default:
  10970. gipd = gii.opaqueData;
  10971. }
  10972. for (var i = 0; i < this._instanceDataParts.length; i++) {
  10973. var part = this._instanceDataParts[i];
  10974. part.freeElements();
  10975. part.dataBuffer = gipd[i]._partData;
  10976. part.renderMode = curRM;
  10977. }
  10978. }
  10979. }
  10980. // Handle changes related to ZOffset
  10981. var visChanged = this._isFlagSet(BABYLON.SmartPropertyPrim.flagVisibilityChanged);
  10982. if (isTransparent || wereTransparent) {
  10983. // Handle visibility change, which is also triggered when the primitive just got created
  10984. if (visChanged || rmChanged) {
  10985. if (this.isVisible && !wereTransparent) {
  10986. if (!this._transparentPrimitiveInfo) {
  10987. // Add the primitive to the list of transparent ones in the group that render is
  10988. this._transparentPrimitiveInfo = rd.addNewTransparentPrimitiveInfo(this, gii);
  10989. }
  10990. }
  10991. else {
  10992. if (this._transparentPrimitiveInfo) {
  10993. rd.removeTransparentPrimitiveInfo(this._transparentPrimitiveInfo);
  10994. this._transparentPrimitiveInfo = null;
  10995. }
  10996. }
  10997. gii.transparentOrderDirty = true;
  10998. }
  10999. }
  11000. var rebuildTrans = false;
  11001. // For each Instance Data part, refresh it to update the data in the DynamicFloatArray
  11002. for (var _i = 0, _a = this._instanceDataParts; _i < _a.length; _i++) {
  11003. var part = _a[_i];
  11004. var justAllocated = false;
  11005. // Check if we need to allocate data elements (hidden prim which becomes visible again)
  11006. if (!part.dataElements && (visChanged || rmChanged || this.isVisible)) {
  11007. part.allocElements();
  11008. justAllocated = true;
  11009. }
  11010. InstanceClassInfo._CurCategories = gii.usedShaderCategories[gii.partIndexFromId.get(part.id.toString())];
  11011. // Will return false if the instance should not be rendered (not visible or other any reasons)
  11012. part.arrayLengthChanged = false;
  11013. if (!this.refreshInstanceDataPart(part)) {
  11014. // Free the data element
  11015. if (part.dataElements) {
  11016. part.freeElements();
  11017. }
  11018. // The refresh couldn't succeed, push the primitive to be dirty again for the next render
  11019. if (this.isVisible) {
  11020. rd._primNewDirtyList.push(this);
  11021. }
  11022. }
  11023. rebuildTrans = rebuildTrans || part.arrayLengthChanged || justAllocated;
  11024. }
  11025. this._instanceDirtyFlags = 0;
  11026. // Make the appropriate data dirty
  11027. if (isTransparent) {
  11028. gii.transparentDirty = true;
  11029. if (rebuildTrans) {
  11030. rd._transparentListChanged = true;
  11031. }
  11032. }
  11033. else if (isAlphaTest) {
  11034. gii.alphaTestDirty = true;
  11035. }
  11036. else {
  11037. gii.opaqueDirty = true;
  11038. }
  11039. this._clearFlags(BABYLON.SmartPropertyPrim.flagVisibilityChanged); // Reset the flag as we've handled the case
  11040. };
  11041. RenderablePrim2D.prototype._updateTransparentSegmentIndices = function (ts) {
  11042. var minOff = BABYLON.Prim2DBase._bigInt;
  11043. var maxOff = 0;
  11044. for (var _i = 0, _a = this._instanceDataParts; _i < _a.length; _i++) {
  11045. var part = _a[_i];
  11046. if (part && part.dataElements) {
  11047. part.dataBuffer.pack();
  11048. for (var _b = 0, _c = part.dataElements; _b < _c.length; _b++) {
  11049. var el = _c[_b];
  11050. minOff = Math.min(minOff, el.offset);
  11051. maxOff = Math.max(maxOff, el.offset);
  11052. }
  11053. ts.startDataIndex = Math.min(ts.startDataIndex, minOff / part.dataBuffer.stride);
  11054. ts.endDataIndex = Math.max(ts.endDataIndex, (maxOff / part.dataBuffer.stride) + 1); // +1 for exclusive
  11055. }
  11056. }
  11057. };
  11058. // This internal method is mainly used for transparency processing
  11059. RenderablePrim2D.prototype._getNextPrimZOrder = function () {
  11060. var length = this._instanceDataParts.length;
  11061. for (var i = 0; i < length; i++) {
  11062. var part = this._instanceDataParts[i];
  11063. if (part) {
  11064. var stride = part.dataBuffer.stride;
  11065. var lastElementOffset = part.dataElements[part.dataElements.length - 1].offset;
  11066. // check if it's the last in the DFA
  11067. if (part.dataBuffer.totalElementCount * stride <= lastElementOffset) {
  11068. return null;
  11069. }
  11070. // Return the Z of the next primitive that lies in the DFA
  11071. return part.dataBuffer[lastElementOffset + stride + this.modelRenderCache._partData[i]._zBiasOffset];
  11072. }
  11073. }
  11074. return null;
  11075. };
  11076. // This internal method is mainly used for transparency processing
  11077. RenderablePrim2D.prototype._getPrevPrimZOrder = function () {
  11078. var length = this._instanceDataParts.length;
  11079. for (var i = 0; i < length; i++) {
  11080. var part = this._instanceDataParts[i];
  11081. if (part) {
  11082. var stride = part.dataBuffer.stride;
  11083. var firstElementOffset = part.dataElements[0].offset;
  11084. // check if it's the first in the DFA
  11085. if (firstElementOffset === 0) {
  11086. return null;
  11087. }
  11088. // Return the Z of the previous primitive that lies in the DFA
  11089. return part.dataBuffer[firstElementOffset - stride + this.modelRenderCache._partData[i]._zBiasOffset];
  11090. }
  11091. }
  11092. return null;
  11093. };
  11094. /**
  11095. * Get the info for a given effect based on the dataPart metadata
  11096. * @param dataPartId partId in part list to get the info
  11097. * @param vertexBufferAttributes vertex buffer attributes to manually add
  11098. * @param uniforms uniforms to manually add
  11099. * @param useInstanced specified if Instanced Array should be used, if null the engine caps will be used (so true if WebGL supports it, false otherwise), but you have the possibility to override the engine capability. However, if you manually set true but the engine does not support Instanced Array, this method will return null
  11100. */
  11101. RenderablePrim2D.prototype.getDataPartEffectInfo = function (dataPartId, vertexBufferAttributes, uniforms, useInstanced) {
  11102. if (uniforms === void 0) { uniforms = null; }
  11103. if (useInstanced === void 0) { useInstanced = null; }
  11104. var dataPart = BABYLON.Tools.first(this._instanceDataParts, function (i) { return i.id === dataPartId; });
  11105. if (!dataPart) {
  11106. return null;
  11107. }
  11108. var instancedArray = this.owner.supportInstancedArray;
  11109. if (useInstanced != null) {
  11110. // Check if the caller ask for Instanced Array and the engine does not support it, return null if it's the case
  11111. if (useInstanced && instancedArray === false) {
  11112. return null;
  11113. }
  11114. // Use the caller's setting
  11115. instancedArray = useInstanced;
  11116. }
  11117. var cti = dataPart.getClassTreeInfo();
  11118. var categories = this.getUsedShaderCategories(dataPart);
  11119. var att = cti.classContent.getShaderAttributes(categories);
  11120. var defines = "";
  11121. categories.forEach(function (c) { defines += "#define " + c + "\n"; });
  11122. if (instancedArray) {
  11123. defines += "#define Instanced\n";
  11124. }
  11125. return {
  11126. attributes: instancedArray ? vertexBufferAttributes.concat(att) : vertexBufferAttributes,
  11127. uniforms: instancedArray ? (uniforms != null ? uniforms : []) : ((uniforms != null) ? att.concat(uniforms) : (att != null ? att : [])),
  11128. defines: defines
  11129. };
  11130. };
  11131. Object.defineProperty(RenderablePrim2D.prototype, "modelRenderCache", {
  11132. get: function () {
  11133. return this._modelRenderCache;
  11134. },
  11135. enumerable: true,
  11136. configurable: true
  11137. });
  11138. RenderablePrim2D.prototype.createModelRenderCache = function (modelKey) {
  11139. return null;
  11140. };
  11141. RenderablePrim2D.prototype.setupModelRenderCache = function (modelRenderCache) {
  11142. };
  11143. RenderablePrim2D.prototype.createInstanceDataParts = function () {
  11144. return null;
  11145. };
  11146. RenderablePrim2D.prototype.getUsedShaderCategories = function (dataPart) {
  11147. return [];
  11148. };
  11149. RenderablePrim2D.prototype.beforeRefreshForLayoutConstruction = function (part) {
  11150. };
  11151. RenderablePrim2D.prototype.afterRefreshForLayoutConstruction = function (part, obj) {
  11152. };
  11153. RenderablePrim2D.prototype.applyActualScaleOnTransform = function () {
  11154. return true;
  11155. };
  11156. RenderablePrim2D.prototype.refreshInstanceDataPart = function (part) {
  11157. if (!this.isVisible) {
  11158. return false;
  11159. }
  11160. part.isVisible = this.isVisible;
  11161. // Which means, if there's only one data element, we're update it from this method, otherwise it is the responsibility of the derived class to call updateInstanceDataPart as many times as needed, properly (look at Text2D's implementation for more information)
  11162. if (part.dataElementCount === 1) {
  11163. part.curElement = 0;
  11164. this.updateInstanceDataPart(part);
  11165. }
  11166. return true;
  11167. };
  11168. /**
  11169. * Update the instanceDataBase level properties of a part
  11170. * @param part the part to update
  11171. * @param positionOffset to use in multi part per primitive (e.g. the Text2D has N parts for N letter to display), this give the offset to apply (e.g. the position of the letter from the bottom/left corner of the text).
  11172. */
  11173. RenderablePrim2D.prototype.updateInstanceDataPart = function (part, positionOffset) {
  11174. if (positionOffset === void 0) { positionOffset = null; }
  11175. var t = this._globalTransform.multiply(this.renderGroup.invGlobalTransform); // Compute the transformation into the renderGroup's space
  11176. var scl = RenderablePrim2D_1._s;
  11177. var trn = RenderablePrim2D_1._t;
  11178. var rot = t.decompose(scl, trn);
  11179. var pas = this.actualScale;
  11180. //let cachedGroup = (this.getExternalData<Group2D>("__cachedGroup__") !== null);
  11181. var canvasScale = this.owner._canvasLevelScale;
  11182. scl.x = pas.x * canvasScale.x * this._postScale.x;
  11183. scl.y = pas.y * canvasScale.y * this._postScale.y;
  11184. trn.multiplyInPlace(canvasScale);
  11185. t = BABYLON.Matrix2D.Compose(this.applyActualScaleOnTransform() ? scl : RenderablePrim2D_1._iV2, rot, trn);
  11186. //console.log(`Update Instance Data Part: ${this.id}`);
  11187. var size = this.renderGroup.viewportSize;
  11188. var zBias = this.actualZOffset;
  11189. var offX = 0;
  11190. var offY = 0;
  11191. // If there's an offset, apply the global transformation matrix on it to get a global offset
  11192. if (positionOffset) {
  11193. offX = positionOffset.x * t.m[0] + positionOffset.y * t.m[2];
  11194. offY = positionOffset.x * t.m[1] + positionOffset.y * t.m[3];
  11195. }
  11196. // Have to convert the coordinates to clip space which is ranged between [-1;1] on X and Y axis, with 0,0 being the left/bottom corner
  11197. // Current coordinates are expressed in renderGroup coordinates ([0, renderGroup.actualSize.width|height]) with 0,0 being at the left/top corner
  11198. // So for X:
  11199. // - tx.x = value * 2 / width: is to switch from [0, renderGroup.width] to [0, 2]
  11200. // - tx.w = (value * 2 / width) - 1: w stores the translation in renderGroup coordinates so (value * 2 / width) to switch to a clip space translation value. - 1 is to offset the overall [0;2] to [-1;1].
  11201. // At last we don't forget to apply the actualScale of the Render Group to tx[0] and ty[1] to propagate scaling correctly
  11202. var w = size.width;
  11203. var h = size.height;
  11204. var invZBias = 1 / zBias;
  11205. var tx = new BABYLON.Vector4(t.m[0] * 2 / w, t.m[2] * 2 / w, 0, ((t.m[4] + offX) * 2 / w) - 1);
  11206. var ty = new BABYLON.Vector4(t.m[1] * 2 / h, t.m[3] * 2 / h, 0, ((t.m[5] + offY) * 2 / h) - 1);
  11207. part.renderingInfo = new BABYLON.Vector3(w, h, this.alignToPixel ? 1 : 0);
  11208. part.transformX = tx;
  11209. part.transformY = ty;
  11210. part.opacity = this.actualOpacity;
  11211. // Stores zBias and it's inverse value because that's needed to compute the clip space W coordinate (which is 1/Z, so 1/zBias)
  11212. part.zBias = new BABYLON.Vector2(zBias, invZBias);
  11213. };
  11214. RenderablePrim2D.prototype._updateRenderMode = function () {
  11215. if (this.isTransparent) {
  11216. this._renderMode = BABYLON.Render2DContext.RenderModeTransparent;
  11217. }
  11218. else if (this.isAlphaTest) {
  11219. this._renderMode = BABYLON.Render2DContext.RenderModeAlphaTest;
  11220. }
  11221. else {
  11222. this._renderMode = BABYLON.Render2DContext.RenderModeOpaque;
  11223. }
  11224. };
  11225. return RenderablePrim2D;
  11226. }(BABYLON.Prim2DBase));
  11227. RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT = BABYLON.Prim2DBase.PRIM2DBASE_PROPCOUNT + 5;
  11228. RenderablePrim2D._toz = BABYLON.Size.Zero();
  11229. RenderablePrim2D._uV = new BABYLON.Vector2(1, 1);
  11230. RenderablePrim2D._s = BABYLON.Vector2.Zero();
  11231. RenderablePrim2D._r = BABYLON.Quaternion.Identity();
  11232. RenderablePrim2D._t = BABYLON.Vector2.Zero();
  11233. RenderablePrim2D._iV2 = new BABYLON.Vector2(1, 1); // Must stay identity vector3
  11234. __decorate([
  11235. BABYLON.dynamicLevelProperty(BABYLON.Prim2DBase.PRIM2DBASE_PROPCOUNT + 0, function (pi) { return RenderablePrim2D_1.isAlphaTestProperty = pi; })
  11236. /**
  11237. * Get/set if the Primitive is from the AlphaTest rendering category.
  11238. * The AlphaTest category is the rendering pass with alpha blend, depth compare and write activated.
  11239. * Primitives that render with an alpha mask should be from this category.
  11240. * The setter should be used only by implementers of new primitive type.
  11241. */
  11242. ], RenderablePrim2D.prototype, "isAlphaTest", null);
  11243. __decorate([
  11244. BABYLON.dynamicLevelProperty(BABYLON.Prim2DBase.PRIM2DBASE_PROPCOUNT + 1, function (pi) { return RenderablePrim2D_1.isTransparentProperty = pi; })
  11245. /**
  11246. * Get/set if the Primitive is from the Transparent rendering category.
  11247. * The setter should be used only by implementers of new primitive type.
  11248. */
  11249. ], RenderablePrim2D.prototype, "isTransparent", null);
  11250. RenderablePrim2D = RenderablePrim2D_1 = __decorate([
  11251. BABYLON.className("RenderablePrim2D", "BABYLON")
  11252. /**
  11253. * The abstract class for primitive that render into the Canvas2D
  11254. */
  11255. ], RenderablePrim2D);
  11256. BABYLON.RenderablePrim2D = RenderablePrim2D;
  11257. var RenderablePrim2D_1;
  11258. })(BABYLON || (BABYLON = {}));
  11259. //# sourceMappingURL=babylon.renderablePrim2d.js.map
  11260. var __extends = (this && this.__extends) || (function () {
  11261. var extendStatics = Object.setPrototypeOf ||
  11262. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  11263. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  11264. return function (d, b) {
  11265. extendStatics(d, b);
  11266. function __() { this.constructor = d; }
  11267. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  11268. };
  11269. })();
  11270. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  11271. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  11272. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  11273. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  11274. return c > 3 && r && Object.defineProperty(target, key, r), r;
  11275. };
  11276. var BABYLON;
  11277. (function (BABYLON) {
  11278. var Shape2D = Shape2D_1 = (function (_super) {
  11279. __extends(Shape2D, _super);
  11280. function Shape2D(settings) {
  11281. var _this = _super.call(this, settings) || this;
  11282. if (!settings) {
  11283. settings = {};
  11284. }
  11285. var borderBrush = null;
  11286. if (settings.border) {
  11287. if (typeof (settings.border) === "string") {
  11288. borderBrush = BABYLON.Canvas2D.GetBrushFromString(settings.border);
  11289. }
  11290. else {
  11291. borderBrush = settings.border;
  11292. }
  11293. }
  11294. var fillBrush = null;
  11295. if (settings.fill) {
  11296. if (typeof (settings.fill) === "string") {
  11297. fillBrush = BABYLON.Canvas2D.GetBrushFromString(settings.fill);
  11298. }
  11299. else {
  11300. fillBrush = settings.fill;
  11301. }
  11302. }
  11303. _this._isTransparent = false;
  11304. _this._oldTransparent = false;
  11305. _this.border = borderBrush;
  11306. _this.fill = fillBrush;
  11307. _this._updateTransparencyStatus();
  11308. _this.borderThickness = settings.borderThickness;
  11309. return _this;
  11310. }
  11311. Object.defineProperty(Shape2D.prototype, "border", {
  11312. get: function () {
  11313. return this._border;
  11314. },
  11315. set: function (value) {
  11316. this._border = value;
  11317. this._updateTransparencyStatus();
  11318. },
  11319. enumerable: true,
  11320. configurable: true
  11321. });
  11322. Object.defineProperty(Shape2D.prototype, "fill", {
  11323. /**
  11324. * Get/set the brush to render the Fill part of the Primitive
  11325. */
  11326. get: function () {
  11327. return this._fill;
  11328. },
  11329. set: function (value) {
  11330. this._fill = value;
  11331. this._updateTransparencyStatus();
  11332. },
  11333. enumerable: true,
  11334. configurable: true
  11335. });
  11336. Object.defineProperty(Shape2D.prototype, "borderThickness", {
  11337. get: function () {
  11338. return this._borderThickness;
  11339. },
  11340. set: function (value) {
  11341. this._borderThickness = value;
  11342. },
  11343. enumerable: true,
  11344. configurable: true
  11345. });
  11346. Shape2D.prototype.getUsedShaderCategories = function (dataPart) {
  11347. var cat = _super.prototype.getUsedShaderCategories.call(this, dataPart);
  11348. // Fill Part
  11349. if (dataPart.id === Shape2D_1.SHAPE2D_FILLPARTID) {
  11350. var fill = this.fill;
  11351. if (fill instanceof BABYLON.SolidColorBrush2D) {
  11352. cat.push(Shape2D_1.SHAPE2D_CATEGORY_FILLSOLID);
  11353. }
  11354. if (fill instanceof BABYLON.GradientColorBrush2D) {
  11355. cat.push(Shape2D_1.SHAPE2D_CATEGORY_FILLGRADIENT);
  11356. }
  11357. }
  11358. // Border Part
  11359. if (dataPart.id === Shape2D_1.SHAPE2D_BORDERPARTID) {
  11360. cat.push(Shape2D_1.SHAPE2D_CATEGORY_BORDER);
  11361. var border = this.border;
  11362. if (border instanceof BABYLON.SolidColorBrush2D) {
  11363. cat.push(Shape2D_1.SHAPE2D_CATEGORY_BORDERSOLID);
  11364. }
  11365. if (border instanceof BABYLON.GradientColorBrush2D) {
  11366. cat.push(Shape2D_1.SHAPE2D_CATEGORY_BORDERGRADIENT);
  11367. }
  11368. }
  11369. return cat;
  11370. };
  11371. //protected applyActualScaleOnTransform(): boolean {
  11372. // return false;
  11373. //}
  11374. Shape2D.prototype.refreshInstanceDataPart = function (part) {
  11375. if (!_super.prototype.refreshInstanceDataPart.call(this, part)) {
  11376. return false;
  11377. }
  11378. // Fill Part
  11379. if (part.id === Shape2D_1.SHAPE2D_FILLPARTID) {
  11380. var d = part;
  11381. if (this.fill) {
  11382. var fill = this.fill;
  11383. if (fill instanceof BABYLON.SolidColorBrush2D) {
  11384. d.fillSolidColor = fill.color;
  11385. }
  11386. else if (fill instanceof BABYLON.GradientColorBrush2D) {
  11387. d.fillGradientColor1 = fill.color1;
  11388. d.fillGradientColor2 = fill.color2;
  11389. var t = BABYLON.Matrix2D.Compose(new BABYLON.Vector2(fill.scale, fill.scale), fill.rotation, new BABYLON.Vector2(fill.translation.x, fill.translation.y));
  11390. var ty = new BABYLON.Vector4(t.m[1], t.m[3], 0, t.m[5]);
  11391. d.fillGradientTY = ty;
  11392. }
  11393. }
  11394. }
  11395. else if (part.id === Shape2D_1.SHAPE2D_BORDERPARTID) {
  11396. var d = part;
  11397. if (this.border) {
  11398. d.borderThickness = this.borderThickness;
  11399. var border = this.border;
  11400. if (border instanceof BABYLON.SolidColorBrush2D) {
  11401. d.borderSolidColor = border.color;
  11402. }
  11403. else if (border instanceof BABYLON.GradientColorBrush2D) {
  11404. d.borderGradientColor1 = border.color1;
  11405. d.borderGradientColor2 = border.color2;
  11406. var t = BABYLON.Matrix2D.Compose(new BABYLON.Vector2(border.scale, border.scale), border.rotation, new BABYLON.Vector2(border.translation.x, border.translation.y));
  11407. var ty = new BABYLON.Vector4(t.m[1], t.m[3], 0, t.m[5]);
  11408. d.borderGradientTY = ty;
  11409. }
  11410. }
  11411. }
  11412. return true;
  11413. };
  11414. Shape2D.prototype._updateTransparencyStatus = function () {
  11415. this._isTransparent = (this._border && this._border.isTransparent()) || (this._fill && this._fill.isTransparent()) || (this.actualOpacity < 1);
  11416. if (this._isTransparent !== this._oldTransparent) {
  11417. this._oldTransparent = this._isTransparent;
  11418. this._updateRenderMode();
  11419. }
  11420. };
  11421. Shape2D.prototype._mustUpdateInstance = function () {
  11422. var res = this._oldTransparent !== this._isTransparent;
  11423. if (res) {
  11424. this._updateRenderMode();
  11425. this._oldTransparent = this._isTransparent;
  11426. }
  11427. return res;
  11428. };
  11429. Shape2D.prototype._isPrimTransparent = function () {
  11430. return this._isTransparent;
  11431. };
  11432. return Shape2D;
  11433. }(BABYLON.RenderablePrim2D));
  11434. Shape2D.SHAPE2D_BORDERPARTID = 1;
  11435. Shape2D.SHAPE2D_FILLPARTID = 2;
  11436. Shape2D.SHAPE2D_CATEGORY_BORDER = "Border";
  11437. Shape2D.SHAPE2D_CATEGORY_BORDERSOLID = "BorderSolid";
  11438. Shape2D.SHAPE2D_CATEGORY_BORDERGRADIENT = "BorderGradient";
  11439. Shape2D.SHAPE2D_CATEGORY_FILLSOLID = "FillSolid";
  11440. Shape2D.SHAPE2D_CATEGORY_FILLGRADIENT = "FillGradient";
  11441. Shape2D.SHAPE2D_PROPCOUNT = BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 5;
  11442. __decorate([
  11443. BABYLON.modelLevelProperty(BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 1, function (pi) { return Shape2D_1.borderProperty = pi; }, true)
  11444. /**
  11445. * Get/set the brush to render the Border part of the Primitive
  11446. */
  11447. ], Shape2D.prototype, "border", null);
  11448. __decorate([
  11449. BABYLON.modelLevelProperty(BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 2, function (pi) { return Shape2D_1.fillProperty = pi; }, true)
  11450. ], Shape2D.prototype, "fill", null);
  11451. __decorate([
  11452. BABYLON.instanceLevelProperty(BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 3, function (pi) { return Shape2D_1.borderThicknessProperty = pi; })
  11453. /**
  11454. * Get/set the thickness of the border part.
  11455. */
  11456. ], Shape2D.prototype, "borderThickness", null);
  11457. Shape2D = Shape2D_1 = __decorate([
  11458. BABYLON.className("Shape2D", "BABYLON")
  11459. /**
  11460. * The abstract class for parametric shape based Primitives types.
  11461. * Shape2D based primitives are composed of two parts: fill and border, both are optional but at least one must be specified.
  11462. * The fill part is the primitive 'body', the border is a border around this body. The border has a thickness that can be changed.
  11463. */
  11464. ], Shape2D);
  11465. BABYLON.Shape2D = Shape2D;
  11466. var Shape2DInstanceData = (function (_super) {
  11467. __extends(Shape2DInstanceData, _super);
  11468. function Shape2DInstanceData() {
  11469. return _super !== null && _super.apply(this, arguments) || this;
  11470. }
  11471. Object.defineProperty(Shape2DInstanceData.prototype, "fillSolidColor", {
  11472. // FILL ATTRIBUTES
  11473. get: function () {
  11474. return null;
  11475. },
  11476. set: function (value) {
  11477. },
  11478. enumerable: true,
  11479. configurable: true
  11480. });
  11481. Object.defineProperty(Shape2DInstanceData.prototype, "fillGradientColor1", {
  11482. get: function () {
  11483. return null;
  11484. },
  11485. set: function (value) {
  11486. },
  11487. enumerable: true,
  11488. configurable: true
  11489. });
  11490. Object.defineProperty(Shape2DInstanceData.prototype, "fillGradientColor2", {
  11491. get: function () {
  11492. return null;
  11493. },
  11494. set: function (value) {
  11495. },
  11496. enumerable: true,
  11497. configurable: true
  11498. });
  11499. Object.defineProperty(Shape2DInstanceData.prototype, "fillGradientTY", {
  11500. get: function () {
  11501. return null;
  11502. },
  11503. set: function (value) {
  11504. },
  11505. enumerable: true,
  11506. configurable: true
  11507. });
  11508. Object.defineProperty(Shape2DInstanceData.prototype, "borderThickness", {
  11509. // BORDER ATTRIBUTES
  11510. get: function () {
  11511. return null;
  11512. },
  11513. set: function (value) {
  11514. },
  11515. enumerable: true,
  11516. configurable: true
  11517. });
  11518. Object.defineProperty(Shape2DInstanceData.prototype, "borderSolidColor", {
  11519. get: function () {
  11520. return null;
  11521. },
  11522. set: function (value) {
  11523. },
  11524. enumerable: true,
  11525. configurable: true
  11526. });
  11527. Object.defineProperty(Shape2DInstanceData.prototype, "borderGradientColor1", {
  11528. get: function () {
  11529. return null;
  11530. },
  11531. set: function (value) {
  11532. },
  11533. enumerable: true,
  11534. configurable: true
  11535. });
  11536. Object.defineProperty(Shape2DInstanceData.prototype, "borderGradientColor2", {
  11537. get: function () {
  11538. return null;
  11539. },
  11540. set: function (value) {
  11541. },
  11542. enumerable: true,
  11543. configurable: true
  11544. });
  11545. Object.defineProperty(Shape2DInstanceData.prototype, "borderGradientTY", {
  11546. get: function () {
  11547. return null;
  11548. },
  11549. set: function (value) {
  11550. },
  11551. enumerable: true,
  11552. configurable: true
  11553. });
  11554. return Shape2DInstanceData;
  11555. }(BABYLON.InstanceDataBase));
  11556. __decorate([
  11557. BABYLON.instanceData(Shape2D.SHAPE2D_CATEGORY_FILLSOLID)
  11558. ], Shape2DInstanceData.prototype, "fillSolidColor", null);
  11559. __decorate([
  11560. BABYLON.instanceData(Shape2D.SHAPE2D_CATEGORY_FILLGRADIENT)
  11561. ], Shape2DInstanceData.prototype, "fillGradientColor1", null);
  11562. __decorate([
  11563. BABYLON.instanceData(Shape2D.SHAPE2D_CATEGORY_FILLGRADIENT)
  11564. ], Shape2DInstanceData.prototype, "fillGradientColor2", null);
  11565. __decorate([
  11566. BABYLON.instanceData(Shape2D.SHAPE2D_CATEGORY_FILLGRADIENT)
  11567. ], Shape2DInstanceData.prototype, "fillGradientTY", null);
  11568. __decorate([
  11569. BABYLON.instanceData(Shape2D.SHAPE2D_CATEGORY_BORDER)
  11570. ], Shape2DInstanceData.prototype, "borderThickness", null);
  11571. __decorate([
  11572. BABYLON.instanceData(Shape2D.SHAPE2D_CATEGORY_BORDERSOLID)
  11573. ], Shape2DInstanceData.prototype, "borderSolidColor", null);
  11574. __decorate([
  11575. BABYLON.instanceData(Shape2D.SHAPE2D_CATEGORY_BORDERGRADIENT)
  11576. ], Shape2DInstanceData.prototype, "borderGradientColor1", null);
  11577. __decorate([
  11578. BABYLON.instanceData(Shape2D.SHAPE2D_CATEGORY_BORDERGRADIENT)
  11579. ], Shape2DInstanceData.prototype, "borderGradientColor2", null);
  11580. __decorate([
  11581. BABYLON.instanceData(Shape2D.SHAPE2D_CATEGORY_BORDERGRADIENT)
  11582. ], Shape2DInstanceData.prototype, "borderGradientTY", null);
  11583. BABYLON.Shape2DInstanceData = Shape2DInstanceData;
  11584. var Shape2D_1;
  11585. })(BABYLON || (BABYLON = {}));
  11586. //# sourceMappingURL=babylon.shape2d.js.map
  11587. var __extends = (this && this.__extends) || (function () {
  11588. var extendStatics = Object.setPrototypeOf ||
  11589. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  11590. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  11591. return function (d, b) {
  11592. extendStatics(d, b);
  11593. function __() { this.constructor = d; }
  11594. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  11595. };
  11596. })();
  11597. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  11598. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  11599. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  11600. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  11601. return c > 3 && r && Object.defineProperty(target, key, r), r;
  11602. };
  11603. var BABYLON;
  11604. (function (BABYLON) {
  11605. var Group2D = Group2D_1 = (function (_super) {
  11606. __extends(Group2D, _super);
  11607. /**
  11608. * Create an Logical or Renderable Group.
  11609. * @param settings a combination of settings, possible ones are
  11610. * - parent: the parent primitive/canvas, must be specified if the primitive is not constructed as a child of another one (i.e. as part of the children array setting)
  11611. * - children: an array of direct children
  11612. * - id a text identifier, for information purpose
  11613. * - position: the X & Y positions relative to its parent. Alternatively the x and y properties can be set. Default is [0;0]
  11614. * - rotation: the initial rotation (in radian) of the primitive. default is 0
  11615. * - scale: the initial scale of the primitive. default is 1. You can alternatively use scaleX &| scaleY to apply non uniform scale
  11616. * - dontInheritParentScale: if set the parent's scale won't be taken into consideration to compute the actualScale property
  11617. * - trackNode: if you want the ScreenSpaceCanvas to track the position of a given Scene Node, use this setting to specify the Node to track
  11618. * - trackNodeOffset: if you use trackNode you may want to specify a 3D Offset to apply to shift the Canvas
  11619. * - opacity: set the overall opacity of the primitive, 1 to be opaque (default), less than 1 to be transparent.
  11620. * - zOrder: override the zOrder with the specified value
  11621. * - origin: define the normalized origin point location, default [0.5;0.5]
  11622. * - size: the size of the group. Alternatively the width and height properties can be set. If null the size will be computed from its content, default is null.
  11623. * - cacheBehavior: Define how the group should behave regarding the Canvas's cache strategy, default is Group2D.GROUPCACHEBEHAVIOR_FOLLOWCACHESTRATEGY
  11624. * - layoutEngine: either an instance of a layout engine based class (StackPanel.Vertical, StackPanel.Horizontal) or a string ('canvas' for Canvas layout, 'StackPanel' or 'HorizontalStackPanel' for horizontal Stack Panel layout, 'VerticalStackPanel' for vertical Stack Panel layout).
  11625. * - isVisible: true if the group must be visible, false for hidden. Default is true.
  11626. * - isPickable: if true the Primitive can be used with interaction mode and will issue Pointer Event. If false it will be ignored for interaction/intersection test. Default value is true.
  11627. * - isContainer: if true the Primitive acts as a container for interaction, if the primitive is not pickable or doesn't intersect, no further test will be perform on its children. If set to false, children will always be considered for intersection/interaction. Default value is true.
  11628. * - childrenFlatZOrder: if true all the children (direct and indirect) will share the same Z-Order. Use this when there's a lot of children which don't overlap. The drawing order IS NOT GUARANTED!
  11629. * - levelCollision: this primitive is an actor of the Collision Manager and only this level will be used for collision (i.e. not the children). Use deepCollision if you want collision detection on the primitives and its children.
  11630. * - deepCollision: this primitive is an actor of the Collision Manager, this level AND ALSO its children will be used for collision (note: you don't need to set the children as level/deepCollision).
  11631. * - layoutData: a instance of a class implementing the ILayoutData interface that contain data to pass to the primitive parent's layout engine
  11632. * - marginTop: top margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  11633. * - marginLeft: left margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  11634. * - marginRight: right margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  11635. * - marginBottom: bottom margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  11636. * - margin: top, left, right and bottom margin formatted as a single string (see PrimitiveThickness.fromString)
  11637. * - marginHAlignment: one value of the PrimitiveAlignment type's static properties
  11638. * - marginVAlignment: one value of the PrimitiveAlignment type's static properties
  11639. * - marginAlignment: a string defining the alignment, see PrimitiveAlignment.fromString
  11640. * - paddingTop: top padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  11641. * - paddingLeft: left padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  11642. * - paddingRight: right padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  11643. * - paddingBottom: bottom padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  11644. * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
  11645. */
  11646. function Group2D(settings) {
  11647. var _this = this;
  11648. if (settings == null) {
  11649. settings = {};
  11650. }
  11651. if (settings.origin == null) {
  11652. settings.origin = new BABYLON.Vector2(0, 0);
  11653. }
  11654. _this = _super.call(this, settings) || this;
  11655. var size = (!settings.size && !settings.width && !settings.height) ? null : (settings.size || (new BABYLON.Size(settings.width || 0, settings.height || 0)));
  11656. if (!(_this instanceof BABYLON.WorldSpaceCanvas2D)) {
  11657. _this._trackedNode = (settings.trackNode == null) ? null : settings.trackNode;
  11658. _this._trackedNodeOffset = (settings.trackNodeOffset == null) ? null : settings.trackNodeOffset;
  11659. if (_this._trackedNode && _this.owner) {
  11660. _this.owner._registerTrackedNode(_this);
  11661. }
  11662. }
  11663. _this._cacheBehavior = (settings.cacheBehavior == null) ? Group2D_1.GROUPCACHEBEHAVIOR_FOLLOWCACHESTRATEGY : settings.cacheBehavior;
  11664. var rd = _this._renderableData;
  11665. if (rd) {
  11666. rd._noResizeOnScale = (_this.cacheBehavior & Group2D_1.GROUPCACHEBEHAVIOR_NORESIZEONSCALE) !== 0;
  11667. }
  11668. _this.size = size;
  11669. _this._viewportPosition = BABYLON.Vector2.Zero();
  11670. _this._viewportSize = BABYLON.Size.Zero();
  11671. return _this;
  11672. }
  11673. Group2D._createCachedCanvasGroup = function (owner) {
  11674. var g = new Group2D_1({ parent: owner, id: "__cachedCanvasGroup__", position: BABYLON.Vector2.Zero(), origin: BABYLON.Vector2.Zero(), size: null, isVisible: true, isPickable: false, dontInheritParentScale: true });
  11675. return g;
  11676. };
  11677. Group2D.prototype.applyCachedTexture = function (vertexData, material) {
  11678. this._bindCacheTarget();
  11679. if (vertexData) {
  11680. var uv = vertexData.uvs;
  11681. var nodeuv = this._renderableData._cacheNodeUVs;
  11682. for (var i = 0; i < 4; i++) {
  11683. uv[i * 2 + 0] = nodeuv[i].x;
  11684. uv[i * 2 + 1] = nodeuv[i].y;
  11685. }
  11686. }
  11687. if (material) {
  11688. material.diffuseTexture = this._renderableData._cacheTexture;
  11689. material.emissiveColor = new BABYLON.Color3(1, 1, 1);
  11690. }
  11691. this._renderableData._cacheTexture.hasAlpha = true;
  11692. this._unbindCacheTarget();
  11693. };
  11694. Object.defineProperty(Group2D.prototype, "cachedRect", {
  11695. /**
  11696. * Allow you to access the information regarding the cached rectangle of the Group2D into the MapTexture.
  11697. * If the `noWorldSpaceNode` options was used at the creation of a WorldSpaceCanvas, the rendering of the canvas must be made by the caller, so typically you want to bind the cacheTexture property to some material/mesh and you MUST use the Group2D.cachedUVs property to get the UV coordinates to use for your quad that will display the Canvas and NOT the PackedRect.UVs property which are incorrect because the allocated surface may be bigger (due to over-provisioning or shrinking without deallocating) than what the Group is actually using.
  11698. */
  11699. get: function () {
  11700. if (!this._renderableData) {
  11701. return null;
  11702. }
  11703. return this._renderableData._cacheNode;
  11704. },
  11705. enumerable: true,
  11706. configurable: true
  11707. });
  11708. Object.defineProperty(Group2D.prototype, "cachedUVs", {
  11709. /**
  11710. * The UVs into the MapTexture that map the cached group
  11711. */
  11712. get: function () {
  11713. if (!this._renderableData) {
  11714. return null;
  11715. }
  11716. return this._renderableData._cacheNodeUVs;
  11717. },
  11718. enumerable: true,
  11719. configurable: true
  11720. });
  11721. Object.defineProperty(Group2D.prototype, "cachedUVsChanged", {
  11722. get: function () {
  11723. if (!this._renderableData) {
  11724. return null;
  11725. }
  11726. if (!this._renderableData._cacheNodeUVsChangedObservable) {
  11727. this._renderableData._cacheNodeUVsChangedObservable = new BABYLON.Observable();
  11728. }
  11729. return this._renderableData._cacheNodeUVsChangedObservable;
  11730. },
  11731. enumerable: true,
  11732. configurable: true
  11733. });
  11734. Object.defineProperty(Group2D.prototype, "cacheTexture", {
  11735. /**
  11736. * Access the texture that maintains a cached version of the Group2D.
  11737. * This is useful only if you're not using a WorldSpaceNode for your WorldSpace Canvas and therefore need to perform the rendering yourself.
  11738. */
  11739. get: function () {
  11740. if (!this._renderableData) {
  11741. return null;
  11742. }
  11743. return this._renderableData._cacheTexture;
  11744. },
  11745. enumerable: true,
  11746. configurable: true
  11747. });
  11748. /**
  11749. * Call this method to remove this Group and its children from the Canvas
  11750. */
  11751. Group2D.prototype.dispose = function () {
  11752. if (!_super.prototype.dispose.call(this)) {
  11753. return false;
  11754. }
  11755. if (this._trackedNode != null) {
  11756. this.owner._unregisterTrackedNode(this);
  11757. this._trackedNode = null;
  11758. }
  11759. if (this._renderableData) {
  11760. this._renderableData.dispose(this.owner);
  11761. this._renderableData = null;
  11762. }
  11763. return true;
  11764. };
  11765. Object.defineProperty(Group2D.prototype, "isRenderableGroup", {
  11766. /**
  11767. * @returns Returns true if the Group render content, false if it's a logical group only
  11768. */
  11769. get: function () {
  11770. return this._isRenderableGroup;
  11771. },
  11772. enumerable: true,
  11773. configurable: true
  11774. });
  11775. Object.defineProperty(Group2D.prototype, "isCachedGroup", {
  11776. /**
  11777. * @returns only meaningful for isRenderableGroup, will be true if the content of the Group is cached into a texture, false if it's rendered every time
  11778. */
  11779. get: function () {
  11780. return this._isCachedGroup;
  11781. },
  11782. enumerable: true,
  11783. configurable: true
  11784. });
  11785. Object.defineProperty(Group2D.prototype, "size", {
  11786. get: function () {
  11787. return this.internalGetSize();
  11788. },
  11789. /**
  11790. * Get/Set the size of the group. If null the size of the group will be determine from its content.
  11791. * BEWARE: if the Group is a RenderableGroup and its content is cache the texture will be resized each time the group is getting bigger. For performance reason the opposite won't be true: the texture won't shrink if the group does.
  11792. */
  11793. set: function (val) {
  11794. this.internalSetSize(val);
  11795. },
  11796. enumerable: true,
  11797. configurable: true
  11798. });
  11799. Object.defineProperty(Group2D.prototype, "viewportSize", {
  11800. get: function () {
  11801. return this._viewportSize;
  11802. },
  11803. enumerable: true,
  11804. configurable: true
  11805. });
  11806. Object.defineProperty(Group2D.prototype, "cacheBehavior", {
  11807. /**
  11808. * Get/set the Cache Behavior, used in case the Canvas Cache Strategy is set to CACHESTRATEGY_ALLGROUPS. Can be either GROUPCACHEBEHAVIOR_CACHEINPARENTGROUP, GROUPCACHEBEHAVIOR_DONTCACHEOVERRIDE or GROUPCACHEBEHAVIOR_FOLLOWCACHESTRATEGY. See their documentation for more information.
  11809. * GROUPCACHEBEHAVIOR_NORESIZEONSCALE can also be set if you set it at creation time.
  11810. * It is critical to understand than you HAVE TO play with this behavior in order to achieve a good performance/memory ratio. Caching all groups would certainly be the worst strategy of all.
  11811. */
  11812. get: function () {
  11813. return this._cacheBehavior;
  11814. },
  11815. enumerable: true,
  11816. configurable: true
  11817. });
  11818. Group2D.prototype._addPrimToDirtyList = function (prim) {
  11819. this._renderableData._primDirtyList.push(prim);
  11820. };
  11821. Group2D.prototype._renderCachedCanvas = function () {
  11822. this.owner._addGroupRenderCount(1);
  11823. this.updateCachedStates(true);
  11824. var context = new BABYLON.PrepareRender2DContext();
  11825. this._prepareGroupRender(context);
  11826. this._groupRender();
  11827. };
  11828. Object.defineProperty(Group2D.prototype, "trackedNode", {
  11829. /**
  11830. * Get/set the Scene's Node that should be tracked, the group's position will follow the projected position of the Node.
  11831. */
  11832. get: function () {
  11833. return this._trackedNode;
  11834. },
  11835. set: function (val) {
  11836. if (val != null) {
  11837. if (!this._isFlagSet(BABYLON.SmartPropertyPrim.flagTrackedGroup)) {
  11838. this.owner._registerTrackedNode(this);
  11839. }
  11840. this._trackedNode = val;
  11841. }
  11842. else {
  11843. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagTrackedGroup)) {
  11844. this.owner._unregisterTrackedNode(this);
  11845. }
  11846. this._trackedNode = null;
  11847. }
  11848. },
  11849. enumerable: true,
  11850. configurable: true
  11851. });
  11852. Object.defineProperty(Group2D.prototype, "trackedNodeOffset", {
  11853. /**
  11854. * Get/set the offset of the tracked node in the tracked node's local space.
  11855. */
  11856. get: function () {
  11857. return this._trackedNodeOffset;
  11858. },
  11859. set: function (val) {
  11860. if (!this._trackedNodeOffset) {
  11861. this._trackedNodeOffset = val.clone();
  11862. }
  11863. else {
  11864. this._trackedNodeOffset.copyFrom(val);
  11865. }
  11866. },
  11867. enumerable: true,
  11868. configurable: true
  11869. });
  11870. Group2D.prototype.levelIntersect = function (intersectInfo) {
  11871. // If we've made it so far it means the boundingInfo intersection test succeed, the Group2D is shaped the same, so we always return true
  11872. return true;
  11873. };
  11874. Group2D.prototype.updateLevelBoundingInfo = function () {
  11875. var size;
  11876. // If the size is set by the user, the boundingInfo is computed from this value
  11877. if (this.size) {
  11878. size = this.size;
  11879. }
  11880. else {
  11881. size = new BABYLON.Size(0, 0);
  11882. }
  11883. BABYLON.BoundingInfo2D.CreateFromSizeToRef(size, this._levelBoundingInfo);
  11884. return true;
  11885. };
  11886. // Method called only on renderable groups to prepare the rendering
  11887. Group2D.prototype._prepareGroupRender = function (context) {
  11888. var sortedDirtyList = null;
  11889. // Update the Global Transformation and visibility status of the changed primitives
  11890. var rd = this._renderableData;
  11891. var curPrimDirtyList = rd._primDirtyList;
  11892. if ((curPrimDirtyList.length > 0) || context.forceRefreshPrimitive) {
  11893. // From now on we use the 'curPrimDirtyList' variable to process the primitives that was marked as dirty
  11894. // But we also allocate a new array in the object's member to get the prim that will be dirty again during the process
  11895. // and that would need another process next time.
  11896. rd._primDirtyList = new Array();
  11897. // Sort the primitives to process them from the highest in the tree to the lowest
  11898. sortedDirtyList = curPrimDirtyList.sort(function (a, b) { return a.hierarchyDepth - b.hierarchyDepth; });
  11899. this.updateCachedStatesOf(sortedDirtyList, true);
  11900. }
  11901. var s = this.actualSize;
  11902. var a = this.actualScale;
  11903. var ss = this.owner._canvasLevelScale;
  11904. var hwsl = 1 / this.owner.engine.getHardwareScalingLevel();
  11905. //let sw = Math.ceil(s.width * a.x * ss.x/* * hwsl*/);
  11906. //let sh = Math.ceil(s.height * a.y *ss.y/* * hwsl*/);
  11907. var sw = s.width * a.x * ss.x;
  11908. var sh = s.height * a.y * ss.y;
  11909. // The dimension must be overridden when using the designSize feature, the ratio is maintain to compute a uniform scale, which is mandatory but if the designSize's ratio is different from the rendering surface's ratio, content will be clipped in some cases.
  11910. // So we set the width/height to the rendering's one because that's what we want for the viewport!
  11911. if ((this instanceof BABYLON.Canvas2D || this.id === "__cachedCanvasGroup__") && this.owner.designSize != null) {
  11912. sw = this.owner.engine.getRenderWidth();
  11913. sh = this.owner.engine.getRenderHeight();
  11914. }
  11915. // Setup the size of the rendering viewport
  11916. // In non cache mode, we're rendering directly to the rendering canvas, in this case we have to detect if the canvas size changed since the previous iteration, if it's the case all primitives must be prepared again because their transformation must be recompute
  11917. if (!this._isCachedGroup) {
  11918. // Compute the WebGL viewport's location/size
  11919. var t = this._globalTransform.getTranslation();
  11920. var rs = this.owner._renderingSize.multiplyByFloats(hwsl, hwsl);
  11921. sh = Math.min(sh, rs.height - t.y);
  11922. sw = Math.min(sw, rs.width - t.x);
  11923. var x = t.x;
  11924. var y = t.y;
  11925. // The viewport where we're rendering must be the size of the canvas if this one fit in the rendering screen or clipped to the screen dimensions if needed
  11926. this._viewportPosition.x = x;
  11927. this._viewportPosition.y = y;
  11928. }
  11929. // For a cachedGroup we also check of the group's actualSize is changing, if it's the case then the rendering zone will be change so we also have to dirty all primitives to prepare them again.
  11930. if (this._viewportSize.width !== sw || this._viewportSize.height !== sh) {
  11931. context.forceRefreshPrimitive = true;
  11932. this._viewportSize.width = sw;
  11933. this._viewportSize.height = sh;
  11934. }
  11935. if ((curPrimDirtyList.length > 0) || context.forceRefreshPrimitive) {
  11936. // If the group is cached, set the dirty flag to true because of the incoming changes
  11937. this._cacheGroupDirty = this._isCachedGroup;
  11938. rd._primNewDirtyList.splice(0);
  11939. // If it's a force refresh, prepare all the children
  11940. if (context.forceRefreshPrimitive) {
  11941. for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
  11942. var p = _a[_i];
  11943. if (!p.isDisposed) {
  11944. p._prepareRender(context);
  11945. }
  11946. }
  11947. }
  11948. else {
  11949. // Each primitive that changed at least once was added into the primDirtyList, we have to sort this level using
  11950. // the hierarchyDepth in order to prepare primitives from top to bottom
  11951. if (!sortedDirtyList) {
  11952. sortedDirtyList = curPrimDirtyList.sort(function (a, b) { return a.hierarchyDepth - b.hierarchyDepth; });
  11953. }
  11954. sortedDirtyList.forEach(function (p) {
  11955. // We need to check if prepare is needed because even if the primitive is in the dirtyList, its parent primitive may also have been modified, then prepared, then recurse on its children primitives (this one for instance) if the changes where impacting them.
  11956. // For instance: a Rect's position change, the position of its children primitives will also change so a prepare will be call on them. If a child was in the dirtyList we will avoid a second prepare by making this check.
  11957. if (!p.isDisposed && p._needPrepare()) {
  11958. p._prepareRender(context);
  11959. }
  11960. });
  11961. }
  11962. // Everything is updated, clear the dirty list
  11963. curPrimDirtyList.forEach(function (p) {
  11964. if (rd._primNewDirtyList.indexOf(p) === -1) {
  11965. p._resetPropertiesDirty();
  11966. }
  11967. else {
  11968. p._setFlags(BABYLON.SmartPropertyPrim.flagNeedRefresh);
  11969. }
  11970. });
  11971. rd._primDirtyList = curPrimDirtyList.concat(rd._primNewDirtyList);
  11972. }
  11973. // A renderable group has a list of direct children that are also renderable groups, we recurse on them to also prepare them
  11974. rd._childrenRenderableGroups.forEach(function (g) {
  11975. g._prepareGroupRender(context);
  11976. });
  11977. };
  11978. Group2D.prototype._groupRender = function () {
  11979. var _this = this;
  11980. var engine = this.owner.engine;
  11981. var failedCount = 0;
  11982. // First recurse to children render group to render them (in their cache or on screen)
  11983. for (var _i = 0, _a = this._renderableData._childrenRenderableGroups; _i < _a.length; _i++) {
  11984. var childGroup = _a[_i];
  11985. childGroup._groupRender();
  11986. }
  11987. // Render the primitives if needed: either if we don't cache the content or if the content is cached but has changed
  11988. if (!this.isCachedGroup || this._cacheGroupDirty) {
  11989. this.owner._addGroupRenderCount(1);
  11990. if (this.isCachedGroup) {
  11991. this._bindCacheTarget();
  11992. }
  11993. else {
  11994. var curVP = engine.setDirectViewport(this._viewportPosition.x, this._viewportPosition.y, this._viewportSize.width, this._viewportSize.height);
  11995. }
  11996. var curAlphaTest = engine.getAlphaTesting() === true;
  11997. var curDepthWrite = engine.getDepthWrite() === true;
  11998. // ===================================================================
  11999. // First pass, update the InstancedArray and render Opaque primitives
  12000. // Disable Alpha Testing, Enable Depth Write
  12001. engine.setAlphaTesting(false);
  12002. engine.setDepthWrite(true);
  12003. // For each different model of primitive to render
  12004. var context_1 = new BABYLON.Render2DContext(BABYLON.Render2DContext.RenderModeOpaque);
  12005. this._renderableData._renderGroupInstancesInfo.forEach(function (k, v) {
  12006. // Prepare the context object, update the WebGL Instanced Array buffer if needed
  12007. var renderCount = _this._prepareContext(engine, context_1, v);
  12008. // If null is returned, there's no opaque data to render
  12009. if (renderCount === null) {
  12010. return;
  12011. }
  12012. // Submit render only if we have something to render (everything may be hidden and the floatarray empty)
  12013. if (!_this.owner.supportInstancedArray || renderCount > 0) {
  12014. // render all the instances of this model, if the render method returns true then our instances are no longer dirty
  12015. var renderFailed = !v.modelRenderCache.render(v, context_1);
  12016. // Update dirty flag/related
  12017. v.opaqueDirty = renderFailed;
  12018. failedCount += renderFailed ? 1 : 0;
  12019. }
  12020. });
  12021. // =======================================================================
  12022. // Second pass, update the InstancedArray and render AlphaTest primitives
  12023. // Enable Alpha Testing, Enable Depth Write
  12024. engine.setAlphaTesting(true);
  12025. engine.setDepthWrite(true);
  12026. // For each different model of primitive to render
  12027. context_1 = new BABYLON.Render2DContext(BABYLON.Render2DContext.RenderModeAlphaTest);
  12028. this._renderableData._renderGroupInstancesInfo.forEach(function (k, v) {
  12029. // Prepare the context object, update the WebGL Instanced Array buffer if needed
  12030. var renderCount = _this._prepareContext(engine, context_1, v);
  12031. // If null is returned, there's no opaque data to render
  12032. if (renderCount === null) {
  12033. return;
  12034. }
  12035. // Submit render only if we have something to render (everything may be hidden and the floatarray empty)
  12036. if (!_this.owner.supportInstancedArray || renderCount > 0) {
  12037. // render all the instances of this model, if the render method returns true then our instances are no longer dirty
  12038. var renderFailed = !v.modelRenderCache.render(v, context_1);
  12039. // Update dirty flag/related
  12040. v.opaqueDirty = renderFailed;
  12041. failedCount += renderFailed ? 1 : 0;
  12042. }
  12043. });
  12044. // =======================================================================
  12045. // Third pass, transparent primitive rendering
  12046. // Enable Alpha Testing, Disable Depth Write
  12047. engine.setAlphaTesting(true);
  12048. engine.setDepthWrite(false);
  12049. // First Check if the transparent List change so we can update the TransparentSegment and PartData (sort if needed)
  12050. if (this._renderableData._transparentListChanged) {
  12051. this._updateTransparentData();
  12052. }
  12053. // From this point on we have up to date data to render, so let's go
  12054. failedCount += this._renderTransparentData();
  12055. // =======================================================================
  12056. // Unbind target/restore viewport setting, clear dirty flag, and quit
  12057. // The group's content is no longer dirty
  12058. this._cacheGroupDirty = failedCount !== 0;
  12059. if (this.isCachedGroup) {
  12060. this._unbindCacheTarget();
  12061. }
  12062. else {
  12063. if (curVP) {
  12064. engine.setViewport(curVP);
  12065. }
  12066. }
  12067. this._renderableData.resetPrimDirtyList();
  12068. // Restore saved states
  12069. engine.setAlphaTesting(curAlphaTest);
  12070. engine.setDepthWrite(curDepthWrite);
  12071. }
  12072. };
  12073. Group2D.prototype._setCacheGroupDirty = function () {
  12074. this._cacheGroupDirty = true;
  12075. };
  12076. Group2D.prototype._updateTransparentData = function () {
  12077. this.owner._addUpdateTransparentDataCount(1);
  12078. var rd = this._renderableData;
  12079. // Sort all the primitive from their depth, max (bottom) to min (top)
  12080. rd._transparentPrimitives.sort(function (a, b) { return b._primitive.actualZOffset - a._primitive.actualZOffset; });
  12081. var checkAndAddPrimInSegment = function (seg, tpiI) {
  12082. var tpi = rd._transparentPrimitives[tpiI];
  12083. // Fast rejection: if gii are different
  12084. if (seg.groupInsanceInfo !== tpi._groupInstanceInfo) {
  12085. return false;
  12086. }
  12087. //let tpiZ = tpi._primitive.actualZOffset;
  12088. // We've made it so far, the tpi can be part of the segment, add it
  12089. tpi._transparentSegment = seg;
  12090. tpi._primitive._updateTransparentSegmentIndices(seg);
  12091. return true;
  12092. };
  12093. // Free the existing TransparentSegments
  12094. for (var _i = 0, _a = rd._transparentSegments; _i < _a.length; _i++) {
  12095. var ts = _a[_i];
  12096. ts.dispose(this.owner.engine);
  12097. }
  12098. rd._transparentSegments.splice(0);
  12099. var prevSeg = null;
  12100. for (var tpiI = 0; tpiI < rd._transparentPrimitives.length; tpiI++) {
  12101. var tpi = rd._transparentPrimitives[tpiI];
  12102. // Check if the Data in which the primitive is stored is not sorted properly
  12103. if (tpi._groupInstanceInfo.transparentOrderDirty) {
  12104. tpi._groupInstanceInfo.sortTransparentData();
  12105. }
  12106. // Reset the segment, we have to create/rebuild it
  12107. tpi._transparentSegment = null;
  12108. // If there's a previous valid segment, check if this prim can be part of it
  12109. if (prevSeg) {
  12110. checkAndAddPrimInSegment(prevSeg, tpiI);
  12111. }
  12112. // If we couldn't insert in the adjacent segments, he have to create one
  12113. if (!tpi._transparentSegment) {
  12114. var ts = new BABYLON.TransparentSegment();
  12115. ts.groupInsanceInfo = tpi._groupInstanceInfo;
  12116. var prim = tpi._primitive;
  12117. ts.startZ = prim.actualZOffset;
  12118. prim._updateTransparentSegmentIndices(ts);
  12119. ts.endZ = ts.startZ;
  12120. tpi._transparentSegment = ts;
  12121. rd._transparentSegments.push(ts);
  12122. }
  12123. // Update prevSeg
  12124. prevSeg = tpi._transparentSegment;
  12125. }
  12126. //rd._firstChangedPrim = null;
  12127. rd._transparentListChanged = false;
  12128. };
  12129. Group2D.prototype._renderTransparentData = function () {
  12130. var failedCount = 0;
  12131. var context = new BABYLON.Render2DContext(BABYLON.Render2DContext.RenderModeTransparent);
  12132. var rd = this._renderableData;
  12133. var useInstanced = this.owner.supportInstancedArray;
  12134. var length = rd._transparentSegments.length;
  12135. for (var i = 0; i < length; i++) {
  12136. context.instancedBuffers = null;
  12137. var ts = rd._transparentSegments[i];
  12138. var gii = ts.groupInsanceInfo;
  12139. var mrc = gii.modelRenderCache;
  12140. var engine = this.owner.engine;
  12141. var count = ts.endDataIndex - ts.startDataIndex;
  12142. // Use Instanced Array if it's supported and if there's at least minPartCountToUseInstancedArray prims to draw.
  12143. // We don't want to create an Instanced Buffer for less that minPartCountToUseInstancedArray prims
  12144. if (useInstanced && count >= this.owner.minPartCountToUseInstancedArray) {
  12145. if (!ts.partBuffers) {
  12146. var buffers = new Array();
  12147. for (var j = 0; j < gii.transparentData.length; j++) {
  12148. var gitd = gii.transparentData[j];
  12149. var dfa = gitd._partData;
  12150. var data = dfa.pack();
  12151. var stride = dfa.stride;
  12152. var neededSize = count * stride * 4;
  12153. var buffer = engine.createInstancesBuffer(neededSize); // Create + bind
  12154. var segData = data.subarray(ts.startDataIndex * stride, ts.endDataIndex * stride);
  12155. engine.updateArrayBuffer(segData);
  12156. buffers.push(buffer);
  12157. }
  12158. ts.partBuffers = buffers;
  12159. }
  12160. else if (gii.transparentDirty) {
  12161. for (var j = 0; j < gii.transparentData.length; j++) {
  12162. var gitd = gii.transparentData[j];
  12163. var dfa = gitd._partData;
  12164. var data = dfa.pack();
  12165. var stride = dfa.stride;
  12166. var buffer = ts.partBuffers[j];
  12167. var segData = data.subarray(ts.startDataIndex * stride, ts.endDataIndex * stride);
  12168. engine.bindArrayBuffer(buffer);
  12169. engine.updateArrayBuffer(segData);
  12170. }
  12171. }
  12172. context.useInstancing = true;
  12173. context.instancesCount = count;
  12174. context.instancedBuffers = ts.partBuffers;
  12175. context.groupInfoPartData = gii.transparentData;
  12176. var renderFailed = !mrc.render(gii, context);
  12177. failedCount += renderFailed ? 1 : 0;
  12178. }
  12179. else {
  12180. context.useInstancing = false;
  12181. context.partDataStartIndex = ts.startDataIndex;
  12182. context.partDataEndIndex = ts.endDataIndex;
  12183. context.groupInfoPartData = gii.transparentData;
  12184. var renderFailed = !mrc.render(gii, context);
  12185. failedCount += renderFailed ? 1 : 0;
  12186. }
  12187. }
  12188. return failedCount;
  12189. };
  12190. Group2D.prototype._prepareContext = function (engine, context, gii) {
  12191. var gipd = null;
  12192. var setDirty;
  12193. var getDirty;
  12194. // Render Mode specifics
  12195. switch (context.renderMode) {
  12196. case BABYLON.Render2DContext.RenderModeOpaque:
  12197. {
  12198. if (!gii.hasOpaqueData) {
  12199. return null;
  12200. }
  12201. setDirty = function (dirty) { gii.opaqueDirty = dirty; };
  12202. getDirty = function () { return gii.opaqueDirty; };
  12203. context.groupInfoPartData = gii.opaqueData;
  12204. gipd = gii.opaqueData;
  12205. break;
  12206. }
  12207. case BABYLON.Render2DContext.RenderModeAlphaTest:
  12208. {
  12209. if (!gii.hasAlphaTestData) {
  12210. return null;
  12211. }
  12212. setDirty = function (dirty) { gii.alphaTestDirty = dirty; };
  12213. getDirty = function () { return gii.alphaTestDirty; };
  12214. context.groupInfoPartData = gii.alphaTestData;
  12215. gipd = gii.alphaTestData;
  12216. break;
  12217. }
  12218. default:
  12219. throw new Error("_prepareContext is only for opaque or alphaTest");
  12220. }
  12221. var renderCount = 0;
  12222. // This part will pack the dynamicfloatarray and update the instanced array WebGLBufffer
  12223. // Skip it if instanced arrays are not supported
  12224. if (this.owner.supportInstancedArray) {
  12225. // Flag for instancing
  12226. context.useInstancing = true;
  12227. // Make sure all the WebGLBuffers of the Instanced Array are created/up to date for the parts to render.
  12228. for (var i = 0; i < gipd.length; i++) {
  12229. var pid = gipd[i];
  12230. // If the instances of the model was changed, pack the data
  12231. var array = pid._partData;
  12232. var instanceData_1 = array.pack();
  12233. renderCount += array.usedElementCount;
  12234. // Compute the size the instance buffer should have
  12235. var neededSize = array.usedElementCount * array.stride * 4;
  12236. // Check if we have to (re)create the instancesBuffer because there's none or the size is too small
  12237. if (!pid._partBuffer || (pid._partBufferSize < neededSize)) {
  12238. if (pid._partBuffer) {
  12239. engine.deleteInstancesBuffer(pid._partBuffer);
  12240. }
  12241. pid._partBuffer = engine.createInstancesBuffer(neededSize); // Create + bind
  12242. pid._partBufferSize = neededSize;
  12243. setDirty(false);
  12244. // Update the WebGL buffer to match the new content of the instances data
  12245. engine.updateArrayBuffer(instanceData_1);
  12246. }
  12247. else if (getDirty()) {
  12248. // Update the WebGL buffer to match the new content of the instances data
  12249. engine.bindArrayBuffer(pid._partBuffer);
  12250. engine.updateArrayBuffer(instanceData_1);
  12251. }
  12252. }
  12253. setDirty(false);
  12254. }
  12255. else {
  12256. context.partDataStartIndex = 0;
  12257. // Find the first valid object to get the count
  12258. if (context.groupInfoPartData.length > 0) {
  12259. var i = 0;
  12260. while (!context.groupInfoPartData[i]) {
  12261. i++;
  12262. }
  12263. context.partDataEndIndex = context.groupInfoPartData[i]._partData.usedElementCount;
  12264. }
  12265. }
  12266. return renderCount;
  12267. };
  12268. Group2D.prototype._setRenderingScale = function (scale) {
  12269. if (this._renderableData._renderingScale === scale) {
  12270. return;
  12271. }
  12272. this._renderableData._renderingScale = scale;
  12273. };
  12274. Group2D.prototype._bindCacheTarget = function () {
  12275. var curWidth;
  12276. var curHeight;
  12277. var rd = this._renderableData;
  12278. var rs = rd._renderingScale;
  12279. var noResizeScale = rd._noResizeOnScale;
  12280. var isCanvas = this.parent == null;
  12281. var scale;
  12282. if (noResizeScale) {
  12283. scale = isCanvas ? Group2D_1._uV : this.parent.actualScale.multiply(this.owner._canvasLevelScale);
  12284. }
  12285. else {
  12286. scale = this.actualScale.multiply(this.owner._canvasLevelScale);
  12287. }
  12288. var actualSize = this.actualSize;
  12289. if (isCanvas && this.owner.cachingStrategy === BABYLON.Canvas2D.CACHESTRATEGY_CANVAS && this.owner.isScreenSpace) {
  12290. if (this.owner.designSize || this.owner.fitRenderingDevice) {
  12291. Group2D_1._s.width = this.owner.engine.getRenderWidth();
  12292. Group2D_1._s.height = this.owner.engine.getRenderHeight();
  12293. }
  12294. else {
  12295. Group2D_1._s.copyFrom(this.owner.size);
  12296. }
  12297. }
  12298. else {
  12299. Group2D_1._s.width = Math.ceil(actualSize.width * scale.x * rs);
  12300. Group2D_1._s.height = Math.ceil(actualSize.height * scale.y * rs);
  12301. }
  12302. var sizeChanged = !Group2D_1._s.equals(rd._cacheSize);
  12303. if (rd._cacheNode) {
  12304. var size = Group2D_1._s2;
  12305. rd._cacheNode.getInnerSizeToRef(size);
  12306. // Check if we have to deallocate because the size is too small
  12307. if ((size.width < Group2D_1._s.width) || (size.height < Group2D_1._s.height)) {
  12308. // For Screen space: over-provisioning of 7% more to avoid frequent resizing for few pixels...
  12309. // For World space: no over-provisioning
  12310. var overprovisioning = this.owner.isScreenSpace ? 1.07 : 1;
  12311. curWidth = Math.floor(Group2D_1._s.width * overprovisioning);
  12312. curHeight = Math.floor(Group2D_1._s.height * overprovisioning);
  12313. //console.log(`[${this._globalTransformProcessStep}] Resize group ${this.id}, width: ${curWidth}, height: ${curHeight}`);
  12314. rd._cacheTexture.freeRect(rd._cacheNode);
  12315. rd._cacheNode = null;
  12316. }
  12317. }
  12318. if (!rd._cacheNode) {
  12319. // Check if we have to allocate a rendering zone in the global cache texture
  12320. var res = this.owner._allocateGroupCache(this, this.parent && this.parent.renderGroup, curWidth ? new BABYLON.Size(curWidth, curHeight) : null, rd._useMipMap, rd._anisotropicLevel);
  12321. rd._cacheNode = res.node;
  12322. rd._cacheTexture = res.texture;
  12323. if (rd._cacheRenderSprite) {
  12324. rd._cacheRenderSprite.dispose();
  12325. }
  12326. rd._cacheRenderSprite = res.sprite;
  12327. sizeChanged = true;
  12328. }
  12329. else if (sizeChanged) {
  12330. var sprite = rd._cacheRenderSprite;
  12331. if (sprite) {
  12332. sprite.size = actualSize;
  12333. sprite.spriteSize = new BABYLON.Size(actualSize.width * scale.x * rs, actualSize.height * scale.y * rs);
  12334. }
  12335. }
  12336. if (sizeChanged) {
  12337. rd._cacheSize.copyFrom(Group2D_1._s);
  12338. rd._cacheNodeUVs = rd._cacheNode.getUVsForCustomSize(rd._cacheSize);
  12339. if (rd._cacheNodeUVsChangedObservable && rd._cacheNodeUVsChangedObservable.hasObservers()) {
  12340. rd._cacheNodeUVsChangedObservable.notifyObservers(rd._cacheNodeUVs);
  12341. }
  12342. this._setFlags(BABYLON.SmartPropertyPrim.flagWorldCacheChanged);
  12343. }
  12344. var pos = Group2D_1._v1;
  12345. rd._cacheNode.getInnerPosToRef(pos);
  12346. rd._cacheTexture.bindTextureForPosSize(pos, Group2D_1._s, true);
  12347. };
  12348. Group2D.prototype._unbindCacheTarget = function () {
  12349. if (this._renderableData._cacheTexture) {
  12350. this._renderableData._cacheTexture.unbindTexture();
  12351. }
  12352. };
  12353. Group2D.prototype._spreadActualScaleDirty = function () {
  12354. if (this._renderableData && this._renderableData._cacheRenderSprite) {
  12355. this.handleGroupChanged(BABYLON.Prim2DBase.actualScaleProperty);
  12356. }
  12357. _super.prototype._spreadActualScaleDirty.call(this);
  12358. };
  12359. Group2D.prototype.handleGroupChanged = function (prop) {
  12360. // This method is only for cachedGroup
  12361. var rd = this._renderableData;
  12362. if (!rd) {
  12363. return;
  12364. }
  12365. var cachedSprite = rd._cacheRenderSprite;
  12366. if (!this.isCachedGroup || !cachedSprite) {
  12367. return;
  12368. }
  12369. // For now we only support these property changes
  12370. // TODO: add more! :)
  12371. switch (prop.id) {
  12372. case BABYLON.Prim2DBase.actualPositionProperty.id:
  12373. cachedSprite.actualPosition = this.actualPosition.clone();
  12374. if (cachedSprite.position != null) {
  12375. cachedSprite.position = cachedSprite.actualPosition.clone();
  12376. }
  12377. break;
  12378. case BABYLON.Prim2DBase.rotationProperty.id:
  12379. cachedSprite.rotation = this.rotation;
  12380. break;
  12381. case BABYLON.Prim2DBase.scaleProperty.id:
  12382. cachedSprite.scale = this.scale;
  12383. break;
  12384. case BABYLON.Prim2DBase.originProperty.id:
  12385. cachedSprite.origin = this.origin.clone();
  12386. break;
  12387. case Group2D_1.actualSizeProperty.id:
  12388. cachedSprite.size = this.actualSize.clone();
  12389. break;
  12390. case Group2D_1.xProperty.id:
  12391. cachedSprite.x = this.x;
  12392. break;
  12393. case Group2D_1.yProperty.id:
  12394. cachedSprite.y = this.y;
  12395. }
  12396. };
  12397. Group2D.prototype.detectGroupStates = function () {
  12398. var isCanvas = this instanceof BABYLON.Canvas2D;
  12399. var canvasStrat = this.owner.cachingStrategy;
  12400. // In Don't Cache mode, only the canvas is renderable, all the other groups are logical. There are not a single cached group.
  12401. if (canvasStrat === BABYLON.Canvas2D.CACHESTRATEGY_DONTCACHE) {
  12402. this._isRenderableGroup = isCanvas;
  12403. this._isCachedGroup = false;
  12404. }
  12405. else if (canvasStrat === BABYLON.Canvas2D.CACHESTRATEGY_CANVAS) {
  12406. if (isCanvas) {
  12407. this._isRenderableGroup = true;
  12408. this._isCachedGroup = true;
  12409. }
  12410. else {
  12411. this._isRenderableGroup = this.id === "__cachedCanvasGroup__";
  12412. this._isCachedGroup = false;
  12413. }
  12414. }
  12415. else if (canvasStrat === BABYLON.Canvas2D.CACHESTRATEGY_TOPLEVELGROUPS) {
  12416. if (isCanvas) {
  12417. this._isRenderableGroup = true;
  12418. this._isCachedGroup = false;
  12419. }
  12420. else {
  12421. if (this.hierarchyDepth === 1) {
  12422. this._isRenderableGroup = true;
  12423. this._isCachedGroup = true;
  12424. }
  12425. else {
  12426. this._isRenderableGroup = false;
  12427. this._isCachedGroup = false;
  12428. }
  12429. }
  12430. }
  12431. else if (canvasStrat === BABYLON.Canvas2D.CACHESTRATEGY_ALLGROUPS) {
  12432. if (isCanvas) {
  12433. this._isRenderableGroup = true;
  12434. this._isCachedGroup = false;
  12435. }
  12436. else {
  12437. var gcb = this.cacheBehavior & Group2D_1.GROUPCACHEBEHAVIOR_OPTIONMASK;
  12438. if ((gcb === Group2D_1.GROUPCACHEBEHAVIOR_DONTCACHEOVERRIDE) || (gcb === Group2D_1.GROUPCACHEBEHAVIOR_CACHEINPARENTGROUP)) {
  12439. this._isRenderableGroup = gcb === Group2D_1.GROUPCACHEBEHAVIOR_DONTCACHEOVERRIDE;
  12440. this._isCachedGroup = false;
  12441. }
  12442. if (gcb === Group2D_1.GROUPCACHEBEHAVIOR_FOLLOWCACHESTRATEGY) {
  12443. this._isRenderableGroup = true;
  12444. this._isCachedGroup = true;
  12445. }
  12446. }
  12447. }
  12448. if (this._isRenderableGroup) {
  12449. // Yes, we do need that check, trust me, unfortunately we can call _detectGroupStates many time on the same object...
  12450. if (!this._renderableData) {
  12451. this._renderableData = new RenderableGroupData();
  12452. }
  12453. }
  12454. // If the group is tagged as renderable we add it to the renderable tree
  12455. if (this._isCachedGroup) {
  12456. this._renderableData._noResizeOnScale = (this.cacheBehavior & Group2D_1.GROUPCACHEBEHAVIOR_NORESIZEONSCALE) !== 0;
  12457. var cur = this.parent;
  12458. while (cur) {
  12459. if (cur instanceof Group2D_1 && cur._isRenderableGroup) {
  12460. if (cur._renderableData._childrenRenderableGroups.indexOf(this) === -1) {
  12461. cur._renderableData._childrenRenderableGroups.push(this);
  12462. }
  12463. break;
  12464. }
  12465. cur = cur.parent;
  12466. }
  12467. }
  12468. };
  12469. Object.defineProperty(Group2D.prototype, "_cachedTexture", {
  12470. get: function () {
  12471. if (this._renderableData) {
  12472. return this._renderableData._cacheTexture;
  12473. }
  12474. return null;
  12475. },
  12476. enumerable: true,
  12477. configurable: true
  12478. });
  12479. return Group2D;
  12480. }(BABYLON.Prim2DBase));
  12481. Group2D.GROUP2D_PROPCOUNT = BABYLON.Prim2DBase.PRIM2DBASE_PROPCOUNT + 5;
  12482. /**
  12483. * Default behavior, the group will use the caching strategy defined at the Canvas Level
  12484. */
  12485. Group2D.GROUPCACHEBEHAVIOR_FOLLOWCACHESTRATEGY = 0;
  12486. /**
  12487. * When used, this group's content won't be cached, no matter which strategy used.
  12488. * If the group is part of a WorldSpace Canvas, its content will be drawn in the Canvas cache bitmap.
  12489. */
  12490. Group2D.GROUPCACHEBEHAVIOR_DONTCACHEOVERRIDE = 1;
  12491. /**
  12492. * When used, the group's content will be cached in the nearest cached parent group/canvas
  12493. */
  12494. Group2D.GROUPCACHEBEHAVIOR_CACHEINPARENTGROUP = 2;
  12495. /**
  12496. * You can specify this behavior to any cached Group2D to indicate that you don't want the cached content to be resized when the Group's actualScale is changing. It will draw the content stretched or shrink which is faster than a resize. This setting is obviously for performance consideration, don't use it if you want the best rendering quality
  12497. */
  12498. Group2D.GROUPCACHEBEHAVIOR_NORESIZEONSCALE = 0x100;
  12499. Group2D.GROUPCACHEBEHAVIOR_OPTIONMASK = 0xFF;
  12500. Group2D._uV = new BABYLON.Vector2(1, 1);
  12501. Group2D._s = BABYLON.Size.Zero();
  12502. Group2D._v1 = BABYLON.Vector2.Zero();
  12503. Group2D._s2 = BABYLON.Size.Zero();
  12504. Group2D._unS = new BABYLON.Vector2(1, 1);
  12505. __decorate([
  12506. BABYLON.instanceLevelProperty(BABYLON.Prim2DBase.PRIM2DBASE_PROPCOUNT + 1, function (pi) { return Group2D_1.sizeProperty = pi; }, false, true)
  12507. ], Group2D.prototype, "size", null);
  12508. Group2D = Group2D_1 = __decorate([
  12509. BABYLON.className("Group2D", "BABYLON")
  12510. /**
  12511. * A non renderable primitive that defines a logical group.
  12512. * Can also serve the purpose of caching its content into a bitmap to reduce rendering overhead
  12513. */
  12514. ], Group2D);
  12515. BABYLON.Group2D = Group2D;
  12516. var RenderableGroupData = (function () {
  12517. function RenderableGroupData() {
  12518. this._primDirtyList = new Array();
  12519. this._primNewDirtyList = new Array();
  12520. this._childrenRenderableGroups = new Array();
  12521. this._renderGroupInstancesInfo = new BABYLON.StringDictionary();
  12522. this._transparentPrimitives = new Array();
  12523. this._transparentSegments = new Array();
  12524. this._transparentListChanged = false;
  12525. this._cacheNode = null;
  12526. this._cacheTexture = null;
  12527. this._cacheRenderSprite = null;
  12528. this._renderingScale = 1;
  12529. this._cacheNodeUVs = null;
  12530. this._cacheNodeUVsChangedObservable = null;
  12531. this._cacheSize = BABYLON.Size.Zero();
  12532. this._useMipMap = false;
  12533. this._anisotropicLevel = 1;
  12534. this._noResizeOnScale = false;
  12535. }
  12536. RenderableGroupData.prototype.dispose = function (owner) {
  12537. var engine = owner.engine;
  12538. if (this._cacheRenderSprite) {
  12539. this._cacheRenderSprite.dispose();
  12540. this._cacheRenderSprite = null;
  12541. }
  12542. if (this._cacheTexture && this._cacheNode) {
  12543. this._cacheTexture.freeRect(this._cacheNode);
  12544. this._cacheTexture = null;
  12545. this._cacheNode = null;
  12546. }
  12547. if (this._primDirtyList) {
  12548. this._primDirtyList.splice(0);
  12549. this._primDirtyList = null;
  12550. }
  12551. if (this._renderGroupInstancesInfo) {
  12552. this._renderGroupInstancesInfo.forEach(function (k, v) {
  12553. v.dispose();
  12554. });
  12555. this._renderGroupInstancesInfo = null;
  12556. }
  12557. if (this._cacheNodeUVsChangedObservable) {
  12558. this._cacheNodeUVsChangedObservable.clear();
  12559. this._cacheNodeUVsChangedObservable = null;
  12560. }
  12561. if (this._transparentSegments) {
  12562. for (var _i = 0, _a = this._transparentSegments; _i < _a.length; _i++) {
  12563. var ts = _a[_i];
  12564. ts.dispose(engine);
  12565. }
  12566. this._transparentSegments.splice(0);
  12567. this._transparentSegments = null;
  12568. }
  12569. };
  12570. RenderableGroupData.prototype.addNewTransparentPrimitiveInfo = function (prim, gii) {
  12571. var tpi = new TransparentPrimitiveInfo();
  12572. tpi._primitive = prim;
  12573. tpi._groupInstanceInfo = gii;
  12574. tpi._transparentSegment = null;
  12575. this._transparentPrimitives.push(tpi);
  12576. this._transparentListChanged = true;
  12577. return tpi;
  12578. };
  12579. RenderableGroupData.prototype.removeTransparentPrimitiveInfo = function (tpi) {
  12580. var index = this._transparentPrimitives.indexOf(tpi);
  12581. if (index !== -1) {
  12582. this._transparentPrimitives.splice(index, 1);
  12583. this._transparentListChanged = true;
  12584. }
  12585. };
  12586. RenderableGroupData.prototype.transparentPrimitiveZChanged = function (tpi) {
  12587. this._transparentListChanged = true;
  12588. //this.updateSmallestZChangedPrim(tpi);
  12589. };
  12590. RenderableGroupData.prototype.resetPrimDirtyList = function () {
  12591. var dirtyList = this._primDirtyList;
  12592. var numDirty = dirtyList.length;
  12593. for (var i = 0; i < numDirty; i++) {
  12594. if (dirtyList[i]._isFlagSet(BABYLON.SmartPropertyPrim.flagPrimInDirtyList)) {
  12595. dirtyList[i]._resetPropertiesDirty();
  12596. }
  12597. }
  12598. dirtyList.length = 0;
  12599. };
  12600. return RenderableGroupData;
  12601. }());
  12602. BABYLON.RenderableGroupData = RenderableGroupData;
  12603. var TransparentPrimitiveInfo = (function () {
  12604. function TransparentPrimitiveInfo() {
  12605. }
  12606. return TransparentPrimitiveInfo;
  12607. }());
  12608. BABYLON.TransparentPrimitiveInfo = TransparentPrimitiveInfo;
  12609. var Group2D_1;
  12610. })(BABYLON || (BABYLON = {}));
  12611. //# sourceMappingURL=babylon.group2d.js.map
  12612. var __extends = (this && this.__extends) || (function () {
  12613. var extendStatics = Object.setPrototypeOf ||
  12614. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  12615. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  12616. return function (d, b) {
  12617. extendStatics(d, b);
  12618. function __() { this.constructor = d; }
  12619. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  12620. };
  12621. })();
  12622. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  12623. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  12624. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  12625. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  12626. return c > 3 && r && Object.defineProperty(target, key, r), r;
  12627. };
  12628. var BABYLON;
  12629. (function (BABYLON) {
  12630. var WireFrame2DRenderCache = (function (_super) {
  12631. __extends(WireFrame2DRenderCache, _super);
  12632. function WireFrame2DRenderCache() {
  12633. var _this = _super !== null && _super.apply(this, arguments) || this;
  12634. _this.effectsReady = false;
  12635. _this.vb = null;
  12636. _this.vtxCount = 0;
  12637. _this.instancingAttributes = null;
  12638. _this.effect = null;
  12639. _this.effectInstanced = null;
  12640. return _this;
  12641. }
  12642. WireFrame2DRenderCache.prototype.render = function (instanceInfo, context) {
  12643. // Do nothing if the shader is still loading/preparing
  12644. if (!this.effectsReady) {
  12645. if ((this.effect && (!this.effect.isReady() || (this.effectInstanced && !this.effectInstanced.isReady())))) {
  12646. return false;
  12647. }
  12648. this.effectsReady = true;
  12649. }
  12650. // Compute the offset locations of the attributes in the vertex shader that will be mapped to the instance buffer data
  12651. var canvas = instanceInfo.owner.owner;
  12652. var engine = canvas.engine;
  12653. var cur = engine.getAlphaMode();
  12654. var effect = context.useInstancing ? this.effectInstanced : this.effect;
  12655. engine.enableEffect(effect);
  12656. engine.bindBuffersDirectly(this.vb, null, [2, 4], 24, effect);
  12657. if (context.renderMode !== BABYLON.Render2DContext.RenderModeOpaque) {
  12658. engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE, true);
  12659. }
  12660. var pid = context.groupInfoPartData[0];
  12661. if (context.useInstancing) {
  12662. if (!this.instancingAttributes) {
  12663. this.instancingAttributes = this.loadInstancingAttributes(WireFrame2D.WIREFRAME2D_MAINPARTID, effect);
  12664. }
  12665. var glBuffer = context.instancedBuffers ? context.instancedBuffers[0] : pid._partBuffer;
  12666. var count = context.instancedBuffers ? context.instancesCount : pid._partData.usedElementCount;
  12667. canvas._addDrawCallCount(1, context.renderMode);
  12668. engine.updateAndBindInstancesBuffer(glBuffer, null, this.instancingAttributes);
  12669. engine.drawUnIndexed(false, 0, this.vtxCount, count);
  12670. // engine.draw(true, 0, 6, count);
  12671. engine.unbindInstanceAttributes();
  12672. }
  12673. else {
  12674. canvas._addDrawCallCount(context.partDataEndIndex - context.partDataStartIndex, context.renderMode);
  12675. for (var i = context.partDataStartIndex; i < context.partDataEndIndex; i++) {
  12676. this.setupUniforms(effect, 0, pid._partData, i);
  12677. engine.drawUnIndexed(false, 0, this.vtxCount);
  12678. // engine.draw(true, 0, 6);
  12679. }
  12680. }
  12681. engine.setAlphaMode(cur, true);
  12682. return true;
  12683. };
  12684. WireFrame2DRenderCache.prototype.updateModelRenderCache = function (prim) {
  12685. var w = prim;
  12686. w._updateVertexBuffer(this);
  12687. return true;
  12688. };
  12689. WireFrame2DRenderCache.prototype.dispose = function () {
  12690. if (!_super.prototype.dispose.call(this)) {
  12691. return false;
  12692. }
  12693. if (this.vb) {
  12694. this._engine._releaseBuffer(this.vb);
  12695. this.vb = null;
  12696. }
  12697. this.effect = null;
  12698. this.effectInstanced = null;
  12699. return true;
  12700. };
  12701. return WireFrame2DRenderCache;
  12702. }(BABYLON.ModelRenderCache));
  12703. BABYLON.WireFrame2DRenderCache = WireFrame2DRenderCache;
  12704. var WireFrameVertex2D = (function () {
  12705. function WireFrameVertex2D(p, c) {
  12706. if (c === void 0) { c = null; }
  12707. this.fromVector2(p);
  12708. if (c != null) {
  12709. this.fromColor4(c);
  12710. }
  12711. else {
  12712. this.r = this.g = this.b = this.a = 1;
  12713. }
  12714. }
  12715. WireFrameVertex2D.prototype.fromVector2 = function (p) {
  12716. this.x = p.x;
  12717. this.y = p.y;
  12718. };
  12719. WireFrameVertex2D.prototype.fromColor3 = function (c) {
  12720. this.r = c.r;
  12721. this.g = c.g;
  12722. this.b = c.b;
  12723. this.a = 1;
  12724. };
  12725. WireFrameVertex2D.prototype.fromColor4 = function (c) {
  12726. this.r = c.r;
  12727. this.g = c.g;
  12728. this.b = c.b;
  12729. this.a = c.a;
  12730. };
  12731. return WireFrameVertex2D;
  12732. }());
  12733. WireFrameVertex2D = __decorate([
  12734. BABYLON.className("WireFrameVertex2D", "BABYLON")
  12735. ], WireFrameVertex2D);
  12736. BABYLON.WireFrameVertex2D = WireFrameVertex2D;
  12737. var WireFrameGroup2D = (function () {
  12738. /**
  12739. * Construct a WireFrameGroup2D object
  12740. * @param id a unique ID among the Groups added to a given WireFrame2D primitive, if you don't specify an id, a random one will be generated. The id is immutable.
  12741. * @param defaultColor specify the default color that will be used when a vertex is pushed, white will be used if not specified.
  12742. */
  12743. function WireFrameGroup2D(id, defaultColor) {
  12744. if (id === void 0) { id = null; }
  12745. if (defaultColor === void 0) { defaultColor = null; }
  12746. this._id = (id == null) ? BABYLON.Tools.RandomId() : id;
  12747. this._uid = BABYLON.Tools.RandomId();
  12748. this._defaultColor = (defaultColor == null) ? new BABYLON.Color4(1, 1, 1, 1) : defaultColor;
  12749. this._buildingStrip = false;
  12750. this._vertices = new Array();
  12751. }
  12752. Object.defineProperty(WireFrameGroup2D.prototype, "uid", {
  12753. get: function () {
  12754. return this._uid;
  12755. },
  12756. enumerable: true,
  12757. configurable: true
  12758. });
  12759. Object.defineProperty(WireFrameGroup2D.prototype, "id", {
  12760. /**
  12761. * Retrieve the ID of the group
  12762. */
  12763. get: function () {
  12764. return this._id;
  12765. },
  12766. enumerable: true,
  12767. configurable: true
  12768. });
  12769. /**
  12770. * Push a vertex in the array of vertices.
  12771. * If you're previously called startLineStrip, the vertex will be pushed twice in order to describe the end of a line and the start of a new one.
  12772. * @param p Position of the vertex
  12773. * @param c Color of the vertex, if null the default color of the group will be used
  12774. */
  12775. WireFrameGroup2D.prototype.pushVertex = function (p, c) {
  12776. if (c === void 0) { c = null; }
  12777. var v = new WireFrameVertex2D(p, (c == null) ? this._defaultColor : c);
  12778. this._vertices.push(v);
  12779. if (this._buildingStrip) {
  12780. var v2 = new WireFrameVertex2D(p, (c == null) ? this._defaultColor : c);
  12781. this._vertices.push(v2);
  12782. }
  12783. };
  12784. /**
  12785. * Start to store a Line Strip. The given vertex will be pushed in the array. The you have to call pushVertex to add subsequent vertices describing the strip and don't forget to call endLineStrip to close the strip!!!
  12786. * @param p Position of the vertex
  12787. * @param c Color of the vertex, if null the default color of the group will be used
  12788. */
  12789. WireFrameGroup2D.prototype.startLineStrip = function (p, c) {
  12790. if (c === void 0) { c = null; }
  12791. this.pushVertex(p, (c == null) ? this._defaultColor : c);
  12792. this._buildingStrip = true;
  12793. };
  12794. /**
  12795. * Close the Strip by storing a last vertex
  12796. * @param p Position of the vertex
  12797. * @param c Color of the vertex, if null the default color of the group will be used
  12798. */
  12799. WireFrameGroup2D.prototype.endLineStrip = function (p, c) {
  12800. if (c === void 0) { c = null; }
  12801. this._buildingStrip = false;
  12802. this.pushVertex(p, (c == null) ? this._defaultColor : c);
  12803. };
  12804. Object.defineProperty(WireFrameGroup2D.prototype, "vertices", {
  12805. /**
  12806. * Access to the array of Vertices, you can manipulate its content but BEWARE of what you're doing!
  12807. */
  12808. get: function () {
  12809. return this._vertices;
  12810. },
  12811. enumerable: true,
  12812. configurable: true
  12813. });
  12814. return WireFrameGroup2D;
  12815. }());
  12816. WireFrameGroup2D = __decorate([
  12817. BABYLON.className("WireFrameGroup2D", "BABYLON")
  12818. /**
  12819. * A WireFrameGroup2D has a unique id (among the WireFrame2D primitive) and a collection of WireFrameVertex2D which form a Line list.
  12820. * A Line is defined by two vertices, the storage of vertices doesn't follow the Line Strip convention, so to create consecutive lines the intermediate vertex must be doubled. The best way to build a Line Strip is to use the startLineStrip, pushVertex and endLineStrip methods.
  12821. * You can manually add vertices using the pushVertex method, but mind that the vertices array must be a multiple of 2 as each line are defined with TWO SEPARATED vertices. I hope this is clear enough.
  12822. */
  12823. ], WireFrameGroup2D);
  12824. BABYLON.WireFrameGroup2D = WireFrameGroup2D;
  12825. var WireFrame2D = WireFrame2D_1 = (function (_super) {
  12826. __extends(WireFrame2D, _super);
  12827. /**
  12828. * Create an WireFrame 2D primitive
  12829. * @param wireFrameGroups an array of WireFrameGroup.
  12830. * @param settings a combination of settings, possible ones are
  12831. * - parent: the parent primitive/canvas, must be specified if the primitive is not constructed as a child of another one (i.e. as part of the children array setting)
  12832. * - children: an array of direct children
  12833. * - id a text identifier, for information purpose
  12834. * - position: the X & Y positions relative to its parent. Alternatively the x and y properties can be set. Default is [0;0]
  12835. * - rotation: the initial rotation (in radian) of the primitive. default is 0
  12836. * - scale: the initial scale of the primitive. default is 1. You can alternatively use scaleX &| scaleY to apply non uniform scale
  12837. * - size: the size of the sprite displayed in the canvas, if not specified the spriteSize will be used
  12838. * - dontInheritParentScale: if set the parent's scale won't be taken into consideration to compute the actualScale property
  12839. * - opacity: set the overall opacity of the primitive, 1 to be opaque (default), less than 1 to be transparent.
  12840. * - zOrder: override the zOrder with the specified value
  12841. * - origin: define the normalized origin point location, default [0.5;0.5]
  12842. * - alignToPixel: the rendered lines will be aligned to the rendering device' pixels
  12843. * - isVisible: true if the sprite must be visible, false for hidden. Default is true.
  12844. * - isPickable: if true the Primitive can be used with interaction mode and will issue Pointer Event. If false it will be ignored for interaction/intersection test. Default value is true.
  12845. * - isContainer: if true the Primitive acts as a container for interaction, if the primitive is not pickable or doesn't intersection, no further test will be perform on its children. If set to false, children will always be considered for intersection/interaction. Default value is true.
  12846. * - childrenFlatZOrder: if true all the children (direct and indirect) will share the same Z-Order. Use this when there's a lot of children which don't overlap. The drawing order IS NOT GUARANTED!
  12847. * - levelCollision: this primitive is an actor of the Collision Manager and only this level will be used for collision (i.e. not the children). Use deepCollision if you want collision detection on the primitives and its children.
  12848. * - deepCollision: this primitive is an actor of the Collision Manager, this level AND ALSO its children will be used for collision (note: you don't need to set the children as level/deepCollision).
  12849. * - layoutData: a instance of a class implementing the ILayoutData interface that contain data to pass to the primitive parent's layout engine
  12850. * - marginTop: top margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  12851. * - marginLeft: left margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  12852. * - marginRight: right margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  12853. * - marginBottom: bottom margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  12854. * - margin: top, left, right and bottom margin formatted as a single string (see PrimitiveThickness.fromString)
  12855. * - marginHAlignment: one value of the PrimitiveAlignment type's static properties
  12856. * - marginVAlignment: one value of the PrimitiveAlignment type's static properties
  12857. * - marginAlignment: a string defining the alignment, see PrimitiveAlignment.fromString
  12858. * - paddingTop: top padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  12859. * - paddingLeft: left padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  12860. * - paddingRight: right padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  12861. * - paddingBottom: bottom padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  12862. * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
  12863. */
  12864. function WireFrame2D(wireFrameGroups, settings) {
  12865. var _this = this;
  12866. if (!settings) {
  12867. settings = {};
  12868. }
  12869. _this = _super.call(this, settings) || this;
  12870. _this._wireFrameGroups = new BABYLON.StringDictionary();
  12871. for (var _i = 0, wireFrameGroups_1 = wireFrameGroups; _i < wireFrameGroups_1.length; _i++) {
  12872. var wfg = wireFrameGroups_1[_i];
  12873. _this._wireFrameGroups.add(wfg.id, wfg);
  12874. }
  12875. _this._vtxTransparent = false;
  12876. if (settings.size != null) {
  12877. _this.size = settings.size;
  12878. }
  12879. _this.alignToPixel = (settings.alignToPixel == null) ? true : settings.alignToPixel;
  12880. return _this;
  12881. }
  12882. Object.defineProperty(WireFrame2D.prototype, "wireFrameGroups", {
  12883. get: function () {
  12884. return this._wireFrameGroups;
  12885. },
  12886. enumerable: true,
  12887. configurable: true
  12888. });
  12889. /**
  12890. * If you change the content of the wireFrameGroups you MUST call this method for the changes to be reflected during rendering
  12891. */
  12892. WireFrame2D.prototype.wireFrameGroupsDirty = function () {
  12893. this._setFlags(BABYLON.SmartPropertyPrim.flagModelUpdate);
  12894. this.onPrimBecomesDirty();
  12895. };
  12896. Object.defineProperty(WireFrame2D.prototype, "size", {
  12897. get: function () {
  12898. if (this._size == null) {
  12899. this._computeMinMaxTrans();
  12900. }
  12901. return this._size;
  12902. },
  12903. set: function (value) {
  12904. this.internalSetSize(value);
  12905. },
  12906. enumerable: true,
  12907. configurable: true
  12908. });
  12909. WireFrame2D.prototype.updateLevelBoundingInfo = function () {
  12910. var v = this._computeMinMaxTrans();
  12911. BABYLON.BoundingInfo2D.CreateFromMinMaxToRef(v.x, v.z, v.y, v.w, this._levelBoundingInfo);
  12912. return true;
  12913. };
  12914. WireFrame2D.prototype.levelIntersect = function (intersectInfo) {
  12915. // TODO !
  12916. return true;
  12917. };
  12918. Object.defineProperty(WireFrame2D.prototype, "alignToPixel", {
  12919. /**
  12920. * Get/set if the sprite rendering should be aligned to the target rendering device pixel or not
  12921. */
  12922. get: function () {
  12923. return this._alignToPixel;
  12924. },
  12925. set: function (value) {
  12926. this._alignToPixel = value;
  12927. },
  12928. enumerable: true,
  12929. configurable: true
  12930. });
  12931. WireFrame2D.prototype.createModelRenderCache = function (modelKey) {
  12932. var renderCache = new WireFrame2DRenderCache(this.owner.engine, modelKey);
  12933. return renderCache;
  12934. };
  12935. WireFrame2D.prototype.setupModelRenderCache = function (modelRenderCache) {
  12936. var renderCache = modelRenderCache;
  12937. var engine = this.owner.engine;
  12938. // Create the VertexBuffer
  12939. this._updateVertexBuffer(renderCache);
  12940. // Get the instanced version of the effect, if the engine does not support it, null is return and we'll only draw on by one
  12941. var ei = this.getDataPartEffectInfo(WireFrame2D_1.WIREFRAME2D_MAINPARTID, ["pos", "col"], [], true);
  12942. if (ei) {
  12943. renderCache.effectInstanced = engine.createEffect("wireframe2d", ei.attributes, ei.uniforms, [], ei.defines, null);
  12944. }
  12945. ei = this.getDataPartEffectInfo(WireFrame2D_1.WIREFRAME2D_MAINPARTID, ["pos", "col"], [], false);
  12946. renderCache.effect = engine.createEffect("wireframe2d", ei.attributes, ei.uniforms, [], ei.defines, null);
  12947. return renderCache;
  12948. };
  12949. WireFrame2D.prototype._updateVertexBuffer = function (mrc) {
  12950. var engine = this.owner.engine;
  12951. if (mrc.vb != null) {
  12952. engine._releaseBuffer(mrc.vb);
  12953. }
  12954. var vtxCount = 0;
  12955. this._wireFrameGroups.forEach(function (k, v) { return vtxCount += v.vertices.length; });
  12956. var vb = new Float32Array(vtxCount * 6);
  12957. var i = 0;
  12958. this._wireFrameGroups.forEach(function (k, v) {
  12959. for (var _i = 0, _a = v.vertices; _i < _a.length; _i++) {
  12960. var vtx = _a[_i];
  12961. vb[i++] = vtx.x;
  12962. vb[i++] = vtx.y;
  12963. vb[i++] = vtx.r;
  12964. vb[i++] = vtx.g;
  12965. vb[i++] = vtx.b;
  12966. vb[i++] = vtx.a;
  12967. }
  12968. });
  12969. mrc.vb = engine.createVertexBuffer(vb);
  12970. mrc.vtxCount = vtxCount;
  12971. };
  12972. WireFrame2D.prototype.refreshInstanceDataPart = function (part) {
  12973. if (!_super.prototype.refreshInstanceDataPart.call(this, part)) {
  12974. return false;
  12975. }
  12976. return true;
  12977. };
  12978. WireFrame2D.prototype._computeMinMaxTrans = function () {
  12979. var xmin = Number.MAX_VALUE;
  12980. var xmax = Number.MIN_VALUE;
  12981. var ymin = Number.MAX_VALUE;
  12982. var ymax = Number.MIN_VALUE;
  12983. var transparent = false;
  12984. this._wireFrameGroups.forEach(function (k, v) {
  12985. for (var _i = 0, _a = v.vertices; _i < _a.length; _i++) {
  12986. var vtx = _a[_i];
  12987. xmin = Math.min(xmin, vtx.x);
  12988. xmax = Math.max(xmax, vtx.x);
  12989. ymin = Math.min(ymin, vtx.y);
  12990. ymax = Math.max(ymax, vtx.y);
  12991. if (vtx.a < 1) {
  12992. transparent = true;
  12993. }
  12994. }
  12995. });
  12996. this._vtxTransparent = transparent;
  12997. this._size = new BABYLON.Size(xmax - xmin, ymax - ymin);
  12998. return new BABYLON.Vector4(xmin, ymin, xmax, ymax);
  12999. };
  13000. WireFrame2D.prototype.createInstanceDataParts = function () {
  13001. return [new WireFrame2DInstanceData(WireFrame2D_1.WIREFRAME2D_MAINPARTID)];
  13002. };
  13003. return WireFrame2D;
  13004. }(BABYLON.RenderablePrim2D));
  13005. WireFrame2D.WIREFRAME2D_MAINPARTID = 1;
  13006. __decorate([
  13007. BABYLON.modelLevelProperty(BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 1, function (pi) { return WireFrame2D_1.wireFrameGroupsProperty = pi; })
  13008. /**
  13009. * Get/set the texture that contains the sprite to display
  13010. */
  13011. ], WireFrame2D.prototype, "wireFrameGroups", null);
  13012. WireFrame2D = WireFrame2D_1 = __decorate([
  13013. BABYLON.className("WireFrame2D", "BABYLON")
  13014. /**
  13015. * Primitive that displays a WireFrame
  13016. */
  13017. ], WireFrame2D);
  13018. BABYLON.WireFrame2D = WireFrame2D;
  13019. var WireFrame2DInstanceData = (function (_super) {
  13020. __extends(WireFrame2DInstanceData, _super);
  13021. function WireFrame2DInstanceData(partId) {
  13022. return _super.call(this, partId, 1) || this;
  13023. }
  13024. return WireFrame2DInstanceData;
  13025. }(BABYLON.InstanceDataBase));
  13026. BABYLON.WireFrame2DInstanceData = WireFrame2DInstanceData;
  13027. var WireFrame2D_1;
  13028. })(BABYLON || (BABYLON = {}));
  13029. var __extends = (this && this.__extends) || (function () {
  13030. var extendStatics = Object.setPrototypeOf ||
  13031. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  13032. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  13033. return function (d, b) {
  13034. extendStatics(d, b);
  13035. function __() { this.constructor = d; }
  13036. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  13037. };
  13038. })();
  13039. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  13040. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  13041. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  13042. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  13043. return c > 3 && r && Object.defineProperty(target, key, r), r;
  13044. };
  13045. var BABYLON;
  13046. (function (BABYLON) {
  13047. var Rectangle2DRenderCache = (function (_super) {
  13048. __extends(Rectangle2DRenderCache, _super);
  13049. function Rectangle2DRenderCache(engine, modelKey) {
  13050. var _this = _super.call(this, engine, modelKey) || this;
  13051. _this.effectsReady = false;
  13052. _this.fillVB = null;
  13053. _this.fillIB = null;
  13054. _this.fillIndicesCount = 0;
  13055. _this.instancingFillAttributes = null;
  13056. _this.effectFill = null;
  13057. _this.effectFillInstanced = null;
  13058. _this.borderVB = null;
  13059. _this.borderIB = null;
  13060. _this.borderIndicesCount = 0;
  13061. _this.instancingBorderAttributes = null;
  13062. _this.effectBorder = null;
  13063. _this.effectBorderInstanced = null;
  13064. return _this;
  13065. }
  13066. Rectangle2DRenderCache.prototype.render = function (instanceInfo, context) {
  13067. // Do nothing if the shader is still loading/preparing
  13068. if (!this.effectsReady) {
  13069. if ((this.effectFill && (!this.effectFill.isReady() || (this.effectFillInstanced && !this.effectFillInstanced.isReady()))) ||
  13070. (this.effectBorder && (!this.effectBorder.isReady() || (this.effectBorderInstanced && !this.effectBorderInstanced.isReady())))) {
  13071. return false;
  13072. }
  13073. this.effectsReady = true;
  13074. }
  13075. var canvas = instanceInfo.owner.owner;
  13076. var engine = canvas.engine;
  13077. var depthFunction = 0;
  13078. if (this.effectFill && this.effectBorder) {
  13079. depthFunction = engine.getDepthFunction();
  13080. engine.setDepthFunctionToLessOrEqual();
  13081. }
  13082. var curAlphaMode = engine.getAlphaMode();
  13083. if (this.effectFill) {
  13084. var partIndex = instanceInfo.partIndexFromId.get(BABYLON.Shape2D.SHAPE2D_FILLPARTID.toString());
  13085. var pid = context.groupInfoPartData[partIndex];
  13086. if (context.renderMode !== BABYLON.Render2DContext.RenderModeOpaque) {
  13087. engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE, true);
  13088. }
  13089. var effect = context.useInstancing ? this.effectFillInstanced : this.effectFill;
  13090. engine.enableEffect(effect);
  13091. engine.bindBuffersDirectly(this.fillVB, this.fillIB, [1], 4, effect);
  13092. if (context.useInstancing) {
  13093. if (!this.instancingFillAttributes) {
  13094. this.instancingFillAttributes = this.loadInstancingAttributes(BABYLON.Shape2D.SHAPE2D_FILLPARTID, effect);
  13095. }
  13096. var glBuffer = context.instancedBuffers ? context.instancedBuffers[partIndex] : pid._partBuffer;
  13097. var count = context.instancedBuffers ? context.instancesCount : pid._partData.usedElementCount;
  13098. canvas._addDrawCallCount(1, context.renderMode);
  13099. engine.updateAndBindInstancesBuffer(glBuffer, null, this.instancingFillAttributes);
  13100. engine.draw(true, 0, this.fillIndicesCount, count);
  13101. engine.unbindInstanceAttributes();
  13102. }
  13103. else {
  13104. canvas._addDrawCallCount(context.partDataEndIndex - context.partDataStartIndex, context.renderMode);
  13105. for (var i = context.partDataStartIndex; i < context.partDataEndIndex; i++) {
  13106. this.setupUniforms(effect, partIndex, pid._partData, i);
  13107. engine.draw(true, 0, this.fillIndicesCount);
  13108. }
  13109. }
  13110. }
  13111. if (this.effectBorder) {
  13112. var partIndex = instanceInfo.partIndexFromId.get(BABYLON.Shape2D.SHAPE2D_BORDERPARTID.toString());
  13113. var pid = context.groupInfoPartData[partIndex];
  13114. if (context.renderMode !== BABYLON.Render2DContext.RenderModeOpaque) {
  13115. engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE, true);
  13116. }
  13117. var effect = context.useInstancing ? this.effectBorderInstanced : this.effectBorder;
  13118. engine.enableEffect(effect);
  13119. engine.bindBuffersDirectly(this.borderVB, this.borderIB, [1], 4, effect);
  13120. if (context.useInstancing) {
  13121. if (!this.instancingBorderAttributes) {
  13122. this.instancingBorderAttributes = this.loadInstancingAttributes(BABYLON.Shape2D.SHAPE2D_BORDERPARTID, effect);
  13123. }
  13124. var glBuffer = context.instancedBuffers ? context.instancedBuffers[partIndex] : pid._partBuffer;
  13125. var count = context.instancedBuffers ? context.instancesCount : pid._partData.usedElementCount;
  13126. canvas._addDrawCallCount(1, context.renderMode);
  13127. engine.updateAndBindInstancesBuffer(glBuffer, null, this.instancingBorderAttributes);
  13128. engine.draw(true, 0, this.borderIndicesCount, count);
  13129. engine.unbindInstanceAttributes();
  13130. }
  13131. else {
  13132. canvas._addDrawCallCount(context.partDataEndIndex - context.partDataStartIndex, context.renderMode);
  13133. for (var i = context.partDataStartIndex; i < context.partDataEndIndex; i++) {
  13134. this.setupUniforms(effect, partIndex, pid._partData, i);
  13135. engine.draw(true, 0, this.borderIndicesCount);
  13136. }
  13137. }
  13138. }
  13139. engine.setAlphaMode(curAlphaMode, true);
  13140. if (this.effectFill && this.effectBorder) {
  13141. engine.setDepthFunction(depthFunction);
  13142. }
  13143. return true;
  13144. };
  13145. Rectangle2DRenderCache.prototype.dispose = function () {
  13146. if (!_super.prototype.dispose.call(this)) {
  13147. return false;
  13148. }
  13149. if (this.fillVB) {
  13150. this._engine._releaseBuffer(this.fillVB);
  13151. this.fillVB = null;
  13152. }
  13153. if (this.fillIB) {
  13154. this._engine._releaseBuffer(this.fillIB);
  13155. this.fillIB = null;
  13156. }
  13157. this.effectFill = null;
  13158. this.effectFillInstanced = null;
  13159. this.effectBorder = null;
  13160. this.effectBorderInstanced = null;
  13161. if (this.borderVB) {
  13162. this._engine._releaseBuffer(this.borderVB);
  13163. this.borderVB = null;
  13164. }
  13165. if (this.borderIB) {
  13166. this._engine._releaseBuffer(this.borderIB);
  13167. this.borderIB = null;
  13168. }
  13169. return true;
  13170. };
  13171. return Rectangle2DRenderCache;
  13172. }(BABYLON.ModelRenderCache));
  13173. BABYLON.Rectangle2DRenderCache = Rectangle2DRenderCache;
  13174. var Rectangle2DInstanceData = (function (_super) {
  13175. __extends(Rectangle2DInstanceData, _super);
  13176. function Rectangle2DInstanceData(partId) {
  13177. return _super.call(this, partId, 1) || this;
  13178. }
  13179. Object.defineProperty(Rectangle2DInstanceData.prototype, "properties", {
  13180. get: function () {
  13181. return null;
  13182. },
  13183. set: function (value) {
  13184. },
  13185. enumerable: true,
  13186. configurable: true
  13187. });
  13188. return Rectangle2DInstanceData;
  13189. }(BABYLON.Shape2DInstanceData));
  13190. __decorate([
  13191. BABYLON.instanceData()
  13192. ], Rectangle2DInstanceData.prototype, "properties", null);
  13193. BABYLON.Rectangle2DInstanceData = Rectangle2DInstanceData;
  13194. var Rectangle2D = Rectangle2D_1 = (function (_super) {
  13195. __extends(Rectangle2D, _super);
  13196. /**
  13197. * Create an Rectangle 2D Shape primitive. May be a sharp rectangle (with sharp corners), or a rounded one.
  13198. * @param settings a combination of settings, possible ones are
  13199. * - parent: the parent primitive/canvas, must be specified if the primitive is not constructed as a child of another one (i.e. as part of the children array setting)
  13200. * - children: an array of direct children
  13201. * - id a text identifier, for information purpose
  13202. * - position: the X & Y positions relative to its parent. Alternatively the x and y settings can be set. Default is [0;0]
  13203. * - rotation: the initial rotation (in radian) of the primitive. default is 0
  13204. * - scale: the initial scale of the primitive. default is 1. You can alternatively use scaleX &| scaleY to apply non uniform scale
  13205. * - dontInheritParentScale: if set the parent's scale won't be taken into consideration to compute the actualScale property
  13206. * - alignToPixel: if true the primitive will be aligned to the target rendering device's pixel
  13207. * - opacity: set the overall opacity of the primitive, 1 to be opaque (default), less than 1 to be transparent.
  13208. * - zOrder: override the zOrder with the specified value
  13209. * - origin: define the normalized origin point location, default [0.5;0.5]
  13210. * - size: the size of the group. Alternatively the width and height settings can be set. Default will be [10;10].
  13211. * - roundRadius: if the rectangle has rounded corner, set their radius, default is 0 (to get a sharp edges rectangle).
  13212. * - fill: the brush used to draw the fill content of the rectangle, you can set null to draw nothing (but you will have to set a border brush), default is a SolidColorBrush of plain white. can also be a string value (see Canvas2D.GetBrushFromString)
  13213. * - border: the brush used to draw the border of the rectangle, you can set null to draw nothing (but you will have to set a fill brush), default is null. can also be a string value (see Canvas2D.GetBrushFromString)
  13214. * - borderThickness: the thickness of the drawn border, default is 1.
  13215. * - isVisible: true if the primitive must be visible, false for hidden. Default is true.
  13216. * - isPickable: if true the Primitive can be used with interaction mode and will issue Pointer Event. If false it will be ignored for interaction/intersection test. Default value is true.
  13217. * - isContainer: if true the Primitive acts as a container for interaction, if the primitive is not pickable or doesn't intersection, no further test will be perform on its children. If set to false, children will always be considered for intersection/interaction. Default value is true.
  13218. * - childrenFlatZOrder: if true all the children (direct and indirect) will share the same Z-Order. Use this when there's a lot of children which don't overlap. The drawing order IS NOT GUARANTED!
  13219. * - levelCollision: this primitive is an actor of the Collision Manager and only this level will be used for collision (i.e. not the children). Use deepCollision if you want collision detection on the primitives and its children.
  13220. * - deepCollision: this primitive is an actor of the Collision Manager, this level AND ALSO its children will be used for collision (note: you don't need to set the children as level/deepCollision).
  13221. * - layoutData: a instance of a class implementing the ILayoutData interface that contain data to pass to the primitive parent's layout engine
  13222. * - marginTop: top margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  13223. * - marginLeft: left margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  13224. * - marginRight: right margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  13225. * - marginBottom: bottom margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  13226. * - margin: top, left, right and bottom margin formatted as a single string (see PrimitiveThickness.fromString)
  13227. * - marginHAlignment: one value of the PrimitiveAlignment type's static properties
  13228. * - marginVAlignment: one value of the PrimitiveAlignment type's static properties
  13229. * - marginAlignment: a string defining the alignment, see PrimitiveAlignment.fromString
  13230. * - paddingTop: top padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  13231. * - paddingLeft: left padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  13232. * - paddingRight: right padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  13233. * - paddingBottom: bottom padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  13234. * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
  13235. */
  13236. function Rectangle2D(settings) {
  13237. var _this = this;
  13238. // Avoid checking every time if the object exists
  13239. if (settings == null) {
  13240. settings = {};
  13241. }
  13242. _this = _super.call(this, settings) || this;
  13243. if (settings.size != null) {
  13244. _this.size = settings.size;
  13245. }
  13246. else if (settings.width || settings.height) {
  13247. var size = new BABYLON.Size(settings.width, settings.height);
  13248. _this.size = size;
  13249. }
  13250. //let size = settings.size || (new Size((settings.width === null) ? null : (settings.width || 10), (settings.height === null) ? null : (settings.height || 10)));
  13251. var roundRadius = (settings.roundRadius == null) ? 0 : settings.roundRadius;
  13252. var borderThickness = (settings.borderThickness == null) ? 1 : settings.borderThickness;
  13253. //this.size = size;
  13254. _this.roundRadius = roundRadius;
  13255. _this.borderThickness = borderThickness;
  13256. return _this;
  13257. }
  13258. Object.defineProperty(Rectangle2D.prototype, "notRounded", {
  13259. get: function () {
  13260. return this._notRounded;
  13261. },
  13262. set: function (value) {
  13263. this._notRounded = value;
  13264. },
  13265. enumerable: true,
  13266. configurable: true
  13267. });
  13268. Object.defineProperty(Rectangle2D.prototype, "roundRadius", {
  13269. get: function () {
  13270. return this._roundRadius;
  13271. },
  13272. set: function (value) {
  13273. this._roundRadius = value;
  13274. this.notRounded = value === 0;
  13275. this._positioningDirty();
  13276. },
  13277. enumerable: true,
  13278. configurable: true
  13279. });
  13280. Rectangle2D.prototype.levelIntersect = function (intersectInfo) {
  13281. // If we got there it mean the boundingInfo intersection succeed, if the rectangle has not roundRadius, it means it succeed!
  13282. if (this.notRounded) {
  13283. return true;
  13284. }
  13285. // If we got so far it means the bounding box at least passed, so we know it's inside the bounding rectangle, but it can be outside the roundedRectangle.
  13286. // The easiest way is to check if the point is inside on of the four corners area (a little square of roundRadius size at the four corners)
  13287. // If it's the case for one, check if the mouse is located in the quarter that we care about (the one who is visible) then finally make a distance check with the roundRadius radius to see if it's inside the circle quarter or outside.
  13288. // First let remove the origin out the equation, to have the rectangle with an origin at bottom/left
  13289. var size = this.size;
  13290. Rectangle2D_1._i0.x = intersectInfo._localPickPosition.x;
  13291. Rectangle2D_1._i0.y = intersectInfo._localPickPosition.y;
  13292. var rr = this.roundRadius;
  13293. var rrs = rr * rr;
  13294. // Check if the point is in the bottom/left quarter area
  13295. Rectangle2D_1._i1.x = rr;
  13296. Rectangle2D_1._i1.y = rr;
  13297. if (Rectangle2D_1._i0.x <= Rectangle2D_1._i1.x && Rectangle2D_1._i0.y <= Rectangle2D_1._i1.y) {
  13298. // Compute the intersection point in the quarter local space
  13299. Rectangle2D_1._i2.x = Rectangle2D_1._i0.x - Rectangle2D_1._i1.x;
  13300. Rectangle2D_1._i2.y = Rectangle2D_1._i0.y - Rectangle2D_1._i1.y;
  13301. // It's a hit if the squared distance is less/equal to the squared radius of the round circle
  13302. return Rectangle2D_1._i2.lengthSquared() <= rrs;
  13303. }
  13304. // Check if the point is in the top/left quarter area
  13305. Rectangle2D_1._i1.x = rr;
  13306. Rectangle2D_1._i1.y = size.height - rr;
  13307. if (Rectangle2D_1._i0.x <= Rectangle2D_1._i1.x && Rectangle2D_1._i0.y >= Rectangle2D_1._i1.y) {
  13308. // Compute the intersection point in the quarter local space
  13309. Rectangle2D_1._i2.x = Rectangle2D_1._i0.x - Rectangle2D_1._i1.x;
  13310. Rectangle2D_1._i2.y = Rectangle2D_1._i0.y - Rectangle2D_1._i1.y;
  13311. // It's a hit if the squared distance is less/equal to the squared radius of the round circle
  13312. return Rectangle2D_1._i2.lengthSquared() <= rrs;
  13313. }
  13314. // Check if the point is in the top/right quarter area
  13315. Rectangle2D_1._i1.x = size.width - rr;
  13316. Rectangle2D_1._i1.y = size.height - rr;
  13317. if (Rectangle2D_1._i0.x >= Rectangle2D_1._i1.x && Rectangle2D_1._i0.y >= Rectangle2D_1._i1.y) {
  13318. // Compute the intersection point in the quarter local space
  13319. Rectangle2D_1._i2.x = Rectangle2D_1._i0.x - Rectangle2D_1._i1.x;
  13320. Rectangle2D_1._i2.y = Rectangle2D_1._i0.y - Rectangle2D_1._i1.y;
  13321. // It's a hit if the squared distance is less/equal to the squared radius of the round circle
  13322. return Rectangle2D_1._i2.lengthSquared() <= rrs;
  13323. }
  13324. // Check if the point is in the bottom/right quarter area
  13325. Rectangle2D_1._i1.x = size.width - rr;
  13326. Rectangle2D_1._i1.y = rr;
  13327. if (Rectangle2D_1._i0.x >= Rectangle2D_1._i1.x && Rectangle2D_1._i0.y <= Rectangle2D_1._i1.y) {
  13328. // Compute the intersection point in the quarter local space
  13329. Rectangle2D_1._i2.x = Rectangle2D_1._i0.x - Rectangle2D_1._i1.x;
  13330. Rectangle2D_1._i2.y = Rectangle2D_1._i0.y - Rectangle2D_1._i1.y;
  13331. // It's a hit if the squared distance is less/equal to the squared radius of the round circle
  13332. return Rectangle2D_1._i2.lengthSquared() <= rrs;
  13333. }
  13334. // At any other locations the point is guarantied to be inside
  13335. return true;
  13336. };
  13337. Rectangle2D.prototype.updateLevelBoundingInfo = function () {
  13338. BABYLON.BoundingInfo2D.CreateFromSizeToRef(this.actualSize, this._levelBoundingInfo);
  13339. return true;
  13340. };
  13341. Rectangle2D.prototype.createModelRenderCache = function (modelKey) {
  13342. var renderCache = new Rectangle2DRenderCache(this.owner.engine, modelKey);
  13343. return renderCache;
  13344. };
  13345. Rectangle2D.prototype.updateTriArray = function () {
  13346. // Not Rounded = sharp edge rect, the default implementation is the right one!
  13347. if (this.notRounded) {
  13348. _super.prototype.updateTriArray.call(this);
  13349. return;
  13350. }
  13351. // Rounded Corner? It's more complicated! :)
  13352. var subDiv = Rectangle2D_1.roundSubdivisions * 4;
  13353. if (this._primTriArray == null) {
  13354. this._primTriArray = new BABYLON.Tri2DArray(subDiv);
  13355. }
  13356. else {
  13357. this._primTriArray.clear(subDiv);
  13358. }
  13359. var size = this.actualSize;
  13360. var w = size.width;
  13361. var h = size.height;
  13362. var r = this.roundRadius;
  13363. var rsub0 = subDiv * 0.25;
  13364. var rsub1 = subDiv * 0.50;
  13365. var rsub2 = subDiv * 0.75;
  13366. var center = new BABYLON.Vector2(0.5 * size.width, 0.5 * size.height);
  13367. var twopi = Math.PI * 2;
  13368. var nru = r / w;
  13369. var nrv = r / h;
  13370. var computePos = function (index, p) {
  13371. // right/bottom
  13372. if (index < rsub0) {
  13373. p.x = 1.0 - nru;
  13374. p.y = nrv;
  13375. }
  13376. else if (index < rsub1) {
  13377. p.x = nru;
  13378. p.y = nrv;
  13379. }
  13380. else if (index < rsub2) {
  13381. p.x = nru;
  13382. p.y = 1.0 - nrv;
  13383. }
  13384. else {
  13385. p.x = 1.0 - nru;
  13386. p.y = 1.0 - nrv;
  13387. }
  13388. var angle = twopi - (index * twopi / (subDiv - 0.5));
  13389. p.x += Math.cos(angle) * nru;
  13390. p.y += Math.sin(angle) * nrv;
  13391. p.x *= w;
  13392. p.y *= h;
  13393. };
  13394. console.log("Genetre TriList for " + this.id);
  13395. var first = BABYLON.Vector2.Zero();
  13396. var cur = BABYLON.Vector2.Zero();
  13397. computePos(0, first);
  13398. var prev = first.clone();
  13399. for (var index = 1; index < subDiv; index++) {
  13400. computePos(index, cur);
  13401. this._primTriArray.storeTriangle(index - 1, center, prev, cur);
  13402. console.log(index - 1 + ", " + center + ", " + prev + ", " + cur);
  13403. prev.copyFrom(cur);
  13404. }
  13405. this._primTriArray.storeTriangle(subDiv - 1, center, first, prev);
  13406. console.log(subDiv - 1 + ", " + center + ", " + prev + ", " + first);
  13407. };
  13408. Rectangle2D.prototype.setupModelRenderCache = function (modelRenderCache) {
  13409. var renderCache = modelRenderCache;
  13410. var engine = this.owner.engine;
  13411. // Need to create WebGL resources for fill part?
  13412. if (this.fill) {
  13413. var vbSize = ((this.notRounded ? 1 : Rectangle2D_1.roundSubdivisions) * 4) + 1;
  13414. var vb = new Float32Array(vbSize);
  13415. for (var i = 0; i < vbSize; i++) {
  13416. vb[i] = i;
  13417. }
  13418. renderCache.fillVB = engine.createVertexBuffer(vb);
  13419. var triCount = vbSize - 1;
  13420. var ib = new Float32Array(triCount * 3);
  13421. for (var i = 0; i < triCount; i++) {
  13422. ib[i * 3 + 0] = 0;
  13423. ib[i * 3 + 2] = i + 1;
  13424. ib[i * 3 + 1] = i + 2;
  13425. }
  13426. ib[triCount * 3 - 2] = 1;
  13427. renderCache.fillIB = engine.createIndexBuffer(ib);
  13428. renderCache.fillIndicesCount = triCount * 3;
  13429. // Get the instanced version of the effect, if the engine does not support it, null is return and we'll only draw on by one
  13430. var ei = this.getDataPartEffectInfo(BABYLON.Shape2D.SHAPE2D_FILLPARTID, ["index"], null, true);
  13431. if (ei) {
  13432. renderCache.effectFillInstanced = engine.createEffect("rect2d", ei.attributes, ei.uniforms, [], ei.defines, null);
  13433. }
  13434. // Get the non instanced version
  13435. ei = this.getDataPartEffectInfo(BABYLON.Shape2D.SHAPE2D_FILLPARTID, ["index"], null, false);
  13436. renderCache.effectFill = engine.createEffect("rect2d", ei.attributes, ei.uniforms, [], ei.defines, null);
  13437. }
  13438. // Need to create WebGL resource for border part?
  13439. if (this.border) {
  13440. var vbSize = (this.notRounded ? 1 : Rectangle2D_1.roundSubdivisions) * 4 * 2;
  13441. var vb = new Float32Array(vbSize);
  13442. for (var i = 0; i < vbSize; i++) {
  13443. vb[i] = i;
  13444. }
  13445. renderCache.borderVB = engine.createVertexBuffer(vb);
  13446. var triCount = vbSize;
  13447. var rs = triCount / 2;
  13448. var ib = new Float32Array(triCount * 3);
  13449. for (var i = 0; i < rs; i++) {
  13450. var r0 = i;
  13451. var r1 = (i + 1) % rs;
  13452. ib[i * 6 + 0] = rs + r1;
  13453. ib[i * 6 + 1] = rs + r0;
  13454. ib[i * 6 + 2] = r0;
  13455. ib[i * 6 + 3] = r1;
  13456. ib[i * 6 + 4] = rs + r1;
  13457. ib[i * 6 + 5] = r0;
  13458. }
  13459. renderCache.borderIB = engine.createIndexBuffer(ib);
  13460. renderCache.borderIndicesCount = triCount * 3;
  13461. // Get the instanced version of the effect, if the engine does not support it, null is return and we'll only draw on by one
  13462. var ei = this.getDataPartEffectInfo(BABYLON.Shape2D.SHAPE2D_BORDERPARTID, ["index"], null, true);
  13463. if (ei) {
  13464. renderCache.effectBorderInstanced = engine.createEffect("rect2d", ei.attributes, ei.uniforms, [], ei.defines, null);
  13465. }
  13466. // Get the non instanced version
  13467. ei = this.getDataPartEffectInfo(BABYLON.Shape2D.SHAPE2D_BORDERPARTID, ["index"], null, false);
  13468. renderCache.effectBorder = engine.createEffect("rect2d", ei.attributes, ei.uniforms, [], ei.defines, null);
  13469. }
  13470. return renderCache;
  13471. };
  13472. // We override this method because if there's a roundRadius set, we will reduce the initial Content Area to make sure the computed area won't intersect with the shape contour. The formula is simple: we shrink the incoming size by the amount of the roundRadius
  13473. Rectangle2D.prototype._getInitialContentAreaToRef = function (primSize, initialContentPosition, initialContentArea) {
  13474. // Fall back to default implementation if there's no round Radius
  13475. if (this._notRounded) {
  13476. _super.prototype._getInitialContentAreaToRef.call(this, primSize, initialContentPosition, initialContentArea);
  13477. }
  13478. else {
  13479. var rr = Math.round((this.roundRadius - (this.roundRadius / Math.sqrt(2))) * 1.3);
  13480. initialContentPosition.x = initialContentPosition.y = rr;
  13481. initialContentArea.width = Math.max(0, primSize.width - (rr * 2));
  13482. initialContentArea.height = Math.max(0, primSize.height - (rr * 2));
  13483. initialContentPosition.z = primSize.width - (initialContentPosition.x + initialContentArea.width);
  13484. initialContentPosition.w = primSize.height - (initialContentPosition.y + initialContentArea.height);
  13485. }
  13486. };
  13487. Rectangle2D.prototype._getActualSizeFromContentToRef = function (primSize, paddingOffset, newPrimSize) {
  13488. // Fall back to default implementation if there's no round Radius
  13489. if (this._notRounded) {
  13490. _super.prototype._getActualSizeFromContentToRef.call(this, primSize, paddingOffset, newPrimSize);
  13491. }
  13492. else {
  13493. var rr = Math.round((this.roundRadius - (this.roundRadius / Math.sqrt(2))) * 1.3);
  13494. newPrimSize.copyFrom(primSize);
  13495. newPrimSize.width += rr * 2;
  13496. newPrimSize.height += rr * 2;
  13497. paddingOffset.x += rr;
  13498. paddingOffset.y += rr;
  13499. paddingOffset.z += rr;
  13500. paddingOffset.w += rr;
  13501. }
  13502. };
  13503. Rectangle2D.prototype.createInstanceDataParts = function () {
  13504. var res = new Array();
  13505. if (this.border) {
  13506. res.push(new Rectangle2DInstanceData(BABYLON.Shape2D.SHAPE2D_BORDERPARTID));
  13507. }
  13508. if (this.fill) {
  13509. res.push(new Rectangle2DInstanceData(BABYLON.Shape2D.SHAPE2D_FILLPARTID));
  13510. }
  13511. return res;
  13512. };
  13513. Rectangle2D.prototype.refreshInstanceDataPart = function (part) {
  13514. if (!_super.prototype.refreshInstanceDataPart.call(this, part)) {
  13515. return false;
  13516. }
  13517. //let s = Rectangle2D._riv0;
  13518. //this.getActualGlobalScaleToRef(s);
  13519. if (part.id === BABYLON.Shape2D.SHAPE2D_BORDERPARTID) {
  13520. var d = part;
  13521. var size = this.actualSize;
  13522. d.properties = new BABYLON.Vector3(size.width /* * s.x*/, size.height /* * s.y*/, this.roundRadius || 0);
  13523. }
  13524. else if (part.id === BABYLON.Shape2D.SHAPE2D_FILLPARTID) {
  13525. var d = part;
  13526. var size = this.actualSize;
  13527. d.properties = new BABYLON.Vector3(size.width /* * s.x*/, size.height /* * s.y*/, this.roundRadius || 0);
  13528. }
  13529. return true;
  13530. };
  13531. return Rectangle2D;
  13532. }(BABYLON.Shape2D));
  13533. Rectangle2D._i0 = BABYLON.Vector2.Zero();
  13534. Rectangle2D._i1 = BABYLON.Vector2.Zero();
  13535. Rectangle2D._i2 = BABYLON.Vector2.Zero();
  13536. Rectangle2D.roundSubdivisions = 16;
  13537. Rectangle2D._riv0 = new BABYLON.Vector2(0, 0);
  13538. __decorate([
  13539. BABYLON.modelLevelProperty(BABYLON.Shape2D.SHAPE2D_PROPCOUNT + 2, function (pi) { return Rectangle2D_1.notRoundedProperty = pi; })
  13540. /**
  13541. * Get if the rectangle is notRound (returns true) or rounded (returns false).
  13542. * Don't use the setter, it's for internal purpose only
  13543. */
  13544. ], Rectangle2D.prototype, "notRounded", null);
  13545. __decorate([
  13546. BABYLON.instanceLevelProperty(BABYLON.Shape2D.SHAPE2D_PROPCOUNT + 3, function (pi) { return Rectangle2D_1.roundRadiusProperty = pi; })
  13547. /**
  13548. * Get/set the round Radius, a value of 0 for a sharp edges rectangle, otherwise the value will be used as the diameter of the round to apply on corder. The Rectangle2D.notRounded property will be updated accordingly.
  13549. */
  13550. ], Rectangle2D.prototype, "roundRadius", null);
  13551. Rectangle2D = Rectangle2D_1 = __decorate([
  13552. BABYLON.className("Rectangle2D", "BABYLON")
  13553. /**
  13554. * The Rectangle Primitive type
  13555. */
  13556. ], Rectangle2D);
  13557. BABYLON.Rectangle2D = Rectangle2D;
  13558. var Rectangle2D_1;
  13559. })(BABYLON || (BABYLON = {}));
  13560. var __extends = (this && this.__extends) || (function () {
  13561. var extendStatics = Object.setPrototypeOf ||
  13562. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  13563. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  13564. return function (d, b) {
  13565. extendStatics(d, b);
  13566. function __() { this.constructor = d; }
  13567. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  13568. };
  13569. })();
  13570. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  13571. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  13572. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  13573. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  13574. return c > 3 && r && Object.defineProperty(target, key, r), r;
  13575. };
  13576. var BABYLON;
  13577. (function (BABYLON) {
  13578. var Ellipse2DRenderCache = (function (_super) {
  13579. __extends(Ellipse2DRenderCache, _super);
  13580. function Ellipse2DRenderCache(engine, modelKey) {
  13581. var _this = _super.call(this, engine, modelKey) || this;
  13582. _this.effectsReady = false;
  13583. _this.fillVB = null;
  13584. _this.fillIB = null;
  13585. _this.fillIndicesCount = 0;
  13586. _this.instancingFillAttributes = null;
  13587. _this.effectFillInstanced = null;
  13588. _this.effectFill = null;
  13589. _this.borderVB = null;
  13590. _this.borderIB = null;
  13591. _this.borderIndicesCount = 0;
  13592. _this.instancingBorderAttributes = null;
  13593. _this.effectBorderInstanced = null;
  13594. _this.effectBorder = null;
  13595. return _this;
  13596. }
  13597. Ellipse2DRenderCache.prototype.render = function (instanceInfo, context) {
  13598. // Do nothing if the shader is still loading/preparing
  13599. if (!this.effectsReady) {
  13600. if ((this.effectFill && (!this.effectFill.isReady() || (this.effectFillInstanced && !this.effectFillInstanced.isReady()))) ||
  13601. (this.effectBorder && (!this.effectBorder.isReady() || (this.effectBorderInstanced && !this.effectBorderInstanced.isReady())))) {
  13602. return false;
  13603. }
  13604. this.effectsReady = true;
  13605. }
  13606. var canvas = instanceInfo.owner.owner;
  13607. var engine = canvas.engine;
  13608. var depthFunction = 0;
  13609. if (this.effectFill && this.effectBorder) {
  13610. depthFunction = engine.getDepthFunction();
  13611. engine.setDepthFunctionToLessOrEqual();
  13612. }
  13613. var curAlphaMode = engine.getAlphaMode();
  13614. if (this.effectFill) {
  13615. var partIndex = instanceInfo.partIndexFromId.get(BABYLON.Shape2D.SHAPE2D_FILLPARTID.toString());
  13616. var pid = context.groupInfoPartData[partIndex];
  13617. if (context.renderMode !== BABYLON.Render2DContext.RenderModeOpaque) {
  13618. engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE, true);
  13619. }
  13620. var effect = context.useInstancing ? this.effectFillInstanced : this.effectFill;
  13621. engine.enableEffect(effect);
  13622. engine.bindBuffersDirectly(this.fillVB, this.fillIB, [1], 4, effect);
  13623. if (context.useInstancing) {
  13624. if (!this.instancingFillAttributes) {
  13625. this.instancingFillAttributes = this.loadInstancingAttributes(BABYLON.Shape2D.SHAPE2D_FILLPARTID, effect);
  13626. }
  13627. var glBuffer = context.instancedBuffers ? context.instancedBuffers[partIndex] : pid._partBuffer;
  13628. var count = context.instancedBuffers ? context.instancesCount : pid._partData.usedElementCount;
  13629. canvas._addDrawCallCount(1, context.renderMode);
  13630. engine.updateAndBindInstancesBuffer(glBuffer, null, this.instancingFillAttributes);
  13631. engine.draw(true, 0, this.fillIndicesCount, count);
  13632. engine.unbindInstanceAttributes();
  13633. }
  13634. else {
  13635. canvas._addDrawCallCount(context.partDataEndIndex - context.partDataStartIndex, context.renderMode);
  13636. for (var i = context.partDataStartIndex; i < context.partDataEndIndex; i++) {
  13637. this.setupUniforms(effect, partIndex, pid._partData, i);
  13638. engine.draw(true, 0, this.fillIndicesCount);
  13639. }
  13640. }
  13641. }
  13642. if (this.effectBorder) {
  13643. var partIndex = instanceInfo.partIndexFromId.get(BABYLON.Shape2D.SHAPE2D_BORDERPARTID.toString());
  13644. var pid = context.groupInfoPartData[partIndex];
  13645. if (context.renderMode !== BABYLON.Render2DContext.RenderModeOpaque) {
  13646. engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE, true);
  13647. }
  13648. var effect = context.useInstancing ? this.effectBorderInstanced : this.effectBorder;
  13649. engine.enableEffect(effect);
  13650. engine.bindBuffersDirectly(this.borderVB, this.borderIB, [1], 4, effect);
  13651. if (context.useInstancing) {
  13652. if (!this.instancingBorderAttributes) {
  13653. this.instancingBorderAttributes = this.loadInstancingAttributes(BABYLON.Shape2D.SHAPE2D_BORDERPARTID, effect);
  13654. }
  13655. var glBuffer = context.instancedBuffers ? context.instancedBuffers[partIndex] : pid._partBuffer;
  13656. var count = context.instancedBuffers ? context.instancesCount : pid._partData.usedElementCount;
  13657. canvas._addDrawCallCount(1, context.renderMode);
  13658. engine.updateAndBindInstancesBuffer(glBuffer, null, this.instancingBorderAttributes);
  13659. engine.draw(true, 0, this.borderIndicesCount, count);
  13660. engine.unbindInstanceAttributes();
  13661. }
  13662. else {
  13663. canvas._addDrawCallCount(context.partDataEndIndex - context.partDataStartIndex, context.renderMode);
  13664. for (var i = context.partDataStartIndex; i < context.partDataEndIndex; i++) {
  13665. this.setupUniforms(effect, partIndex, pid._partData, i);
  13666. engine.draw(true, 0, this.borderIndicesCount);
  13667. }
  13668. }
  13669. }
  13670. engine.setAlphaMode(curAlphaMode, true);
  13671. if (this.effectFill && this.effectBorder) {
  13672. engine.setDepthFunction(depthFunction);
  13673. }
  13674. return true;
  13675. };
  13676. Ellipse2DRenderCache.prototype.dispose = function () {
  13677. if (!_super.prototype.dispose.call(this)) {
  13678. return false;
  13679. }
  13680. if (this.fillVB) {
  13681. this._engine._releaseBuffer(this.fillVB);
  13682. this.fillVB = null;
  13683. }
  13684. if (this.fillIB) {
  13685. this._engine._releaseBuffer(this.fillIB);
  13686. this.fillIB = null;
  13687. }
  13688. this.effectFill = null;
  13689. this.effectFillInstanced = null;
  13690. this.effectBorder = null;
  13691. this.effectBorderInstanced = null;
  13692. if (this.borderVB) {
  13693. this._engine._releaseBuffer(this.borderVB);
  13694. this.borderVB = null;
  13695. }
  13696. if (this.borderIB) {
  13697. this._engine._releaseBuffer(this.borderIB);
  13698. this.borderIB = null;
  13699. }
  13700. return true;
  13701. };
  13702. return Ellipse2DRenderCache;
  13703. }(BABYLON.ModelRenderCache));
  13704. BABYLON.Ellipse2DRenderCache = Ellipse2DRenderCache;
  13705. var Ellipse2DInstanceData = (function (_super) {
  13706. __extends(Ellipse2DInstanceData, _super);
  13707. function Ellipse2DInstanceData(partId) {
  13708. return _super.call(this, partId, 1) || this;
  13709. }
  13710. Object.defineProperty(Ellipse2DInstanceData.prototype, "properties", {
  13711. get: function () {
  13712. return null;
  13713. },
  13714. set: function (value) {
  13715. },
  13716. enumerable: true,
  13717. configurable: true
  13718. });
  13719. return Ellipse2DInstanceData;
  13720. }(BABYLON.Shape2DInstanceData));
  13721. __decorate([
  13722. BABYLON.instanceData()
  13723. ], Ellipse2DInstanceData.prototype, "properties", null);
  13724. BABYLON.Ellipse2DInstanceData = Ellipse2DInstanceData;
  13725. var Ellipse2D = Ellipse2D_1 = (function (_super) {
  13726. __extends(Ellipse2D, _super);
  13727. /**
  13728. * Create an Ellipse 2D Shape primitive
  13729. * @param settings a combination of settings, possible ones are
  13730. * - parent: the parent primitive/canvas, must be specified if the primitive is not constructed as a child of another one (i.e. as part of the children array setting)
  13731. * - children: an array of direct children
  13732. * - id: a text identifier, for information purpose
  13733. * - position: the X & Y positions relative to its parent. Alternatively the x and y properties can be set. Default is [0;0]
  13734. * - rotation: the initial rotation (in radian) of the primitive. default is 0
  13735. * - scale: the initial scale of the primitive. default is 1. You can alternatively use scaleX &| scaleY to apply non uniform scale
  13736. * - dontInheritParentScale: if set the parent's scale won't be taken into consideration to compute the actualScale property
  13737. * - alignToPixel: if true the primitive will be aligned to the target rendering device's pixel
  13738. * - opacity: set the overall opacity of the primitive, 1 to be opaque (default), less than 1 to be transparent.
  13739. * - zOrder: override the zOrder with the specified value
  13740. * - origin: define the normalized origin point location, default [0.5;0.5]
  13741. * - size: the size of the group. Alternatively the width and height properties can be set. Default will be [10;10].
  13742. * - subdivision: the number of subdivision to create the ellipse perimeter, default is 64.
  13743. * - fill: the brush used to draw the fill content of the ellipse, you can set null to draw nothing (but you will have to set a border brush), default is a SolidColorBrush of plain white. can also be a string value (see Canvas2D.GetBrushFromString)
  13744. * - border: the brush used to draw the border of the ellipse, you can set null to draw nothing (but you will have to set a fill brush), default is null. can be a string value (see Canvas2D.GetBrushFromString)
  13745. * - borderThickness: the thickness of the drawn border, default is 1.
  13746. * - isVisible: true if the group must be visible, false for hidden. Default is true.
  13747. * - isPickable: if true the Primitive can be used with interaction mode and will issue Pointer Event. If false it will be ignored for interaction/intersection test. Default value is true.
  13748. * - isContainer: if true the Primitive acts as a container for interaction, if the primitive is not pickable or doesn't intersection, no further test will be perform on its children. If set to false, children will always be considered for intersection/interaction. Default value is true.
  13749. * - childrenFlatZOrder: if true all the children (direct and indirect) will share the same Z-Order. Use this when there's a lot of children which don't overlap. The drawing order IS NOT GUARANTED!
  13750. * - levelCollision: this primitive is an actor of the Collision Manager and only this level will be used for collision (i.e. not the children). Use deepCollision if you want collision detection on the primitives and its children.
  13751. * - deepCollision: this primitive is an actor of the Collision Manager, this level AND ALSO its children will be used for collision (note: you don't need to set the children as level/deepCollision).
  13752. * - layoutData: a instance of a class implementing the ILayoutData interface that contain data to pass to the primitive parent's layout engine
  13753. * - marginTop: top margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  13754. * - marginLeft: left margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  13755. * - marginRight: right margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  13756. * - marginBottom: bottom margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  13757. * - margin: top, left, right and bottom margin formatted as a single string (see PrimitiveThickness.fromString)
  13758. * - marginHAlignment: one value of the PrimitiveAlignment type's static properties
  13759. * - marginVAlignment: one value of the PrimitiveAlignment type's static properties
  13760. * - marginAlignment: a string defining the alignment, see PrimitiveAlignment.fromString
  13761. * - paddingTop: top padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  13762. * - paddingLeft: left padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  13763. * - paddingRight: right padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  13764. * - paddingBottom: bottom padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  13765. * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
  13766. */
  13767. function Ellipse2D(settings) {
  13768. var _this = this;
  13769. // Avoid checking every time if the object exists
  13770. if (settings == null) {
  13771. settings = {};
  13772. }
  13773. _this = _super.call(this, settings) || this;
  13774. if (settings.size != null) {
  13775. _this.size = settings.size;
  13776. }
  13777. else if (settings.width || settings.height) {
  13778. var size = new BABYLON.Size(settings.width, settings.height);
  13779. _this.size = size;
  13780. }
  13781. var sub = (settings.subdivisions == null) ? 64 : settings.subdivisions;
  13782. _this.subdivisions = sub;
  13783. return _this;
  13784. }
  13785. Object.defineProperty(Ellipse2D.prototype, "subdivisions", {
  13786. get: function () {
  13787. return this._subdivisions;
  13788. },
  13789. set: function (value) {
  13790. this._subdivisions = value;
  13791. },
  13792. enumerable: true,
  13793. configurable: true
  13794. });
  13795. Ellipse2D.prototype.levelIntersect = function (intersectInfo) {
  13796. var w = this.size.width / 2;
  13797. var h = this.size.height / 2;
  13798. var x = intersectInfo._localPickPosition.x - w;
  13799. var y = intersectInfo._localPickPosition.y - h;
  13800. return ((x * x) / (w * w) + (y * y) / (h * h)) <= 1;
  13801. };
  13802. Ellipse2D.prototype.updateLevelBoundingInfo = function () {
  13803. BABYLON.BoundingInfo2D.CreateFromSizeToRef(this.actualSize, this._levelBoundingInfo);
  13804. return true;
  13805. };
  13806. Ellipse2D.prototype.updateTriArray = function () {
  13807. var subDiv = this._subdivisions;
  13808. if (this._primTriArray == null) {
  13809. this._primTriArray = new BABYLON.Tri2DArray(subDiv);
  13810. }
  13811. else {
  13812. this._primTriArray.clear(subDiv);
  13813. }
  13814. var size = this.actualSize;
  13815. var center = new BABYLON.Vector2(0.5 * size.width, 0.5 * size.height);
  13816. var v1 = BABYLON.Vector2.Zero();
  13817. var v2 = BABYLON.Vector2.Zero();
  13818. for (var i = 0; i < subDiv; i++) {
  13819. var angle1 = Math.PI * 2 * (i - 1) / subDiv;
  13820. var angle2 = Math.PI * 2 * i / subDiv;
  13821. v1.x = ((Math.cos(angle1) / 2.0) + 0.5) * size.width;
  13822. v1.y = ((Math.sin(angle1) / 2.0) + 0.5) * size.height;
  13823. v2.x = ((Math.cos(angle2) / 2.0) + 0.5) * size.width;
  13824. v2.y = ((Math.sin(angle2) / 2.0) + 0.5) * size.height;
  13825. this._primTriArray.storeTriangle(i, center, v1, v2);
  13826. }
  13827. };
  13828. Ellipse2D.prototype.createModelRenderCache = function (modelKey) {
  13829. var renderCache = new Ellipse2DRenderCache(this.owner.engine, modelKey);
  13830. return renderCache;
  13831. };
  13832. Ellipse2D.prototype.setupModelRenderCache = function (modelRenderCache) {
  13833. var renderCache = modelRenderCache;
  13834. var engine = this.owner.engine;
  13835. // Need to create WebGL resources for fill part?
  13836. if (this.fill) {
  13837. var vbSize = this.subdivisions + 1;
  13838. var vb = new Float32Array(vbSize);
  13839. for (var i = 0; i < vbSize; i++) {
  13840. vb[i] = i;
  13841. }
  13842. renderCache.fillVB = engine.createVertexBuffer(vb);
  13843. var triCount = vbSize - 1;
  13844. var ib = new Float32Array(triCount * 3);
  13845. for (var i = 0; i < triCount; i++) {
  13846. ib[i * 3 + 0] = 0;
  13847. ib[i * 3 + 2] = i + 2;
  13848. ib[i * 3 + 1] = i + 1;
  13849. }
  13850. ib[triCount * 3 - 1] = 1;
  13851. renderCache.fillIB = engine.createIndexBuffer(ib);
  13852. renderCache.fillIndicesCount = triCount * 3;
  13853. // Get the instanced version of the effect, if the engine does not support it, null is return and we'll only draw on by one
  13854. var ei = this.getDataPartEffectInfo(BABYLON.Shape2D.SHAPE2D_FILLPARTID, ["index"], null, true);
  13855. if (ei) {
  13856. renderCache.effectFillInstanced = engine.createEffect({ vertex: "ellipse2d", fragment: "ellipse2d" }, ei.attributes, ei.uniforms, [], ei.defines, null);
  13857. }
  13858. // Get the non instanced version
  13859. ei = this.getDataPartEffectInfo(BABYLON.Shape2D.SHAPE2D_FILLPARTID, ["index"], null, false);
  13860. renderCache.effectFill = engine.createEffect({ vertex: "ellipse2d", fragment: "ellipse2d" }, ei.attributes, ei.uniforms, [], ei.defines, null);
  13861. }
  13862. // Need to create WebGL resource for border part?
  13863. if (this.border) {
  13864. var vbSize = this.subdivisions * 2;
  13865. var vb = new Float32Array(vbSize);
  13866. for (var i = 0; i < vbSize; i++) {
  13867. vb[i] = i;
  13868. }
  13869. renderCache.borderVB = engine.createVertexBuffer(vb);
  13870. var triCount = vbSize;
  13871. var rs = triCount / 2;
  13872. var ib = new Float32Array(triCount * 3);
  13873. for (var i = 0; i < rs; i++) {
  13874. var r0 = i;
  13875. var r1 = (i + 1) % rs;
  13876. ib[i * 6 + 0] = rs + r1;
  13877. ib[i * 6 + 1] = rs + r0;
  13878. ib[i * 6 + 2] = r0;
  13879. ib[i * 6 + 3] = r1;
  13880. ib[i * 6 + 4] = rs + r1;
  13881. ib[i * 6 + 5] = r0;
  13882. }
  13883. renderCache.borderIB = engine.createIndexBuffer(ib);
  13884. renderCache.borderIndicesCount = (triCount * 3);
  13885. // Get the instanced version of the effect, if the engine does not support it, null is return and we'll only draw on by one
  13886. var ei = this.getDataPartEffectInfo(BABYLON.Shape2D.SHAPE2D_BORDERPARTID, ["index"], null, true);
  13887. if (ei) {
  13888. renderCache.effectBorderInstanced = engine.createEffect("ellipse2d", ei.attributes, ei.uniforms, [], ei.defines, null);
  13889. }
  13890. // Get the non instanced version
  13891. ei = this.getDataPartEffectInfo(BABYLON.Shape2D.SHAPE2D_BORDERPARTID, ["index"], null, false);
  13892. renderCache.effectBorder = engine.createEffect("ellipse2d", ei.attributes, ei.uniforms, [], ei.defines, null);
  13893. }
  13894. return renderCache;
  13895. };
  13896. Ellipse2D.prototype.createInstanceDataParts = function () {
  13897. var res = new Array();
  13898. if (this.border) {
  13899. res.push(new Ellipse2DInstanceData(BABYLON.Shape2D.SHAPE2D_BORDERPARTID));
  13900. }
  13901. if (this.fill) {
  13902. res.push(new Ellipse2DInstanceData(BABYLON.Shape2D.SHAPE2D_FILLPARTID));
  13903. }
  13904. return res;
  13905. };
  13906. Ellipse2D.prototype.refreshInstanceDataPart = function (part) {
  13907. if (!_super.prototype.refreshInstanceDataPart.call(this, part)) {
  13908. return false;
  13909. }
  13910. //let s = Ellipse2D._riv0;
  13911. //this.getActualGlobalScaleToRef(s);
  13912. if (part.id === BABYLON.Shape2D.SHAPE2D_BORDERPARTID) {
  13913. var d = part;
  13914. var size = this.actualSize;
  13915. d.properties = new BABYLON.Vector3(size.width /* * s.x*/, size.height /* * s.y*/, this.subdivisions);
  13916. }
  13917. else if (part.id === BABYLON.Shape2D.SHAPE2D_FILLPARTID) {
  13918. var d = part;
  13919. var size = this.actualSize;
  13920. d.properties = new BABYLON.Vector3(size.width /* * s.x*/, size.height /* * s.y*/, this.subdivisions);
  13921. }
  13922. return true;
  13923. };
  13924. return Ellipse2D;
  13925. }(BABYLON.Shape2D));
  13926. Ellipse2D._riv0 = new BABYLON.Vector2(0, 0);
  13927. __decorate([
  13928. BABYLON.modelLevelProperty(BABYLON.Shape2D.SHAPE2D_PROPCOUNT + 2, function (pi) { return Ellipse2D_1.subdivisionsProperty = pi; })
  13929. /**
  13930. * Get/set the number of subdivisions used to draw the ellipsis. Default is 64.
  13931. */
  13932. ], Ellipse2D.prototype, "subdivisions", null);
  13933. Ellipse2D = Ellipse2D_1 = __decorate([
  13934. BABYLON.className("Ellipse2D", "BABYLON")
  13935. /**
  13936. * Ellipse Primitive class
  13937. */
  13938. ], Ellipse2D);
  13939. BABYLON.Ellipse2D = Ellipse2D;
  13940. var Ellipse2D_1;
  13941. })(BABYLON || (BABYLON = {}));
  13942. var __extends = (this && this.__extends) || (function () {
  13943. var extendStatics = Object.setPrototypeOf ||
  13944. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  13945. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  13946. return function (d, b) {
  13947. extendStatics(d, b);
  13948. function __() { this.constructor = d; }
  13949. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  13950. };
  13951. })();
  13952. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  13953. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  13954. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  13955. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  13956. return c > 3 && r && Object.defineProperty(target, key, r), r;
  13957. };
  13958. var BABYLON;
  13959. (function (BABYLON) {
  13960. var Sprite2DRenderCache = (function (_super) {
  13961. __extends(Sprite2DRenderCache, _super);
  13962. function Sprite2DRenderCache() {
  13963. var _this = _super !== null && _super.apply(this, arguments) || this;
  13964. _this.effectsReady = false;
  13965. _this.vb = null;
  13966. _this.ib = null;
  13967. _this.instancingAttributes = null;
  13968. _this.texture = null;
  13969. _this.effect = null;
  13970. _this.effectInstanced = null;
  13971. return _this;
  13972. }
  13973. Sprite2DRenderCache.prototype.render = function (instanceInfo, context) {
  13974. // Do nothing if the shader is still loading/preparing
  13975. if (!this.effectsReady) {
  13976. if ((this.effect && (!this.effect.isReady() || (this.effectInstanced && !this.effectInstanced.isReady())))) {
  13977. return false;
  13978. }
  13979. this.effectsReady = true;
  13980. }
  13981. // Compute the offset locations of the attributes in the vertex shader that will be mapped to the instance buffer data
  13982. var canvas = instanceInfo.owner.owner;
  13983. var engine = canvas.engine;
  13984. var cur = engine.getAlphaMode();
  13985. var effect = context.useInstancing ? this.effectInstanced : this.effect;
  13986. engine.enableEffect(effect);
  13987. effect.setTexture("diffuseSampler", this.texture);
  13988. engine.bindBuffersDirectly(this.vb, this.ib, [1], 4, effect);
  13989. if (context.renderMode !== BABYLON.Render2DContext.RenderModeOpaque) {
  13990. engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE, true);
  13991. }
  13992. effect.setBool("alphaTest", context.renderMode === BABYLON.Render2DContext.RenderModeAlphaTest);
  13993. var pid = context.groupInfoPartData[0];
  13994. if (context.useInstancing) {
  13995. if (!this.instancingAttributes) {
  13996. this.instancingAttributes = this.loadInstancingAttributes(Sprite2D.SPRITE2D_MAINPARTID, effect);
  13997. }
  13998. var glBuffer = context.instancedBuffers ? context.instancedBuffers[0] : pid._partBuffer;
  13999. var count = context.instancedBuffers ? context.instancesCount : pid._partData.usedElementCount;
  14000. canvas._addDrawCallCount(1, context.renderMode);
  14001. engine.updateAndBindInstancesBuffer(glBuffer, null, this.instancingAttributes);
  14002. engine.draw(true, 0, 6, count);
  14003. engine.unbindInstanceAttributes();
  14004. }
  14005. else {
  14006. canvas._addDrawCallCount(context.partDataEndIndex - context.partDataStartIndex, context.renderMode);
  14007. for (var i = context.partDataStartIndex; i < context.partDataEndIndex; i++) {
  14008. this.setupUniforms(effect, 0, pid._partData, i);
  14009. engine.draw(true, 0, 6);
  14010. }
  14011. }
  14012. engine.setAlphaMode(cur, true);
  14013. return true;
  14014. };
  14015. Sprite2DRenderCache.prototype.dispose = function () {
  14016. if (!_super.prototype.dispose.call(this)) {
  14017. return false;
  14018. }
  14019. if (this.vb) {
  14020. this._engine._releaseBuffer(this.vb);
  14021. this.vb = null;
  14022. }
  14023. if (this.ib) {
  14024. this._engine._releaseBuffer(this.ib);
  14025. this.ib = null;
  14026. }
  14027. //if (this.texture) {
  14028. // this.texture.dispose();
  14029. // this.texture = null;
  14030. //}
  14031. this.effect = null;
  14032. this.effectInstanced = null;
  14033. return true;
  14034. };
  14035. return Sprite2DRenderCache;
  14036. }(BABYLON.ModelRenderCache));
  14037. BABYLON.Sprite2DRenderCache = Sprite2DRenderCache;
  14038. var Sprite2D = Sprite2D_1 = (function (_super) {
  14039. __extends(Sprite2D, _super);
  14040. /**
  14041. * Create an 2D Sprite primitive
  14042. * @param texture the texture that stores the sprite to render
  14043. * @param settings a combination of settings, possible ones are
  14044. * - parent: the parent primitive/canvas, must be specified if the primitive is not constructed as a child of another one (i.e. as part of the children array setting)
  14045. * - children: an array of direct children
  14046. * - id a text identifier, for information purpose
  14047. * - position: the X & Y positions relative to its parent. Alternatively the x and y properties can be set. Default is [0;0]
  14048. * - rotation: the initial rotation (in radian) of the primitive. default is 0
  14049. * - scale: the initial scale of the primitive. default is 1. You can alternatively use scaleX &| scaleY to apply non uniform scale
  14050. * - size: the size of the sprite displayed in the canvas, if not specified the spriteSize will be used
  14051. * - dontInheritParentScale: if set the parent's scale won't be taken into consideration to compute the actualScale property
  14052. * - alignToPixel: if true the sprite's texels will be aligned to the rendering viewport pixels, ensuring the best rendering quality but slow animations won't be done as smooth as if you set false. If false a texel could lies between two pixels, being blended by the texture sampling mode you choose, the rendering result won't be as good, but very slow animation will be overall better looking. Default is true: content will be aligned.
  14053. * - opacity: set the overall opacity of the primitive, 1 to be opaque (default), less than 1 to be transparent.
  14054. * - zOrder: override the zOrder with the specified value
  14055. * - origin: define the normalized origin point location, default [0.5;0.5]
  14056. * - spriteSize: the size of the sprite (in pixels) as it is stored in the texture, if null the size of the given texture will be used, default is null.
  14057. * - spriteLocation: the location (in pixels) in the texture of the top/left corner of the Sprite to display, default is null (0,0)
  14058. * - scale9: draw the sprite as a Scale9 sprite, see http://yannickloriot.com/2013/03/9-patch-technique-in-cocos2d/ for more info. x, y, w, z are left, bottom, right, top coordinate of the resizable box
  14059. * - invertY: if true the texture Y will be inverted, default is false.
  14060. * - isVisible: true if the sprite must be visible, false for hidden. Default is true.
  14061. * - isPickable: if true the Primitive can be used with interaction mode and will issue Pointer Event. If false it will be ignored for interaction/intersection test. Default value is true.
  14062. * - isContainer: if true the Primitive acts as a container for interaction, if the primitive is not pickable or doesn't intersection, no further test will be perform on its children. If set to false, children will always be considered for intersection/interaction. Default value is true.
  14063. * - childrenFlatZOrder: if true all the children (direct and indirect) will share the same Z-Order. Use this when there's a lot of children which don't overlap. The drawing order IS NOT GUARANTED!
  14064. * - levelCollision: this primitive is an actor of the Collision Manager and only this level will be used for collision (i.e. not the children). Use deepCollision if you want collision detection on the primitives and its children.
  14065. * - deepCollision: this primitive is an actor of the Collision Manager, this level AND ALSO its children will be used for collision (note: you don't need to set the children as level/deepCollision).
  14066. * - layoutData: a instance of a class implementing the ILayoutData interface that contain data to pass to the primitive parent's layout engine
  14067. * - marginTop: top margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  14068. * - marginLeft: left margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  14069. * - marginRight: right margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  14070. * - marginBottom: bottom margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  14071. * - margin: top, left, right and bottom margin formatted as a single string (see PrimitiveThickness.fromString)
  14072. * - marginHAlignment: one value of the PrimitiveAlignment type's static properties
  14073. * - marginVAlignment: one value of the PrimitiveAlignment type's static properties
  14074. * - marginAlignment: a string defining the alignment, see PrimitiveAlignment.fromString
  14075. * - paddingTop: top padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  14076. * - paddingLeft: left padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  14077. * - paddingRight: right padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  14078. * - paddingBottom: bottom padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  14079. * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
  14080. */
  14081. function Sprite2D(texture, settings) {
  14082. var _this = this;
  14083. if (!settings) {
  14084. settings = {};
  14085. }
  14086. _this = _super.call(this, settings) || this;
  14087. _this.texture = texture;
  14088. // This is removed to let the user the possibility to setup the addressing mode he wants
  14089. //this.texture.wrapU = Texture.CLAMP_ADDRESSMODE;
  14090. //this.texture.wrapV = Texture.CLAMP_ADDRESSMODE;
  14091. _this._useSize = false;
  14092. _this._spriteSize = (settings.spriteSize != null) ? settings.spriteSize.clone() : null;
  14093. _this._spriteLocation = (settings.spriteLocation != null) ? settings.spriteLocation.clone() : new BABYLON.Vector2(0, 0);
  14094. if (settings.size != null) {
  14095. _this.size = settings.size;
  14096. }
  14097. _this._updatePositioningState();
  14098. _this.spriteFrame = 0;
  14099. _this.invertY = (settings.invertY == null) ? false : settings.invertY;
  14100. _this.alignToPixel = (settings.alignToPixel == null) ? true : settings.alignToPixel;
  14101. _this.useAlphaFromTexture = true;
  14102. _this._scale9 = (settings.scale9 != null) ? settings.scale9.clone() : null;
  14103. // If the user doesn't set a size, we'll use the texture's one, but if the texture is not loading, we HAVE to set a temporary dummy size otherwise the positioning engine will switch the marginAlignement to stretch/stretch, and WE DON'T WANT THAT.
  14104. // The fucking delayed texture sprite bug is fixed!
  14105. if (settings.spriteSize == null) {
  14106. _this.spriteSize = new BABYLON.Size(10, 10);
  14107. }
  14108. if (settings.spriteSize == null || !texture.isReady()) {
  14109. if (texture.isReady()) {
  14110. var s = texture.getBaseSize();
  14111. _this.spriteSize = new BABYLON.Size(s.width, s.height);
  14112. _this._updateSpriteScaleFactor();
  14113. }
  14114. else {
  14115. texture.onLoadObservable.add(function () {
  14116. if (settings.spriteSize == null) {
  14117. var s = texture.getBaseSize();
  14118. _this.spriteSize = new BABYLON.Size(s.width, s.height);
  14119. }
  14120. _this._updateSpriteScaleFactor();
  14121. _this._positioningDirty();
  14122. _this._setLayoutDirty();
  14123. _this._instanceDirtyFlags |= BABYLON.Prim2DBase.originProperty.flagId | Sprite2D_1.textureProperty.flagId; // To make sure the sprite is issued again for render
  14124. });
  14125. }
  14126. }
  14127. return _this;
  14128. }
  14129. Object.defineProperty(Sprite2D.prototype, "texture", {
  14130. get: function () {
  14131. return this._texture;
  14132. },
  14133. set: function (value) {
  14134. this._texture = value;
  14135. this._oldTextureHasAlpha = this._texture && this.texture.hasAlpha;
  14136. },
  14137. enumerable: true,
  14138. configurable: true
  14139. });
  14140. Object.defineProperty(Sprite2D.prototype, "useAlphaFromTexture", {
  14141. get: function () {
  14142. return this._useAlphaFromTexture;
  14143. },
  14144. set: function (value) {
  14145. if (this._useAlphaFromTexture === value) {
  14146. return;
  14147. }
  14148. this._useAlphaFromTexture = value;
  14149. this._updateRenderMode();
  14150. },
  14151. enumerable: true,
  14152. configurable: true
  14153. });
  14154. Object.defineProperty(Sprite2D.prototype, "size", {
  14155. get: function () {
  14156. if (this._size == null) {
  14157. return this.spriteSize;
  14158. }
  14159. return this.internalGetSize();
  14160. },
  14161. set: function (value) {
  14162. this._useSize = value != null;
  14163. this.internalSetSize(value);
  14164. this._updateSpriteScaleFactor();
  14165. },
  14166. enumerable: true,
  14167. configurable: true
  14168. });
  14169. Object.defineProperty(Sprite2D.prototype, "spriteSize", {
  14170. get: function () {
  14171. return this._spriteSize;
  14172. },
  14173. set: function (value) {
  14174. if (!this._spriteSize) {
  14175. this._spriteSize = value.clone();
  14176. }
  14177. else {
  14178. this._spriteSize.copyFrom(value);
  14179. }
  14180. this._updateSpriteScaleFactor();
  14181. },
  14182. enumerable: true,
  14183. configurable: true
  14184. });
  14185. Object.defineProperty(Sprite2D.prototype, "spriteLocation", {
  14186. get: function () {
  14187. return this._spriteLocation;
  14188. },
  14189. set: function (value) {
  14190. if (!this._spriteLocation) {
  14191. this._spriteLocation = value.clone();
  14192. }
  14193. else {
  14194. this._spriteLocation.copyFrom(value);
  14195. }
  14196. },
  14197. enumerable: true,
  14198. configurable: true
  14199. });
  14200. Object.defineProperty(Sprite2D.prototype, "spriteFrame", {
  14201. get: function () {
  14202. return this._spriteFrame;
  14203. },
  14204. set: function (value) {
  14205. this._spriteFrame = value;
  14206. },
  14207. enumerable: true,
  14208. configurable: true
  14209. });
  14210. Object.defineProperty(Sprite2D.prototype, "invertY", {
  14211. get: function () {
  14212. return this._invertY;
  14213. },
  14214. set: function (value) {
  14215. this._invertY = value;
  14216. },
  14217. enumerable: true,
  14218. configurable: true
  14219. });
  14220. Object.defineProperty(Sprite2D.prototype, "isScale9", {
  14221. get: function () {
  14222. return this._scale9 !== null;
  14223. },
  14224. enumerable: true,
  14225. configurable: true
  14226. });
  14227. //@instanceLevelProperty(RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 7, pi => Sprite2D.spriteScaleFactorProperty = pi)
  14228. ///**
  14229. // * Get/set the sprite location (in pixels) in the texture
  14230. // */
  14231. //public get spriteScaleFactor(): Vector2 {
  14232. // return this._spriteScaleFactor;
  14233. //}
  14234. //public set spriteScaleFactor(value: Vector2) {
  14235. // this._spriteScaleFactor = value;
  14236. //}
  14237. Sprite2D.prototype.updateLevelBoundingInfo = function () {
  14238. BABYLON.BoundingInfo2D.CreateFromSizeToRef(this.size, this._levelBoundingInfo);
  14239. return true;
  14240. };
  14241. /**
  14242. * Get the animatable array (see http://doc.babylonjs.com/tutorials/Animations)
  14243. */
  14244. Sprite2D.prototype.getAnimatables = function () {
  14245. var res = new Array();
  14246. if (this.texture && this.texture.animations && this.texture.animations.length > 0) {
  14247. res.push(this.texture);
  14248. }
  14249. return res;
  14250. };
  14251. Sprite2D.prototype.levelIntersect = function (intersectInfo) {
  14252. // If we've made it so far it means the boundingInfo intersection test succeed, the Sprite2D is shaped the same, so we always return true
  14253. return true;
  14254. };
  14255. Object.defineProperty(Sprite2D.prototype, "isSizeAuto", {
  14256. get: function () {
  14257. return this.size == null;
  14258. },
  14259. enumerable: true,
  14260. configurable: true
  14261. });
  14262. Sprite2D.prototype.createModelRenderCache = function (modelKey) {
  14263. var renderCache = new Sprite2DRenderCache(this.owner.engine, modelKey);
  14264. return renderCache;
  14265. };
  14266. Sprite2D.prototype.setupModelRenderCache = function (modelRenderCache) {
  14267. var renderCache = modelRenderCache;
  14268. var engine = this.owner.engine;
  14269. var vb = new Float32Array(4);
  14270. for (var i = 0; i < 4; i++) {
  14271. vb[i] = i;
  14272. }
  14273. renderCache.vb = engine.createVertexBuffer(vb);
  14274. var ib = new Float32Array(6);
  14275. ib[0] = 0;
  14276. ib[1] = 2;
  14277. ib[2] = 1;
  14278. ib[3] = 0;
  14279. ib[4] = 3;
  14280. ib[5] = 2;
  14281. renderCache.ib = engine.createIndexBuffer(ib);
  14282. renderCache.texture = this.texture;
  14283. // Get the instanced version of the effect, if the engine does not support it, null is return and we'll only draw on by one
  14284. var ei = this.getDataPartEffectInfo(Sprite2D_1.SPRITE2D_MAINPARTID, ["index"], ["alphaTest"], true);
  14285. if (ei) {
  14286. renderCache.effectInstanced = engine.createEffect("sprite2d", ei.attributes, ei.uniforms, ["diffuseSampler"], ei.defines, null);
  14287. }
  14288. ei = this.getDataPartEffectInfo(Sprite2D_1.SPRITE2D_MAINPARTID, ["index"], ["alphaTest"], false);
  14289. renderCache.effect = engine.createEffect("sprite2d", ei.attributes, ei.uniforms, ["diffuseSampler"], ei.defines, null);
  14290. return renderCache;
  14291. };
  14292. Sprite2D.prototype.getUsedShaderCategories = function (dataPart) {
  14293. var cat = _super.prototype.getUsedShaderCategories.call(this, dataPart);
  14294. if (dataPart.id === Sprite2D_1.SPRITE2D_MAINPARTID) {
  14295. var useScale9 = this._scale9 != null;
  14296. if (useScale9) {
  14297. cat.push(Sprite2D_1.SHAPE2D_CATEGORY_SCALE9);
  14298. }
  14299. }
  14300. return cat;
  14301. };
  14302. Sprite2D.prototype.createInstanceDataParts = function () {
  14303. return [new Sprite2DInstanceData(Sprite2D_1.SPRITE2D_MAINPARTID)];
  14304. };
  14305. Sprite2D.prototype.beforeRefreshForLayoutConstruction = function (part) {
  14306. Sprite2D_1.layoutConstructMode = true;
  14307. };
  14308. // if obj contains something, we restore the _text property
  14309. Sprite2D.prototype.afterRefreshForLayoutConstruction = function (part, obj) {
  14310. Sprite2D_1.layoutConstructMode = false;
  14311. };
  14312. Sprite2D.prototype.refreshInstanceDataPart = function (part) {
  14313. if (!_super.prototype.refreshInstanceDataPart.call(this, part)) {
  14314. return false;
  14315. }
  14316. if (!this.texture.isReady() && !Sprite2D_1.layoutConstructMode) {
  14317. return false;
  14318. }
  14319. if (part.id === Sprite2D_1.SPRITE2D_MAINPARTID) {
  14320. var d = this._instanceDataParts[0];
  14321. if (Sprite2D_1.layoutConstructMode) {
  14322. d.topLeftUV = BABYLON.Vector2.Zero();
  14323. d.sizeUV = BABYLON.Vector2.Zero();
  14324. d.properties = BABYLON.Vector3.Zero();
  14325. d.textureSize = BABYLON.Vector2.Zero();
  14326. d.scaleFactor = BABYLON.Vector2.Zero();
  14327. if (this.isScale9) {
  14328. d.scale9 = BABYLON.Vector4.Zero();
  14329. }
  14330. }
  14331. else {
  14332. var ts = this.texture.getBaseSize();
  14333. var ss = this.spriteSize;
  14334. var sl = this.spriteLocation;
  14335. var ssf = this.actualScale;
  14336. d.topLeftUV = new BABYLON.Vector2(sl.x / ts.width, sl.y / ts.height);
  14337. var suv = new BABYLON.Vector2(ss.width / ts.width, ss.height / ts.height);
  14338. d.sizeUV = suv;
  14339. d.scaleFactor = ssf;
  14340. Sprite2D_1._prop.x = this.spriteFrame;
  14341. Sprite2D_1._prop.y = this.invertY ? 1 : 0;
  14342. Sprite2D_1._prop.z = this.alignToPixel ? 1 : 0;
  14343. d.properties = Sprite2D_1._prop;
  14344. d.textureSize = new BABYLON.Vector2(ts.width, ts.height);
  14345. var scale9 = this._scale9;
  14346. if (scale9 != null) {
  14347. var normalizedScale9 = new BABYLON.Vector4(scale9.x * suv.x / ss.width, scale9.y * suv.y / ss.height, scale9.z * suv.x / ss.width, scale9.w * suv.y / ss.height);
  14348. d.scale9 = normalizedScale9;
  14349. }
  14350. }
  14351. }
  14352. return true;
  14353. };
  14354. Sprite2D.prototype._mustUpdateInstance = function () {
  14355. var res = this._oldTextureHasAlpha !== (this.texture != null && this.texture.hasAlpha);
  14356. this._oldTextureHasAlpha = this.texture != null && this.texture.hasAlpha;
  14357. if (res) {
  14358. this._updateRenderMode();
  14359. }
  14360. return res;
  14361. };
  14362. Sprite2D.prototype._useTextureAlpha = function () {
  14363. return this.texture != null && this.texture.hasAlpha;
  14364. };
  14365. Sprite2D.prototype._shouldUseAlphaFromTexture = function () {
  14366. return this.texture != null && this.texture.hasAlpha && this.useAlphaFromTexture;
  14367. };
  14368. Sprite2D.prototype._updateSpriteScaleFactor = function () {
  14369. if (!this._useSize) {
  14370. return;
  14371. }
  14372. var sS = this.spriteSize;
  14373. var s = this.size;
  14374. if (s == null || sS == null) {
  14375. return;
  14376. }
  14377. this._postScale.x = s.width / sS.width;
  14378. this._postScale.y = s.height / sS.height;
  14379. };
  14380. return Sprite2D;
  14381. }(BABYLON.RenderablePrim2D));
  14382. Sprite2D.SPRITE2D_MAINPARTID = 1;
  14383. Sprite2D.SHAPE2D_CATEGORY_SCALE9 = "Scale9";
  14384. Sprite2D._prop = BABYLON.Vector3.Zero();
  14385. Sprite2D.layoutConstructMode = false;
  14386. __decorate([
  14387. BABYLON.modelLevelProperty(BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 1, function (pi) { return Sprite2D_1.textureProperty = pi; })
  14388. /**
  14389. * Get/set the texture that contains the sprite to display
  14390. */
  14391. ], Sprite2D.prototype, "texture", null);
  14392. __decorate([
  14393. BABYLON.dynamicLevelProperty(BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 2, function (pi) { return Sprite2D_1.useAlphaFromTextureProperty = pi; })
  14394. /**
  14395. * If true and the texture has an Alpha Channel which is used (BaseTexture.hasAlpha = true) the Sprite2d will be rendered as a Transparent Primitive, if false and the texture has an Alpha Channel which is used (BaseTexture.hasAlpha = true) the Sprite2d will be rendered as Alpha Test. If false or if the Texture has no alpha or it's not used (BaseTexture.hasAlpha = false) the Sprite2d will be rendered as an Opaque Primitive
  14396. */
  14397. ], Sprite2D.prototype, "useAlphaFromTexture", null);
  14398. __decorate([
  14399. BABYLON.instanceLevelProperty(BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 4, function (pi) { return Sprite2D_1.spriteSizeProperty = pi; }, false, true)
  14400. /**
  14401. * Get/set the sprite location (in pixels) in the texture
  14402. */
  14403. ], Sprite2D.prototype, "spriteSize", null);
  14404. __decorate([
  14405. BABYLON.instanceLevelProperty(BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 5, function (pi) { return Sprite2D_1.spriteLocationProperty = pi; })
  14406. /**
  14407. * Get/set the sprite location (in pixels) in the texture
  14408. */
  14409. ], Sprite2D.prototype, "spriteLocation", null);
  14410. __decorate([
  14411. BABYLON.instanceLevelProperty(BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 6, function (pi) { return Sprite2D_1.spriteFrameProperty = pi; })
  14412. /**
  14413. * Get/set the sprite frame to display.
  14414. * The frame number is just an offset applied horizontally, based on the sprite's width. it does not wrap, all the frames must be on the same line.
  14415. */
  14416. ], Sprite2D.prototype, "spriteFrame", null);
  14417. __decorate([
  14418. BABYLON.instanceLevelProperty(BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 7, function (pi) { return Sprite2D_1.invertYProperty = pi; })
  14419. /**
  14420. * Get/set if the sprite texture coordinates should be inverted on the Y axis
  14421. */
  14422. ], Sprite2D.prototype, "invertY", null);
  14423. __decorate([
  14424. BABYLON.modelLevelProperty(BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 8, function (pi) { return Sprite2D_1.spriteScale9Property = pi; })
  14425. /**
  14426. * Get/set the texture that contains the sprite to display
  14427. */
  14428. ], Sprite2D.prototype, "isScale9", null);
  14429. Sprite2D = Sprite2D_1 = __decorate([
  14430. BABYLON.className("Sprite2D", "BABYLON")
  14431. /**
  14432. * Primitive that displays a Sprite/Picture
  14433. */
  14434. ], Sprite2D);
  14435. BABYLON.Sprite2D = Sprite2D;
  14436. var Sprite2DInstanceData = (function (_super) {
  14437. __extends(Sprite2DInstanceData, _super);
  14438. function Sprite2DInstanceData(partId) {
  14439. return _super.call(this, partId, 1) || this;
  14440. }
  14441. Object.defineProperty(Sprite2DInstanceData.prototype, "topLeftUV", {
  14442. get: function () {
  14443. return null;
  14444. },
  14445. set: function (value) {
  14446. },
  14447. enumerable: true,
  14448. configurable: true
  14449. });
  14450. Object.defineProperty(Sprite2DInstanceData.prototype, "sizeUV", {
  14451. get: function () {
  14452. return null;
  14453. },
  14454. set: function (value) {
  14455. },
  14456. enumerable: true,
  14457. configurable: true
  14458. });
  14459. Object.defineProperty(Sprite2DInstanceData.prototype, "scaleFactor", {
  14460. get: function () {
  14461. return null;
  14462. },
  14463. set: function (value) {
  14464. },
  14465. enumerable: true,
  14466. configurable: true
  14467. });
  14468. Object.defineProperty(Sprite2DInstanceData.prototype, "textureSize", {
  14469. get: function () {
  14470. return null;
  14471. },
  14472. set: function (value) {
  14473. },
  14474. enumerable: true,
  14475. configurable: true
  14476. });
  14477. Object.defineProperty(Sprite2DInstanceData.prototype, "properties", {
  14478. // 3 floats being:
  14479. // - x: frame number to display
  14480. // - y: invertY setting
  14481. // - z: alignToPixel setting
  14482. get: function () {
  14483. return null;
  14484. },
  14485. set: function (value) {
  14486. },
  14487. enumerable: true,
  14488. configurable: true
  14489. });
  14490. Object.defineProperty(Sprite2DInstanceData.prototype, "scale9", {
  14491. get: function () {
  14492. return null;
  14493. },
  14494. set: function (value) {
  14495. },
  14496. enumerable: true,
  14497. configurable: true
  14498. });
  14499. return Sprite2DInstanceData;
  14500. }(BABYLON.InstanceDataBase));
  14501. __decorate([
  14502. BABYLON.instanceData()
  14503. ], Sprite2DInstanceData.prototype, "topLeftUV", null);
  14504. __decorate([
  14505. BABYLON.instanceData()
  14506. ], Sprite2DInstanceData.prototype, "sizeUV", null);
  14507. __decorate([
  14508. BABYLON.instanceData(Sprite2D.SHAPE2D_CATEGORY_SCALE9)
  14509. ], Sprite2DInstanceData.prototype, "scaleFactor", null);
  14510. __decorate([
  14511. BABYLON.instanceData()
  14512. ], Sprite2DInstanceData.prototype, "textureSize", null);
  14513. __decorate([
  14514. BABYLON.instanceData()
  14515. ], Sprite2DInstanceData.prototype, "properties", null);
  14516. __decorate([
  14517. BABYLON.instanceData(Sprite2D.SHAPE2D_CATEGORY_SCALE9)
  14518. ], Sprite2DInstanceData.prototype, "scale9", null);
  14519. BABYLON.Sprite2DInstanceData = Sprite2DInstanceData;
  14520. var Sprite2D_1;
  14521. })(BABYLON || (BABYLON = {}));
  14522. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  14523. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  14524. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  14525. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  14526. return c > 3 && r && Object.defineProperty(target, key, r), r;
  14527. };
  14528. var BABYLON;
  14529. (function (BABYLON) {
  14530. /**
  14531. * This class will contains information about a sub picture present in an Atlas Picture.
  14532. */
  14533. var AtlasSubPictureInfo = (function () {
  14534. function AtlasSubPictureInfo() {
  14535. }
  14536. return AtlasSubPictureInfo;
  14537. }());
  14538. BABYLON.AtlasSubPictureInfo = AtlasSubPictureInfo;
  14539. /**
  14540. * This class represent an Atlas Picture, it contains the information of all the sub pictures and the Texture that stores the bitmap.
  14541. * You get an instance of this class using methods of the AtlasPictureInfoFactory
  14542. */
  14543. var AtlasPictureInfo = (function () {
  14544. function AtlasPictureInfo() {
  14545. }
  14546. /**
  14547. * Creates many sprite from the Atlas Picture
  14548. * @param filterCallback a predicate if true is returned then the corresponding sub picture will be used to create a sprite.
  14549. * The Predicate has many parameters:
  14550. * - index: just an index incremented at each sub picture submitted for Sprite creation
  14551. * - name: the sub picture's name
  14552. * - aspi: the AtlasSubPictureInfo corresponding to the submitted sub picture
  14553. * - settings: the Sprite2D creation settings, you can alter this JSON object but BEWARE, the alterations will be kept for subsequent Sprite2D creations!
  14554. * @param spriteSettings The Sprite2D settings to use for Sprite creation, this JSON object will be passed to the filterCallback for you to alter it, if needed.
  14555. */
  14556. AtlasPictureInfo.prototype.createSprites = function (filterCallback, spriteSettings) {
  14557. var _this = this;
  14558. var res = new Array();
  14559. var index = 0;
  14560. this.subPictures.forEach(function (k, v) {
  14561. if (!filterCallback || filterCallback(index++, k, v, spriteSettings)) {
  14562. var s = _this.createSprite(k, spriteSettings);
  14563. if (s) {
  14564. res.push(s);
  14565. }
  14566. }
  14567. });
  14568. return res;
  14569. };
  14570. /**
  14571. * Create one Sprite from a sub picture
  14572. * @param subPictureName the name of the sub picture to use
  14573. * @param spriteSettings the Sprite2D settings to use for the Sprite instance creation
  14574. */
  14575. AtlasPictureInfo.prototype.createSprite = function (subPictureName, spriteSettings) {
  14576. var spi = this.subPictures.get(subPictureName);
  14577. if (!spi) {
  14578. return null;
  14579. }
  14580. if (!spriteSettings) {
  14581. spriteSettings = {};
  14582. }
  14583. var s = spriteSettings;
  14584. s.id = subPictureName;
  14585. s.spriteLocation = spi.location;
  14586. s.spriteSize = spi.size;
  14587. var sprite = new BABYLON.Sprite2D(this.texture, spriteSettings);
  14588. return sprite;
  14589. };
  14590. return AtlasPictureInfo;
  14591. }());
  14592. BABYLON.AtlasPictureInfo = AtlasPictureInfo;
  14593. /**
  14594. * This if the Factory class containing static method to create Atlas Pictures Info objects or add new loaders
  14595. */
  14596. var AtlasPictureInfoFactory = (function () {
  14597. function AtlasPictureInfoFactory() {
  14598. }
  14599. /**
  14600. * Add a custom loader
  14601. * @param fileExtension must be the file extension (without the dot) of the file that is loaded by this loader (e.g.: json)
  14602. * @param plugin the instance of the loader
  14603. */
  14604. AtlasPictureInfoFactory.addLoader = function (fileExtension, plugin) {
  14605. var a = AtlasPictureInfoFactory.plugins.getOrAddWithFactory(fileExtension.toLocaleLowerCase(), function () { return new Array(); });
  14606. a.push(plugin);
  14607. };
  14608. /**
  14609. * Load an Atlas Picture Info object from a data file at a given url and with a given texture
  14610. * @param texture the texture containing the atlas bitmap
  14611. * @param url the URL of the Atlas Info data file
  14612. * @param onLoad a callback that will be called when the AtlasPictureInfo object will be loaded and ready
  14613. * @param onError a callback that will be called in case of error
  14614. */
  14615. AtlasPictureInfoFactory.loadFromUrl = function (texture, url, onLoad, onError) {
  14616. if (onError === void 0) { onError = null; }
  14617. BABYLON.Tools.LoadFile(url, function (data) {
  14618. var ext = url.split('.').pop().split(/\#|\?/)[0];
  14619. var plugins = AtlasPictureInfoFactory.plugins.get(ext.toLocaleLowerCase());
  14620. if (!plugins) {
  14621. if (onError) {
  14622. onError("couldn't find a plugin for this file extension", -1);
  14623. }
  14624. return;
  14625. }
  14626. for (var _i = 0, plugins_1 = plugins; _i < plugins_1.length; _i++) {
  14627. var p = plugins_1[_i];
  14628. var ret = p.loadFile(data);
  14629. if (ret) {
  14630. if (ret.api) {
  14631. ret.api.texture = texture;
  14632. if (onLoad) {
  14633. onLoad(ret.api);
  14634. }
  14635. }
  14636. else if (onError) {
  14637. onError(ret.errorMsg, ret.errorCode);
  14638. }
  14639. return;
  14640. }
  14641. }
  14642. if (onError) {
  14643. onError("No plugin to load this Atlas Data file format", -1);
  14644. }
  14645. }, null, null, null, function () {
  14646. if (onError) {
  14647. onError("Couldn't load file", -1);
  14648. }
  14649. });
  14650. return null;
  14651. };
  14652. return AtlasPictureInfoFactory;
  14653. }());
  14654. AtlasPictureInfoFactory.plugins = new BABYLON.StringDictionary();
  14655. BABYLON.AtlasPictureInfoFactory = AtlasPictureInfoFactory;
  14656. // Loader class for the TexturePacker's JSON Array data format
  14657. var JSONArrayLoader = JSONArrayLoader_1 = (function () {
  14658. function JSONArrayLoader() {
  14659. }
  14660. JSONArrayLoader.prototype.loadFile = function (content) {
  14661. var errorMsg = null;
  14662. var errorCode = 0;
  14663. var root = null;
  14664. var api = null;
  14665. try {
  14666. var frames_1;
  14667. var meta = void 0;
  14668. try {
  14669. root = JSON.parse(content);
  14670. frames_1 = root.frames;
  14671. meta = root.meta;
  14672. if (!frames_1 || !meta) {
  14673. throw Error("Not a JSON Array file format");
  14674. }
  14675. }
  14676. catch (ex1) {
  14677. return null;
  14678. }
  14679. api = new AtlasPictureInfo();
  14680. api.atlasSize = new BABYLON.Size(meta.size.w, meta.size.h);
  14681. api.subPictures = new BABYLON.StringDictionary();
  14682. for (var _i = 0, frames_2 = frames_1; _i < frames_2.length; _i++) {
  14683. var f = frames_2[_i];
  14684. var aspi = new AtlasSubPictureInfo();
  14685. aspi.name = f.filename;
  14686. aspi.location = new BABYLON.Vector2(f.frame.x, api.atlasSize.height - (f.frame.y + f.frame.h));
  14687. aspi.size = new BABYLON.Size(f.frame.w, f.frame.h);
  14688. api.subPictures.add(aspi.name, aspi);
  14689. }
  14690. }
  14691. catch (ex2) {
  14692. errorMsg = "Unknown Exception: " + ex2;
  14693. errorCode = -2;
  14694. }
  14695. return { api: api, errorMsg: errorMsg, errorCode: errorCode };
  14696. };
  14697. return JSONArrayLoader;
  14698. }());
  14699. JSONArrayLoader = JSONArrayLoader_1 = __decorate([
  14700. AtlasLoaderPlugin("json", new JSONArrayLoader_1())
  14701. ], JSONArrayLoader);
  14702. /**
  14703. * Use this decorator when you declare an Atlas Loader Class for the loader to register itself automatically.
  14704. * @param fileExtension the extension of the file that the plugin is loading (there can be many plugin for the same extension)
  14705. * @param plugin an instance of the plugin class to add to the AtlasPictureInfoFactory
  14706. */
  14707. function AtlasLoaderPlugin(fileExtension, plugin) {
  14708. return function () {
  14709. AtlasPictureInfoFactory.addLoader(fileExtension, plugin);
  14710. };
  14711. }
  14712. BABYLON.AtlasLoaderPlugin = AtlasLoaderPlugin;
  14713. var JSONArrayLoader_1;
  14714. })(BABYLON || (BABYLON = {}));
  14715. var __extends = (this && this.__extends) || (function () {
  14716. var extendStatics = Object.setPrototypeOf ||
  14717. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  14718. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  14719. return function (d, b) {
  14720. extendStatics(d, b);
  14721. function __() { this.constructor = d; }
  14722. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  14723. };
  14724. })();
  14725. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  14726. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  14727. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  14728. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  14729. return c > 3 && r && Object.defineProperty(target, key, r), r;
  14730. };
  14731. var BABYLON;
  14732. (function (BABYLON) {
  14733. var Text2DRenderCache = (function (_super) {
  14734. __extends(Text2DRenderCache, _super);
  14735. function Text2DRenderCache() {
  14736. var _this = _super !== null && _super.apply(this, arguments) || this;
  14737. _this.effectsReady = false;
  14738. _this.vb = null;
  14739. _this.ib = null;
  14740. _this.instancingAttributes = null;
  14741. _this.fontTexture = null;
  14742. _this.effect = null;
  14743. _this.effectInstanced = null;
  14744. _this.fontPremulAlpha = false;
  14745. return _this;
  14746. }
  14747. Text2DRenderCache.prototype.render = function (instanceInfo, context) {
  14748. // Do nothing if the shader is still loading/preparing
  14749. if (!this.effectsReady) {
  14750. if ((this.effect && (!this.effect.isReady() || (this.effectInstanced && !this.effectInstanced.isReady())))) {
  14751. return false;
  14752. }
  14753. this.effectsReady = true;
  14754. }
  14755. var canvas = instanceInfo.owner.owner;
  14756. var engine = canvas.engine;
  14757. this.fontTexture.update();
  14758. var effect = context.useInstancing ? this.effectInstanced : this.effect;
  14759. engine.enableEffect(effect);
  14760. effect.setTexture("diffuseSampler", this.fontTexture);
  14761. engine.bindBuffersDirectly(this.vb, this.ib, [1], 4, effect);
  14762. var sdf = this.fontTexture.isSignedDistanceField;
  14763. // Enable alpha mode only if the texture is not using SDF, SDF is rendered in AlphaTest mode, which mean no alpha blend
  14764. var curAlphaMode;
  14765. if (!sdf) {
  14766. curAlphaMode = engine.getAlphaMode();
  14767. engine.setAlphaMode(this.fontPremulAlpha ? BABYLON.Engine.ALPHA_PREMULTIPLIED : BABYLON.Engine.ALPHA_COMBINE, true);
  14768. }
  14769. var pid = context.groupInfoPartData[0];
  14770. if (context.useInstancing) {
  14771. if (!this.instancingAttributes) {
  14772. this.instancingAttributes = this.loadInstancingAttributes(Text2D.TEXT2D_MAINPARTID, effect);
  14773. }
  14774. var glBuffer = context.instancedBuffers ? context.instancedBuffers[0] : pid._partBuffer;
  14775. var count = context.instancedBuffers ? context.instancesCount : pid._partData.usedElementCount;
  14776. canvas._addDrawCallCount(1, context.renderMode);
  14777. engine.updateAndBindInstancesBuffer(glBuffer, null, this.instancingAttributes);
  14778. engine.draw(true, 0, 6, count);
  14779. engine.unbindInstanceAttributes();
  14780. }
  14781. else {
  14782. canvas._addDrawCallCount(context.partDataEndIndex - context.partDataStartIndex, context.renderMode);
  14783. for (var i = context.partDataStartIndex; i < context.partDataEndIndex; i++) {
  14784. this.setupUniforms(effect, 0, pid._partData, i);
  14785. engine.draw(true, 0, 6);
  14786. }
  14787. }
  14788. if (!sdf) {
  14789. engine.setAlphaMode(curAlphaMode, true);
  14790. }
  14791. return true;
  14792. };
  14793. Text2DRenderCache.prototype.dispose = function () {
  14794. if (!_super.prototype.dispose.call(this)) {
  14795. return false;
  14796. }
  14797. if (this.vb) {
  14798. this._engine._releaseBuffer(this.vb);
  14799. this.vb = null;
  14800. }
  14801. if (this.ib) {
  14802. this._engine._releaseBuffer(this.ib);
  14803. this.ib = null;
  14804. }
  14805. if (this.fontTexture) {
  14806. this.fontTexture.decCachedFontTextureCounter();
  14807. this.fontTexture = null;
  14808. }
  14809. this.effect = null;
  14810. this.effectInstanced = null;
  14811. return true;
  14812. };
  14813. return Text2DRenderCache;
  14814. }(BABYLON.ModelRenderCache));
  14815. BABYLON.Text2DRenderCache = Text2DRenderCache;
  14816. var Text2DInstanceData = (function (_super) {
  14817. __extends(Text2DInstanceData, _super);
  14818. function Text2DInstanceData(partId, dataElementCount) {
  14819. return _super.call(this, partId, dataElementCount) || this;
  14820. }
  14821. Object.defineProperty(Text2DInstanceData.prototype, "topLeftUV", {
  14822. get: function () {
  14823. return null;
  14824. },
  14825. set: function (value) {
  14826. },
  14827. enumerable: true,
  14828. configurable: true
  14829. });
  14830. Object.defineProperty(Text2DInstanceData.prototype, "sizeUV", {
  14831. get: function () {
  14832. return null;
  14833. },
  14834. set: function (value) {
  14835. },
  14836. enumerable: true,
  14837. configurable: true
  14838. });
  14839. Object.defineProperty(Text2DInstanceData.prototype, "textureSize", {
  14840. get: function () {
  14841. return null;
  14842. },
  14843. set: function (value) {
  14844. },
  14845. enumerable: true,
  14846. configurable: true
  14847. });
  14848. Object.defineProperty(Text2DInstanceData.prototype, "color", {
  14849. get: function () {
  14850. return null;
  14851. },
  14852. set: function (value) {
  14853. },
  14854. enumerable: true,
  14855. configurable: true
  14856. });
  14857. Object.defineProperty(Text2DInstanceData.prototype, "superSampleFactor", {
  14858. get: function () {
  14859. return null;
  14860. },
  14861. set: function (value) {
  14862. },
  14863. enumerable: true,
  14864. configurable: true
  14865. });
  14866. return Text2DInstanceData;
  14867. }(BABYLON.InstanceDataBase));
  14868. __decorate([
  14869. BABYLON.instanceData()
  14870. ], Text2DInstanceData.prototype, "topLeftUV", null);
  14871. __decorate([
  14872. BABYLON.instanceData()
  14873. ], Text2DInstanceData.prototype, "sizeUV", null);
  14874. __decorate([
  14875. BABYLON.instanceData()
  14876. ], Text2DInstanceData.prototype, "textureSize", null);
  14877. __decorate([
  14878. BABYLON.instanceData()
  14879. ], Text2DInstanceData.prototype, "color", null);
  14880. __decorate([
  14881. BABYLON.instanceData()
  14882. ], Text2DInstanceData.prototype, "superSampleFactor", null);
  14883. BABYLON.Text2DInstanceData = Text2DInstanceData;
  14884. var Text2D = Text2D_1 = (function (_super) {
  14885. __extends(Text2D, _super);
  14886. /**
  14887. * Create a Text primitive
  14888. * @param text the text to display
  14889. * @param settings a combination of settings, possible ones are
  14890. * - parent: the parent primitive/canvas, must be specified if the primitive is not constructed as a child of another one (i.e. as part of the children array setting)
  14891. * - children: an array of direct children
  14892. * - id a text identifier, for information purpose
  14893. * - position: the X & Y positions relative to its parent. Alternatively the x and y properties can be set. Default is [0;0]
  14894. * - rotation: the initial rotation (in radian) of the primitive. default is 0
  14895. * - scale: the initial scale of the primitive. default is 1. You can alternatively use scaleX &| scaleY to apply non uniform scale
  14896. * - dontInheritParentScale: if set the parent's scale won't be taken into consideration to compute the actualScale property
  14897. * - alignToPixel: if true the primitive will be aligned to the target rendering device's pixel
  14898. * - opacity: set the overall opacity of the primitive, 1 to be opaque (default), less than 1 to be transparent.
  14899. * - zOrder: override the zOrder with the specified value
  14900. * - origin: define the normalized origin point location, default [0.5;0.5]
  14901. * - fontName: the name/size/style of the font to use, following the CSS notation. Default is "12pt Arial".
  14902. * - fontSuperSample: if true the text will be rendered with a superSampled font (the font is twice the given size). Use this settings if the text lies in world space or if it's scaled in.
  14903. * - signedDistanceField: if true the text will be rendered using the SignedDistanceField technique. This technique has the advantage to be rendered order independent (then much less drawing calls), but only works on font that are a little more than one pixel wide on the screen but the rendering quality is excellent whatever the font size is on the screen (which is the purpose of this technique). Outlining/Shadow is not supported right now. If you can, you should use this mode, the quality and the performances are the best. Note that fontSuperSample has no effect when this mode is on.
  14904. * - bitmapFontTexture: set a BitmapFontTexture to use instead of a fontName.
  14905. * - defaultFontColor: the color by default to apply on each letter of the text to display, default is plain white.
  14906. * - useBilinearFiltering: if true a FontTexture using Bilinear filtering will be used, if false a FontTexture using Nearest filtering will be used. If not specified then bilinear will be chosen for Signed Distance Field mode or a Text2D inside a WorldSpaceCanvas2D, otherwise nearest will be chose.
  14907. * - areaSize: the size of the area in which to display the text, default is auto-fit from text content.
  14908. * - tabulationSize: number of space character to insert when a tabulation is encountered, default is 4
  14909. * - isVisible: true if the text must be visible, false for hidden. Default is true.
  14910. * - isPickable: if true the Primitive can be used with interaction mode and will issue Pointer Event. If false it will be ignored for interaction/intersection test. Default value is true.
  14911. * - isContainer: if true the Primitive acts as a container for interaction, if the primitive is not pickable or doesn't intersection, no further test will be perform on its children. If set to false, children will always be considered for intersection/interaction. Default value is true.
  14912. * - childrenFlatZOrder: if true all the children (direct and indirect) will share the same Z-Order. Use this when there's a lot of children which don't overlap. The drawing order IS NOT GUARANTED!
  14913. * - levelCollision: this primitive is an actor of the Collision Manager and only this level will be used for collision (i.e. not the children). Use deepCollision if you want collision detection on the primitives and its children.
  14914. * - deepCollision: this primitive is an actor of the Collision Manager, this level AND ALSO its children will be used for collision (note: you don't need to set the children as level/deepCollision).
  14915. * - layoutData: a instance of a class implementing the ILayoutData interface that contain data to pass to the primitive parent's layout engine
  14916. * - marginTop: top margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  14917. * - marginLeft: left margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  14918. * - marginRight: right margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  14919. * - marginBottom: bottom margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  14920. * - margin: top, left, right and bottom margin formatted as a single string (see PrimitiveThickness.fromString)
  14921. * - marginHAlignment: one value of the PrimitiveAlignment type's static properties
  14922. * - marginVAlignment: one value of the PrimitiveAlignment type's static properties
  14923. * - marginAlignment: a string defining the alignment, see PrimitiveAlignment.fromString
  14924. * - paddingTop: top padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  14925. * - paddingLeft: left padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  14926. * - paddingRight: right padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  14927. * - paddingBottom: bottom padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  14928. * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
  14929. * - textAlignmentH: align text horizontally (Text2D.AlignLeft, Text2D.AlignCenter, Text2D.AlignRight)
  14930. * - textAlignmentV: align text vertically (Text2D.AlignTop, Text2D.AlignCenter, Text2D.AlignBottom)
  14931. * - textAlignment: a string defining the text alignment, text can be: [<h:|horizontal:><left|right|center>], [<v:|vertical:><top|bottom|center>]
  14932. * - wordWrap: if true the text will wrap inside content area
  14933. */
  14934. function Text2D(text, settings) {
  14935. var _this = this;
  14936. if (!settings) {
  14937. settings = {};
  14938. }
  14939. _this = _super.call(this, settings) || this;
  14940. if (settings.bitmapFontTexture != null) {
  14941. _this._fontTexture = settings.bitmapFontTexture;
  14942. _this._fontName = null;
  14943. _this._fontSuperSample = false;
  14944. _this._fontSDF = false;
  14945. _this._textureIsPremulAlpha = _this._fontTexture.isPremultipliedAlpha;
  14946. var ft = _this._fontTexture;
  14947. if (ft != null && !ft.isReady()) {
  14948. ft.onLoadObservable.add(function () {
  14949. _this._positioningDirty();
  14950. _this._setLayoutDirty();
  14951. _this._instanceDirtyFlags |= BABYLON.Prim2DBase.originProperty.flagId; // To make sure the Text2D is issued again for render
  14952. });
  14953. }
  14954. }
  14955. else {
  14956. _this._fontName = (settings.fontName == null) ? "12pt Arial" : settings.fontName;
  14957. _this._fontSuperSample = (settings.fontSuperSample != null && settings.fontSuperSample);
  14958. _this._fontSDF = (settings.fontSignedDistanceField != null && settings.fontSignedDistanceField);
  14959. }
  14960. _this._defaultFontColor = (settings.defaultFontColor == null) ? new BABYLON.Color4(1, 1, 1, 1) : settings.defaultFontColor.clone();
  14961. _this._tabulationSize = (settings.tabulationSize == null) ? 4 : settings.tabulationSize;
  14962. _this._textureIsPremulAlpha = true; //settings.fontTexturePremulAlpha === true;
  14963. _this._textSize = null;
  14964. _this.text = text;
  14965. if (settings.size != null) {
  14966. _this.size = settings.size;
  14967. _this._sizeSetByUser = true;
  14968. }
  14969. else {
  14970. _this.size = null;
  14971. }
  14972. _this._useBilinearFiltering = (settings.useBilinearFiltering != null) ? settings.useBilinearFiltering : null;
  14973. _this._fontBilinearFiltering = false;
  14974. // Text rendering must always be aligned to the target's pixel to ensure a good quality
  14975. _this.alignToPixel = true;
  14976. _this.textAlignmentH = (settings.textAlignmentH == null) ? Text2D_1.AlignLeft : settings.textAlignmentH;
  14977. _this.textAlignmentV = (settings.textAlignmentV == null) ? Text2D_1.AlignTop : settings.textAlignmentV;
  14978. _this.textAlignment = (settings.textAlignment == null) ? "" : settings.textAlignment;
  14979. _this._wordWrap = (settings.wordWrap == null) ? false : settings.wordWrap;
  14980. _this._updateRenderMode();
  14981. return _this;
  14982. }
  14983. Object.defineProperty(Text2D, "AlignLeft", {
  14984. /**
  14985. * Alignment is made relative to the left edge of the Content Area. Valid for horizontal alignment only.
  14986. */
  14987. get: function () { return Text2D_1._AlignLeft; },
  14988. enumerable: true,
  14989. configurable: true
  14990. });
  14991. Object.defineProperty(Text2D, "AlignTop", {
  14992. /**
  14993. * Alignment is made relative to the top edge of the Content Area. Valid for vertical alignment only.
  14994. */
  14995. get: function () { return Text2D_1._AlignTop; },
  14996. enumerable: true,
  14997. configurable: true
  14998. });
  14999. Object.defineProperty(Text2D, "AlignRight", {
  15000. /**
  15001. * Alignment is made relative to the right edge of the Content Area. Valid for horizontal alignment only.
  15002. */
  15003. get: function () { return Text2D_1._AlignRight; },
  15004. enumerable: true,
  15005. configurable: true
  15006. });
  15007. Object.defineProperty(Text2D, "AlignBottom", {
  15008. /**
  15009. * Alignment is made relative to the bottom edge of the Content Area. Valid for vertical alignment only.
  15010. */
  15011. get: function () { return Text2D_1._AlignBottom; },
  15012. enumerable: true,
  15013. configurable: true
  15014. });
  15015. Object.defineProperty(Text2D, "AlignCenter", {
  15016. /**
  15017. * Alignment is made to center the text from equal distance to the opposite edges of the Content Area
  15018. */
  15019. get: function () { return Text2D_1._AlignCenter; },
  15020. enumerable: true,
  15021. configurable: true
  15022. });
  15023. Object.defineProperty(Text2D.prototype, "fontName", {
  15024. get: function () {
  15025. return this._fontName;
  15026. },
  15027. set: function (value) {
  15028. if (this._fontName) {
  15029. throw new Error("Font Name change is not supported right now.");
  15030. }
  15031. this._fontName = value;
  15032. },
  15033. enumerable: true,
  15034. configurable: true
  15035. });
  15036. Object.defineProperty(Text2D.prototype, "defaultFontColor", {
  15037. get: function () {
  15038. return this._defaultFontColor;
  15039. },
  15040. set: function (value) {
  15041. if (!this._defaultFontColor) {
  15042. this._defaultFontColor = value.clone();
  15043. }
  15044. else {
  15045. this._defaultFontColor.copyFrom(value);
  15046. }
  15047. },
  15048. enumerable: true,
  15049. configurable: true
  15050. });
  15051. Object.defineProperty(Text2D.prototype, "text", {
  15052. get: function () {
  15053. return this._text;
  15054. },
  15055. set: function (value) {
  15056. if (!value) {
  15057. value = "";
  15058. }
  15059. this._text = value;
  15060. this._textSize = null; // A change of text will reset the TextSize which will be recomputed next time it's used
  15061. if (!this._sizeSetByUser) {
  15062. this._size = null;
  15063. this._actualSize = null;
  15064. }
  15065. this._updateCharCount();
  15066. // Trigger a textSize to for a sizeChange if necessary, which is needed for layout to recompute
  15067. var s = this.textSize;
  15068. },
  15069. enumerable: true,
  15070. configurable: true
  15071. });
  15072. Object.defineProperty(Text2D.prototype, "size", {
  15073. get: function () {
  15074. if (this._size != null) {
  15075. return this._size;
  15076. }
  15077. return this.textSize;
  15078. },
  15079. set: function (value) {
  15080. this.internalSetSize(value);
  15081. },
  15082. enumerable: true,
  15083. configurable: true
  15084. });
  15085. Object.defineProperty(Text2D.prototype, "fontSuperSample", {
  15086. get: function () {
  15087. return this._fontTexture && this._fontTexture.isSuperSampled;
  15088. },
  15089. enumerable: true,
  15090. configurable: true
  15091. });
  15092. Object.defineProperty(Text2D.prototype, "fontSignedDistanceField", {
  15093. get: function () {
  15094. return this._fontTexture && this._fontTexture.isSignedDistanceField;
  15095. },
  15096. enumerable: true,
  15097. configurable: true
  15098. });
  15099. Object.defineProperty(Text2D.prototype, "textureIsPremulAlpha", {
  15100. get: function () {
  15101. return this._textureIsPremulAlpha;
  15102. },
  15103. set: function (value) {
  15104. this._textureIsPremulAlpha = value;
  15105. },
  15106. enumerable: true,
  15107. configurable: true
  15108. });
  15109. Object.defineProperty(Text2D.prototype, "isSizeAuto", {
  15110. get: function () {
  15111. return false;
  15112. },
  15113. enumerable: true,
  15114. configurable: true
  15115. });
  15116. Object.defineProperty(Text2D.prototype, "isVerticalSizeAuto", {
  15117. get: function () {
  15118. return false;
  15119. },
  15120. enumerable: true,
  15121. configurable: true
  15122. });
  15123. Object.defineProperty(Text2D.prototype, "isHorizontalSizeAuto", {
  15124. get: function () {
  15125. return false;
  15126. },
  15127. enumerable: true,
  15128. configurable: true
  15129. });
  15130. Object.defineProperty(Text2D.prototype, "textSize", {
  15131. /**
  15132. * Get the area that bounds the text associated to the primitive
  15133. */
  15134. get: function () {
  15135. if (!this._textSize) {
  15136. if (this.owner && this._text) {
  15137. var ft = this.fontTexture;
  15138. if (ft == null) {
  15139. return Text2D_1.nullSize;
  15140. }
  15141. var newSize = ft.measureText(this._text, this._tabulationSize);
  15142. if (!newSize.equals(this._textSize)) {
  15143. this.onPrimitivePropertyDirty(BABYLON.Prim2DBase.sizeProperty.flagId);
  15144. this._positioningDirty();
  15145. }
  15146. this._textSize = newSize;
  15147. }
  15148. else {
  15149. return Text2D_1.nullSize;
  15150. }
  15151. }
  15152. return this._textSize;
  15153. },
  15154. enumerable: true,
  15155. configurable: true
  15156. });
  15157. Text2D.prototype.onSetOwner = function () {
  15158. if (!this._textSize) {
  15159. this.onPrimitivePropertyDirty(BABYLON.Prim2DBase.sizeProperty.flagId);
  15160. this._setLayoutDirty();
  15161. this._positioningDirty();
  15162. this._actualSize = null;
  15163. this._setFlags(BABYLON.SmartPropertyPrim.flagLevelBoundingInfoDirty | BABYLON.SmartPropertyPrim.flagBoundingInfoDirty);
  15164. }
  15165. };
  15166. Object.defineProperty(Text2D.prototype, "fontTexture", {
  15167. get: function () {
  15168. if (this._fontTexture) {
  15169. return this._fontTexture;
  15170. }
  15171. if (this.fontName == null || this.owner == null || this.owner.scene == null) {
  15172. return null;
  15173. }
  15174. this._fontBilinearFiltering = (this._useBilinearFiltering === null) ? (this.owner instanceof BABYLON.WorldSpaceCanvas2D) : this._useBilinearFiltering;
  15175. this._fontTexture = BABYLON.FontTexture.GetCachedFontTexture(this.owner.scene, this.fontName, this._fontSuperSample, this._fontSDF, this._fontBilinearFiltering);
  15176. this._textureIsPremulAlpha = this._fontTexture.isPremultipliedAlpha;
  15177. return this._fontTexture;
  15178. },
  15179. enumerable: true,
  15180. configurable: true
  15181. });
  15182. /**
  15183. * Dispose the primitive, remove it from its parent
  15184. */
  15185. Text2D.prototype.dispose = function () {
  15186. if (!_super.prototype.dispose.call(this)) {
  15187. return false;
  15188. }
  15189. if (this._fontTexture) {
  15190. BABYLON.FontTexture.ReleaseCachedFontTexture(this.owner.scene, this.fontName, this._fontSuperSample, this._fontSDF, this._fontBilinearFiltering);
  15191. this._fontTexture = null;
  15192. }
  15193. return true;
  15194. };
  15195. Text2D.prototype.updateLevelBoundingInfo = function () {
  15196. if (!this.owner || !this._text) {
  15197. return false;
  15198. }
  15199. var asize = this.actualSize;
  15200. if (asize.width === 0 && asize.height === 0) {
  15201. return false;
  15202. }
  15203. BABYLON.BoundingInfo2D.CreateFromSizeToRef(this.actualSize, this._levelBoundingInfo);
  15204. return true;
  15205. };
  15206. Object.defineProperty(Text2D.prototype, "textAlignment", {
  15207. /**
  15208. * You can get/set the text alignment through this property
  15209. */
  15210. get: function () {
  15211. return this._textAlignment;
  15212. },
  15213. set: function (value) {
  15214. this._textAlignment = value;
  15215. this._setTextAlignmentfromString(value);
  15216. },
  15217. enumerable: true,
  15218. configurable: true
  15219. });
  15220. Text2D.prototype.levelIntersect = function (intersectInfo) {
  15221. // For now I can't do something better that boundingInfo is a hit, detecting an intersection on a particular letter would be possible, but do we really need it? Not for now...
  15222. return true;
  15223. };
  15224. Text2D.prototype.createModelRenderCache = function (modelKey) {
  15225. var renderCache = new Text2DRenderCache(this.owner.engine, modelKey);
  15226. return renderCache;
  15227. };
  15228. Text2D.prototype.setupModelRenderCache = function (modelRenderCache) {
  15229. var renderCache = modelRenderCache;
  15230. var engine = this.owner.engine;
  15231. renderCache.fontTexture = this.fontTexture;
  15232. renderCache.fontTexture.incCachedFontTextureCounter();
  15233. renderCache.fontPremulAlpha = this.textureIsPremulAlpha;
  15234. var vb = new Float32Array(4);
  15235. for (var i = 0; i < 4; i++) {
  15236. vb[i] = i;
  15237. }
  15238. renderCache.vb = engine.createVertexBuffer(vb);
  15239. var ib = new Float32Array(6);
  15240. ib[0] = 0;
  15241. ib[1] = 2;
  15242. ib[2] = 1;
  15243. ib[3] = 0;
  15244. ib[4] = 3;
  15245. ib[5] = 2;
  15246. renderCache.ib = engine.createIndexBuffer(ib);
  15247. // Get the instanced version of the effect, if the engine does not support it, null is return and we'll only draw on by one
  15248. var ei = this.getDataPartEffectInfo(Text2D_1.TEXT2D_MAINPARTID, ["index"], null, true);
  15249. if (ei) {
  15250. renderCache.effectInstanced = engine.createEffect("text2d", ei.attributes, ei.uniforms, ["diffuseSampler"], ei.defines, null);
  15251. }
  15252. ei = this.getDataPartEffectInfo(Text2D_1.TEXT2D_MAINPARTID, ["index"], null, false);
  15253. renderCache.effect = engine.createEffect("text2d", ei.attributes, ei.uniforms, ["diffuseSampler"], ei.defines, null);
  15254. return renderCache;
  15255. };
  15256. Text2D.prototype.createInstanceDataParts = function () {
  15257. return [new Text2DInstanceData(Text2D_1.TEXT2D_MAINPARTID, this._charCount)];
  15258. };
  15259. // Looks like a hack!? Yes! Because that's what it is!
  15260. // For the InstanceData layer to compute correctly we need to set all the properties involved, which won't be the case if there's no text
  15261. // This method is called before the layout construction for us to detect this case, set some text and return the initial one to restore it after (there can be some text without char to display, say "\t\n" for instance)
  15262. Text2D.prototype.beforeRefreshForLayoutConstruction = function (part) {
  15263. if (!this._charCount) {
  15264. var curText = this._text;
  15265. this.text = "A";
  15266. return curText;
  15267. }
  15268. };
  15269. // if obj contains something, we restore the _text property
  15270. Text2D.prototype.afterRefreshForLayoutConstruction = function (part, obj) {
  15271. if (obj !== undefined) {
  15272. this.text = obj;
  15273. }
  15274. };
  15275. Text2D.prototype.getUsedShaderCategories = function (dataPart) {
  15276. var cat = _super.prototype.getUsedShaderCategories.call(this, dataPart);
  15277. if (this._fontSDF) {
  15278. cat.push(Text2D_1.TEXT2D_CATEGORY_SDF);
  15279. }
  15280. if (this._fontTexture instanceof BABYLON.FontTexture) {
  15281. cat.push(Text2D_1.TEXT2D_CATEGORY_FONTTEXTURE);
  15282. }
  15283. return cat;
  15284. };
  15285. Text2D.prototype.refreshInstanceDataPart = function (part) {
  15286. if (!_super.prototype.refreshInstanceDataPart.call(this, part)) {
  15287. return false;
  15288. }
  15289. if (part.id === Text2D_1.TEXT2D_MAINPARTID) {
  15290. var d = part;
  15291. var ft = this.fontTexture;
  15292. var texture = ft;
  15293. if (!texture) {
  15294. return false;
  15295. }
  15296. var superSampleFactor = texture.isSuperSampled ? 0.5 : 1;
  15297. var ts = texture.getSize();
  15298. var offset = BABYLON.Vector2.Zero();
  15299. var lh = ft.lineHeight;
  15300. d.dataElementCount = this._charCount;
  15301. d.curElement = 0;
  15302. var lineLengths = [];
  15303. var charWidths = [];
  15304. var charsPerLine = [];
  15305. var numCharsCurrenLine = 0;
  15306. var contentAreaWidth = this.contentArea.width;
  15307. var contentAreaHeight = this.contentArea.height;
  15308. var numCharsCurrentWord = 0;
  15309. var widthCurrentWord = 0;
  15310. var numWordsPerLine = 0;
  15311. var text = this.text;
  15312. var tabWidth = this._tabulationSize * texture.spaceWidth;
  15313. // First pass: analyze the text to build data like pixel length of each lines, width of each char, number of char per line
  15314. for (var i_1 = 0; i_1 < text.length; i_1++) {
  15315. var char = text[i_1];
  15316. numCharsCurrenLine++;
  15317. charWidths[i_1] = 0;
  15318. // Line feed
  15319. if (this._isWhiteSpaceCharVert(char)) {
  15320. lineLengths.push(offset.x);
  15321. charsPerLine.push(numCharsCurrenLine - 1);
  15322. numCharsCurrenLine = 1;
  15323. offset.x = 0;
  15324. if (widthCurrentWord > 0) {
  15325. numWordsPerLine++;
  15326. }
  15327. numWordsPerLine = 0;
  15328. numCharsCurrentWord = 0;
  15329. widthCurrentWord = 0;
  15330. continue;
  15331. }
  15332. var ci = texture.getChar(char);
  15333. var charWidth = 0;
  15334. if (char === "\t") {
  15335. charWidth = tabWidth;
  15336. }
  15337. else {
  15338. charWidth = ci.xAdvance;
  15339. }
  15340. offset.x += charWidth;
  15341. charWidths[i_1] = charWidth;
  15342. if (this._isWhiteSpaceCharHoriz(char)) {
  15343. if (widthCurrentWord > 0) {
  15344. numWordsPerLine++;
  15345. }
  15346. numCharsCurrentWord = 0;
  15347. widthCurrentWord = 0;
  15348. }
  15349. else {
  15350. widthCurrentWord += ci.xAdvance;
  15351. numCharsCurrentWord++;
  15352. }
  15353. if (this._wordWrap && numWordsPerLine > 0 && offset.x > contentAreaWidth) {
  15354. lineLengths.push(offset.x - widthCurrentWord);
  15355. numCharsCurrenLine -= numCharsCurrentWord;
  15356. var j = i_1 - numCharsCurrentWord;
  15357. //skip white space at the end of this line
  15358. while (this._isWhiteSpaceCharHoriz(text[j])) {
  15359. lineLengths[lineLengths.length - 1] -= charWidths[j];
  15360. j--;
  15361. }
  15362. charsPerLine.push(numCharsCurrenLine);
  15363. if (this._isWhiteSpaceCharHoriz(text[i_1])) {
  15364. //skip white space at the beginning of next line
  15365. var numSpaces = 0;
  15366. while (this._isWhiteSpaceCharHoriz(text[i_1 + numSpaces])) {
  15367. numSpaces++;
  15368. charWidths[i_1 + numSpaces] = 0;
  15369. }
  15370. i_1 += numSpaces - 1;
  15371. offset.x = 0;
  15372. numCharsCurrenLine = numSpaces - 1;
  15373. }
  15374. else {
  15375. numCharsCurrenLine = numCharsCurrentWord;
  15376. offset.x = widthCurrentWord;
  15377. }
  15378. numWordsPerLine = 0;
  15379. }
  15380. }
  15381. lineLengths.push(offset.x);
  15382. charsPerLine.push(numCharsCurrenLine);
  15383. //skip white space at the end
  15384. var i = text.length - 1;
  15385. while (this._isWhiteSpaceCharHoriz(text[i])) {
  15386. lineLengths[lineLengths.length - 1] -= charWidths[i];
  15387. i--;
  15388. }
  15389. var charNum = 0;
  15390. var maxLineLen = 0;
  15391. var alignH = this.textAlignmentH;
  15392. var alignV = this.textAlignmentV;
  15393. offset.x = 0;
  15394. if (alignH == Text2D_1.AlignRight || alignH == Text2D_1.AlignCenter) {
  15395. for (var i_2 = 0; i_2 < lineLengths.length; i_2++) {
  15396. if (lineLengths[i_2] > maxLineLen) {
  15397. maxLineLen = lineLengths[i_2];
  15398. }
  15399. }
  15400. }
  15401. var textHeight = lineLengths.length * lh;
  15402. var offsetX = this.padding.leftPixels;
  15403. if (alignH == Text2D_1.AlignRight) {
  15404. offsetX += contentAreaWidth - maxLineLen;
  15405. }
  15406. else if (alignH == Text2D_1.AlignCenter) {
  15407. offsetX += (contentAreaWidth - maxLineLen) * .5;
  15408. }
  15409. offset.x += Math.floor(offsetX);
  15410. offset.y += contentAreaHeight + textHeight - lh;
  15411. offset.y += this.padding.bottomPixels;
  15412. if (alignV == Text2D_1.AlignBottom) {
  15413. offset.y -= contentAreaHeight;
  15414. }
  15415. else if (alignV == Text2D_1.AlignCenter) {
  15416. offset.y -= (contentAreaHeight - textHeight) * .5 + lineLengths.length * lh;
  15417. }
  15418. else {
  15419. offset.y -= lineLengths.length * lh;
  15420. }
  15421. var lineHeight = texture.lineHeight;
  15422. for (var i_3 = 0; i_3 < lineLengths.length; i_3++) {
  15423. var numChars = charsPerLine[i_3];
  15424. var lineLength = lineLengths[i_3];
  15425. if (alignH == Text2D_1.AlignRight) {
  15426. offset.x += maxLineLen - lineLength;
  15427. }
  15428. else if (alignH == Text2D_1.AlignCenter) {
  15429. offset.x += (maxLineLen - lineLength) * .5;
  15430. }
  15431. for (var j = 0; j < numChars; j++) {
  15432. var char = text[charNum];
  15433. var charWidth = charWidths[charNum];
  15434. if (char !== "\t" && !this._isWhiteSpaceCharVert(char)) {
  15435. //make sure space char gets processed here or overlapping can occur when text is set
  15436. var ci = texture.getChar(char);
  15437. var partOffset = new BABYLON.Vector2(Math.floor(offset.x + ci.xOffset), Math.floor(offset.y + ci.yOffset));
  15438. this.updateInstanceDataPart(d, partOffset);
  15439. d.topLeftUV = ci.topLeftUV;
  15440. var suv = ci.bottomRightUV.subtract(ci.topLeftUV);
  15441. d.sizeUV = suv;
  15442. d.textureSize = new BABYLON.Vector2(ts.width, ts.height);
  15443. d.color = this.defaultFontColor;
  15444. d.superSampleFactor = superSampleFactor;
  15445. //console.log(`Char: ${char}, Offset: ${partOffset}`);
  15446. ++d.curElement;
  15447. }
  15448. offset.x += Math.floor(charWidth);
  15449. charNum++;
  15450. }
  15451. offset.x = offsetX;
  15452. offset.y -= lineHeight;
  15453. }
  15454. }
  15455. return true;
  15456. };
  15457. Text2D.prototype._isWhiteSpaceCharHoriz = function (char) {
  15458. if (char === " " || char === "\t") {
  15459. return true;
  15460. }
  15461. };
  15462. Text2D.prototype._isWhiteSpaceCharVert = function (char) {
  15463. if (char === "\n" || char === "\r") {
  15464. return true;
  15465. }
  15466. };
  15467. Text2D.prototype._updateCharCount = function () {
  15468. var count = 0;
  15469. for (var _i = 0, _a = this._text; _i < _a.length; _i++) {
  15470. var char = _a[_i];
  15471. if (char === "\r" || char === "\n" || char === "\t" || char < " ") {
  15472. continue;
  15473. }
  15474. ++count;
  15475. }
  15476. this._charCount = count;
  15477. };
  15478. Text2D.prototype._setTextAlignmentfromString = function (value) {
  15479. var m = value.trim().split(",");
  15480. for (var _i = 0, m_1 = m; _i < m_1.length; _i++) {
  15481. var v = m_1[_i];
  15482. v = v.toLocaleLowerCase().trim();
  15483. // Horizontal
  15484. var i = v.indexOf("h:");
  15485. if (i === -1) {
  15486. i = v.indexOf("horizontal:");
  15487. }
  15488. if (i !== -1) {
  15489. v = v.substr(v.indexOf(":") + 1);
  15490. this._setTextAlignmentHorizontal(v);
  15491. continue;
  15492. }
  15493. // Vertical
  15494. i = v.indexOf("v:");
  15495. if (i === -1) {
  15496. i = v.indexOf("vertical:");
  15497. }
  15498. if (i !== -1) {
  15499. v = v.substr(v.indexOf(":") + 1);
  15500. this._setTextAlignmentVertical(v);
  15501. continue;
  15502. }
  15503. }
  15504. };
  15505. Text2D.prototype._setTextAlignmentHorizontal = function (text) {
  15506. var v = text.trim().toLocaleLowerCase();
  15507. switch (v) {
  15508. case "left":
  15509. this.textAlignmentH = Text2D_1.AlignLeft;
  15510. return;
  15511. case "right":
  15512. this.textAlignmentH = Text2D_1.AlignRight;
  15513. return;
  15514. case "center":
  15515. this.textAlignmentH = Text2D_1.AlignCenter;
  15516. return;
  15517. }
  15518. };
  15519. Text2D.prototype._setTextAlignmentVertical = function (text) {
  15520. var v = text.trim().toLocaleLowerCase();
  15521. switch (v) {
  15522. case "top":
  15523. this.textAlignmentV = Text2D_1.AlignTop;
  15524. return;
  15525. case "bottom":
  15526. this.textAlignmentV = Text2D_1.AlignBottom;
  15527. return;
  15528. case "center":
  15529. this.textAlignmentV = Text2D_1.AlignCenter;
  15530. return;
  15531. }
  15532. };
  15533. Text2D.prototype._useTextureAlpha = function () {
  15534. return this._fontSDF;
  15535. };
  15536. Text2D.prototype._shouldUseAlphaFromTexture = function () {
  15537. return !this._fontSDF;
  15538. };
  15539. return Text2D;
  15540. }(BABYLON.RenderablePrim2D));
  15541. Text2D.TEXT2D_MAINPARTID = 1;
  15542. Text2D.TEXT2D_CATEGORY_SDF = "SignedDistanceField";
  15543. Text2D.TEXT2D_CATEGORY_FONTTEXTURE = "FontTexture";
  15544. Text2D._AlignLeft = 1;
  15545. Text2D._AlignTop = 1; // Same as left
  15546. Text2D._AlignRight = 2;
  15547. Text2D._AlignBottom = 2; // Same as right
  15548. Text2D._AlignCenter = 3;
  15549. __decorate([
  15550. BABYLON.modelLevelProperty(BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 1, function (pi) { return Text2D_1.fontProperty = pi; }, false, true)
  15551. /**
  15552. * Get/set the font name to use, using HTML CSS notation.
  15553. * Set is not supported right now.
  15554. */
  15555. ], Text2D.prototype, "fontName", null);
  15556. __decorate([
  15557. BABYLON.dynamicLevelProperty(BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 2, function (pi) { return Text2D_1.defaultFontColorProperty = pi; })
  15558. /**
  15559. * Get/set the font default color
  15560. */
  15561. ], Text2D.prototype, "defaultFontColor", null);
  15562. __decorate([
  15563. BABYLON.instanceLevelProperty(BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 3, function (pi) { return Text2D_1.textProperty = pi; }, false, true)
  15564. /**
  15565. * Get/set the text to render.
  15566. * \n \t character are supported.
  15567. */
  15568. ], Text2D.prototype, "text", null);
  15569. __decorate([
  15570. BABYLON.instanceLevelProperty(BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 4, function (pi) { return Text2D_1.sizeProperty = pi; })
  15571. /**
  15572. * Get/set the size of the area where the text is drawn.
  15573. * You should not set this size, the default behavior compute the size based on the actual text.
  15574. */
  15575. ], Text2D.prototype, "size", null);
  15576. __decorate([
  15577. BABYLON.modelLevelProperty(BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 5, function (pi) { return Text2D_1.fontSuperSampleProperty = pi; }, false, false)
  15578. /**
  15579. * Get/set the font name to use, using HTML CSS notation.
  15580. * Set is not supported right now.
  15581. */
  15582. ], Text2D.prototype, "fontSuperSample", null);
  15583. __decorate([
  15584. BABYLON.modelLevelProperty(BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 6, function (pi) { return Text2D_1.fontSignedDistanceFieldProperty = pi; }, false, false)
  15585. /**
  15586. * Get/set the font name to use, using HTML CSS notation.
  15587. * Set is not supported right now.
  15588. */
  15589. ], Text2D.prototype, "fontSignedDistanceField", null);
  15590. __decorate([
  15591. BABYLON.instanceLevelProperty(BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 7, function (pi) { return Text2D_1.textureIsPremulAlphaProperty = pi; })
  15592. /**
  15593. * Set to true if the FontTexture use Premultiplied Alpha, default is false
  15594. */
  15595. ], Text2D.prototype, "textureIsPremulAlpha", null);
  15596. __decorate([
  15597. BABYLON.modelLevelProperty(BABYLON.RenderablePrim2D.RENDERABLEPRIM2D_PROPCOUNT + 8, function (pi) { return Text2D_1.fontTextureProperty = pi; })
  15598. ], Text2D.prototype, "fontTexture", null);
  15599. Text2D = Text2D_1 = __decorate([
  15600. BABYLON.className("Text2D", "BABYLON")
  15601. /**
  15602. * Primitive that render text using a specific font
  15603. */
  15604. ], Text2D);
  15605. BABYLON.Text2D = Text2D;
  15606. var Text2D_1;
  15607. })(BABYLON || (BABYLON = {}));
  15608. var __extends = (this && this.__extends) || (function () {
  15609. var extendStatics = Object.setPrototypeOf ||
  15610. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  15611. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  15612. return function (d, b) {
  15613. extendStatics(d, b);
  15614. function __() { this.constructor = d; }
  15615. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  15616. };
  15617. })();
  15618. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  15619. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  15620. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  15621. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  15622. return c > 3 && r && Object.defineProperty(target, key, r), r;
  15623. };
  15624. var BABYLON;
  15625. (function (BABYLON) {
  15626. var Lines2DRenderCache = (function (_super) {
  15627. __extends(Lines2DRenderCache, _super);
  15628. function Lines2DRenderCache(engine, modelKey) {
  15629. var _this = _super.call(this, engine, modelKey) || this;
  15630. _this.effectsReady = false;
  15631. _this.fillVB = null;
  15632. _this.fillIB = null;
  15633. _this.fillIndicesCount = 0;
  15634. _this.instancingFillAttributes = null;
  15635. _this.effectFill = null;
  15636. _this.effectFillInstanced = null;
  15637. _this.borderVB = null;
  15638. _this.borderIB = null;
  15639. _this.borderIndicesCount = 0;
  15640. _this.instancingBorderAttributes = null;
  15641. _this.effectBorder = null;
  15642. _this.effectBorderInstanced = null;
  15643. return _this;
  15644. }
  15645. Lines2DRenderCache.prototype.render = function (instanceInfo, context) {
  15646. // Do nothing if the shader is still loading/preparing
  15647. if (!this.effectsReady) {
  15648. if ((this.effectFill && (!this.effectFill.isReady() || (this.effectFillInstanced && !this.effectFillInstanced.isReady()))) ||
  15649. (this.effectBorder && (!this.effectBorder.isReady() || (this.effectBorderInstanced && !this.effectBorderInstanced.isReady())))) {
  15650. return false;
  15651. }
  15652. this.effectsReady = true;
  15653. }
  15654. var canvas = instanceInfo.owner.owner;
  15655. var engine = canvas.engine;
  15656. engine.setState(false, undefined, true);
  15657. var depthFunction = 0;
  15658. if (this.effectFill && this.effectBorder) {
  15659. depthFunction = engine.getDepthFunction();
  15660. engine.setDepthFunctionToLessOrEqual();
  15661. }
  15662. var curAlphaMode = engine.getAlphaMode();
  15663. if (this.effectFill) {
  15664. var partIndex = instanceInfo.partIndexFromId.get(BABYLON.Shape2D.SHAPE2D_FILLPARTID.toString());
  15665. var pid = context.groupInfoPartData[partIndex];
  15666. if (context.renderMode !== BABYLON.Render2DContext.RenderModeOpaque) {
  15667. engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE, true);
  15668. }
  15669. var effect = context.useInstancing ? this.effectFillInstanced : this.effectFill;
  15670. engine.enableEffect(effect);
  15671. engine.bindBuffersDirectly(this.fillVB, this.fillIB, [2], 2 * 4, effect);
  15672. if (context.useInstancing) {
  15673. if (!this.instancingFillAttributes) {
  15674. this.instancingFillAttributes = this.loadInstancingAttributes(BABYLON.Shape2D.SHAPE2D_FILLPARTID, effect);
  15675. }
  15676. var glBuffer = context.instancedBuffers ? context.instancedBuffers[partIndex] : pid._partBuffer;
  15677. var count = context.instancedBuffers ? context.instancesCount : pid._partData.usedElementCount;
  15678. canvas._addDrawCallCount(1, context.renderMode);
  15679. engine.updateAndBindInstancesBuffer(glBuffer, null, this.instancingFillAttributes);
  15680. engine.draw(true, 0, this.fillIndicesCount, count);
  15681. engine.unbindInstanceAttributes();
  15682. }
  15683. else {
  15684. canvas._addDrawCallCount(context.partDataEndIndex - context.partDataStartIndex, context.renderMode);
  15685. for (var i = context.partDataStartIndex; i < context.partDataEndIndex; i++) {
  15686. this.setupUniforms(effect, partIndex, pid._partData, i);
  15687. engine.draw(true, 0, this.fillIndicesCount);
  15688. }
  15689. }
  15690. }
  15691. if (this.effectBorder) {
  15692. var partIndex = instanceInfo.partIndexFromId.get(BABYLON.Shape2D.SHAPE2D_BORDERPARTID.toString());
  15693. var pid = context.groupInfoPartData[partIndex];
  15694. if (context.renderMode !== BABYLON.Render2DContext.RenderModeOpaque) {
  15695. engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE, true);
  15696. }
  15697. var effect = context.useInstancing ? this.effectBorderInstanced : this.effectBorder;
  15698. engine.enableEffect(effect);
  15699. engine.bindBuffersDirectly(this.borderVB, this.borderIB, [2], 2 * 4, effect);
  15700. if (context.useInstancing) {
  15701. if (!this.instancingBorderAttributes) {
  15702. this.instancingBorderAttributes = this.loadInstancingAttributes(BABYLON.Shape2D.SHAPE2D_BORDERPARTID, effect);
  15703. }
  15704. var glBuffer = context.instancedBuffers ? context.instancedBuffers[partIndex] : pid._partBuffer;
  15705. var count = context.instancedBuffers ? context.instancesCount : pid._partData.usedElementCount;
  15706. canvas._addDrawCallCount(1, context.renderMode);
  15707. engine.updateAndBindInstancesBuffer(glBuffer, null, this.instancingBorderAttributes);
  15708. engine.draw(true, 0, this.borderIndicesCount, count);
  15709. engine.unbindInstanceAttributes();
  15710. }
  15711. else {
  15712. canvas._addDrawCallCount(context.partDataEndIndex - context.partDataStartIndex, context.renderMode);
  15713. for (var i = context.partDataStartIndex; i < context.partDataEndIndex; i++) {
  15714. this.setupUniforms(effect, partIndex, pid._partData, i);
  15715. engine.draw(true, 0, this.borderIndicesCount);
  15716. }
  15717. }
  15718. }
  15719. engine.setAlphaMode(curAlphaMode, true);
  15720. if (this.effectFill && this.effectBorder) {
  15721. engine.setDepthFunction(depthFunction);
  15722. }
  15723. return true;
  15724. };
  15725. Lines2DRenderCache.prototype.dispose = function () {
  15726. if (!_super.prototype.dispose.call(this)) {
  15727. return false;
  15728. }
  15729. if (this.fillVB) {
  15730. this._engine._releaseBuffer(this.fillVB);
  15731. this.fillVB = null;
  15732. }
  15733. if (this.fillIB) {
  15734. this._engine._releaseBuffer(this.fillIB);
  15735. this.fillIB = null;
  15736. }
  15737. this.effectFill = null;
  15738. this.effectFillInstanced = null;
  15739. this.effectBorder = null;
  15740. this.effectBorderInstanced = null;
  15741. if (this.borderVB) {
  15742. this._engine._releaseBuffer(this.borderVB);
  15743. this.borderVB = null;
  15744. }
  15745. if (this.borderIB) {
  15746. this._engine._releaseBuffer(this.borderIB);
  15747. this.borderIB = null;
  15748. }
  15749. return true;
  15750. };
  15751. return Lines2DRenderCache;
  15752. }(BABYLON.ModelRenderCache));
  15753. BABYLON.Lines2DRenderCache = Lines2DRenderCache;
  15754. var Lines2DInstanceData = (function (_super) {
  15755. __extends(Lines2DInstanceData, _super);
  15756. function Lines2DInstanceData(partId) {
  15757. return _super.call(this, partId, 1) || this;
  15758. }
  15759. Object.defineProperty(Lines2DInstanceData.prototype, "boundingMin", {
  15760. get: function () {
  15761. return null;
  15762. },
  15763. set: function (value) {
  15764. },
  15765. enumerable: true,
  15766. configurable: true
  15767. });
  15768. Object.defineProperty(Lines2DInstanceData.prototype, "boundingMax", {
  15769. get: function () {
  15770. return null;
  15771. },
  15772. set: function (value) {
  15773. },
  15774. enumerable: true,
  15775. configurable: true
  15776. });
  15777. return Lines2DInstanceData;
  15778. }(BABYLON.Shape2DInstanceData));
  15779. __decorate([
  15780. BABYLON.instanceData(BABYLON.Shape2D.SHAPE2D_CATEGORY_FILLGRADIENT)
  15781. ], Lines2DInstanceData.prototype, "boundingMin", null);
  15782. __decorate([
  15783. BABYLON.instanceData(BABYLON.Shape2D.SHAPE2D_CATEGORY_FILLGRADIENT)
  15784. ], Lines2DInstanceData.prototype, "boundingMax", null);
  15785. BABYLON.Lines2DInstanceData = Lines2DInstanceData;
  15786. var Lines2D = Lines2D_1 = (function (_super) {
  15787. __extends(Lines2D, _super);
  15788. /**
  15789. * Create an 2D Lines Shape primitive. The defined lines may be opened or closed (see below)
  15790. * @param points an array that describe the points to use to draw the line, must contain at least two entries.
  15791. * @param settings a combination of settings, possible ones are
  15792. * - parent: the parent primitive/canvas, must be specified if the primitive is not constructed as a child of another one (i.e. as part of the children array setting)
  15793. * - children: an array of direct children
  15794. * - id a text identifier, for information purpose
  15795. * - position: the X & Y positions relative to its parent. Alternatively the x and y properties can be set. Default is [0;0]
  15796. * - rotation: the initial rotation (in radian) of the primitive. default is 0
  15797. * - scale: the initial scale of the primitive. default is 1. You can alternatively use scaleX &| scaleY to apply non uniform scale
  15798. * - dontInheritParentScale: if set the parent's scale won't be taken into consideration to compute the actualScale property
  15799. * - alignToPixel: if true the primitive will be aligned to the target rendering device's pixel
  15800. * - opacity: set the overall opacity of the primitive, 1 to be opaque (default), less than 1 to be transparent.
  15801. * - zOrder: override the zOrder with the specified value
  15802. * - origin: define the normalized origin point location, default [0.5;0.5]
  15803. * - fillThickness: the thickness of the fill part of the line, can be null to draw nothing (but a border brush must be given), default is 1.
  15804. * - closed: if false the lines are said to be opened, the first point and the latest DON'T connect. if true the lines are said to be closed, the first and last point will be connected by a line. For instance you can define the 4 points of a rectangle, if you set closed to true a 4 edges rectangle will be drawn. If you set false, only three edges will be drawn, the edge formed by the first and last point won't exist. Default is false.
  15805. * - startCap: Draw a cap of the given type at the start of the first line, you can't define a Cap if the Lines2D is closed. Default is Lines2D.NoCap.
  15806. * - endCap: Draw a cap of the given type at the end of the last line, you can't define a Cap if the Lines2D is closed. Default is Lines2D.NoCap.
  15807. * - fill: the brush used to draw the fill content of the lines, you can set null to draw nothing (but you will have to set a border brush), default is a SolidColorBrush of plain white. can be a string value (see Canvas2D.GetBrushFromString)
  15808. * - border: the brush used to draw the border of the lines, you can set null to draw nothing (but you will have to set a fill brush), default is null. can be a string value (see Canvas2D.GetBrushFromString)
  15809. * - borderThickness: the thickness of the drawn border, default is 1.
  15810. * - isVisible: true if the primitive must be visible, false for hidden. Default is true.
  15811. * - isPickable: if true the Primitive can be used with interaction mode and will issue Pointer Event. If false it will be ignored for interaction/intersection test. Default value is true.
  15812. * - isContainer: if true the Primitive acts as a container for interaction, if the primitive is not pickable or doesn't intersection, no further test will be perform on its children. If set to false, children will always be considered for intersection/interaction. Default value is true.
  15813. * - childrenFlatZOrder: if true all the children (direct and indirect) will share the same Z-Order. Use this when there's a lot of children which don't overlap. The drawing order IS NOT GUARANTED!
  15814. * - levelCollision: this primitive is an actor of the Collision Manager and only this level will be used for collision (i.e. not the children). Use deepCollision if you want collision detection on the primitives and its children.
  15815. * - deepCollision: this primitive is an actor of the Collision Manager, this level AND ALSO its children will be used for collision (note: you don't need to set the children as level/deepCollision).
  15816. * - layoutData: a instance of a class implementing the ILayoutData interface that contain data to pass to the primitive parent's layout engine
  15817. * - marginTop: top margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  15818. * - marginLeft: left margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  15819. * - marginRight: right margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  15820. * - marginBottom: bottom margin, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  15821. * - margin: top, left, right and bottom margin formatted as a single string (see PrimitiveThickness.fromString)
  15822. * - marginHAlignment: one value of the PrimitiveAlignment type's static properties
  15823. * - marginVAlignment: one value of the PrimitiveAlignment type's static properties
  15824. * - marginAlignment: a string defining the alignment, see PrimitiveAlignment.fromString
  15825. * - paddingTop: top padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  15826. * - paddingLeft: left padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  15827. * - paddingRight: right padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  15828. * - paddingBottom: bottom padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  15829. * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
  15830. */
  15831. function Lines2D(points, settings) {
  15832. var _this = this;
  15833. if (!settings) {
  15834. settings = {};
  15835. }
  15836. _this = _super.call(this, settings) || this;
  15837. _this._fillVB = null;
  15838. _this._fillIB = null;
  15839. _this._borderVB = null;
  15840. _this._borderIB = null;
  15841. _this._boundingMin = null;
  15842. _this._boundingMax = null;
  15843. var fillThickness = (settings.fillThickness == null) ? 1 : settings.fillThickness;
  15844. var startCap = (settings.startCap == null) ? 0 : settings.startCap;
  15845. var endCap = (settings.endCap == null) ? 0 : settings.endCap;
  15846. var closed = (settings.closed == null) ? false : settings.closed;
  15847. _this.points = points;
  15848. _this.fillThickness = fillThickness;
  15849. _this.startCap = startCap;
  15850. _this.endCap = endCap;
  15851. _this.closed = closed;
  15852. return _this;
  15853. }
  15854. Object.defineProperty(Lines2D, "NoCap", {
  15855. /**
  15856. * No Cap to apply on the extremity
  15857. */
  15858. get: function () { return Lines2D_1._noCap; },
  15859. enumerable: true,
  15860. configurable: true
  15861. });
  15862. Object.defineProperty(Lines2D, "RoundCap", {
  15863. /**
  15864. * A round cap, will use the line thickness as diameter
  15865. */
  15866. get: function () { return Lines2D_1._roundCap; },
  15867. enumerable: true,
  15868. configurable: true
  15869. });
  15870. Object.defineProperty(Lines2D, "TriangleCap", {
  15871. /**
  15872. * Creates a triangle at the extremity.
  15873. */
  15874. get: function () { return Lines2D_1._triangleCap; },
  15875. enumerable: true,
  15876. configurable: true
  15877. });
  15878. Object.defineProperty(Lines2D, "SquareAnchorCap", {
  15879. /**
  15880. * Creates a Square anchor at the extremity, the square size is twice the thickness of the line
  15881. */
  15882. get: function () { return Lines2D_1._squareAnchorCap; },
  15883. enumerable: true,
  15884. configurable: true
  15885. });
  15886. Object.defineProperty(Lines2D, "RoundAnchorCap", {
  15887. /**
  15888. * Creates a round anchor at the extremity, the diameter is twice the thickness of the line
  15889. */
  15890. get: function () { return Lines2D_1._roundAnchorCap; },
  15891. enumerable: true,
  15892. configurable: true
  15893. });
  15894. Object.defineProperty(Lines2D, "DiamondAnchorCap", {
  15895. /**
  15896. * Creates a diamond anchor at the extremity.
  15897. */
  15898. get: function () { return Lines2D_1._diamondAnchorCap; },
  15899. enumerable: true,
  15900. configurable: true
  15901. });
  15902. Object.defineProperty(Lines2D, "ArrowCap", {
  15903. /**
  15904. * Creates an arrow anchor at the extremity. the arrow base size is twice the thickness of the line
  15905. */
  15906. get: function () { return Lines2D_1._arrowCap; },
  15907. enumerable: true,
  15908. configurable: true
  15909. });
  15910. Object.defineProperty(Lines2D.prototype, "points", {
  15911. get: function () {
  15912. return this._points;
  15913. },
  15914. set: function (value) {
  15915. this._points = value;
  15916. this._primTriArrayDirty = true;
  15917. this._boundingBoxDirty();
  15918. },
  15919. enumerable: true,
  15920. configurable: true
  15921. });
  15922. Object.defineProperty(Lines2D.prototype, "fillThickness", {
  15923. get: function () {
  15924. return this._fillThickness;
  15925. },
  15926. set: function (value) {
  15927. this._fillThickness = value;
  15928. },
  15929. enumerable: true,
  15930. configurable: true
  15931. });
  15932. Object.defineProperty(Lines2D.prototype, "closed", {
  15933. get: function () {
  15934. return this._closed;
  15935. },
  15936. set: function (value) {
  15937. this._closed = value;
  15938. },
  15939. enumerable: true,
  15940. configurable: true
  15941. });
  15942. Object.defineProperty(Lines2D.prototype, "startCap", {
  15943. get: function () {
  15944. return this._startCap;
  15945. },
  15946. set: function (value) {
  15947. this._startCap = value;
  15948. },
  15949. enumerable: true,
  15950. configurable: true
  15951. });
  15952. Object.defineProperty(Lines2D.prototype, "endCap", {
  15953. get: function () {
  15954. return this._endCap;
  15955. },
  15956. set: function (value) {
  15957. this._endCap = value;
  15958. },
  15959. enumerable: true,
  15960. configurable: true
  15961. });
  15962. Lines2D.prototype.levelIntersect = function (intersectInfo) {
  15963. var p = intersectInfo._localPickPosition;
  15964. this.updateTriArray();
  15965. return this._primTriArray.doesContain(p);
  15966. };
  15967. Object.defineProperty(Lines2D.prototype, "boundingMin", {
  15968. get: function () {
  15969. if (!this._boundingMin) {
  15970. this._computeLines2D();
  15971. }
  15972. return this._boundingMin;
  15973. },
  15974. enumerable: true,
  15975. configurable: true
  15976. });
  15977. Object.defineProperty(Lines2D.prototype, "boundingMax", {
  15978. get: function () {
  15979. if (!this._boundingMax) {
  15980. this._computeLines2D();
  15981. }
  15982. return this._boundingMax;
  15983. },
  15984. enumerable: true,
  15985. configurable: true
  15986. });
  15987. Lines2D.prototype.getUsedShaderCategories = function (dataPart) {
  15988. var res = _super.prototype.getUsedShaderCategories.call(this, dataPart);
  15989. // Remove the BORDER category, we don't use it in the VertexShader
  15990. var i = res.indexOf(BABYLON.Shape2D.SHAPE2D_CATEGORY_BORDER);
  15991. if (i !== -1) {
  15992. res.splice(i, 1);
  15993. }
  15994. return res;
  15995. };
  15996. Lines2D.prototype.updateLevelBoundingInfo = function () {
  15997. if (!this._boundingMin) {
  15998. this._computeLines2D();
  15999. }
  16000. BABYLON.BoundingInfo2D.CreateFromMinMaxToRef(this._boundingMin.x, this._boundingMax.x, this._boundingMin.y, this._boundingMax.y, this._levelBoundingInfo);
  16001. return true;
  16002. };
  16003. Lines2D.prototype.createModelRenderCache = function (modelKey) {
  16004. var renderCache = new Lines2DRenderCache(this.owner.engine, modelKey);
  16005. return renderCache;
  16006. };
  16007. ///////////////////////////////////////////////////////////////////////////////////
  16008. // Methods for Lines building
  16009. Lines2D.prototype._perp = function (v, res) {
  16010. res.x = v.y;
  16011. res.y = -v.x;
  16012. };
  16013. ;
  16014. Lines2D.prototype._direction = function (a, b, res) {
  16015. a.subtractToRef(b, res);
  16016. res.normalize();
  16017. };
  16018. Lines2D.prototype._computeMiter = function (tangent, miter, a, b) {
  16019. a.addToRef(b, tangent);
  16020. tangent.normalize();
  16021. miter.x = -tangent.y;
  16022. miter.y = tangent.x;
  16023. Lines2D_1._miterTps.x = -a.y;
  16024. Lines2D_1._miterTps.y = a.x;
  16025. return 1 / BABYLON.Vector2.Dot(miter, Lines2D_1._miterTps);
  16026. };
  16027. Lines2D.prototype._intersect = function (x1, y1, x2, y2, x3, y3, x4, y4) {
  16028. var d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
  16029. if (d === 0)
  16030. return false;
  16031. var xi = ((x3 - x4) * (x1 * y2 - y1 * x2) - (x1 - x2) * (x3 * y4 - y3 * x4)) / d; // Intersection point is xi/yi, just in case...
  16032. //let yi = ((y3 - y4) * (x1 * y2 - y1 * x2) - (y1 - y2) * (x3 * y4 - y3 * x4)) / d; // That's why I left it commented
  16033. if (xi < Math.min(x1, x2) || xi > Math.max(x1, x2))
  16034. return false;
  16035. if (xi < Math.min(x3, x4) || xi > Math.max(x3, x4))
  16036. return false;
  16037. return true;
  16038. };
  16039. Lines2D.prototype._updateMinMax = function (array, offset) {
  16040. if (offset >= array.length) {
  16041. return;
  16042. }
  16043. this._boundingMin.x = Math.min(this._boundingMin.x, array[offset]);
  16044. this._boundingMax.x = Math.max(this._boundingMax.x, array[offset]);
  16045. this._boundingMin.y = Math.min(this._boundingMin.y, array[offset + 1]);
  16046. this._boundingMax.y = Math.max(this._boundingMax.y, array[offset + 1]);
  16047. };
  16048. Lines2D.prototype._store = function (array, contour, index, max, p, n, halfThickness, borderThickness, detectFlip) {
  16049. var borderMode = borderThickness != null && !isNaN(borderThickness);
  16050. var off = index * (borderMode ? 8 : 4);
  16051. // Mandatory because we'll be out of bound in case of closed line, for the very last point (which is a duplicate of the first that we don't store in the vb)
  16052. if (off >= array.length) {
  16053. return;
  16054. }
  16055. // Store start/end normal, we need it for the cap construction
  16056. if (index === 0) {
  16057. this._perp(n, Lines2D_1._startDir);
  16058. }
  16059. else if (index === max - 1) {
  16060. this._perp(n, Lines2D_1._endDir);
  16061. Lines2D_1._endDir.x *= -1;
  16062. Lines2D_1._endDir.y *= -1;
  16063. }
  16064. var swap = false;
  16065. array[off + 0] = p.x + n.x * halfThickness;
  16066. array[off + 1] = p.y + n.y * halfThickness;
  16067. array[off + 2] = p.x + n.x * -halfThickness;
  16068. array[off + 3] = p.y + n.y * -halfThickness;
  16069. this._updateMinMax(array, off);
  16070. this._updateMinMax(array, off + 2);
  16071. // If an index is given we check if the two segments formed between [index+0;detectFlip+0] and [index+2;detectFlip+2] intersect themselves.
  16072. // It should not be the case, they should be parallel, so if they cross, we switch the order of storage to ensure we'll have parallel lines
  16073. if (detectFlip != 0) {
  16074. // Flip if intersect
  16075. var flipOff = detectFlip * (borderMode ? 8 : 4);
  16076. if (this._intersect(array[off + 0], array[off + 1], array[flipOff + 0], array[flipOff + 1], array[off + 2], array[off + 3], array[flipOff + 2], array[flipOff + 3])) {
  16077. swap = true;
  16078. var tps = array[off + 0];
  16079. array[off + 0] = array[off + 2];
  16080. array[off + 2] = tps;
  16081. tps = array[off + 1];
  16082. array[off + 1] = array[off + 3];
  16083. array[off + 3] = tps;
  16084. }
  16085. }
  16086. if (borderMode) {
  16087. var t = halfThickness + borderThickness;
  16088. array[off + 4] = p.x + n.x * (swap ? -t : t);
  16089. array[off + 5] = p.y + n.y * (swap ? -t : t);
  16090. array[off + 6] = p.x + n.x * (swap ? t : -t);
  16091. array[off + 7] = p.y + n.y * (swap ? t : -t);
  16092. this._updateMinMax(array, off + 4);
  16093. this._updateMinMax(array, off + 6);
  16094. }
  16095. if (contour) {
  16096. off += borderMode ? 4 : 0;
  16097. contour.push(new BABYLON.Vector2(array[off + 0], array[off + 1]));
  16098. contour.push(new BABYLON.Vector2(array[off + 2], array[off + 3]));
  16099. }
  16100. };
  16101. Lines2D.prototype._getCapSize = function (type, border) {
  16102. if (border === void 0) { border = false; }
  16103. var sd = Lines2D_1._roundCapSubDiv;
  16104. // If no array given, we call this to get the size
  16105. var vbsize = 0, ibsize = 0;
  16106. switch (type) {
  16107. case Lines2D_1.NoCap:
  16108. {
  16109. // If the line is not close and we're computing border, we add the size to generate the edge border
  16110. if (!this.closed && border) {
  16111. vbsize = 4;
  16112. ibsize = 6;
  16113. }
  16114. else {
  16115. vbsize = ibsize = 0;
  16116. }
  16117. break;
  16118. }
  16119. case Lines2D_1.RoundCap:
  16120. {
  16121. if (border) {
  16122. vbsize = sd;
  16123. ibsize = (sd - 2) * 3;
  16124. }
  16125. else {
  16126. vbsize = (sd / 2) + 1;
  16127. ibsize = (sd / 2) * 3;
  16128. }
  16129. break;
  16130. }
  16131. case Lines2D_1.ArrowCap:
  16132. {
  16133. if (border) {
  16134. vbsize = 12;
  16135. ibsize = 24;
  16136. }
  16137. else {
  16138. vbsize = 3;
  16139. ibsize = 3;
  16140. }
  16141. break;
  16142. }
  16143. case Lines2D_1.TriangleCap:
  16144. {
  16145. if (border) {
  16146. vbsize = 6;
  16147. ibsize = 12;
  16148. }
  16149. else {
  16150. vbsize = 3;
  16151. ibsize = 3;
  16152. }
  16153. break;
  16154. }
  16155. case Lines2D_1.DiamondAnchorCap:
  16156. {
  16157. if (border) {
  16158. vbsize = 10;
  16159. ibsize = 24;
  16160. }
  16161. else {
  16162. vbsize = 5;
  16163. ibsize = 9;
  16164. }
  16165. break;
  16166. }
  16167. case Lines2D_1.SquareAnchorCap:
  16168. {
  16169. if (border) {
  16170. vbsize = 12;
  16171. ibsize = 30;
  16172. }
  16173. else {
  16174. vbsize = 4;
  16175. ibsize = 6;
  16176. }
  16177. break;
  16178. }
  16179. case Lines2D_1.RoundAnchorCap:
  16180. {
  16181. if (border) {
  16182. vbsize = sd * 2;
  16183. ibsize = (sd - 1) * 6;
  16184. }
  16185. else {
  16186. vbsize = sd + 1;
  16187. ibsize = (sd + 1) * 3;
  16188. }
  16189. break;
  16190. }
  16191. }
  16192. return { vbsize: vbsize * 2, ibsize: ibsize };
  16193. };
  16194. Lines2D.prototype._storeVertex = function (vb, baseOffset, index, basePos, rotation, vertex, contour) {
  16195. var c = Math.cos(rotation);
  16196. var s = Math.sin(rotation);
  16197. Lines2D_1._tpsV.x = (c * vertex.x) + (-s * vertex.y) + basePos.x;
  16198. Lines2D_1._tpsV.y = (s * vertex.x) + (c * vertex.y) + basePos.y;
  16199. var offset = baseOffset + (index * 2);
  16200. vb[offset + 0] = Lines2D_1._tpsV.x;
  16201. vb[offset + 1] = Lines2D_1._tpsV.y;
  16202. if (contour) {
  16203. contour.push(Lines2D_1._tpsV.x);
  16204. contour.push(Lines2D_1._tpsV.y);
  16205. }
  16206. this._updateMinMax(vb, offset);
  16207. return (baseOffset + index * 2) / 2;
  16208. };
  16209. Lines2D.prototype._storeIndex = function (ib, baseOffset, index, vertexIndex) {
  16210. ib[baseOffset + index] = vertexIndex;
  16211. };
  16212. Lines2D.prototype._buildCap = function (vb, vbi, ib, ibi, pos, thickness, borderThickness, type, capDir, contour) {
  16213. // Compute the transformation from the direction of the cap to build relative to our default orientation [1;0] (our cap are by default pointing toward right, horizontal
  16214. var sd = Lines2D_1._roundCapSubDiv;
  16215. var dir = new BABYLON.Vector2(1, 0);
  16216. var angle = Math.atan2(capDir.y, capDir.x) - Math.atan2(dir.y, dir.x);
  16217. var ht = thickness / 2;
  16218. var t = thickness;
  16219. var borderMode = borderThickness != null;
  16220. var bt = borderThickness;
  16221. switch (type) {
  16222. case Lines2D_1.NoCap:
  16223. if (borderMode && !this.closed) {
  16224. var vi = 0;
  16225. var ii = 0;
  16226. var v1 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(0, ht + bt), contour);
  16227. var v2 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(bt, ht + bt), contour);
  16228. var v3 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(bt, -(ht + bt)), contour);
  16229. var v4 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(0, -(ht + bt)), contour);
  16230. this._storeIndex(ib, ibi, ii++, v1);
  16231. this._storeIndex(ib, ibi, ii++, v2);
  16232. this._storeIndex(ib, ibi, ii++, v3);
  16233. this._storeIndex(ib, ibi, ii++, v1);
  16234. this._storeIndex(ib, ibi, ii++, v3);
  16235. this._storeIndex(ib, ibi, ii++, v4);
  16236. }
  16237. break;
  16238. case Lines2D_1.ArrowCap:
  16239. ht *= 2;
  16240. case Lines2D_1.TriangleCap:
  16241. {
  16242. if (borderMode) {
  16243. var f = type === Lines2D_1.TriangleCap ? bt : Math.sqrt(bt * bt * 2);
  16244. var v1 = this._storeVertex(vb, vbi, 0, pos, angle, new BABYLON.Vector2(0, ht), null);
  16245. var v2 = this._storeVertex(vb, vbi, 1, pos, angle, new BABYLON.Vector2(ht, 0), null);
  16246. var v3 = this._storeVertex(vb, vbi, 2, pos, angle, new BABYLON.Vector2(0, -ht), null);
  16247. var v4 = this._storeVertex(vb, vbi, 3, pos, angle, new BABYLON.Vector2(0, ht + f), contour);
  16248. var v5 = this._storeVertex(vb, vbi, 4, pos, angle, new BABYLON.Vector2(ht + f, 0), contour);
  16249. var v6 = this._storeVertex(vb, vbi, 5, pos, angle, new BABYLON.Vector2(0, -(ht + f)), contour);
  16250. var ii = 0;
  16251. this._storeIndex(ib, ibi, ii++, v1);
  16252. this._storeIndex(ib, ibi, ii++, v4);
  16253. this._storeIndex(ib, ibi, ii++, v5);
  16254. this._storeIndex(ib, ibi, ii++, v1);
  16255. this._storeIndex(ib, ibi, ii++, v5);
  16256. this._storeIndex(ib, ibi, ii++, v2);
  16257. this._storeIndex(ib, ibi, ii++, v6);
  16258. this._storeIndex(ib, ibi, ii++, v3);
  16259. this._storeIndex(ib, ibi, ii++, v2);
  16260. this._storeIndex(ib, ibi, ii++, v6);
  16261. this._storeIndex(ib, ibi, ii++, v2);
  16262. this._storeIndex(ib, ibi, ii++, v5);
  16263. if (type === Lines2D_1.ArrowCap) {
  16264. var rht = thickness / 2;
  16265. var v10 = this._storeVertex(vb, vbi, 9, pos, angle, new BABYLON.Vector2(0, -(rht + bt)), null);
  16266. var v12 = this._storeVertex(vb, vbi, 11, pos, angle, new BABYLON.Vector2(-bt, -(ht + f)), contour);
  16267. var v11 = this._storeVertex(vb, vbi, 10, pos, angle, new BABYLON.Vector2(-bt, -(rht + bt)), contour);
  16268. var v7 = this._storeVertex(vb, vbi, 6, pos, angle, new BABYLON.Vector2(0, rht + bt), null);
  16269. var v8 = this._storeVertex(vb, vbi, 7, pos, angle, new BABYLON.Vector2(-bt, rht + bt), contour);
  16270. var v9 = this._storeVertex(vb, vbi, 8, pos, angle, new BABYLON.Vector2(-bt, ht + f), contour);
  16271. this._storeIndex(ib, ibi, ii++, v7);
  16272. this._storeIndex(ib, ibi, ii++, v8);
  16273. this._storeIndex(ib, ibi, ii++, v9);
  16274. this._storeIndex(ib, ibi, ii++, v7);
  16275. this._storeIndex(ib, ibi, ii++, v9);
  16276. this._storeIndex(ib, ibi, ii++, v4);
  16277. this._storeIndex(ib, ibi, ii++, v10);
  16278. this._storeIndex(ib, ibi, ii++, v12);
  16279. this._storeIndex(ib, ibi, ii++, v11);
  16280. this._storeIndex(ib, ibi, ii++, v10);
  16281. this._storeIndex(ib, ibi, ii++, v6);
  16282. this._storeIndex(ib, ibi, ii++, v12);
  16283. }
  16284. }
  16285. else {
  16286. var v1 = this._storeVertex(vb, vbi, 0, pos, angle, new BABYLON.Vector2(0, ht), contour);
  16287. var v2 = this._storeVertex(vb, vbi, 1, pos, angle, new BABYLON.Vector2(ht, 0), contour);
  16288. var v3 = this._storeVertex(vb, vbi, 2, pos, angle, new BABYLON.Vector2(0, -ht), contour);
  16289. this._storeIndex(ib, ibi, 0, v1);
  16290. this._storeIndex(ib, ibi, 1, v2);
  16291. this._storeIndex(ib, ibi, 2, v3);
  16292. }
  16293. break;
  16294. }
  16295. case Lines2D_1.RoundCap:
  16296. {
  16297. if (borderMode) {
  16298. var curA = -Math.PI / 2;
  16299. var incA = Math.PI / (sd / 2 - 1);
  16300. var ii = 0;
  16301. for (var i = 0; i < (sd / 2); i++) {
  16302. var v1 = this._storeVertex(vb, vbi, i * 2 + 0, pos, angle, new BABYLON.Vector2(Math.cos(curA) * ht, Math.sin(curA) * ht), null);
  16303. var v2 = this._storeVertex(vb, vbi, i * 2 + 1, pos, angle, new BABYLON.Vector2(Math.cos(curA) * (ht + bt), Math.sin(curA) * (ht + bt)), contour);
  16304. if (i > 0) {
  16305. this._storeIndex(ib, ibi, ii++, v1 - 2);
  16306. this._storeIndex(ib, ibi, ii++, v2 - 2);
  16307. this._storeIndex(ib, ibi, ii++, v2);
  16308. this._storeIndex(ib, ibi, ii++, v1 - 2);
  16309. this._storeIndex(ib, ibi, ii++, v2);
  16310. this._storeIndex(ib, ibi, ii++, v1);
  16311. }
  16312. curA += incA;
  16313. }
  16314. }
  16315. else {
  16316. var c = this._storeVertex(vb, vbi, 0, pos, angle, new BABYLON.Vector2(0, 0), null);
  16317. var curA = -Math.PI / 2;
  16318. var incA = Math.PI / (sd / 2 - 1);
  16319. this._storeVertex(vb, vbi, 1, pos, angle, new BABYLON.Vector2(Math.cos(curA) * ht, Math.sin(curA) * ht), null);
  16320. curA += incA;
  16321. for (var i = 1; i < (sd / 2); i++) {
  16322. var v2 = this._storeVertex(vb, vbi, i + 1, pos, angle, new BABYLON.Vector2(Math.cos(curA) * ht, Math.sin(curA) * ht), contour);
  16323. this._storeIndex(ib, ibi, i * 3 + 0, c);
  16324. this._storeIndex(ib, ibi, i * 3 + 1, v2 - 1);
  16325. this._storeIndex(ib, ibi, i * 3 + 2, v2);
  16326. curA += incA;
  16327. }
  16328. }
  16329. break;
  16330. }
  16331. case Lines2D_1.SquareAnchorCap:
  16332. {
  16333. var vi = 0;
  16334. var c = borderMode ? null : contour;
  16335. var v1 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(0, t), c);
  16336. var v2 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(t * 2, t), c);
  16337. var v3 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(t * 2, -t), c);
  16338. var v4 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(0, -t), c);
  16339. if (borderMode) {
  16340. var v5 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(0, ht + bt), null);
  16341. var v6 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(-bt, ht + bt), contour);
  16342. var v7 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(-bt, t + bt), contour);
  16343. var v8 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(t * 2 + bt, t + bt), contour);
  16344. var v9 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(t * 2 + bt, -(t + bt)), contour);
  16345. var v10 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(-bt, -(t + bt)), contour);
  16346. var v11 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(-bt, -(ht + bt)), contour);
  16347. var v12 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(0, -(ht + bt)), null);
  16348. var ii = 0;
  16349. this._storeIndex(ib, ibi, ii++, v6);
  16350. this._storeIndex(ib, ibi, ii++, v1);
  16351. this._storeIndex(ib, ibi, ii++, v5);
  16352. this._storeIndex(ib, ibi, ii++, v6);
  16353. this._storeIndex(ib, ibi, ii++, v7);
  16354. this._storeIndex(ib, ibi, ii++, v1);
  16355. this._storeIndex(ib, ibi, ii++, v1);
  16356. this._storeIndex(ib, ibi, ii++, v7);
  16357. this._storeIndex(ib, ibi, ii++, v8);
  16358. this._storeIndex(ib, ibi, ii++, v1);
  16359. this._storeIndex(ib, ibi, ii++, v8);
  16360. this._storeIndex(ib, ibi, ii++, v2);
  16361. this._storeIndex(ib, ibi, ii++, v2);
  16362. this._storeIndex(ib, ibi, ii++, v8);
  16363. this._storeIndex(ib, ibi, ii++, v9);
  16364. this._storeIndex(ib, ibi, ii++, v2);
  16365. this._storeIndex(ib, ibi, ii++, v9);
  16366. this._storeIndex(ib, ibi, ii++, v3);
  16367. this._storeIndex(ib, ibi, ii++, v3);
  16368. this._storeIndex(ib, ibi, ii++, v9);
  16369. this._storeIndex(ib, ibi, ii++, v10);
  16370. this._storeIndex(ib, ibi, ii++, v3);
  16371. this._storeIndex(ib, ibi, ii++, v10);
  16372. this._storeIndex(ib, ibi, ii++, v4);
  16373. this._storeIndex(ib, ibi, ii++, v10);
  16374. this._storeIndex(ib, ibi, ii++, v11);
  16375. this._storeIndex(ib, ibi, ii++, v4);
  16376. this._storeIndex(ib, ibi, ii++, v11);
  16377. this._storeIndex(ib, ibi, ii++, v12);
  16378. this._storeIndex(ib, ibi, ii++, v4);
  16379. }
  16380. else {
  16381. this._storeIndex(ib, ibi, 0, v1);
  16382. this._storeIndex(ib, ibi, 1, v2);
  16383. this._storeIndex(ib, ibi, 2, v3);
  16384. this._storeIndex(ib, ibi, 3, v1);
  16385. this._storeIndex(ib, ibi, 4, v3);
  16386. this._storeIndex(ib, ibi, 5, v4);
  16387. }
  16388. break;
  16389. }
  16390. case Lines2D_1.RoundAnchorCap:
  16391. {
  16392. var cpos = Math.sqrt(t * t - ht * ht);
  16393. var center = new BABYLON.Vector2(cpos, 0);
  16394. var curA = BABYLON.Tools.ToRadians(-150);
  16395. var incA = BABYLON.Tools.ToRadians(300) / (sd - 1);
  16396. if (borderMode) {
  16397. var ii = 0;
  16398. for (var i = 0; i < sd; i++) {
  16399. var v1 = this._storeVertex(vb, vbi, i * 2 + 0, pos, angle, new BABYLON.Vector2(cpos + Math.cos(curA) * t, Math.sin(curA) * t), null);
  16400. var v2 = this._storeVertex(vb, vbi, i * 2 + 1, pos, angle, new BABYLON.Vector2(cpos + Math.cos(curA) * (t + bt), Math.sin(curA) * (t + bt)), contour);
  16401. if (i > 0) {
  16402. this._storeIndex(ib, ibi, ii++, v1 - 2);
  16403. this._storeIndex(ib, ibi, ii++, v2 - 2);
  16404. this._storeIndex(ib, ibi, ii++, v2);
  16405. this._storeIndex(ib, ibi, ii++, v1 - 2);
  16406. this._storeIndex(ib, ibi, ii++, v2);
  16407. this._storeIndex(ib, ibi, ii++, v1);
  16408. }
  16409. curA += incA;
  16410. }
  16411. }
  16412. else {
  16413. var c = this._storeVertex(vb, vbi, 0, pos, angle, center, null);
  16414. this._storeVertex(vb, vbi, 1, pos, angle, new BABYLON.Vector2(cpos + Math.cos(curA) * t, Math.sin(curA) * t), null);
  16415. curA += incA;
  16416. for (var i = 1; i < sd; i++) {
  16417. var v2 = this._storeVertex(vb, vbi, i + 1, pos, angle, new BABYLON.Vector2(cpos + Math.cos(curA) * t, Math.sin(curA) * t), contour);
  16418. this._storeIndex(ib, ibi, i * 3 + 0, c);
  16419. this._storeIndex(ib, ibi, i * 3 + 1, v2 - 1);
  16420. this._storeIndex(ib, ibi, i * 3 + 2, v2);
  16421. curA += incA;
  16422. }
  16423. this._storeIndex(ib, ibi, sd * 3 + 0, c);
  16424. this._storeIndex(ib, ibi, sd * 3 + 1, c + 1);
  16425. this._storeIndex(ib, ibi, sd * 3 + 2, c + sd);
  16426. }
  16427. break;
  16428. }
  16429. case Lines2D_1.DiamondAnchorCap:
  16430. {
  16431. var vi = 0;
  16432. var c = borderMode ? null : contour;
  16433. var v1 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(0, ht), c);
  16434. var v2 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(ht, t), c);
  16435. var v3 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(ht * 3, 0), c);
  16436. var v4 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(ht, -t), c);
  16437. var v5 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(0, -ht), c);
  16438. if (borderMode) {
  16439. var f = Math.sqrt(bt * bt * 2);
  16440. var v6 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(-f, ht), contour);
  16441. var v7 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(ht, t + f), contour);
  16442. var v8 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(ht * 3 + f, 0), contour);
  16443. var v9 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(ht, -(t + f)), contour);
  16444. var v10 = this._storeVertex(vb, vbi, vi++, pos, angle, new BABYLON.Vector2(-f, -ht), contour);
  16445. var ii = 0;
  16446. this._storeIndex(ib, ibi, ii++, v6);
  16447. this._storeIndex(ib, ibi, ii++, v7);
  16448. this._storeIndex(ib, ibi, ii++, v1);
  16449. this._storeIndex(ib, ibi, ii++, v1);
  16450. this._storeIndex(ib, ibi, ii++, v7);
  16451. this._storeIndex(ib, ibi, ii++, v2);
  16452. this._storeIndex(ib, ibi, ii++, v2);
  16453. this._storeIndex(ib, ibi, ii++, v7);
  16454. this._storeIndex(ib, ibi, ii++, v8);
  16455. this._storeIndex(ib, ibi, ii++, v2);
  16456. this._storeIndex(ib, ibi, ii++, v8);
  16457. this._storeIndex(ib, ibi, ii++, v3);
  16458. this._storeIndex(ib, ibi, ii++, v3);
  16459. this._storeIndex(ib, ibi, ii++, v8);
  16460. this._storeIndex(ib, ibi, ii++, v9);
  16461. this._storeIndex(ib, ibi, ii++, v3);
  16462. this._storeIndex(ib, ibi, ii++, v9);
  16463. this._storeIndex(ib, ibi, ii++, v4);
  16464. this._storeIndex(ib, ibi, ii++, v4);
  16465. this._storeIndex(ib, ibi, ii++, v9);
  16466. this._storeIndex(ib, ibi, ii++, v10);
  16467. this._storeIndex(ib, ibi, ii++, v4);
  16468. this._storeIndex(ib, ibi, ii++, v10);
  16469. this._storeIndex(ib, ibi, ii++, v5);
  16470. }
  16471. else {
  16472. this._storeIndex(ib, ibi, 0, v1);
  16473. this._storeIndex(ib, ibi, 1, v2);
  16474. this._storeIndex(ib, ibi, 2, v3);
  16475. this._storeIndex(ib, ibi, 3, v1);
  16476. this._storeIndex(ib, ibi, 4, v3);
  16477. this._storeIndex(ib, ibi, 5, v5);
  16478. this._storeIndex(ib, ibi, 6, v5);
  16479. this._storeIndex(ib, ibi, 7, v3);
  16480. this._storeIndex(ib, ibi, 8, v4);
  16481. }
  16482. break;
  16483. }
  16484. }
  16485. return null;
  16486. };
  16487. Lines2D.prototype._buildLine = function (vb, contour, ht, bt) {
  16488. var lineA = BABYLON.Vector2.Zero();
  16489. var lineB = BABYLON.Vector2.Zero();
  16490. var tangent = BABYLON.Vector2.Zero();
  16491. var miter = BABYLON.Vector2.Zero();
  16492. var curNormal = null;
  16493. if (this.closed) {
  16494. this.points.push(this.points[0]);
  16495. }
  16496. var total = this.points.length;
  16497. for (var i = 1; i < total; i++) {
  16498. var last = this.points[i - 1];
  16499. var cur = this.points[i];
  16500. var next = (i < (this.points.length - 1)) ? this.points[i + 1] : null;
  16501. this._direction(cur, last, lineA);
  16502. if (!curNormal) {
  16503. curNormal = BABYLON.Vector2.Zero();
  16504. this._perp(lineA, curNormal);
  16505. }
  16506. if (i === 1) {
  16507. this._store(vb, contour, 0, total, this.points[0], curNormal, ht, bt);
  16508. }
  16509. if (!next) {
  16510. this._perp(lineA, curNormal);
  16511. this._store(vb, contour, i, total, this.points[i], curNormal, ht, bt, i - 1);
  16512. }
  16513. else {
  16514. this._direction(next, cur, lineB);
  16515. var miterLen = this._computeMiter(tangent, miter, lineA, lineB);
  16516. this._store(vb, contour, i, total, this.points[i], miter, miterLen * ht, miterLen * bt, i - 1);
  16517. }
  16518. }
  16519. if (this.points.length > 2 && this.closed) {
  16520. var last2 = this.points[total - 2];
  16521. var cur2 = this.points[0];
  16522. var next2 = this.points[1];
  16523. this._direction(cur2, last2, lineA);
  16524. this._direction(next2, cur2, lineB);
  16525. this._perp(lineA, curNormal);
  16526. var miterLen2 = this._computeMiter(tangent, miter, lineA, lineB);
  16527. this._store(vb, null, 0, total, this.points[0], miter, miterLen2 * ht, miterLen2 * bt, 1);
  16528. // Patch contour
  16529. if (contour) {
  16530. var off = (bt == null) ? 0 : 4;
  16531. contour[0].x = vb[off + 0];
  16532. contour[0].y = vb[off + 1];
  16533. contour[1].x = vb[off + 2];
  16534. contour[1].y = vb[off + 3];
  16535. }
  16536. }
  16537. // Remove the point we added at the beginning
  16538. if (this.closed) {
  16539. this.points.splice(total - 1);
  16540. }
  16541. };
  16542. // Methods for Lines building
  16543. ///////////////////////////////////////////////////////////////////////////////////
  16544. Lines2D.prototype.setupModelRenderCache = function (modelRenderCache) {
  16545. var renderCache = modelRenderCache;
  16546. var engine = this.owner.engine;
  16547. if (this._fillVB === null) {
  16548. this._computeLines2D();
  16549. }
  16550. // Need to create WebGL resources for fill part?
  16551. if (this.fill) {
  16552. renderCache.fillVB = engine.createVertexBuffer(this._fillVB);
  16553. renderCache.fillIB = engine.createIndexBuffer(this._fillIB);
  16554. renderCache.fillIndicesCount = this._fillIB.length;
  16555. // Get the instanced version of the effect, if the engine does not support it, null is return and we'll only draw on by one
  16556. var ei = this.getDataPartEffectInfo(BABYLON.Shape2D.SHAPE2D_FILLPARTID, ["position"], null, true);
  16557. if (ei) {
  16558. renderCache.effectFillInstanced = engine.createEffect("lines2d", ei.attributes, ei.uniforms, [], ei.defines, null);
  16559. }
  16560. // Get the non instanced version
  16561. ei = this.getDataPartEffectInfo(BABYLON.Shape2D.SHAPE2D_FILLPARTID, ["position"], null, false);
  16562. renderCache.effectFill = engine.createEffect("lines2d", ei.attributes, ei.uniforms, [], ei.defines, null);
  16563. }
  16564. // Need to create WebGL resources for border part?
  16565. if (this.border) {
  16566. renderCache.borderVB = engine.createVertexBuffer(this._borderVB);
  16567. renderCache.borderIB = engine.createIndexBuffer(this._borderIB);
  16568. renderCache.borderIndicesCount = this._borderIB.length;
  16569. // Get the instanced version of the effect, if the engine does not support it, null is return and we'll only draw on by one
  16570. var ei = this.getDataPartEffectInfo(BABYLON.Shape2D.SHAPE2D_BORDERPARTID, ["position"], null, true);
  16571. if (ei) {
  16572. renderCache.effectBorderInstanced = engine.createEffect({ vertex: "lines2d", fragment: "lines2d" }, ei.attributes, ei.uniforms, [], ei.defines, null);
  16573. }
  16574. // Get the non instanced version
  16575. ei = this.getDataPartEffectInfo(BABYLON.Shape2D.SHAPE2D_BORDERPARTID, ["position"], null, false);
  16576. renderCache.effectBorder = engine.createEffect({ vertex: "lines2d", fragment: "lines2d" }, ei.attributes, ei.uniforms, [], ei.defines, null);
  16577. }
  16578. this._fillVB = null;
  16579. this._fillIB = null;
  16580. this._borderVB = null;
  16581. this._borderIB = null;
  16582. return renderCache;
  16583. };
  16584. Lines2D.prototype.updateTriArray = function () {
  16585. if (this._primTriArrayDirty) {
  16586. this._computeLines2D();
  16587. }
  16588. };
  16589. Lines2D.prototype._computeLines2D = function () {
  16590. // Init min/max because their being computed here
  16591. this._boundingMin = new BABYLON.Vector2(Number.MAX_VALUE, Number.MAX_VALUE);
  16592. this._boundingMax = new BABYLON.Vector2(Number.MIN_VALUE, Number.MIN_VALUE);
  16593. var contour = new Array();
  16594. var startCapContour = new Array();
  16595. var endCapContour = new Array();
  16596. // Need to create WebGL resources for fill part?
  16597. if (this.fill) {
  16598. var startCapInfo = this._getCapSize(this.startCap);
  16599. var endCapInfo = this._getCapSize(this.endCap);
  16600. var count = this.points.length;
  16601. var vbSize = (count * 2 * 2) + startCapInfo.vbsize + endCapInfo.vbsize;
  16602. this._fillVB = new Float32Array(vbSize);
  16603. var vb = this._fillVB;
  16604. var ht = this.fillThickness / 2;
  16605. var total = this.points.length;
  16606. this._buildLine(vb, this.border ? null : contour, ht);
  16607. var max = total * 2;
  16608. var triCount = (count - (this.closed ? 0 : 1)) * 2;
  16609. this._fillIB = new Float32Array(triCount * 3 + startCapInfo.ibsize + endCapInfo.ibsize);
  16610. var ib = this._fillIB;
  16611. for (var i = 0; i < triCount; i += 2) {
  16612. ib[i * 3 + 0] = i + 0;
  16613. ib[i * 3 + 1] = i + 1;
  16614. ib[i * 3 + 2] = (i + 2) % max;
  16615. ib[i * 3 + 3] = i + 1;
  16616. ib[i * 3 + 4] = (i + 3) % max;
  16617. ib[i * 3 + 5] = (i + 2) % max;
  16618. }
  16619. this._buildCap(vb, count * 2 * 2, ib, triCount * 3, this.points[0], this.fillThickness, null, this.startCap, Lines2D_1._startDir, this.border ? null : startCapContour);
  16620. this._buildCap(vb, (count * 2 * 2) + startCapInfo.vbsize, ib, (triCount * 3) + startCapInfo.ibsize, this.points[total - 1], this.fillThickness, null, this.endCap, Lines2D_1._endDir, this.border ? null : startCapContour);
  16621. }
  16622. // Need to create WebGL resources for border part?
  16623. if (this.border) {
  16624. var startCapInfo = this._getCapSize(this.startCap, true);
  16625. var endCapInfo = this._getCapSize(this.endCap, true);
  16626. var count = this.points.length;
  16627. var vbSize = (count * 2 * 2 * 2) + startCapInfo.vbsize + endCapInfo.vbsize;
  16628. this._borderVB = new Float32Array(vbSize);
  16629. var vb = this._borderVB;
  16630. var ht = this.fillThickness / 2;
  16631. var bt = this.borderThickness;
  16632. var total = this.points.length;
  16633. this._buildLine(vb, contour, ht, bt);
  16634. var max = total * 2 * 2;
  16635. var triCount = (count - (this.closed ? 0 : 1)) * 2 * 2;
  16636. this._borderIB = new Float32Array(triCount * 3 + startCapInfo.ibsize + endCapInfo.ibsize);
  16637. var ib = this._borderIB;
  16638. for (var i = 0; i < triCount; i += 4) {
  16639. ib[i * 3 + 0] = i + 0;
  16640. ib[i * 3 + 1] = i + 2;
  16641. ib[i * 3 + 2] = (i + 6) % max;
  16642. ib[i * 3 + 3] = i + 0;
  16643. ib[i * 3 + 4] = (i + 6) % max;
  16644. ib[i * 3 + 5] = (i + 4) % max;
  16645. ib[i * 3 + 6] = i + 3;
  16646. ib[i * 3 + 7] = i + 1;
  16647. ib[i * 3 + 8] = (i + 5) % max;
  16648. ib[i * 3 + 9] = i + 3;
  16649. ib[i * 3 + 10] = (i + 5) % max;
  16650. ib[i * 3 + 11] = (i + 7) % max;
  16651. }
  16652. this._buildCap(vb, count * 2 * 2 * 2, ib, triCount * 3, this.points[0], this.fillThickness, this.borderThickness, this.startCap, Lines2D_1._startDir, startCapContour);
  16653. this._buildCap(vb, (count * 2 * 2 * 2) + startCapInfo.vbsize, ib, (triCount * 3) + startCapInfo.ibsize, this.points[total - 1], this.fillThickness, this.borderThickness, this.endCap, Lines2D_1._endDir, endCapContour);
  16654. }
  16655. var startCapTri;
  16656. if (startCapContour.length > 0) {
  16657. startCapTri = Earcut.earcut(startCapContour, null, 2);
  16658. }
  16659. var endCapTri;
  16660. if (endCapContour.length > 0) {
  16661. endCapTri = Earcut.earcut(endCapContour, null, 2);
  16662. }
  16663. // Build the Tri2DArray using the contour info from the shape and the caps (if any)
  16664. {
  16665. var pl = this.points.length;
  16666. // Count the number of needed triangles
  16667. var count = ((this.closed ? pl : (pl - 1)) * 2) + (startCapTri != null ? ((startCapTri.length + endCapTri.length) / 3) : 0);
  16668. // Init/Clear the TriArray
  16669. if (!this._primTriArray) {
  16670. this._primTriArray = new BABYLON.Tri2DArray(count);
  16671. }
  16672. else {
  16673. this._primTriArray.clear(count);
  16674. }
  16675. var pta_1 = this._primTriArray;
  16676. var l = this.closed ? pl + 1 : pl;
  16677. Lines2D_1._prevA.copyFrom(contour[0]);
  16678. Lines2D_1._prevB.copyFrom(contour[1]);
  16679. var si_1 = 0;
  16680. for (var i = 1; i < l; i++) {
  16681. Lines2D_1._curA.copyFrom(contour[(i % pl) * 2 + 0]);
  16682. Lines2D_1._curB.copyFrom(contour[(i % pl) * 2 + 1]);
  16683. pta_1.storeTriangle(si_1++, Lines2D_1._prevA, Lines2D_1._prevB, Lines2D_1._curA);
  16684. pta_1.storeTriangle(si_1++, Lines2D_1._curA, Lines2D_1._prevB, Lines2D_1._curB);
  16685. Lines2D_1._prevA.x = Lines2D_1._curA.x;
  16686. Lines2D_1._prevA.y = Lines2D_1._curA.y;
  16687. Lines2D_1._prevB.x = Lines2D_1._curB.x;
  16688. Lines2D_1._prevB.y = Lines2D_1._curB.y;
  16689. }
  16690. var capIntersect = function (tri, points) {
  16691. var l = tri.length;
  16692. for (var i = 0; i < l; i += 3) {
  16693. Lines2D_1._curA.x = points[tri[i + 0] * 2 + 0];
  16694. Lines2D_1._curA.y = points[tri[i + 0] * 2 + 1];
  16695. Lines2D_1._curB.copyFrom(Lines2D_1._curA);
  16696. Lines2D_1._curA.x = points[tri[i + 1] * 2 + 0];
  16697. Lines2D_1._curA.y = points[tri[i + 1] * 2 + 1];
  16698. Lines2D_1._prevA.copyFrom(Lines2D_1._curA);
  16699. Lines2D_1._curA.x = points[tri[i + 2] * 2 + 0];
  16700. Lines2D_1._curA.y = points[tri[i + 2] * 2 + 1];
  16701. Lines2D_1._prevB.copyFrom(Lines2D_1._curA);
  16702. pta_1.storeTriangle(si_1++, Lines2D_1._prevA, Lines2D_1._prevB, Lines2D_1._curB);
  16703. }
  16704. return false;
  16705. };
  16706. if (startCapTri) {
  16707. if (startCapTri) {
  16708. capIntersect(startCapTri, startCapContour);
  16709. }
  16710. if (endCapTri) {
  16711. capIntersect(endCapTri, endCapContour);
  16712. }
  16713. }
  16714. this._primTriArrayDirty = false;
  16715. }
  16716. var bs = this._boundingMax.subtract(this._boundingMin);
  16717. // If the size is not size we were computing the first pass to determine the size took by the primitive
  16718. if (!this._size) {
  16719. // Set the size and compute a second time to consider the size while computing the points using the origin
  16720. this._size = new BABYLON.Size(bs.x, bs.y);
  16721. this._updatePositioningState();
  16722. }
  16723. this._size.width = bs.x;
  16724. this._size.height = bs.y;
  16725. this._actualSize = null;
  16726. };
  16727. Object.defineProperty(Lines2D.prototype, "size", {
  16728. get: function () {
  16729. if (this._size == null) {
  16730. this._computeLines2D();
  16731. }
  16732. return this._size;
  16733. },
  16734. enumerable: true,
  16735. configurable: true
  16736. });
  16737. Lines2D.prototype.createInstanceDataParts = function () {
  16738. var res = new Array();
  16739. if (this.border) {
  16740. res.push(new Lines2DInstanceData(BABYLON.Shape2D.SHAPE2D_BORDERPARTID));
  16741. }
  16742. if (this.fill) {
  16743. res.push(new Lines2DInstanceData(BABYLON.Shape2D.SHAPE2D_FILLPARTID));
  16744. }
  16745. return res;
  16746. };
  16747. Lines2D.prototype.applyActualScaleOnTransform = function () {
  16748. return true;
  16749. };
  16750. Lines2D.prototype.refreshInstanceDataPart = function (part) {
  16751. if (!_super.prototype.refreshInstanceDataPart.call(this, part)) {
  16752. return false;
  16753. }
  16754. if (part.id === BABYLON.Shape2D.SHAPE2D_BORDERPARTID) {
  16755. var d = part;
  16756. if (this.border instanceof BABYLON.GradientColorBrush2D) {
  16757. d.boundingMin = this.boundingMin;
  16758. d.boundingMax = this.boundingMax;
  16759. }
  16760. }
  16761. else if (part.id === BABYLON.Shape2D.SHAPE2D_FILLPARTID) {
  16762. var d = part;
  16763. if (this.fill instanceof BABYLON.GradientColorBrush2D) {
  16764. d.boundingMin = this.boundingMin;
  16765. d.boundingMax = this.boundingMax;
  16766. }
  16767. }
  16768. return true;
  16769. };
  16770. return Lines2D;
  16771. }(BABYLON.Shape2D));
  16772. Lines2D._prevA = BABYLON.Vector2.Zero();
  16773. Lines2D._prevB = BABYLON.Vector2.Zero();
  16774. Lines2D._curA = BABYLON.Vector2.Zero();
  16775. Lines2D._curB = BABYLON.Vector2.Zero();
  16776. Lines2D._miterTps = BABYLON.Vector2.Zero();
  16777. Lines2D._startDir = BABYLON.Vector2.Zero();
  16778. Lines2D._endDir = BABYLON.Vector2.Zero();
  16779. Lines2D._tpsV = BABYLON.Vector2.Zero();
  16780. Lines2D._noCap = 0;
  16781. Lines2D._roundCap = 1;
  16782. Lines2D._triangleCap = 2;
  16783. Lines2D._squareAnchorCap = 3;
  16784. Lines2D._roundAnchorCap = 4;
  16785. Lines2D._diamondAnchorCap = 5;
  16786. Lines2D._arrowCap = 6;
  16787. Lines2D._roundCapSubDiv = 36;
  16788. __decorate([
  16789. BABYLON.modelLevelProperty(BABYLON.Shape2D.SHAPE2D_PROPCOUNT + 1, function (pi) { return Lines2D_1.pointsProperty = pi; })
  16790. /**
  16791. * Get the list of points that define the Lines2D primitive. You shouldn't try to change the list or its content. it's not supported right now.
  16792. */
  16793. ], Lines2D.prototype, "points", null);
  16794. __decorate([
  16795. BABYLON.modelLevelProperty(BABYLON.Shape2D.SHAPE2D_PROPCOUNT + 2, function (pi) { return Lines2D_1.fillThicknessProperty = pi; })
  16796. /**
  16797. * Get the thickness of the line. You shouldn't try to change this value, it's not supported right now.
  16798. */
  16799. ], Lines2D.prototype, "fillThickness", null);
  16800. __decorate([
  16801. BABYLON.modelLevelProperty(BABYLON.Shape2D.SHAPE2D_PROPCOUNT + 3, function (pi) { return Lines2D_1.closedProperty = pi; })
  16802. /**
  16803. * Get if the Lines2D is a closed shape (true) or an opened one (false).
  16804. * Don't change this property, setter is for internal purpose only.
  16805. */
  16806. ], Lines2D.prototype, "closed", null);
  16807. __decorate([
  16808. BABYLON.modelLevelProperty(BABYLON.Shape2D.SHAPE2D_PROPCOUNT + 4, function (pi) { return Lines2D_1.startCapProperty = pi; })
  16809. /**
  16810. * Get the start cap of the line. You shouldn't try to change this value, it's not supported right now.
  16811. */
  16812. ], Lines2D.prototype, "startCap", null);
  16813. __decorate([
  16814. BABYLON.modelLevelProperty(BABYLON.Shape2D.SHAPE2D_PROPCOUNT + 5, function (pi) { return Lines2D_1.endCapProperty = pi; })
  16815. /**
  16816. * Get the end cap of the line. You shouldn't try to change this value, it's not supported right now.
  16817. */
  16818. ], Lines2D.prototype, "endCap", null);
  16819. Lines2D = Lines2D_1 = __decorate([
  16820. BABYLON.className("Lines2D", "BABYLON")
  16821. /**
  16822. * Primitive drawing a series of line segments
  16823. */
  16824. ], Lines2D);
  16825. BABYLON.Lines2D = Lines2D;
  16826. var Lines2D_1;
  16827. })(BABYLON || (BABYLON = {}));
  16828. var __extends = (this && this.__extends) || (function () {
  16829. var extendStatics = Object.setPrototypeOf ||
  16830. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  16831. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  16832. return function (d, b) {
  16833. extendStatics(d, b);
  16834. function __() { this.constructor = d; }
  16835. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  16836. };
  16837. })();
  16838. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  16839. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  16840. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  16841. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  16842. return c > 3 && r && Object.defineProperty(target, key, r), r;
  16843. };
  16844. var BABYLON;
  16845. (function (BABYLON) {
  16846. // This class contains data that lifetime is bounding to the Babylon Engine object
  16847. var Canvas2DEngineBoundData = (function () {
  16848. function Canvas2DEngineBoundData() {
  16849. this._modelCache = new BABYLON.StringDictionary();
  16850. }
  16851. Canvas2DEngineBoundData.prototype.GetOrAddModelCache = function (key, factory) {
  16852. return this._modelCache.getOrAddWithFactory(key, factory);
  16853. };
  16854. Canvas2DEngineBoundData.prototype.DisposeModelRenderCache = function (modelRenderCache) {
  16855. if (!modelRenderCache.isDisposed) {
  16856. return false;
  16857. }
  16858. this._modelCache.remove(modelRenderCache.modelKey);
  16859. return true;
  16860. };
  16861. return Canvas2DEngineBoundData;
  16862. }());
  16863. BABYLON.Canvas2DEngineBoundData = Canvas2DEngineBoundData;
  16864. var Canvas2D = Canvas2D_1 = (function (_super) {
  16865. __extends(Canvas2D, _super);
  16866. function Canvas2D(scene, settings) {
  16867. var _this = _super.call(this, settings) || this;
  16868. /**
  16869. * If you set your own WorldSpaceNode to display the Canvas2D you have to provide your own implementation of this method which computes the local position in the Canvas based on the given 3D World one.
  16870. * Beware that you have to take under consideration the origin and unitScaleFactor in your calculations! Good luck!
  16871. */
  16872. _this.worldSpaceToNodeLocal = function (worldPos) {
  16873. var node = _this._worldSpaceNode;
  16874. if (!node) {
  16875. return;
  16876. }
  16877. var mtx = node.getWorldMatrix().clone();
  16878. mtx.invert();
  16879. var usf = _this.unitScaleFactor;
  16880. var v = BABYLON.Vector3.TransformCoordinates(worldPos, mtx);
  16881. var res = new BABYLON.Vector2(v.x, v.y);
  16882. var size = _this.actualSize;
  16883. res.x += (size.width / usf) * 0.5; // res is centered, make it relative to bottom/left
  16884. res.y += (size.height / usf) * 0.5;
  16885. res.x *= usf; // multiply by the unitScaleFactor, which defines if the canvas is nth time bigger than the original world plane
  16886. res.y *= usf;
  16887. return res;
  16888. };
  16889. /**
  16890. * If you use a custom WorldSpaceCanvasNode you have to override this property to update the UV of your object to reflect the changes due to a resizing of the cached bitmap
  16891. */
  16892. _this.worldSpaceCacheChanged = function () {
  16893. var plane = _this.worldSpaceCanvasNode;
  16894. var vd = BABYLON.VertexData.ExtractFromMesh(plane); //new VertexData();
  16895. vd.uvs = new Float32Array(8);
  16896. var material = plane.material;
  16897. var tex = _this._renderableData._cacheTexture;
  16898. if (material.diffuseTexture !== tex) {
  16899. material.diffuseTexture = tex;
  16900. tex.hasAlpha = true;
  16901. }
  16902. var nodeuv = _this._renderableData._cacheNodeUVs;
  16903. for (var i = 0; i < 4; i++) {
  16904. vd.uvs[i * 2 + 0] = nodeuv[i].x;
  16905. vd.uvs[i * 2 + 1] = nodeuv[i].y;
  16906. }
  16907. vd.applyToMesh(plane);
  16908. };
  16909. _this._notifDebugMode = false;
  16910. /**
  16911. * Instanced Array will be create if there's at least this number of parts/prim that can fit into it
  16912. */
  16913. _this.minPartCountToUseInstancedArray = 5;
  16914. _this._mapCounter = 0;
  16915. _this._cachedCanvasGroup = null;
  16916. _this._renderingGroupObserver = null;
  16917. _this._beforeRenderObserver = null;
  16918. _this._afterRenderObserver = null;
  16919. _this._profileInfoText = null;
  16920. BABYLON.Prim2DBase._isCanvasInit = false;
  16921. if (!settings) {
  16922. settings = {};
  16923. }
  16924. if (_this._cachingStrategy !== Canvas2D_1.CACHESTRATEGY_TOPLEVELGROUPS) {
  16925. _this._background = new BABYLON.Rectangle2D({ parent: _this, id: "###CANVAS BACKGROUND###", size: settings.size }); //TODO CHECK when size is null
  16926. _this._background.zOrder = 1.0;
  16927. _this._background.isPickable = false;
  16928. _this._background.origin = BABYLON.Vector2.Zero();
  16929. _this._background.levelVisible = false;
  16930. if (settings.backgroundRoundRadius != null) {
  16931. _this.backgroundRoundRadius = settings.backgroundRoundRadius;
  16932. }
  16933. if (settings.backgroundBorder != null) {
  16934. if (typeof (settings.backgroundBorder) === "string") {
  16935. _this.backgroundBorder = Canvas2D_1.GetBrushFromString(settings.backgroundBorder);
  16936. }
  16937. else {
  16938. _this.backgroundBorder = settings.backgroundBorder;
  16939. }
  16940. }
  16941. if (settings.backgroundBorderThickNess != null) {
  16942. _this.backgroundBorderThickness = settings.backgroundBorderThickNess;
  16943. }
  16944. if (settings.backgroundFill != null) {
  16945. if (typeof (settings.backgroundFill) === "string") {
  16946. _this.backgroundFill = Canvas2D_1.GetBrushFromString(settings.backgroundFill);
  16947. }
  16948. else {
  16949. _this.backgroundFill = settings.backgroundFill;
  16950. }
  16951. }
  16952. // Put a handler to resize the background whenever the canvas is resizing
  16953. _this.propertyChanged.add(function (e, s) {
  16954. if (e.propertyName === "size") {
  16955. _this._background.size = _this.size;
  16956. }
  16957. }, BABYLON.Group2D.sizeProperty.flagId);
  16958. _this._background._patchHierarchy(_this);
  16959. }
  16960. var engine = scene.getEngine();
  16961. _this.__engineData = engine.getOrAddExternalDataWithFactory("__BJSCANVAS2D__", function (k) { return new Canvas2DEngineBoundData(); });
  16962. _this._primPointerInfo = new BABYLON.PrimitivePointerInfo();
  16963. _this._capturedPointers = new BABYLON.StringDictionary();
  16964. _this._pickStartingPosition = BABYLON.Vector2.Zero();
  16965. _this._hierarchyLevelMaxSiblingCount = 50;
  16966. _this._hierarchyDepth = 0;
  16967. _this._zOrder = 0;
  16968. _this._zMax = 1;
  16969. _this._scene = scene;
  16970. _this._engine = engine;
  16971. _this._renderingSize = new BABYLON.Size(0, 0);
  16972. _this._curHWScale = 0;
  16973. _this._canvasLevelScale = new BABYLON.Vector2(1, 1);
  16974. _this._designSize = settings.designSize || null;
  16975. _this._designUseHorizAxis = settings.designUseHorizAxis === true;
  16976. if (!_this._trackedGroups) {
  16977. _this._trackedGroups = new Array();
  16978. }
  16979. _this._maxAdaptiveWorldSpaceCanvasSize = null;
  16980. _this._groupCacheMaps = new BABYLON.StringDictionary();
  16981. _this._patchHierarchy(_this);
  16982. var enableInteraction = (settings.enableInteraction == null) ? true : settings.enableInteraction;
  16983. _this._fitRenderingDevice = !settings.size;
  16984. if (!settings.size) {
  16985. settings.size = new BABYLON.Size(engine.getRenderWidth(), engine.getRenderHeight());
  16986. }
  16987. // Register scene dispose to also dispose the canvas when it'll happens
  16988. scene.onDisposeObservable.add(function (d, s) {
  16989. _this.dispose();
  16990. });
  16991. if (_this._isScreenSpace) {
  16992. if (settings.renderingPhase) {
  16993. if (!settings.renderingPhase.camera || settings.renderingPhase.renderingGroupID == null) {
  16994. throw Error("You have to specify a valid camera and renderingGroup");
  16995. }
  16996. _this._renderingGroupObserver = _this._scene.onRenderingGroupObservable.add(function (e, s) {
  16997. if ((_this._scene.activeCamera === settings.renderingPhase.camera) && (e.renderStage === BABYLON.RenderingGroupInfo.STAGE_POSTTRANSPARENT)) {
  16998. _this._engine.clear(null, false, true, true);
  16999. BABYLON.C2DLogging._startFrameRender();
  17000. _this._render();
  17001. BABYLON.C2DLogging._endFrameRender();
  17002. }
  17003. }, Math.pow(2, settings.renderingPhase.renderingGroupID));
  17004. }
  17005. else {
  17006. _this._afterRenderObserver = _this._scene.onAfterRenderObservable.add(function (d, s) {
  17007. _this._engine.clear(null, false, true, true);
  17008. BABYLON.C2DLogging._startFrameRender();
  17009. _this._render();
  17010. BABYLON.C2DLogging._endFrameRender();
  17011. });
  17012. }
  17013. }
  17014. else {
  17015. _this._beforeRenderObserver = _this._scene.onBeforeRenderObservable.add(function (d, s) {
  17016. BABYLON.C2DLogging._startFrameRender();
  17017. _this._render();
  17018. BABYLON.C2DLogging._endFrameRender();
  17019. });
  17020. }
  17021. _this._supprtInstancedArray = _this._engine.getCaps().instancedArrays !== null;
  17022. //this._supprtInstancedArray = false; // TODO REMOVE!!!
  17023. // Setup the canvas for interaction (or not)
  17024. _this._setupInteraction(enableInteraction);
  17025. // Initialize the Primitive Collision Manager
  17026. if (settings.enableCollisionManager) {
  17027. var enableBorders = settings.collisionManagerUseBorders;
  17028. _this._primitiveCollisionManager = (settings.customCollisionManager == null) ? BABYLON.PrimitiveCollisionManagerBase.allocBasicPCM(_this, enableBorders) : settings.customCollisionManager(_this, enableBorders);
  17029. }
  17030. // Register this instance
  17031. Canvas2D_1._INSTANCES.push(_this);
  17032. return _this;
  17033. }
  17034. Object.defineProperty(Canvas2D.prototype, "drawCallsOpaqueCounter", {
  17035. get: function () {
  17036. if (!this._drawCallsOpaqueCounter) {
  17037. this._drawCallsOpaqueCounter = new BABYLON.PerfCounter();
  17038. }
  17039. return this._drawCallsOpaqueCounter;
  17040. },
  17041. enumerable: true,
  17042. configurable: true
  17043. });
  17044. Object.defineProperty(Canvas2D.prototype, "drawCallsAlphaTestCounter", {
  17045. get: function () {
  17046. if (!this._drawCallsAlphaTestCounter) {
  17047. this._drawCallsAlphaTestCounter = new BABYLON.PerfCounter();
  17048. }
  17049. return this._drawCallsAlphaTestCounter;
  17050. },
  17051. enumerable: true,
  17052. configurable: true
  17053. });
  17054. Object.defineProperty(Canvas2D.prototype, "drawCallsTransparentCounter", {
  17055. get: function () {
  17056. if (!this._drawCallsTransparentCounter) {
  17057. this._drawCallsTransparentCounter = new BABYLON.PerfCounter();
  17058. }
  17059. return this._drawCallsTransparentCounter;
  17060. },
  17061. enumerable: true,
  17062. configurable: true
  17063. });
  17064. Object.defineProperty(Canvas2D.prototype, "groupRenderCounter", {
  17065. get: function () {
  17066. if (!this._groupRenderCounter) {
  17067. this._groupRenderCounter = new BABYLON.PerfCounter();
  17068. }
  17069. return this._groupRenderCounter;
  17070. },
  17071. enumerable: true,
  17072. configurable: true
  17073. });
  17074. Object.defineProperty(Canvas2D.prototype, "updateTransparentDataCounter", {
  17075. get: function () {
  17076. if (!this._updateTransparentDataCounter) {
  17077. this._updateTransparentDataCounter = new BABYLON.PerfCounter();
  17078. }
  17079. return this._updateTransparentDataCounter;
  17080. },
  17081. enumerable: true,
  17082. configurable: true
  17083. });
  17084. Object.defineProperty(Canvas2D.prototype, "updateCachedStateCounter", {
  17085. get: function () {
  17086. if (!this._updateCachedStateCounter) {
  17087. this._updateCachedStateCounter = new BABYLON.PerfCounter();
  17088. }
  17089. return this._updateCachedStateCounter;
  17090. },
  17091. enumerable: true,
  17092. configurable: true
  17093. });
  17094. Object.defineProperty(Canvas2D.prototype, "updateLayoutCounter", {
  17095. get: function () {
  17096. if (!this._updateLayoutCounter) {
  17097. this._updateLayoutCounter = new BABYLON.PerfCounter();
  17098. }
  17099. return this._updateLayoutCounter;
  17100. },
  17101. enumerable: true,
  17102. configurable: true
  17103. });
  17104. Object.defineProperty(Canvas2D.prototype, "updatePositioningCounter", {
  17105. get: function () {
  17106. if (!this._updatePositioningCounter) {
  17107. this._updatePositioningCounter = new BABYLON.PerfCounter();
  17108. }
  17109. return this._updatePositioningCounter;
  17110. },
  17111. enumerable: true,
  17112. configurable: true
  17113. });
  17114. Object.defineProperty(Canvas2D.prototype, "updateLocalTransformCounter", {
  17115. get: function () {
  17116. if (!this._updateLocalTransformCounter) {
  17117. this._updateLocalTransformCounter = new BABYLON.PerfCounter();
  17118. }
  17119. return this._updateLocalTransformCounter;
  17120. },
  17121. enumerable: true,
  17122. configurable: true
  17123. });
  17124. Object.defineProperty(Canvas2D.prototype, "updateGlobalTransformCounter", {
  17125. get: function () {
  17126. if (!this._updateGlobalTransformCounter) {
  17127. this._updateGlobalTransformCounter = new BABYLON.PerfCounter();
  17128. }
  17129. return this._updateGlobalTransformCounter;
  17130. },
  17131. enumerable: true,
  17132. configurable: true
  17133. });
  17134. Object.defineProperty(Canvas2D.prototype, "boundingInfoRecomputeCounter", {
  17135. get: function () {
  17136. if (!this._boundingInfoRecomputeCounter) {
  17137. this._boundingInfoRecomputeCounter = new BABYLON.PerfCounter();
  17138. }
  17139. return this._boundingInfoRecomputeCounter;
  17140. },
  17141. enumerable: true,
  17142. configurable: true
  17143. });
  17144. Object.defineProperty(Canvas2D.prototype, "layoutBoundingInfoUpdateCounter", {
  17145. get: function () {
  17146. if (!this._layoutBoundingInfoUpdateCounter) {
  17147. this._layoutBoundingInfoUpdateCounter = new BABYLON.PerfCounter();
  17148. }
  17149. return this._layoutBoundingInfoUpdateCounter;
  17150. },
  17151. enumerable: true,
  17152. configurable: true
  17153. });
  17154. Object.defineProperty(Canvas2D.prototype, "canvasRenderTimeCounter", {
  17155. get: function () {
  17156. if (!this._canvasRenderTimeCounter) {
  17157. this._canvasRenderTimeCounter = new BABYLON.PerfCounter();
  17158. }
  17159. return this._canvasRenderTimeCounter;
  17160. },
  17161. enumerable: true,
  17162. configurable: true
  17163. });
  17164. Object.defineProperty(Canvas2D, "instances", {
  17165. get: function () {
  17166. return Canvas2D_1._INSTANCES;
  17167. },
  17168. enumerable: true,
  17169. configurable: true
  17170. });
  17171. Object.defineProperty(Canvas2D.prototype, "primitiveCollisionManager", {
  17172. get: function () {
  17173. return this._primitiveCollisionManager;
  17174. },
  17175. enumerable: true,
  17176. configurable: true
  17177. });
  17178. Canvas2D.prototype._canvasPreInit = function (settings) {
  17179. var cachingStrategy = (settings.cachingStrategy == null) ? Canvas2D_1.CACHESTRATEGY_DONTCACHE : settings.cachingStrategy;
  17180. this._cachingStrategy = cachingStrategy;
  17181. this._isScreenSpace = (settings.isScreenSpace == null) ? true : settings.isScreenSpace;
  17182. this._hierarchyDepth = 0;
  17183. };
  17184. Canvas2D.prototype._setupInteraction = function (enable) {
  17185. var _this = this;
  17186. // No change detection
  17187. if (enable === this._interactionEnabled) {
  17188. return;
  17189. }
  17190. // Set the new state
  17191. this._interactionEnabled = enable;
  17192. // ScreenSpace mode
  17193. if (this._isScreenSpace) {
  17194. // Disable interaction
  17195. if (!enable) {
  17196. if (this._scenePrePointerObserver) {
  17197. this.scene.onPrePointerObservable.remove(this._scenePrePointerObserver);
  17198. this._scenePrePointerObserver = null;
  17199. }
  17200. return;
  17201. }
  17202. // Enable Interaction
  17203. // Register the observable
  17204. this._scenePrePointerObserver = this.scene.onPrePointerObservable.add(function (e, s) {
  17205. if (_this.isVisible === false) {
  17206. return;
  17207. }
  17208. _this._handlePointerEventForInteraction(e, e.localPosition, s);
  17209. });
  17210. }
  17211. else {
  17212. var scene = this.scene;
  17213. if (enable) {
  17214. scene.constantlyUpdateMeshUnderPointer = true;
  17215. this._scenePointerObserver = scene.onPointerObservable.add(function (e, s) {
  17216. if (_this.isVisible === false) {
  17217. return;
  17218. }
  17219. if (e.pickInfo.hit && e.pickInfo.pickedMesh === _this._worldSpaceNode && _this.worldSpaceToNodeLocal) {
  17220. var localPos = _this.worldSpaceToNodeLocal(e.pickInfo.pickedPoint);
  17221. _this._handlePointerEventForInteraction(e, localPos, s);
  17222. }
  17223. else if (_this._actualIntersectionList && _this._actualIntersectionList.length > 0) {
  17224. _this._handlePointerEventForInteraction(e, null, s);
  17225. }
  17226. });
  17227. }
  17228. else {
  17229. if (this._scenePointerObserver) {
  17230. this.scene.onPointerObservable.remove(this._scenePointerObserver);
  17231. this._scenePointerObserver = null;
  17232. }
  17233. }
  17234. }
  17235. };
  17236. /**
  17237. * Internal method, you should use the Prim2DBase version instead
  17238. */
  17239. Canvas2D.prototype._setPointerCapture = function (pointerId, primitive) {
  17240. if (this.isPointerCaptured(pointerId)) {
  17241. return false;
  17242. }
  17243. // Try to capture the pointer on the HTML side
  17244. try {
  17245. this.engine.getRenderingCanvas().setPointerCapture(pointerId);
  17246. }
  17247. catch (e) {
  17248. //Nothing to do with the error. Execution will continue.
  17249. }
  17250. this._primPointerInfo.updateRelatedTarget(primitive, BABYLON.Vector2.Zero());
  17251. this._bubbleNotifyPrimPointerObserver(primitive, BABYLON.PrimitivePointerInfo.PointerGotCapture, null);
  17252. this._capturedPointers.add(pointerId.toString(), primitive);
  17253. return true;
  17254. };
  17255. /**
  17256. * Internal method, you should use the Prim2DBase version instead
  17257. */
  17258. Canvas2D.prototype._releasePointerCapture = function (pointerId, primitive) {
  17259. if (this._capturedPointers.get(pointerId.toString()) !== primitive) {
  17260. return false;
  17261. }
  17262. // Try to release the pointer on the HTML side
  17263. try {
  17264. this.engine.getRenderingCanvas().releasePointerCapture(pointerId);
  17265. }
  17266. catch (e) {
  17267. //Nothing to do with the error. Execution will continue.
  17268. }
  17269. this._primPointerInfo.updateRelatedTarget(primitive, BABYLON.Vector2.Zero());
  17270. this._bubbleNotifyPrimPointerObserver(primitive, BABYLON.PrimitivePointerInfo.PointerLostCapture, null);
  17271. this._capturedPointers.remove(pointerId.toString());
  17272. return true;
  17273. };
  17274. /**
  17275. * Determine if the given pointer is captured or not
  17276. * @param pointerId the Id of the pointer
  17277. * @return true if it's captured, false otherwise
  17278. */
  17279. Canvas2D.prototype.isPointerCaptured = function (pointerId) {
  17280. return this._capturedPointers.contains(pointerId.toString());
  17281. };
  17282. Canvas2D.prototype.getCapturedPrimitive = function (pointerId) {
  17283. // Avoid unnecessary lookup
  17284. if (this._capturedPointers.count === 0) {
  17285. return null;
  17286. }
  17287. return this._capturedPointers.get(pointerId.toString());
  17288. };
  17289. Canvas2D.prototype._handlePointerEventForInteraction = function (eventData, localPosition, eventState) {
  17290. // Dispose check
  17291. if (this.isDisposed) {
  17292. return;
  17293. }
  17294. // Update the this._primPointerInfo structure we'll send to observers using the PointerEvent data
  17295. if (localPosition) {
  17296. if (!this._updatePointerInfo(eventData, localPosition)) {
  17297. return;
  17298. }
  17299. }
  17300. else {
  17301. this._primPointerInfo.canvasPointerPos = null;
  17302. }
  17303. var capturedPrim = this.getCapturedPrimitive(this._primPointerInfo.pointerId);
  17304. // Make sure the intersection list is up to date, we maintain this list either in response of a mouse event (here) or before rendering the canvas.
  17305. // Why before rendering the canvas? because some primitives may move and get away/under the mouse cursor (which is not moving). So we need to update at both location in order to always have an accurate list, which is needed for the hover state change.
  17306. this._updateIntersectionList(localPosition ? this._primPointerInfo.canvasPointerPos : null, capturedPrim !== null, true);
  17307. // Update the over status, same as above, it's could be done here or during rendering, but will be performed only once per render frame
  17308. this._updateOverStatus(true);
  17309. // Check if we have nothing to raise
  17310. if (!this._actualOverPrimitive && !capturedPrim) {
  17311. return;
  17312. }
  17313. // Update the relatedTarget info with the over primitive or the captured one (if any)
  17314. var targetPrim = capturedPrim || this._actualOverPrimitive.prim;
  17315. var targetPointerPos = capturedPrim ? this._primPointerInfo.canvasPointerPos.subtract(new BABYLON.Vector2(targetPrim.globalTransform.m[4], targetPrim.globalTransform.m[5])) : this._actualOverPrimitive.intersectionLocation;
  17316. this._primPointerInfo.updateRelatedTarget(targetPrim, targetPointerPos);
  17317. // Analyze the pointer event type and fire proper events on the primitive
  17318. var skip = false;
  17319. if (eventData.type === BABYLON.PointerEventTypes.POINTERWHEEL) {
  17320. skip = !this._bubbleNotifyPrimPointerObserver(targetPrim, BABYLON.PrimitivePointerInfo.PointerMouseWheel, eventData);
  17321. }
  17322. else if (eventData.type === BABYLON.PointerEventTypes.POINTERMOVE) {
  17323. skip = !this._bubbleNotifyPrimPointerObserver(targetPrim, BABYLON.PrimitivePointerInfo.PointerMove, eventData);
  17324. }
  17325. else if (eventData.type === BABYLON.PointerEventTypes.POINTERDOWN) {
  17326. skip = !this._bubbleNotifyPrimPointerObserver(targetPrim, BABYLON.PrimitivePointerInfo.PointerDown, eventData);
  17327. }
  17328. else if (eventData.type === BABYLON.PointerEventTypes.POINTERUP) {
  17329. skip = !this._bubbleNotifyPrimPointerObserver(targetPrim, BABYLON.PrimitivePointerInfo.PointerUp, eventData);
  17330. }
  17331. eventState.skipNextObservers = skip;
  17332. };
  17333. Canvas2D.prototype._updatePointerInfo = function (eventData, localPosition) {
  17334. var s = this._canvasLevelScale.multiplyByFloats(this.scaleX, this.scaleY);
  17335. var pii = this._primPointerInfo;
  17336. pii.cancelBubble = false;
  17337. if (!pii.canvasPointerPos) {
  17338. pii.canvasPointerPos = BABYLON.Vector2.Zero();
  17339. }
  17340. var camera = this._scene.cameraToUseForPointers || this._scene.activeCamera;
  17341. if (!camera || !camera.viewport) {
  17342. return false;
  17343. }
  17344. var engine = this._scene.getEngine();
  17345. if (this._isScreenSpace) {
  17346. var cameraViewport = camera.viewport;
  17347. var renderWidth = engine.getRenderWidth();
  17348. var renderHeight = engine.getRenderHeight();
  17349. // console.log(`Render Width: ${renderWidth} Height: ${renderHeight}, localX: ${localPosition.x}, localY: ${localPosition.y}`);
  17350. var viewport = cameraViewport.toGlobal(renderWidth, renderHeight);
  17351. // Moving coordinates to local viewport world
  17352. var x = localPosition.x - viewport.x;
  17353. var y = localPosition.y - viewport.y;
  17354. pii.canvasPointerPos.x = (x - this.actualPosition.x) / s.x;
  17355. pii.canvasPointerPos.y = (renderHeight - y - this.actualPosition.y) / s.y;
  17356. }
  17357. else {
  17358. pii.canvasPointerPos.x = localPosition.x / s.x;
  17359. pii.canvasPointerPos.y = localPosition.y / s.x;
  17360. }
  17361. //console.log(`UpdatePointerInfo for ${this.id}, X:${pii.canvasPointerPos.x}, Y:${pii.canvasPointerPos.y}`);
  17362. pii.mouseWheelDelta = 0;
  17363. if (eventData.type === BABYLON.PointerEventTypes.POINTERWHEEL) {
  17364. var event = eventData.event;
  17365. if (event.wheelDelta) {
  17366. pii.mouseWheelDelta = event.wheelDelta / (BABYLON.PrimitivePointerInfo.MouseWheelPrecision * 40);
  17367. }
  17368. else if (event.detail) {
  17369. pii.mouseWheelDelta = -event.detail / BABYLON.PrimitivePointerInfo.MouseWheelPrecision;
  17370. }
  17371. }
  17372. else {
  17373. var pe = eventData.event;
  17374. pii.ctrlKey = pe.ctrlKey;
  17375. pii.altKey = pe.altKey;
  17376. pii.shiftKey = pe.shiftKey;
  17377. pii.metaKey = pe.metaKey;
  17378. pii.button = pe.button;
  17379. pii.buttons = pe.buttons;
  17380. pii.pointerId = pe.pointerId;
  17381. pii.width = pe.width;
  17382. pii.height = pe.height;
  17383. pii.presssure = pe.pressure;
  17384. pii.tilt.x = pe.tiltX;
  17385. pii.tilt.y = pe.tiltY;
  17386. pii.isCaptured = this.getCapturedPrimitive(pe.pointerId) !== null;
  17387. }
  17388. return true;
  17389. };
  17390. Canvas2D.prototype._updateIntersectionList = function (mouseLocalPos, isCapture, force) {
  17391. if (!force && (this.scene.getRenderId() === this._intersectionRenderId)) {
  17392. return;
  17393. }
  17394. var ii = Canvas2D_1._interInfo;
  17395. var outCase = mouseLocalPos == null;
  17396. if (!outCase) {
  17397. // A little safe guard, it might happens than the event is triggered before the first render and nothing is computed, this simple check will make sure everything will be fine
  17398. if (!this._globalTransform) {
  17399. this.updateCachedStates(true);
  17400. }
  17401. ii.pickPosition.x = mouseLocalPos.x;
  17402. ii.pickPosition.y = mouseLocalPos.y;
  17403. ii.findFirstOnly = false;
  17404. // Fast rejection: test if the mouse pointer is outside the canvas's bounding Info
  17405. if (!isCapture && !this.levelBoundingInfo.doesIntersect(ii.pickPosition)) {
  17406. // Reset intersection info as we don't hit anything
  17407. ii.intersectedPrimitives = new Array();
  17408. ii.topMostIntersectedPrimitive = null;
  17409. }
  17410. else {
  17411. // The pointer is inside the Canvas, do an intersection test
  17412. this.intersect(ii);
  17413. // Sort primitives to get them from top to bottom
  17414. ii.intersectedPrimitives = ii.intersectedPrimitives.sort(function (a, b) { return a.prim.actualZOffset - b.prim.actualZOffset; });
  17415. }
  17416. }
  17417. {
  17418. // Update prev/actual intersection info, fire "overPrim" property change if needed
  17419. this._previousIntersectionList = this._actualIntersectionList;
  17420. this._actualIntersectionList = outCase ? new Array() : ii.intersectedPrimitives;
  17421. this._previousOverPrimitive = this._actualOverPrimitive;
  17422. this._actualOverPrimitive = outCase ? null : ii.topMostIntersectedPrimitive;
  17423. var prev = (this._previousOverPrimitive != null) ? this._previousOverPrimitive.prim : null;
  17424. var actual = (this._actualOverPrimitive != null) ? this._actualOverPrimitive.prim : null;
  17425. if (prev !== actual) {
  17426. this.onPropertyChanged("overPrim", this._previousOverPrimitive ? this._previousOverPrimitive.prim : null, this._actualOverPrimitive ? this._actualOverPrimitive.prim : null);
  17427. }
  17428. }
  17429. this._intersectionRenderId = this.scene.getRenderId();
  17430. };
  17431. // Based on the previousIntersectionList and the actualInstersectionList we can determined which primitives are being hover state or loosing it
  17432. Canvas2D.prototype._updateOverStatus = function (force) {
  17433. if ((!force && (this.scene.getRenderId() === this._hoverStatusRenderId)) || !this._actualIntersectionList) {
  17434. return;
  17435. }
  17436. if (this._previousIntersectionList == null) {
  17437. this._previousIntersectionList = [];
  17438. }
  17439. // Detect a change of over
  17440. var prevPrim = this._previousOverPrimitive ? this._previousOverPrimitive.prim : null;
  17441. var actualPrim = this._actualOverPrimitive ? this._actualOverPrimitive.prim : null;
  17442. if (prevPrim !== actualPrim) {
  17443. // Detect if the current pointer is captured, only fire event if they belong to the capture primitive
  17444. var capturedPrim = this.getCapturedPrimitive(this._primPointerInfo.pointerId);
  17445. // See the NOTE section of: https://www.w3.org/TR/pointerevents/#setting-pointer-capture
  17446. if (capturedPrim) {
  17447. if (capturedPrim === prevPrim) {
  17448. this._primPointerInfo.updateRelatedTarget(prevPrim, this._previousOverPrimitive.intersectionLocation);
  17449. this._bubbleNotifyPrimPointerObserver(prevPrim, BABYLON.PrimitivePointerInfo.PointerOut, null);
  17450. }
  17451. else if (capturedPrim === actualPrim) {
  17452. this._primPointerInfo.updateRelatedTarget(actualPrim, this._actualOverPrimitive.intersectionLocation);
  17453. this._bubbleNotifyPrimPointerObserver(actualPrim, BABYLON.PrimitivePointerInfo.PointerOver, null);
  17454. }
  17455. }
  17456. else {
  17457. var _loop_1 = function (prev) {
  17458. if (!BABYLON.Tools.first(this_1._actualIntersectionList, function (pii) { return pii.prim === prev.prim; })) {
  17459. this_1._primPointerInfo.updateRelatedTarget(prev.prim, prev.intersectionLocation);
  17460. this_1._bubbleNotifyPrimPointerObserver(prev.prim, BABYLON.PrimitivePointerInfo.PointerOut, null);
  17461. }
  17462. };
  17463. var this_1 = this;
  17464. // Check for Out & Leave
  17465. for (var _i = 0, _a = this._previousIntersectionList; _i < _a.length; _i++) {
  17466. var prev = _a[_i];
  17467. _loop_1(prev);
  17468. }
  17469. var _loop_2 = function (actual) {
  17470. if (!BABYLON.Tools.first(this_2._previousIntersectionList, function (pii) { return pii.prim === actual.prim; })) {
  17471. this_2._primPointerInfo.updateRelatedTarget(actual.prim, actual.intersectionLocation);
  17472. this_2._bubbleNotifyPrimPointerObserver(actual.prim, BABYLON.PrimitivePointerInfo.PointerOver, null);
  17473. }
  17474. };
  17475. var this_2 = this;
  17476. // Check for Over & Enter
  17477. for (var _b = 0, _c = this._actualIntersectionList; _b < _c.length; _b++) {
  17478. var actual = _c[_b];
  17479. _loop_2(actual);
  17480. }
  17481. }
  17482. }
  17483. this._hoverStatusRenderId = this.scene.getRenderId();
  17484. };
  17485. Canvas2D.prototype._updatePrimPointerPos = function (prim) {
  17486. if (this._primPointerInfo.isCaptured) {
  17487. this._primPointerInfo.primitivePointerPos = this._primPointerInfo.relatedTargetPointerPos;
  17488. }
  17489. else {
  17490. for (var _i = 0, _a = this._actualIntersectionList; _i < _a.length; _i++) {
  17491. var pii = _a[_i];
  17492. if (pii.prim === prim) {
  17493. this._primPointerInfo.primitivePointerPos = pii.intersectionLocation;
  17494. return;
  17495. }
  17496. }
  17497. }
  17498. };
  17499. Canvas2D.prototype._debugExecObserver = function (prim, mask) {
  17500. if (!this._notifDebugMode) {
  17501. return;
  17502. }
  17503. var debug = "";
  17504. for (var i = 0; i < prim.hierarchyDepth; i++) {
  17505. debug += " ";
  17506. }
  17507. var pii = this._primPointerInfo;
  17508. debug += "[RID:" + this.scene.getRenderId() + "] [" + prim.hierarchyDepth + "] event:" + BABYLON.PrimitivePointerInfo.getEventTypeName(mask) + ", id: " + prim.id + " (" + BABYLON.Tools.getClassName(prim) + "), primPos: " + pii.primitivePointerPos.toString() + ", canvasPos: " + pii.canvasPointerPos.toString() + ", relatedTarget: " + pii.relatedTarget.id;
  17509. console.log(debug);
  17510. };
  17511. Canvas2D.prototype._bubbleNotifyPrimPointerObserver = function (prim, mask, eventData) {
  17512. var ppi = this._primPointerInfo;
  17513. var event = eventData ? eventData.event : null;
  17514. var cur = prim;
  17515. while (cur && !cur.isDisposed) {
  17516. this._updatePrimPointerPos(cur);
  17517. // For the first level we have to fire Enter or Leave for corresponding Over or Out
  17518. if (cur === prim) {
  17519. // Fire the proper notification
  17520. if (mask === BABYLON.PrimitivePointerInfo.PointerOver) {
  17521. this._debugExecObserver(prim, BABYLON.PrimitivePointerInfo.PointerEnter);
  17522. prim._pointerEventObservable.notifyObservers(ppi, BABYLON.PrimitivePointerInfo.PointerEnter);
  17523. }
  17524. else if (mask === BABYLON.PrimitivePointerInfo.PointerOut) {
  17525. this._debugExecObserver(prim, BABYLON.PrimitivePointerInfo.PointerLeave);
  17526. prim._pointerEventObservable.notifyObservers(ppi, BABYLON.PrimitivePointerInfo.PointerLeave);
  17527. }
  17528. }
  17529. // Exec the observers
  17530. this._debugExecObserver(cur, mask);
  17531. if (!cur._pointerEventObservable.notifyObservers(ppi, mask) && eventData instanceof BABYLON.PointerInfoPre) {
  17532. eventData.skipOnPointerObservable = true;
  17533. return false;
  17534. }
  17535. this._triggerActionManager(cur, ppi, mask, event);
  17536. // Bubble canceled? If we're not executing PointerOver or PointerOut, quit immediately
  17537. // If it's PointerOver/Out we have to trigger PointerEnter/Leave no matter what
  17538. if (ppi.cancelBubble) {
  17539. return false;
  17540. }
  17541. // Loop to the parent
  17542. cur = cur.parent;
  17543. }
  17544. return true;
  17545. };
  17546. Canvas2D.prototype._triggerActionManager = function (prim, ppi, mask, eventData) {
  17547. var _this = this;
  17548. // A little safe guard, it might happens than the event is triggered before the first render and nothing is computed, this simple check will make sure everything will be fine
  17549. if (!this._globalTransform) {
  17550. this.updateCachedStates(true);
  17551. }
  17552. // Process Trigger related to PointerDown
  17553. if ((mask & BABYLON.PrimitivePointerInfo.PointerDown) !== 0) {
  17554. // On pointer down, record the current position and time to be able to trick PickTrigger and LongPressTrigger
  17555. this._pickStartingPosition = ppi.primitivePointerPos.clone();
  17556. this._pickStartingTime = new Date().getTime();
  17557. this._pickedDownPrim = null;
  17558. if (prim.actionManager) {
  17559. this._pickedDownPrim = prim;
  17560. if (prim.actionManager.hasPickTriggers) {
  17561. var actionEvent = BABYLON.ActionEvent.CreateNewFromPrimitive(prim, ppi.primitivePointerPos, eventData);
  17562. switch (eventData.button) {
  17563. case 0:
  17564. prim.actionManager.processTrigger(BABYLON.ActionManager.OnLeftPickTrigger, actionEvent);
  17565. break;
  17566. case 1:
  17567. prim.actionManager.processTrigger(BABYLON.ActionManager.OnCenterPickTrigger, actionEvent);
  17568. break;
  17569. case 2:
  17570. prim.actionManager.processTrigger(BABYLON.ActionManager.OnRightPickTrigger, actionEvent);
  17571. break;
  17572. }
  17573. prim.actionManager.processTrigger(BABYLON.ActionManager.OnPickDownTrigger, actionEvent);
  17574. }
  17575. if (prim.actionManager.hasSpecificTrigger(BABYLON.ActionManager.OnLongPressTrigger)) {
  17576. window.setTimeout(function () {
  17577. var ppi = _this._primPointerInfo;
  17578. var capturedPrim = _this.getCapturedPrimitive(ppi.pointerId);
  17579. _this._updateIntersectionList(ppi.canvasPointerPos, capturedPrim !== null, true);
  17580. _this._updateOverStatus(false);
  17581. var ii = new BABYLON.IntersectInfo2D();
  17582. ii.pickPosition = ppi.canvasPointerPos.clone();
  17583. ii.findFirstOnly = false;
  17584. _this.intersect(ii);
  17585. if (ii.isPrimIntersected(prim) !== null) {
  17586. if (prim.actionManager) {
  17587. if (_this._pickStartingTime !== 0 && ((new Date().getTime() - _this._pickStartingTime) > BABYLON.Scene.LongPressDelay) && (Math.abs(_this._pickStartingPosition.x - ii.pickPosition.x) < BABYLON.Scene.DragMovementThreshold && Math.abs(_this._pickStartingPosition.y - ii.pickPosition.y) < BABYLON.Scene.DragMovementThreshold)) {
  17588. _this._pickStartingTime = 0;
  17589. prim.actionManager.processTrigger(BABYLON.ActionManager.OnLongPressTrigger, BABYLON.ActionEvent.CreateNewFromPrimitive(prim, ppi.primitivePointerPos, eventData));
  17590. }
  17591. }
  17592. }
  17593. }, BABYLON.Scene.LongPressDelay);
  17594. }
  17595. }
  17596. }
  17597. else if ((mask & BABYLON.PrimitivePointerInfo.PointerUp) !== 0) {
  17598. this._pickStartingTime = 0;
  17599. var actionEvent = BABYLON.ActionEvent.CreateNewFromPrimitive(prim, ppi.primitivePointerPos, eventData);
  17600. if (prim.actionManager) {
  17601. // OnPickUpTrigger
  17602. prim.actionManager.processTrigger(BABYLON.ActionManager.OnPickUpTrigger, actionEvent);
  17603. // OnPickTrigger
  17604. if (Math.abs(this._pickStartingPosition.x - ppi.canvasPointerPos.x) < BABYLON.Scene.DragMovementThreshold && Math.abs(this._pickStartingPosition.y - ppi.canvasPointerPos.y) < BABYLON.Scene.DragMovementThreshold) {
  17605. prim.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger, actionEvent);
  17606. }
  17607. }
  17608. // OnPickOutTrigger
  17609. if (this._pickedDownPrim && this._pickedDownPrim.actionManager && (this._pickedDownPrim !== prim)) {
  17610. this._pickedDownPrim.actionManager.processTrigger(BABYLON.ActionManager.OnPickOutTrigger, actionEvent);
  17611. }
  17612. }
  17613. else if ((mask & BABYLON.PrimitivePointerInfo.PointerOver) !== 0) {
  17614. if (prim.actionManager) {
  17615. var actionEvent = BABYLON.ActionEvent.CreateNewFromPrimitive(prim, ppi.primitivePointerPos, eventData);
  17616. prim.actionManager.processTrigger(BABYLON.ActionManager.OnPointerOverTrigger, actionEvent);
  17617. }
  17618. }
  17619. else if ((mask & BABYLON.PrimitivePointerInfo.PointerOut) !== 0) {
  17620. if (prim.actionManager) {
  17621. var actionEvent = BABYLON.ActionEvent.CreateNewFromPrimitive(prim, ppi.primitivePointerPos, eventData);
  17622. prim.actionManager.processTrigger(BABYLON.ActionManager.OnPointerOutTrigger, actionEvent);
  17623. }
  17624. }
  17625. };
  17626. /**
  17627. * Don't forget to call the dispose method when you're done with the Canvas instance.
  17628. * But don't worry, if you dispose its scene, the canvas will be automatically disposed too.
  17629. */
  17630. Canvas2D.prototype.dispose = function () {
  17631. if (!_super.prototype.dispose.call(this)) {
  17632. return false;
  17633. }
  17634. if (this._profilingCanvas) {
  17635. this._profilingCanvas.dispose();
  17636. this._profilingCanvas = null;
  17637. }
  17638. if (this.interactionEnabled) {
  17639. this._setupInteraction(false);
  17640. }
  17641. if (this._renderingGroupObserver) {
  17642. this._scene.onRenderingGroupObservable.remove(this._renderingGroupObserver);
  17643. this._renderingGroupObserver = null;
  17644. }
  17645. if (this._beforeRenderObserver) {
  17646. this._scene.onBeforeRenderObservable.remove(this._beforeRenderObserver);
  17647. this._beforeRenderObserver = null;
  17648. }
  17649. if (this._afterRenderObserver) {
  17650. this._scene.onAfterRenderObservable.remove(this._afterRenderObserver);
  17651. this._afterRenderObserver = null;
  17652. }
  17653. if (this._groupCacheMaps) {
  17654. this._groupCacheMaps.forEach(function (k, m) { return m.forEach(function (e) { return e.dispose(); }); });
  17655. this._groupCacheMaps = null;
  17656. }
  17657. // Unregister this instance
  17658. var index = Canvas2D_1._INSTANCES.indexOf(this);
  17659. if (index > -1) {
  17660. Canvas2D_1._INSTANCES.splice(index, 1);
  17661. }
  17662. return true;
  17663. };
  17664. Object.defineProperty(Canvas2D.prototype, "scene", {
  17665. /**
  17666. * Accessor to the Scene that owns the Canvas
  17667. * @returns The instance of the Scene object
  17668. */
  17669. get: function () {
  17670. return this._scene;
  17671. },
  17672. enumerable: true,
  17673. configurable: true
  17674. });
  17675. Object.defineProperty(Canvas2D.prototype, "engine", {
  17676. /**
  17677. * Accessor to the Engine that drives the Scene used by this Canvas
  17678. * @returns The instance of the Engine object
  17679. */
  17680. get: function () {
  17681. return this._engine;
  17682. },
  17683. enumerable: true,
  17684. configurable: true
  17685. });
  17686. Object.defineProperty(Canvas2D.prototype, "renderObservable", {
  17687. /**
  17688. * And observable called during the Canvas rendering process.
  17689. * This observable is called twice per render, each time with a different mask:
  17690. * - 1: before render is executed
  17691. * - 2: after render is executed
  17692. */
  17693. get: function () {
  17694. if (!this._renderObservable) {
  17695. this._renderObservable = new BABYLON.Observable();
  17696. }
  17697. return this._renderObservable;
  17698. },
  17699. enumerable: true,
  17700. configurable: true
  17701. });
  17702. Object.defineProperty(Canvas2D.prototype, "cachingStrategy", {
  17703. /**
  17704. * Accessor of the Caching Strategy used by this Canvas.
  17705. * See Canvas2D.CACHESTRATEGY_xxxx static members for more information
  17706. * @returns the value corresponding to the used strategy.
  17707. */
  17708. get: function () {
  17709. return this._cachingStrategy;
  17710. },
  17711. enumerable: true,
  17712. configurable: true
  17713. });
  17714. Object.defineProperty(Canvas2D.prototype, "isScreenSpace", {
  17715. /**
  17716. * Return true if the Canvas is a Screen Space one, false if it's a World Space one.
  17717. * @returns {}
  17718. */
  17719. get: function () {
  17720. return this._isScreenSpace;
  17721. },
  17722. enumerable: true,
  17723. configurable: true
  17724. });
  17725. Object.defineProperty(Canvas2D.prototype, "worldSpaceCanvasNode", {
  17726. /**
  17727. * Only valid for World Space Canvas, returns the scene node that displays the canvas
  17728. */
  17729. get: function () {
  17730. return this._worldSpaceNode;
  17731. },
  17732. set: function (val) {
  17733. this._worldSpaceNode = val;
  17734. },
  17735. enumerable: true,
  17736. configurable: true
  17737. });
  17738. Object.defineProperty(Canvas2D.prototype, "supportInstancedArray", {
  17739. /**
  17740. * Check if the WebGL Instanced Array extension is supported or not
  17741. */
  17742. get: function () {
  17743. return this._supprtInstancedArray;
  17744. },
  17745. enumerable: true,
  17746. configurable: true
  17747. });
  17748. Object.defineProperty(Canvas2D.prototype, "backgroundFill", {
  17749. /**
  17750. * Property that defines the fill object used to draw the background of the Canvas.
  17751. * Note that Canvas with a Caching Strategy of
  17752. * @returns If the background is not set, null will be returned, otherwise a valid fill object is returned.
  17753. */
  17754. get: function () {
  17755. if (!this._background || !this._background.isVisible) {
  17756. return null;
  17757. }
  17758. return this._background.fill;
  17759. },
  17760. set: function (value) {
  17761. this.checkBackgroundAvailability();
  17762. if (value === this._background.fill) {
  17763. return;
  17764. }
  17765. this._background.fill = value;
  17766. this._background.levelVisible = true;
  17767. },
  17768. enumerable: true,
  17769. configurable: true
  17770. });
  17771. Object.defineProperty(Canvas2D.prototype, "backgroundBorder", {
  17772. /**
  17773. * Property that defines the border object used to draw the background of the Canvas.
  17774. * @returns If the background is not set, null will be returned, otherwise a valid border object is returned.
  17775. */
  17776. get: function () {
  17777. if (!this._background || !this._background.isVisible) {
  17778. return null;
  17779. }
  17780. return this._background.border;
  17781. },
  17782. set: function (value) {
  17783. this.checkBackgroundAvailability();
  17784. if (value === this._background.border) {
  17785. return;
  17786. }
  17787. this._background.border = value;
  17788. this._background.levelVisible = true;
  17789. },
  17790. enumerable: true,
  17791. configurable: true
  17792. });
  17793. Object.defineProperty(Canvas2D.prototype, "backgroundBorderThickness", {
  17794. /**
  17795. * Property that defines the thickness of the border object used to draw the background of the Canvas.
  17796. * @returns If the background is not set, null will be returned, otherwise a valid number matching the thickness is returned.
  17797. */
  17798. get: function () {
  17799. if (!this._background || !this._background.isVisible) {
  17800. return null;
  17801. }
  17802. return this._background.borderThickness;
  17803. },
  17804. set: function (value) {
  17805. this.checkBackgroundAvailability();
  17806. if (value === this._background.borderThickness) {
  17807. return;
  17808. }
  17809. this._background.borderThickness = value;
  17810. },
  17811. enumerable: true,
  17812. configurable: true
  17813. });
  17814. Object.defineProperty(Canvas2D.prototype, "backgroundRoundRadius", {
  17815. /**
  17816. * You can set the roundRadius of the background
  17817. * @returns The current roundRadius
  17818. */
  17819. get: function () {
  17820. if (!this._background || !this._background.isVisible) {
  17821. return null;
  17822. }
  17823. return this._background.roundRadius;
  17824. },
  17825. set: function (value) {
  17826. this.checkBackgroundAvailability();
  17827. if (value === this._background.roundRadius) {
  17828. return;
  17829. }
  17830. this._background.roundRadius = value;
  17831. this._background.levelVisible = true;
  17832. },
  17833. enumerable: true,
  17834. configurable: true
  17835. });
  17836. Object.defineProperty(Canvas2D.prototype, "interactionEnabled", {
  17837. /**
  17838. * Enable/Disable interaction for this Canvas
  17839. * When enabled the Prim2DBase.pointerEventObservable property will notified when appropriate events occur
  17840. */
  17841. get: function () {
  17842. return this._interactionEnabled;
  17843. },
  17844. set: function (enable) {
  17845. this._setupInteraction(enable);
  17846. },
  17847. enumerable: true,
  17848. configurable: true
  17849. });
  17850. Object.defineProperty(Canvas2D.prototype, "fitRenderingDevice", {
  17851. get: function () {
  17852. return this._fitRenderingDevice;
  17853. },
  17854. enumerable: true,
  17855. configurable: true
  17856. });
  17857. Object.defineProperty(Canvas2D.prototype, "designSize", {
  17858. get: function () {
  17859. return this._designSize;
  17860. },
  17861. enumerable: true,
  17862. configurable: true
  17863. });
  17864. Object.defineProperty(Canvas2D.prototype, "designSizeUseHorizAxis", {
  17865. get: function () {
  17866. return this._designUseHorizAxis;
  17867. },
  17868. enumerable: true,
  17869. configurable: true
  17870. });
  17871. Object.defineProperty(Canvas2D.prototype, "designSizeUseHorizeAxis", {
  17872. set: function (value) {
  17873. this._designUseHorizAxis = value;
  17874. },
  17875. enumerable: true,
  17876. configurable: true
  17877. });
  17878. Object.defineProperty(Canvas2D.prototype, "overPrim", {
  17879. /**
  17880. * Return
  17881. */
  17882. get: function () {
  17883. if (this._actualIntersectionList && this._actualIntersectionList.length > 0) {
  17884. return this._actualIntersectionList[0].prim;
  17885. }
  17886. return null;
  17887. },
  17888. enumerable: true,
  17889. configurable: true
  17890. });
  17891. Object.defineProperty(Canvas2D.prototype, "_engineData", {
  17892. /**
  17893. * Access the babylon.js' engine bound data, do not invoke this method, it's for internal purpose only
  17894. * @returns {}
  17895. */
  17896. get: function () {
  17897. return this.__engineData;
  17898. },
  17899. enumerable: true,
  17900. configurable: true
  17901. });
  17902. Object.defineProperty(Canvas2D.prototype, "unitScaleFactor", {
  17903. get: function () {
  17904. return this._unitScaleFactor;
  17905. },
  17906. enumerable: true,
  17907. configurable: true
  17908. });
  17909. Canvas2D.prototype.createCanvasProfileInfoCanvas = function () {
  17910. if (this._profilingCanvas) {
  17911. return this._profilingCanvas;
  17912. }
  17913. var canvas = new ScreenSpaceCanvas2D(this.scene, {
  17914. id: "ProfileInfoCanvas", cachingStrategy: Canvas2D_1.CACHESTRATEGY_DONTCACHE, children: [
  17915. new BABYLON.Rectangle2D({
  17916. id: "ProfileBorder", border: "#FFFFFFFF", borderThickness: 2, roundRadius: 5, fill: "#C04040C0", marginAlignment: "h: left, v: top", margin: "10", padding: "10", children: [
  17917. new BABYLON.Text2D("Stats", { id: "ProfileInfoText", marginAlignment: "h: left, v: top", fontName: "12pt Lucida Console", fontSignedDistanceField: true })
  17918. ]
  17919. })
  17920. ]
  17921. });
  17922. this._profileInfoText = canvas.findById("ProfileInfoText");
  17923. this._profilingCanvas = canvas;
  17924. return canvas;
  17925. };
  17926. Canvas2D.prototype.checkBackgroundAvailability = function () {
  17927. if (this._cachingStrategy === Canvas2D_1.CACHESTRATEGY_TOPLEVELGROUPS) {
  17928. throw Error("Can't use Canvas Background with the caching strategy TOPLEVELGROUPS");
  17929. }
  17930. };
  17931. Canvas2D.prototype._initPerfMetrics = function () {
  17932. this.drawCallsOpaqueCounter.fetchNewFrame();
  17933. this.drawCallsAlphaTestCounter.fetchNewFrame();
  17934. this.drawCallsTransparentCounter.fetchNewFrame();
  17935. this.groupRenderCounter.fetchNewFrame();
  17936. this.updateTransparentDataCounter.fetchNewFrame();
  17937. this.updateCachedStateCounter.fetchNewFrame();
  17938. this.updateLayoutCounter.fetchNewFrame();
  17939. this.updatePositioningCounter.fetchNewFrame();
  17940. this.updateLocalTransformCounter.fetchNewFrame();
  17941. this.updateGlobalTransformCounter.fetchNewFrame();
  17942. this.boundingInfoRecomputeCounter.fetchNewFrame();
  17943. this.layoutBoundingInfoUpdateCounter.fetchNewFrame();
  17944. this.canvasRenderTimeCounter.beginMonitoring();
  17945. };
  17946. Canvas2D.prototype._fetchPerfMetrics = function () {
  17947. this.drawCallsOpaqueCounter.addCount(0, true);
  17948. this.drawCallsAlphaTestCounter.addCount(0, true);
  17949. this.drawCallsTransparentCounter.addCount(0, true);
  17950. this.groupRenderCounter.addCount(0, true);
  17951. this.updateTransparentDataCounter.addCount(0, true);
  17952. this.updateCachedStateCounter.addCount(0, true);
  17953. this.updateLayoutCounter.addCount(0, true);
  17954. this.updatePositioningCounter.addCount(0, true);
  17955. this.updateLocalTransformCounter.addCount(0, true);
  17956. this.updateGlobalTransformCounter.addCount(0, true);
  17957. this.boundingInfoRecomputeCounter.addCount(0, true);
  17958. this.layoutBoundingInfoUpdateCounter.addCount(0, true);
  17959. this.canvasRenderTimeCounter.endMonitoring(true);
  17960. };
  17961. Canvas2D.prototype._updateProfileCanvas = function () {
  17962. if (this._profileInfoText == null) {
  17963. return;
  17964. }
  17965. var format = function (v) { return (Math.round(v * 100) / 100).toString(); };
  17966. var p = "Render Time: avg:" + format(this.canvasRenderTimeCounter.lastSecAverage) + "ms " + format(this.canvasRenderTimeCounter.current) + "ms\n" +
  17967. "Draw Calls:\n" +
  17968. (" - Opaque: " + format(this.drawCallsOpaqueCounter.current) + ", (avg:" + format(this.drawCallsOpaqueCounter.lastSecAverage) + ", t:" + format(this.drawCallsOpaqueCounter.total) + ")\n") +
  17969. (" - AlphaTest: " + format(this.drawCallsAlphaTestCounter.current) + ", (avg:" + format(this.drawCallsAlphaTestCounter.lastSecAverage) + ", t:" + format(this.drawCallsAlphaTestCounter.total) + ")\n") +
  17970. (" - Transparent: " + format(this.drawCallsTransparentCounter.current) + ", (avg:" + format(this.drawCallsTransparentCounter.lastSecAverage) + ", t:" + format(this.drawCallsTransparentCounter.total) + ")\n") +
  17971. ("Group Render: " + this.groupRenderCounter.current + ", (avg:" + format(this.groupRenderCounter.lastSecAverage) + ", t:" + format(this.groupRenderCounter.total) + ")\n") +
  17972. ("Update Transparent Data: " + this.updateTransparentDataCounter.current + ", (avg:" + format(this.updateTransparentDataCounter.lastSecAverage) + ", t:" + format(this.updateTransparentDataCounter.total) + ")\n") +
  17973. ("Update Cached States: " + this.updateCachedStateCounter.current + ", (avg:" + format(this.updateCachedStateCounter.lastSecAverage) + ", t:" + format(this.updateCachedStateCounter.total) + ")\n") +
  17974. (" - Update Layout: " + this.updateLayoutCounter.current + ", (avg:" + format(this.updateLayoutCounter.lastSecAverage) + ", t:" + format(this.updateLayoutCounter.total) + ")\n") +
  17975. (" - Update Positioning: " + this.updatePositioningCounter.current + ", (avg:" + format(this.updatePositioningCounter.lastSecAverage) + ", t:" + format(this.updatePositioningCounter.total) + ")\n") +
  17976. (" - Update Local Trans: " + this.updateLocalTransformCounter.current + ", (avg:" + format(this.updateLocalTransformCounter.lastSecAverage) + ", t:" + format(this.updateLocalTransformCounter.total) + ")\n") +
  17977. (" - Update Global Trans: " + this.updateGlobalTransformCounter.current + ", (avg:" + format(this.updateGlobalTransformCounter.lastSecAverage) + ", t:" + format(this.updateGlobalTransformCounter.total) + ")\n") +
  17978. (" - BoundingInfo Recompute: " + this.boundingInfoRecomputeCounter.current + ", (avg:" + format(this.boundingInfoRecomputeCounter.lastSecAverage) + ", t:" + format(this.boundingInfoRecomputeCounter.total) + ")\n") +
  17979. (" - LayoutBoundingInfo Recompute: " + this.layoutBoundingInfoUpdateCounter.current + ", (avg:" + format(this.layoutBoundingInfoUpdateCounter.lastSecAverage) + ", t:" + format(this.layoutBoundingInfoUpdateCounter.total) + ")");
  17980. this._profileInfoText.text = p;
  17981. };
  17982. Canvas2D.prototype._addDrawCallCount = function (count, renderMode) {
  17983. switch (renderMode) {
  17984. case BABYLON.Render2DContext.RenderModeOpaque:
  17985. this._drawCallsOpaqueCounter.addCount(count, false);
  17986. return;
  17987. case BABYLON.Render2DContext.RenderModeAlphaTest:
  17988. this._drawCallsAlphaTestCounter.addCount(count, false);
  17989. return;
  17990. case BABYLON.Render2DContext.RenderModeTransparent:
  17991. this._drawCallsTransparentCounter.addCount(count, false);
  17992. return;
  17993. }
  17994. };
  17995. Canvas2D.prototype._addGroupRenderCount = function (count) {
  17996. if (this._groupRenderCounter) {
  17997. this._groupRenderCounter.addCount(count, false);
  17998. }
  17999. };
  18000. Canvas2D.prototype._addUpdateTransparentDataCount = function (count) {
  18001. if (this._updateTransparentDataCounter) {
  18002. this._updateTransparentDataCounter.addCount(count, false);
  18003. }
  18004. };
  18005. Canvas2D.prototype.addUpdateCachedStateCounter = function (count) {
  18006. if (this._updateCachedStateCounter) {
  18007. this._updateCachedStateCounter.addCount(count, false);
  18008. }
  18009. };
  18010. Canvas2D.prototype.addUpdateLayoutCounter = function (count) {
  18011. if (this._updateLayoutCounter) {
  18012. this._updateLayoutCounter.addCount(count, false);
  18013. }
  18014. };
  18015. Canvas2D.prototype.addUpdatePositioningCounter = function (count) {
  18016. if (this._updatePositioningCounter) {
  18017. this._updatePositioningCounter.addCount(count, false);
  18018. }
  18019. };
  18020. Canvas2D.prototype.addupdateLocalTransformCounter = function (count) {
  18021. if (this._updateLocalTransformCounter) {
  18022. this._updateLocalTransformCounter.addCount(count, false);
  18023. }
  18024. };
  18025. Canvas2D.prototype.addUpdateGlobalTransformCounter = function (count) {
  18026. if (this._updateGlobalTransformCounter) {
  18027. this._updateGlobalTransformCounter.addCount(count, false);
  18028. }
  18029. };
  18030. Canvas2D.prototype.addLayoutBoundingInfoUpdateCounter = function (count) {
  18031. if (this._layoutBoundingInfoUpdateCounter) {
  18032. this._layoutBoundingInfoUpdateCounter.addCount(count, false);
  18033. }
  18034. };
  18035. Canvas2D.prototype._updateTrackedNodes = function () {
  18036. // Get the used camera
  18037. var cam = this.scene.cameraToUseForPointers || this.scene.activeCamera;
  18038. // Compute some matrix stuff
  18039. cam.getViewMatrix().multiplyToRef(cam.getProjectionMatrix(), Canvas2D_1._m);
  18040. var rh = this.engine.getRenderHeight();
  18041. var v = cam.viewport.toGlobal(this.engine.getRenderWidth(), rh);
  18042. var tmpVec3 = Canvas2D_1._tmpVec3;
  18043. var tmpMtx = Canvas2D_1._tmpMtx;
  18044. // Compute the screen position of each group that track a given scene node
  18045. for (var _i = 0, _a = this._trackedGroups; _i < _a.length; _i++) {
  18046. var group = _a[_i];
  18047. if (group.isDisposed) {
  18048. continue;
  18049. }
  18050. var node = group.trackedNode;
  18051. var worldMtx = node.getWorldMatrix();
  18052. if (group.trackedNodeOffset) {
  18053. BABYLON.Vector3.TransformCoordinatesToRef(group.trackedNodeOffset, worldMtx, tmpVec3);
  18054. tmpMtx.copyFrom(worldMtx);
  18055. worldMtx = tmpMtx;
  18056. worldMtx.setTranslation(tmpVec3);
  18057. }
  18058. var proj = BABYLON.Vector3.Project(Canvas2D_1._v, worldMtx, Canvas2D_1._m, v);
  18059. // Set the visibility state accordingly, if the position is outside the frustum (well on the Z planes only...) set the group to hidden
  18060. group.levelVisible = proj.z >= 0 && proj.z < 1.0;
  18061. var s = this.scale;
  18062. group.x = Math.round(proj.x / s);
  18063. group.y = Math.round((rh - proj.y) / s);
  18064. }
  18065. // If it's a WorldSpaceCanvas and it's tracking a node, let's update the WSC transformation data
  18066. if (this._trackNode) {
  18067. var rot = null;
  18068. var scale = null;
  18069. var worldmtx = this._trackNode.getWorldMatrix();
  18070. var pos = worldmtx.getTranslation().add(this._trackNodeOffset);
  18071. var wsc = this;
  18072. var wsn = wsc.worldSpaceCanvasNode;
  18073. if (this._trackNodeBillboard) {
  18074. var viewMtx = cam.getViewMatrix().clone().invert();
  18075. viewMtx.decompose(Canvas2D_1.tS, Canvas2D_1.tR, Canvas2D_1.tT);
  18076. rot = Canvas2D_1.tR.clone();
  18077. }
  18078. worldmtx.decompose(Canvas2D_1.tS, Canvas2D_1.tR, Canvas2D_1.tT);
  18079. var mtx = BABYLON.Matrix.Compose(Canvas2D_1.tS, Canvas2D_1.tR, BABYLON.Vector3.Zero());
  18080. pos = worldmtx.getTranslation().add(BABYLON.Vector3.TransformCoordinates(this._trackNodeOffset, mtx));
  18081. if (Canvas2D_1.tS.lengthSquared() !== 1) {
  18082. scale = Canvas2D_1.tS.clone();
  18083. }
  18084. if (!this._trackNodeBillboard) {
  18085. rot = Canvas2D_1.tR.clone();
  18086. }
  18087. if (wsn instanceof BABYLON.AbstractMesh) {
  18088. wsn.position = pos;
  18089. wsn.rotationQuaternion = rot;
  18090. if (scale) {
  18091. wsn.scaling = scale;
  18092. }
  18093. }
  18094. else {
  18095. throw new Error("Can't Track another Scene Node Type than AbstractMesh right now, call me lazy!");
  18096. }
  18097. }
  18098. };
  18099. /**
  18100. * Call this method change you want to have layout related data computed and up to date (layout area, primitive area, local/global transformation matrices)
  18101. */
  18102. Canvas2D.prototype.updateCanvasLayout = function (forceRecompute) {
  18103. this._updateCanvasState(forceRecompute);
  18104. };
  18105. Canvas2D.prototype._updateAdaptiveSizeWorldCanvas = function () {
  18106. if (this._globalTransformStep < 2) {
  18107. return;
  18108. }
  18109. var n = this.worldSpaceCanvasNode;
  18110. var bi = n.getBoundingInfo().boundingBox;
  18111. var v = bi.vectorsWorld;
  18112. var cam = this.scene.cameraToUseForPointers || this.scene.activeCamera;
  18113. cam.getViewMatrix().multiplyToRef(cam.getProjectionMatrix(), Canvas2D_1._m);
  18114. if (Canvas2D_1._m.m[15] < BABYLON.Epsilon && Canvas2D_1._m.m[15] >= 0) {
  18115. Canvas2D_1._m.m[15] = BABYLON.Epsilon;
  18116. }
  18117. else if (Canvas2D_1._m.m[15] > -BABYLON.Epsilon && Canvas2D_1._m.m[15] <= 0) {
  18118. Canvas2D_1._m.m[15] = -BABYLON.Epsilon;
  18119. }
  18120. var vp = cam.viewport.toGlobal(this.engine.getRenderWidth(), this.engine.getRenderHeight());
  18121. var projPoints = new Array(4);
  18122. for (var i = 0; i < 4; i++) {
  18123. projPoints[i] = BABYLON.Vector3.Project(v[i], Canvas2D_1._mI, Canvas2D_1._m, vp);
  18124. }
  18125. var left = projPoints[3].subtract(projPoints[0]).length();
  18126. var top = projPoints[3].subtract(projPoints[1]).length();
  18127. var right = projPoints[1].subtract(projPoints[2]).length();
  18128. var bottom = projPoints[2].subtract(projPoints[0]).length();
  18129. var w = Math.round(Math.max(top, bottom));
  18130. var h = Math.round(Math.max(right, left));
  18131. var isW = w > h;
  18132. // Basically if it's under 256 we use 256, otherwise we take the biggest power of 2
  18133. var edge = Math.max(w, h);
  18134. if (edge < 256) {
  18135. edge = 256;
  18136. }
  18137. else {
  18138. edge = Math.pow(2, Math.ceil(Math.log(edge) / Math.log(2)));
  18139. }
  18140. // Clip values if needed
  18141. edge = Math.min(edge, this._maxAdaptiveWorldSpaceCanvasSize - 4); // -4 is to consider the border of 2 pixels, other we couldn't allocate a rect
  18142. var newScale = edge / ((isW) ? this.size.width : this.size.height);
  18143. if (newScale !== this._renderableData._renderingScale) {
  18144. var scale = newScale;
  18145. //console.log(`New adaptive scale for Canvas ${this.id}, w: ${w}, h: ${h}, scale: ${scale}, edge: ${edge}, isW: ${isW}`);
  18146. this._setRenderingScale(scale);
  18147. }
  18148. };
  18149. Canvas2D.prototype._updateCanvasState = function (forceRecompute) {
  18150. // Check if the update has already been made for this render Frame
  18151. if (!forceRecompute && this.scene.getRenderId() === this._updateRenderId) {
  18152. return;
  18153. }
  18154. // Detect a change of HWRendering scale
  18155. var hwsl = this.engine.getHardwareScalingLevel();
  18156. this._curHWScale = hwsl;
  18157. // Detect a change of rendering size
  18158. var renderingSizeChanged = false;
  18159. var newWidth = this.engine.getRenderWidth() * hwsl;
  18160. if (newWidth !== this._renderingSize.width) {
  18161. renderingSizeChanged = true;
  18162. }
  18163. this._renderingSize.width = newWidth;
  18164. var newHeight = this.engine.getRenderHeight() * hwsl;
  18165. if (newHeight !== this._renderingSize.height) {
  18166. renderingSizeChanged = true;
  18167. }
  18168. this._renderingSize.height = newHeight;
  18169. var prevCLS = Canvas2D_1._pCLS;
  18170. prevCLS.copyFrom(this._canvasLevelScale);
  18171. // If there's a design size, update the scale according to the renderingSize
  18172. if (this._designSize) {
  18173. var scale = void 0;
  18174. if (this._designUseHorizAxis) {
  18175. scale = this._renderingSize.width / (this._designSize.width * hwsl);
  18176. }
  18177. else {
  18178. scale = this._renderingSize.height / (this._designSize.height * hwsl);
  18179. }
  18180. this.size = this._designSize.clone();
  18181. this._canvasLevelScale.copyFromFloats(scale, scale);
  18182. }
  18183. else {
  18184. var ratio = 1 / this._curHWScale;
  18185. this._canvasLevelScale.copyFromFloats(ratio, ratio);
  18186. }
  18187. if (!prevCLS.equals(this._canvasLevelScale)) {
  18188. for (var _i = 0, _a = this.children; _i < _a.length; _i++) {
  18189. var child = _a[_i];
  18190. child._setFlags(BABYLON.SmartPropertyPrim.flagLocalTransformDirty | BABYLON.SmartPropertyPrim.flagGlobalTransformDirty);
  18191. }
  18192. this._setLayoutDirty();
  18193. }
  18194. // If the canvas fit the rendering size and it changed, update
  18195. if (!this._designSize && renderingSizeChanged && this._fitRenderingDevice) {
  18196. this.size = this._renderingSize.clone();
  18197. if (this._background) {
  18198. this._background.size = this.size;
  18199. }
  18200. // Dirty the Layout at the Canvas level to recompute as the size changed
  18201. this._setLayoutDirty();
  18202. }
  18203. var context = new BABYLON.PrepareRender2DContext();
  18204. ++this._globalTransformProcessStep;
  18205. this._setFlags(BABYLON.SmartPropertyPrim.flagLocalTransformDirty | BABYLON.SmartPropertyPrim.flagGlobalTransformDirty);
  18206. this.updateCachedStates(false);
  18207. this._prepareGroupRender(context);
  18208. this._updateRenderId = this.scene.getRenderId();
  18209. };
  18210. /**
  18211. * Method that renders the Canvas, you should not invoke
  18212. */
  18213. Canvas2D.prototype._render = function () {
  18214. this._initPerfMetrics();
  18215. if (this._renderObservable && this._renderObservable.hasObservers()) {
  18216. this._renderObservable.notifyObservers(this, Canvas2D_1.RENDEROBSERVABLE_PRE);
  18217. }
  18218. this._updateTrackedNodes();
  18219. this._updateCanvasState(false);
  18220. // Nothing to do is the Canvas is not visible
  18221. if (this.isVisible === false) {
  18222. return;
  18223. }
  18224. if (!this._isScreenSpace) {
  18225. this._updateAdaptiveSizeWorldCanvas();
  18226. }
  18227. this._updateCanvasState(false);
  18228. if (this._primitiveCollisionManager) {
  18229. this._primitiveCollisionManager._update();
  18230. }
  18231. if (this._primPointerInfo.canvasPointerPos) {
  18232. this._updateIntersectionList(this._primPointerInfo.canvasPointerPos, false, false);
  18233. this._updateOverStatus(false);
  18234. }
  18235. this.engine.setState(false, undefined, true);
  18236. this._groupRender();
  18237. if (!this._isScreenSpace) {
  18238. if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagWorldCacheChanged)) {
  18239. this.worldSpaceCacheChanged();
  18240. this._clearFlags(BABYLON.SmartPropertyPrim.flagWorldCacheChanged);
  18241. }
  18242. }
  18243. // If the canvas is cached at canvas level, we must manually render the sprite that will display its content
  18244. if (this._cachingStrategy === Canvas2D_1.CACHESTRATEGY_CANVAS && this._cachedCanvasGroup) {
  18245. this._cachedCanvasGroup._renderCachedCanvas();
  18246. }
  18247. this._fetchPerfMetrics();
  18248. this._updateProfileCanvas();
  18249. if (this._renderObservable && this._renderObservable.hasObservers()) {
  18250. this._renderObservable.notifyObservers(this, Canvas2D_1.RENDEROBSERVABLE_POST);
  18251. }
  18252. };
  18253. /**
  18254. * Internal method that allocate a cache for the given group.
  18255. * Caching is made using a collection of MapTexture where many groups have their bitmap cache stored inside.
  18256. * @param group The group to allocate the cache of.
  18257. * @return custom type with the PackedRect instance giving information about the cache location into the texture and also the MapTexture instance that stores the cache.
  18258. */
  18259. Canvas2D.prototype._allocateGroupCache = function (group, parent, minSize, useMipMap, anisotropicLevel) {
  18260. if (useMipMap === void 0) { useMipMap = false; }
  18261. if (anisotropicLevel === void 0) { anisotropicLevel = 1; }
  18262. var key = (useMipMap ? "MipMap" : "NoMipMap") + "_" + anisotropicLevel;
  18263. var rd = group._renderableData;
  18264. var rs = rd._renderingScale;
  18265. var noResizeScale = rd._noResizeOnScale;
  18266. var isCanvas = parent == null;
  18267. var scale;
  18268. if (noResizeScale) {
  18269. scale = isCanvas ? Canvas2D_1._unS : group.parent.actualScale.multiply(this._canvasLevelScale);
  18270. }
  18271. else {
  18272. scale = group.actualScale.multiply(this._canvasLevelScale);
  18273. }
  18274. scale.x *= rs;
  18275. scale.y *= rs;
  18276. // Determine size
  18277. var size = group.actualSize;
  18278. var scaledSize = new BABYLON.Size(size.width * scale.x, size.height * scale.y);
  18279. var roundedScaledSize = new BABYLON.Size(Math.ceil(scaledSize.width), Math.ceil(scaledSize.height));
  18280. var originalSize = scaledSize.clone();
  18281. if (minSize) {
  18282. roundedScaledSize.width = Math.max(minSize.width, roundedScaledSize.width);
  18283. roundedScaledSize.height = Math.max(minSize.height, roundedScaledSize.height);
  18284. }
  18285. var mapArray = this._groupCacheMaps.getOrAddWithFactory(key, function () { return new Array(); });
  18286. // Try to find a spot in one of the cached texture
  18287. var res = null;
  18288. var map;
  18289. for (var _i = 0, mapArray_1 = mapArray; _i < mapArray_1.length; _i++) {
  18290. var _map = mapArray_1[_i];
  18291. map = _map;
  18292. var node = map.allocateRect(roundedScaledSize);
  18293. if (node) {
  18294. res = { node: node, texture: map };
  18295. break;
  18296. }
  18297. }
  18298. // Couldn't find a map that could fit the rect, create a new map for it
  18299. if (!res) {
  18300. var mapSize = new BABYLON.Size(Canvas2D_1._groupTextureCacheSize, Canvas2D_1._groupTextureCacheSize);
  18301. // Check if the predefined size would fit, other create a custom size using the nearest bigger power of 2
  18302. if (roundedScaledSize.width > mapSize.width || roundedScaledSize.height > mapSize.height) {
  18303. mapSize.width = Math.pow(2, Math.ceil(Math.log(roundedScaledSize.width) / Math.log(2)));
  18304. mapSize.height = Math.pow(2, Math.ceil(Math.log(roundedScaledSize.height) / Math.log(2)));
  18305. }
  18306. var id = "groupsMapChache" + this._mapCounter++ + "forCanvas" + this.id;
  18307. map = new BABYLON.MapTexture(id, this._scene, mapSize, useMipMap ? BABYLON.Texture.TRILINEAR_SAMPLINGMODE : BABYLON.Texture.BILINEAR_SAMPLINGMODE, useMipMap, 2);
  18308. map.hasAlpha = true;
  18309. map.anisotropicFilteringLevel = 4;
  18310. mapArray.splice(0, 0, map);
  18311. //let debug = false;
  18312. //if (debug) {
  18313. // let sprite = new Sprite2D(map, { parent: this, x: 10, y: 10, id: "__cachedSpriteOfGroup__Debug", alignToPixel: true });
  18314. //}
  18315. var node = map.allocateRect(roundedScaledSize);
  18316. res = { node: node, texture: map };
  18317. }
  18318. // Check if we have to create a Sprite that will display the content of the Canvas which is cached.
  18319. // Don't do it in case of the group being a worldspace canvas (because its texture is bound to a WorldSpaceCanvas node)
  18320. if (group !== this || this._isScreenSpace) {
  18321. var node = res.node;
  18322. var pos = Canvas2D_1._cv1;
  18323. node.getInnerPosToRef(pos);
  18324. // Special case if the canvas is entirely cached: create a group that will have a single sprite it will be rendered specifically at the very end of the rendering process
  18325. var sprite = void 0;
  18326. if (this._cachingStrategy === Canvas2D_1.CACHESTRATEGY_CANVAS) {
  18327. if (this._cachedCanvasGroup) {
  18328. this._cachedCanvasGroup.dispose();
  18329. }
  18330. this._cachedCanvasGroup = BABYLON.Group2D._createCachedCanvasGroup(this);
  18331. sprite = new BABYLON.Sprite2D(map, { parent: this._cachedCanvasGroup, id: "__cachedCanvasSprite__", spriteSize: originalSize, size: size, alignToPixel: true, spriteLocation: pos });
  18332. sprite.zOrder = 1;
  18333. sprite.origin = BABYLON.Vector2.Zero();
  18334. }
  18335. else {
  18336. sprite = new BABYLON.Sprite2D(map, { parent: parent, id: "__cachedSpriteOfGroup__" + group.id, x: group.x, y: group.y, spriteSize: originalSize, size: size, spriteLocation: pos, alignToPixel: true, dontInheritParentScale: true });
  18337. sprite.origin = group.origin.clone();
  18338. sprite.addExternalData("__cachedGroup__", group);
  18339. sprite.pointerEventObservable.add(function (e, s) {
  18340. if (group.pointerEventObservable !== null) {
  18341. group.pointerEventObservable.notifyObservers(e, s.mask);
  18342. }
  18343. });
  18344. res.sprite = sprite;
  18345. }
  18346. if (sprite && noResizeScale) {
  18347. var relScale = isCanvas ? group.actualScale : group.actualScale.divide(group.parent.actualScale);
  18348. sprite.scaleX = relScale.x;
  18349. sprite.scaleY = relScale.y;
  18350. }
  18351. }
  18352. return res;
  18353. };
  18354. /**
  18355. * Internal method used to register a Scene Node to track position for the given group
  18356. * Do not invoke this method, for internal purpose only.
  18357. * @param group the group to track its associated Scene Node
  18358. */
  18359. Canvas2D.prototype._registerTrackedNode = function (group) {
  18360. if (group._isFlagSet(BABYLON.SmartPropertyPrim.flagTrackedGroup)) {
  18361. return;
  18362. }
  18363. if (!this._trackedGroups) {
  18364. this._trackedGroups = new Array();
  18365. }
  18366. this._trackedGroups.push(group);
  18367. group._setFlags(BABYLON.SmartPropertyPrim.flagTrackedGroup);
  18368. };
  18369. /**
  18370. * Internal method used to unregister a tracked Scene Node
  18371. * Do not invoke this method, it's for internal purpose only.
  18372. * @param group the group to unregister its tracked Scene Node from.
  18373. */
  18374. Canvas2D.prototype._unregisterTrackedNode = function (group) {
  18375. if (!group._isFlagSet(BABYLON.SmartPropertyPrim.flagTrackedGroup)) {
  18376. return;
  18377. }
  18378. var i = this._trackedGroups.indexOf(group);
  18379. if (i !== -1) {
  18380. this._trackedGroups.splice(i, 1);
  18381. }
  18382. group._clearFlags(BABYLON.SmartPropertyPrim.flagTrackedGroup);
  18383. };
  18384. /**
  18385. * Get a Solid Color Brush instance matching the given color.
  18386. * @param color The color to retrieve
  18387. * @return A shared instance of the SolidColorBrush2D class that use the given color
  18388. */
  18389. Canvas2D.GetSolidColorBrush = function (color) {
  18390. return Canvas2D_1._solidColorBrushes.getOrAddWithFactory(color.toHexString(), function () { return new BABYLON.SolidColorBrush2D(color.clone(), true); });
  18391. };
  18392. /**
  18393. * Get a Solid Color Brush instance matching the given color expressed as a CSS formatted hexadecimal value.
  18394. * @param color The color to retrieve
  18395. * @return A shared instance of the SolidColorBrush2D class that uses the given color
  18396. */
  18397. Canvas2D.GetSolidColorBrushFromHex = function (hexValue) {
  18398. return Canvas2D_1._solidColorBrushes.getOrAddWithFactory(hexValue, function () { return new BABYLON.SolidColorBrush2D(BABYLON.Color4.FromHexString(hexValue), true); });
  18399. };
  18400. /**
  18401. * Get a Gradient Color Brush
  18402. * @param color1 starting color
  18403. * @param color2 engine color
  18404. * @param translation translation vector to apply. default is [0;0]
  18405. * @param rotation rotation in radian to apply to the brush, initial direction is top to bottom. rotation is counter clockwise. default is 0.
  18406. * @param scale scaling factor to apply. default is 1.
  18407. */
  18408. Canvas2D.GetGradientColorBrush = function (color1, color2, translation, rotation, scale) {
  18409. if (translation === void 0) { translation = BABYLON.Vector2.Zero(); }
  18410. if (rotation === void 0) { rotation = 0; }
  18411. if (scale === void 0) { scale = 1; }
  18412. return Canvas2D_1._gradientColorBrushes.getOrAddWithFactory(BABYLON.GradientColorBrush2D.BuildKey(color1, color2, translation, rotation, scale), function () { return new BABYLON.GradientColorBrush2D(color1, color2, translation, rotation, scale, true); });
  18413. };
  18414. /**
  18415. * Create a solid or gradient brush from a string value.
  18416. * @param brushString should be either
  18417. * - "solid: #RRGGBBAA" or "#RRGGBBAA"
  18418. * - "gradient: #FF808080, #FFFFFFF[, [10:20], 180, 1]" for color1, color2, translation, rotation (degree), scale. The last three are optionals, but if specified must be is this order. "gradient:" can be omitted.
  18419. */
  18420. Canvas2D.GetBrushFromString = function (brushString) {
  18421. // Note: yes, I hate/don't know RegEx.. Feel free to add your contribution to the cause!
  18422. brushString = brushString.trim();
  18423. var split = brushString.split(",");
  18424. // Solid, formatted as: "[solid:]#FF808080"
  18425. if (split.length === 1) {
  18426. var value = null;
  18427. if (brushString.indexOf("solid:") === 0) {
  18428. value = brushString.substr(6).trim();
  18429. }
  18430. else if (brushString.indexOf("#") === 0) {
  18431. value = brushString;
  18432. }
  18433. else {
  18434. return null;
  18435. }
  18436. return Canvas2D_1.GetSolidColorBrushFromHex(value);
  18437. }
  18438. else {
  18439. if (split[0].indexOf("gradient:") === 0) {
  18440. split[0] = split[0].substr(9).trim();
  18441. }
  18442. try {
  18443. var start = BABYLON.Color4.FromHexString(split[0].trim());
  18444. var end = BABYLON.Color4.FromHexString(split[1].trim());
  18445. var t = BABYLON.Vector2.Zero();
  18446. if (split.length > 2) {
  18447. var v = split[2].trim();
  18448. if (v.charAt(0) !== "[" || v.charAt(v.length - 1) !== "]") {
  18449. return null;
  18450. }
  18451. var sep = v.indexOf(":");
  18452. var x = parseFloat(v.substr(1, sep));
  18453. var y = parseFloat(v.substr(sep + 1, v.length - (sep + 1)));
  18454. t = new BABYLON.Vector2(x, y);
  18455. }
  18456. var r = 0;
  18457. if (split.length > 3) {
  18458. r = BABYLON.Tools.ToRadians(parseFloat(split[3].trim()));
  18459. }
  18460. var s = 1;
  18461. if (split.length > 4) {
  18462. s = parseFloat(split[4].trim());
  18463. }
  18464. return Canvas2D_1.GetGradientColorBrush(start, end, t, r, s);
  18465. }
  18466. catch (e) {
  18467. return null;
  18468. }
  18469. }
  18470. };
  18471. return Canvas2D;
  18472. }(BABYLON.Group2D));
  18473. /**
  18474. * In this strategy only the direct children groups of the Canvas will be cached, their whole content (whatever the sub groups they have) into a single bitmap.
  18475. * This strategy doesn't allow primitives added directly as children of the Canvas.
  18476. * You typically want to use this strategy of a screenSpace fullscreen canvas: you don't want a bitmap cache taking the whole screen resolution but still want the main contents (say UI in the topLeft and rightBottom for instance) to be efficiently cached.
  18477. */
  18478. Canvas2D.CACHESTRATEGY_TOPLEVELGROUPS = 1;
  18479. /**
  18480. * In this strategy each group will have its own cache bitmap (except if a given group explicitly defines the DONTCACHEOVERRIDE or CACHEINPARENTGROUP behaviors).
  18481. * This strategy is typically used if the canvas has some groups that are frequently animated. Unchanged ones will have a steady cache and the others will be refreshed when they change, reducing the redraw operation count to their content only.
  18482. * When using this strategy, group instances can rely on the DONTCACHEOVERRIDE or CACHEINPARENTGROUP behaviors to minimize the amount of cached bitmaps.
  18483. * Note that in this mode the Canvas itself is not cached, it only contains the sprites of its direct children group to render, there's no point to cache the whole canvas, sprites will be rendered pretty efficiently, the memory cost would be too great for the value of it.
  18484. */
  18485. Canvas2D.CACHESTRATEGY_ALLGROUPS = 2;
  18486. /**
  18487. * In this strategy the whole canvas is cached into a single bitmap containing every primitives it owns, at the exception of the ones that are owned by a group having the DONTCACHEOVERRIDE behavior (these primitives will be directly drawn to the viewport at each render for screenSpace Canvas or be part of the Canvas cache bitmap for worldSpace Canvas).
  18488. */
  18489. Canvas2D.CACHESTRATEGY_CANVAS = 3;
  18490. /**
  18491. * This strategy is used to recompose/redraw the canvas entirely at each viewport render.
  18492. * Use this strategy if memory is a concern above rendering performances and/or if the canvas is frequently animated (hence reducing the benefits of caching).
  18493. * Note that you can't use this strategy for WorldSpace Canvas, they need at least a top level group caching.
  18494. */
  18495. Canvas2D.CACHESTRATEGY_DONTCACHE = 4;
  18496. /**
  18497. * Observable Mask to be notified before rendering is made
  18498. */
  18499. Canvas2D.RENDEROBSERVABLE_PRE = 1;
  18500. /**
  18501. * Observable Mask to be notified after rendering is made
  18502. */
  18503. Canvas2D.RENDEROBSERVABLE_POST = 2;
  18504. Canvas2D._INSTANCES = [];
  18505. Canvas2D._zMinDelta = 1 / (Math.pow(2, 24) - 1);
  18506. Canvas2D._interInfo = new BABYLON.IntersectInfo2D();
  18507. Canvas2D._v = BABYLON.Vector3.Zero(); // Must stay zero
  18508. Canvas2D._cv1 = BABYLON.Vector2.Zero(); // Must stay zero
  18509. Canvas2D._m = BABYLON.Matrix.Identity();
  18510. Canvas2D._mI = BABYLON.Matrix.Identity(); // Must stay identity
  18511. Canvas2D.tS = BABYLON.Vector3.Zero();
  18512. Canvas2D.tT = BABYLON.Vector3.Zero();
  18513. Canvas2D.tR = BABYLON.Quaternion.Identity();
  18514. Canvas2D._tmpMtx = BABYLON.Matrix.Identity();
  18515. Canvas2D._tmpVec3 = BABYLON.Vector3.Zero();
  18516. Canvas2D._pCLS = BABYLON.Vector2.Zero();
  18517. /**
  18518. * Define the default size used for both the width and height of a MapTexture to allocate.
  18519. * Note that some MapTexture might be bigger than this size if the first node to allocate is bigger in width or height
  18520. */
  18521. Canvas2D._groupTextureCacheSize = 1024;
  18522. Canvas2D._solidColorBrushes = new BABYLON.StringDictionary();
  18523. Canvas2D._gradientColorBrushes = new BABYLON.StringDictionary();
  18524. __decorate([
  18525. BABYLON.logMethod("==========CANVAS RENDER===============")
  18526. ], Canvas2D.prototype, "_render", null);
  18527. Canvas2D = Canvas2D_1 = __decorate([
  18528. BABYLON.className("Canvas2D", "BABYLON")
  18529. /**
  18530. * The Canvas2D main class.
  18531. * This class is extended in both ScreenSpaceCanvas2D and WorldSpaceCanvas2D which are designed only for semantic use.
  18532. * User creates a Screen or WorldSpace canvas which is a 2D surface area that will draw the primitives that were added as children.
  18533. */
  18534. ], Canvas2D);
  18535. BABYLON.Canvas2D = Canvas2D;
  18536. var WorldSpaceCanvas2D = (function (_super) {
  18537. __extends(WorldSpaceCanvas2D, _super);
  18538. /**
  18539. * Create a new 2D WorldSpace Rendering Canvas, it is a 2D rectangle that has a size (width/height) and a world transformation information to place it in the world space.
  18540. * This kind of canvas can't have its Primitives directly drawn in the Viewport, they need to be cached in a bitmap at some point, as a consequence the DONT_CACHE strategy is unavailable. For now only CACHESTRATEGY_CANVAS is supported, but the remaining strategies will be soon.
  18541. * @param scene the Scene that owns the Canvas
  18542. * @param size the dimension of the Canvas in World Space
  18543. * @param settings a combination of settings, possible ones are
  18544. * - children: an array of direct children primitives
  18545. * - id: a text identifier, for information purpose only, default is null.
  18546. * - unitScaleFactor: if specified the created canvas will be with a width of size.width*unitScaleFactor and a height of size.height.unitScaleFactor. If not specified, the unit of 1 is used. You can use this setting when you're dealing with a 3D world with small coordinates and you need a Canvas having bigger coordinates (typically to display text with better quality).
  18547. * - worldPosition the position of the Canvas in World Space, default is [0,0,0]
  18548. * - worldRotation the rotation of the Canvas in World Space, default is Quaternion.Identity()
  18549. * - trackNode: if you want the WorldSpaceCanvas to track the position/rotation/scale of a given Scene Node, use this setting to specify the Node to track
  18550. * - trackNodeOffset: if you use trackNode you may want to specify a 3D Offset to apply to shift the Canvas
  18551. * - trackNodeBillboard: if true the WorldSpaceCanvas will always face the screen
  18552. * - sideOrientation: Unexpected behavior occur if the value is different from Mesh.DEFAULTSIDE right now, so please use this one, which is the default.
  18553. * - cachingStrategy Must be CACHESTRATEGY_CANVAS for now, which is the default.
  18554. * - enableInteraction: if true the pointer events will be listened and rerouted to the appropriate primitives of the Canvas2D through the Prim2DBase.onPointerEventObservable observable property. Default is false (the opposite of ScreenSpace).
  18555. * - isVisible: true if the canvas must be visible, false for hidden. Default is true.
  18556. * - backgroundRoundRadius: the round radius of the background, either backgroundFill or backgroundBorder must be specified.
  18557. * - backgroundFill: the brush to use to create a background fill for the canvas. can be a string value (see Canvas2D.GetBrushFromString) or a IBrush2D instance.
  18558. * - backgroundBorder: the brush to use to create a background border for the canvas. can be a string value (see Canvas2D.GetBrushFromString) or a IBrush2D instance.
  18559. * - backgroundBorderThickness: if a backgroundBorder is specified, its thickness can be set using this property
  18560. * - customWorldSpaceNode: if specified the Canvas will be rendered in this given Node. But it's the responsibility of the caller to set the "worldSpaceToNodeLocal" property to compute the hit of the mouse ray into the node (in world coordinate system) as well as rendering the cached bitmap in the node itself. The properties cachedRect and cachedTexture of Group2D will give you what you need to do that.
  18561. * - maxAdaptiveCanvasSize: set the max size (width and height) of the bitmap that will contain the cached version of the WorldSpace Canvas. Default is 1024 or less if it's not supported. In any case the value you give will be clipped by the maximum that WebGL supports on the running device. You can set any size, more than 1024 if you want, but testing proved it's a good max value for non "retina" like screens.
  18562. * - paddingTop: top padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  18563. * - paddingLeft: left padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  18564. * - paddingRight: right padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  18565. * - paddingBottom: bottom padding, can be a number (will be pixels) or a string (see PrimitiveThickness.fromString)
  18566. * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
  18567. */
  18568. function WorldSpaceCanvas2D(scene, size, settings) {
  18569. var _this = this;
  18570. BABYLON.Prim2DBase._isCanvasInit = true;
  18571. var s = settings;
  18572. s.isScreenSpace = false;
  18573. if (settings.unitScaleFactor != null) {
  18574. s.size = size.multiplyByFloats(settings.unitScaleFactor, settings.unitScaleFactor);
  18575. }
  18576. else {
  18577. s.size = size.clone();
  18578. }
  18579. settings.cachingStrategy = (settings.cachingStrategy == null) ? Canvas2D.CACHESTRATEGY_CANVAS : settings.cachingStrategy;
  18580. if (settings.cachingStrategy !== Canvas2D.CACHESTRATEGY_CANVAS) {
  18581. throw new Error("Right now only the CACHESTRATEGY_CANVAS cache Strategy is supported for WorldSpace Canvas. More will come soon!");
  18582. }
  18583. _this = _super.call(this, scene, settings) || this;
  18584. BABYLON.Prim2DBase._isCanvasInit = false;
  18585. _this._unitScaleFactor = (settings.unitScaleFactor != null) ? settings.unitScaleFactor : 1;
  18586. _this._renderableData._useMipMap = true;
  18587. _this._renderableData._anisotropicLevel = 8;
  18588. //if (cachingStrategy === Canvas2D.CACHESTRATEGY_DONTCACHE) {
  18589. // throw new Error("CACHESTRATEGY_DONTCACHE cache Strategy can't be used for WorldSpace Canvas");
  18590. //}
  18591. _this._trackNode = (settings.trackNode != null) ? settings.trackNode : null;
  18592. _this._trackNodeOffset = (settings.trackNodeOffset != null) ? settings.trackNodeOffset : BABYLON.Vector3.Zero();
  18593. _this._trackNodeBillboard = (settings.trackNodeBillboard != null) ? settings.trackNodeBillboard : true;
  18594. var createWorldSpaceNode = !settings || (settings.customWorldSpaceNode == null);
  18595. _this._customWorldSpaceNode = !createWorldSpaceNode;
  18596. var id = settings ? settings.id || null : null;
  18597. // Set the max size of texture allowed for the adaptive render of the world space canvas cached bitmap
  18598. var capMaxTextSize = _this.engine.getCaps().maxRenderTextureSize;
  18599. var defaultTextSize = (Math.min(capMaxTextSize, 1024)); // Default is 1K if allowed otherwise the max allowed
  18600. if (settings.maxAdaptiveCanvasSize == null) {
  18601. _this._maxAdaptiveWorldSpaceCanvasSize = defaultTextSize;
  18602. }
  18603. else {
  18604. // We still clip the given value with the max allowed, the user may not be aware of these limitations
  18605. _this._maxAdaptiveWorldSpaceCanvasSize = Math.min(settings.maxAdaptiveCanvasSize, capMaxTextSize);
  18606. }
  18607. if (createWorldSpaceNode) {
  18608. var plane = new BABYLON.WorldSpaceCanvas2DNode(id, scene, _this);
  18609. var vertexData = BABYLON.VertexData.CreatePlane({
  18610. width: size.width,
  18611. height: size.height,
  18612. sideOrientation: settings && settings.sideOrientation || BABYLON.Mesh.DEFAULTSIDE
  18613. });
  18614. var mtl = new BABYLON.StandardMaterial(id + "_Material", scene);
  18615. _this.applyCachedTexture(vertexData, mtl);
  18616. vertexData.applyToMesh(plane, true);
  18617. mtl.specularColor = new BABYLON.Color3(0, 0, 0);
  18618. mtl.disableLighting = true;
  18619. mtl.useAlphaFromDiffuseTexture = true;
  18620. if (settings && settings.sideOrientation) {
  18621. mtl.backFaceCulling = (settings.sideOrientation === BABYLON.Mesh.DEFAULTSIDE || settings.sideOrientation === BABYLON.Mesh.FRONTSIDE);
  18622. }
  18623. plane.position = settings && settings.worldPosition || BABYLON.Vector3.Zero();
  18624. plane.rotationQuaternion = settings && settings.worldRotation || BABYLON.Quaternion.Identity();
  18625. plane.material = mtl;
  18626. _this._worldSpaceNode = plane;
  18627. }
  18628. else {
  18629. _this._worldSpaceNode = settings.customWorldSpaceNode;
  18630. _this.applyCachedTexture(null, null);
  18631. }
  18632. _this.propertyChanged.add(function (e, st) {
  18633. if (e.propertyName !== "isVisible") {
  18634. return;
  18635. }
  18636. var mesh = _this._worldSpaceNode;
  18637. if (mesh) {
  18638. mesh.isVisible = e.newValue;
  18639. }
  18640. }, BABYLON.Prim2DBase.isVisibleProperty.flagId);
  18641. return _this;
  18642. }
  18643. WorldSpaceCanvas2D.prototype.dispose = function () {
  18644. if (!_super.prototype.dispose.call(this)) {
  18645. return false;
  18646. }
  18647. if (!this._customWorldSpaceNode && this._worldSpaceNode) {
  18648. this._worldSpaceNode.dispose();
  18649. this._worldSpaceNode = null;
  18650. }
  18651. };
  18652. Object.defineProperty(WorldSpaceCanvas2D.prototype, "trackNode", {
  18653. get: function () {
  18654. return this._trackNode;
  18655. },
  18656. set: function (value) {
  18657. if (this._trackNode === value) {
  18658. return;
  18659. }
  18660. this._trackNode = value;
  18661. },
  18662. enumerable: true,
  18663. configurable: true
  18664. });
  18665. Object.defineProperty(WorldSpaceCanvas2D.prototype, "trackNodeOffset", {
  18666. get: function () {
  18667. return this._trackNodeOffset;
  18668. },
  18669. set: function (value) {
  18670. if (!this._trackNodeOffset) {
  18671. this._trackNodeOffset = value.clone();
  18672. }
  18673. else {
  18674. this._trackNodeOffset.copyFrom(value);
  18675. }
  18676. },
  18677. enumerable: true,
  18678. configurable: true
  18679. });
  18680. Object.defineProperty(WorldSpaceCanvas2D.prototype, "trackNodeBillboard", {
  18681. get: function () {
  18682. return this._trackNodeBillboard;
  18683. },
  18684. set: function (value) {
  18685. this._trackNodeBillboard = value;
  18686. },
  18687. enumerable: true,
  18688. configurable: true
  18689. });
  18690. return WorldSpaceCanvas2D;
  18691. }(Canvas2D));
  18692. WorldSpaceCanvas2D = __decorate([
  18693. BABYLON.className("WorldSpaceCanvas2D", "BABYLON")
  18694. /**
  18695. * Class to create a WorldSpace Canvas2D.
  18696. */
  18697. ], WorldSpaceCanvas2D);
  18698. BABYLON.WorldSpaceCanvas2D = WorldSpaceCanvas2D;
  18699. var ScreenSpaceCanvas2D = (function (_super) {
  18700. __extends(ScreenSpaceCanvas2D, _super);
  18701. /**
  18702. * Create a new 2D ScreenSpace Rendering Canvas, it is a 2D rectangle that has a size (width/height) and a position relative to the bottom/left corner of the screen.
  18703. * ScreenSpace Canvas will be drawn in the Viewport as a 2D Layer lying to the top of the 3D Scene. Typically used for traditional UI.
  18704. * All caching strategies will be available.
  18705. * PLEASE NOTE: the origin of a Screen Space Canvas is set to [0;0] (bottom/left) which is different than the default origin of a Primitive which is centered [0.5;0.5]
  18706. * @param scene the Scene that owns the Canvas
  18707. * @param settings a combination of settings, possible ones are
  18708. * - children: an array of direct children primitives
  18709. * - id: a text identifier, for information purpose only
  18710. * - x: the position along the x axis (horizontal), relative to the left edge of the viewport. you can alternatively use the position setting.
  18711. * - y: the position along the y axis (vertically), relative to the bottom edge of the viewport. you can alternatively use the position setting.
  18712. * - position: the position of the canvas, relative from the bottom/left of the scene's viewport. Alternatively you can set the x and y properties directly. Default value is [0, 0]
  18713. * - width: the width of the Canvas. you can alternatively use the size setting.
  18714. * - height: the height of the Canvas. you can alternatively use the size setting.
  18715. * - size: the Size of the canvas. Alternatively the width and height properties can be set. If null two behaviors depend on the cachingStrategy: if it's CACHESTRATEGY_CACHECANVAS then it will always auto-fit the rendering device, in all the other modes it will fit the content of the Canvas
  18716. * - renderingPhase: you can specify for which camera and which renderGroup this canvas will render to enable interleaving of 3D/2D content through the use of renderinGroup. As a rendering Group is rendered for each camera, you have to specify in the scope of which camera you want the canvas' render to be made. Default behavior will render the Canvas at the very end of the render loop.
  18717. * - designSize: if you want to set the canvas content based on fixed coordinates whatever the final canvas dimension would be, set this. For instance a designSize of 360*640 will give you the possibility to specify all the children element in this frame. The Canvas' true size will be the HTMLCanvas' size: for instance it could be 720*1280, then a uniform scale of 2 will be applied on the Canvas to keep the absolute coordinates working as expecting. If the ratios of the designSize and the true Canvas size are not the same, then the scale is computed following the designUseHorizAxis member by using either the size of the horizontal axis or the vertical axis.
  18718. * - designUseHorizAxis: you can set this member if you use designSize to specify which axis is priority to compute the scale when the ratio of the canvas' size is different from the designSize's one.
  18719. * - cachingStrategy: either CACHESTRATEGY_TOPLEVELGROUPS, CACHESTRATEGY_ALLGROUPS, CACHESTRATEGY_CANVAS, CACHESTRATEGY_DONTCACHE. Please refer to their respective documentation for more information. Default is Canvas2D.CACHESTRATEGY_DONTCACHE
  18720. * - enableInteraction: if true the pointer events will be listened and rerouted to the appropriate primitives of the Canvas2D through the Prim2DBase.onPointerEventObservable observable property. Default is true.
  18721. * - isVisible: true if the canvas must be visible, false for hidden. Default is true.
  18722. * - backgroundRoundRadius: the round radius of the background, either backgroundFill or backgroundBorder must be specified.
  18723. * - backgroundFill: the brush to use to create a background fill for the canvas. can be a string value (see BABYLON.Canvas2D.GetBrushFromString) or a IBrush2D instance.
  18724. * - backgroundBorder: the brush to use to create a background border for the canvas. can be a string value (see BABYLON.Canvas2D.GetBrushFromString) or a IBrush2D instance.
  18725. * - backgroundBorderThickness: if a backgroundBorder is specified, its thickness can be set using this property
  18726. * - customWorldSpaceNode: if specified the Canvas will be rendered in this given Node. But it's the responsibility of the caller to set the "worldSpaceToNodeLocal" property to compute the hit of the mouse ray into the node (in world coordinate system) as well as rendering the cached bitmap in the node itself. The properties cachedRect and cachedTexture of Group2D will give you what you need to do that.
  18727. * - paddingTop: top padding, can be a number (will be pixels) or a string (see BABYLON.PrimitiveThickness.fromString)
  18728. * - paddingLeft: left padding, can be a number (will be pixels) or a string (see BABYLON.PrimitiveThickness.fromString)
  18729. * - paddingRight: right padding, can be a number (will be pixels) or a string (see BABYLON.PrimitiveThickness.fromString)
  18730. * - paddingBottom: bottom padding, can be a number (will be pixels) or a string (see BABYLON.PrimitiveThickness.fromString)
  18731. * - padding: top, left, right and bottom padding formatted as a single string (see BABYLON.PrimitiveThickness.fromString)
  18732. */
  18733. function ScreenSpaceCanvas2D(scene, settings) {
  18734. var _this = this;
  18735. BABYLON.Prim2DBase._isCanvasInit = true;
  18736. _this = _super.call(this, scene, settings) || this;
  18737. return _this;
  18738. }
  18739. return ScreenSpaceCanvas2D;
  18740. }(Canvas2D));
  18741. ScreenSpaceCanvas2D = __decorate([
  18742. BABYLON.className("ScreenSpaceCanvas2D", "BABYLON")
  18743. /**
  18744. * Class to create a ScreenSpace Canvas2D
  18745. */
  18746. ], ScreenSpaceCanvas2D);
  18747. BABYLON.ScreenSpaceCanvas2D = ScreenSpaceCanvas2D;
  18748. var Canvas2D_1;
  18749. })(BABYLON || (BABYLON = {}));
  18750. var __extends = (this && this.__extends) || (function () {
  18751. var extendStatics = Object.setPrototypeOf ||
  18752. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  18753. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  18754. return function (d, b) {
  18755. extendStatics(d, b);
  18756. function __() { this.constructor = d; }
  18757. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  18758. };
  18759. })();
  18760. var BABYLON;
  18761. (function (BABYLON) {
  18762. /**
  18763. * This is the class that is used to display a World Space Canvas into a 3D scene
  18764. */
  18765. var WorldSpaceCanvas2DNode = (function (_super) {
  18766. __extends(WorldSpaceCanvas2DNode, _super);
  18767. function WorldSpaceCanvas2DNode(name, scene, canvas) {
  18768. var _this = _super.call(this, name, scene) || this;
  18769. _this._canvas = canvas;
  18770. return _this;
  18771. }
  18772. WorldSpaceCanvas2DNode.prototype.dispose = function () {
  18773. _super.prototype.dispose.call(this);
  18774. if (this._canvas) {
  18775. this._canvas.dispose();
  18776. this._canvas = null;
  18777. }
  18778. };
  18779. return WorldSpaceCanvas2DNode;
  18780. }(BABYLON.Mesh));
  18781. BABYLON.WorldSpaceCanvas2DNode = WorldSpaceCanvas2DNode;
  18782. })(BABYLON || (BABYLON = {}));
  18783. var __extends = (this && this.__extends) || (function () {
  18784. var extendStatics = Object.setPrototypeOf ||
  18785. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  18786. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  18787. return function (d, b) {
  18788. extendStatics(d, b);
  18789. function __() { this.constructor = d; }
  18790. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  18791. };
  18792. })();
  18793. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  18794. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  18795. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  18796. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  18797. return c > 3 && r && Object.defineProperty(target, key, r), r;
  18798. };
  18799. var BABYLON;
  18800. (function (BABYLON) {
  18801. var Command = (function () {
  18802. function Command(execute, canExecute) {
  18803. if (!execute) {
  18804. throw Error("At least an execute lambda must be given at Command creation time");
  18805. }
  18806. this._canExecuteChanged = null;
  18807. this._lastCanExecuteResult = null;
  18808. this.execute = execute;
  18809. this.canExecute = canExecute;
  18810. }
  18811. Command.prototype.canExecute = function (parameter) {
  18812. var res = true;
  18813. if (this._canExecute) {
  18814. res = this._canExecute(parameter);
  18815. }
  18816. if (res !== this._lastCanExecuteResult) {
  18817. if (this._canExecuteChanged && this._canExecuteChanged.hasObservers()) {
  18818. this._canExecuteChanged.notifyObservers(null);
  18819. }
  18820. this._lastCanExecuteResult = res;
  18821. }
  18822. return res;
  18823. };
  18824. Command.prototype.execute = function (parameter) {
  18825. this._execute(parameter);
  18826. };
  18827. Object.defineProperty(Command.prototype, "canExecuteChanged", {
  18828. get: function () {
  18829. if (!this._canExecuteChanged) {
  18830. this._canExecuteChanged = new BABYLON.Observable();
  18831. }
  18832. return this._canExecuteChanged;
  18833. },
  18834. enumerable: true,
  18835. configurable: true
  18836. });
  18837. return Command;
  18838. }());
  18839. BABYLON.Command = Command;
  18840. var UIElement = (function (_super) {
  18841. __extends(UIElement, _super);
  18842. function UIElement(settings) {
  18843. var _this = _super.call(this) || this;
  18844. if (!settings) {
  18845. throw Error("A settings object must be passed with at least either a parent or owner parameter");
  18846. }
  18847. var type = BABYLON.Tools.getFullClassName(_this);
  18848. _this._ownerWindow = null;
  18849. _this._parent = null;
  18850. _this._visualPlaceholder = null;
  18851. _this._visualTemplateRoot = null;
  18852. _this._visualChildrenPlaceholder = null;
  18853. _this._hierarchyDepth = 0;
  18854. _this._renderingTemplateName = (settings.templateName != null) ? settings.templateName : GUIManager.DefaultTemplateName;
  18855. _this._style = (settings.styleName != null) ? GUIManager.getStyle(type, settings.styleName) : null;
  18856. _this._flags = 0;
  18857. _this._id = (settings.id != null) ? settings.id : null;
  18858. _this._uid = null;
  18859. _this._width = (settings.width != null) ? settings.width : null;
  18860. _this._height = (settings.height != null) ? settings.height : null;
  18861. _this._minWidth = (settings.minWidth != null) ? settings.minWidth : 0;
  18862. _this._minHeight = (settings.minHeight != null) ? settings.minHeight : 0;
  18863. _this._maxWidth = (settings.maxWidth != null) ? settings.maxWidth : Number.MAX_VALUE;
  18864. _this._maxHeight = (settings.maxHeight != null) ? settings.maxHeight : Number.MAX_VALUE;
  18865. _this._margin = null;
  18866. _this._padding = null;
  18867. _this._marginAlignment = null;
  18868. _this._setFlags(UIElement.flagIsVisible | UIElement.flagIsEnabled);
  18869. // Default Margin Alignment for UIElement is stretch for horizontal/vertical and not left/bottom (which is the default for Canvas2D Primitives)
  18870. //this.marginAlignment.horizontal = PrimitiveAlignment.AlignStretch;
  18871. //this.marginAlignment.vertical = PrimitiveAlignment.AlignStretch;
  18872. // Set the layout/margin stuffs
  18873. if (settings.marginTop) {
  18874. _this.margin.setTop(settings.marginTop);
  18875. }
  18876. if (settings.marginLeft) {
  18877. _this.margin.setLeft(settings.marginLeft);
  18878. }
  18879. if (settings.marginRight) {
  18880. _this.margin.setRight(settings.marginRight);
  18881. }
  18882. if (settings.marginBottom) {
  18883. _this.margin.setBottom(settings.marginBottom);
  18884. }
  18885. if (settings.margin) {
  18886. if (typeof settings.margin === "string") {
  18887. _this.margin.fromString(settings.margin);
  18888. }
  18889. else {
  18890. _this.margin.fromUniformPixels(settings.margin);
  18891. }
  18892. }
  18893. if (settings.marginHAlignment) {
  18894. _this.marginAlignment.horizontal = settings.marginHAlignment;
  18895. }
  18896. if (settings.marginVAlignment) {
  18897. _this.marginAlignment.vertical = settings.marginVAlignment;
  18898. }
  18899. if (settings.marginAlignment) {
  18900. _this.marginAlignment.fromString(settings.marginAlignment);
  18901. }
  18902. if (settings.paddingTop) {
  18903. _this.padding.setTop(settings.paddingTop);
  18904. }
  18905. if (settings.paddingLeft) {
  18906. _this.padding.setLeft(settings.paddingLeft);
  18907. }
  18908. if (settings.paddingRight) {
  18909. _this.padding.setRight(settings.paddingRight);
  18910. }
  18911. if (settings.paddingBottom) {
  18912. _this.padding.setBottom(settings.paddingBottom);
  18913. }
  18914. if (settings.padding) {
  18915. _this.padding.fromString(settings.padding);
  18916. }
  18917. if (settings.paddingHAlignment) {
  18918. _this.paddingAlignment.horizontal = settings.paddingHAlignment;
  18919. }
  18920. if (settings.paddingVAlignment) {
  18921. _this.paddingAlignment.vertical = settings.paddingVAlignment;
  18922. }
  18923. if (settings.paddingAlignment) {
  18924. _this.paddingAlignment.fromString(settings.paddingAlignment);
  18925. }
  18926. if (settings.parent != null) {
  18927. _this._parent = settings.parent;
  18928. _this._hierarchyDepth = _this._parent._hierarchyDepth + 1;
  18929. }
  18930. return _this;
  18931. }
  18932. Object.defineProperty(UIElement, "enabledState", {
  18933. get: function () {
  18934. return UIElement._enableState;
  18935. },
  18936. enumerable: true,
  18937. configurable: true
  18938. });
  18939. Object.defineProperty(UIElement, "disabledState", {
  18940. get: function () {
  18941. return UIElement._disabledState;
  18942. },
  18943. enumerable: true,
  18944. configurable: true
  18945. });
  18946. Object.defineProperty(UIElement, "mouseOverState", {
  18947. get: function () {
  18948. return UIElement._mouseOverState;
  18949. },
  18950. enumerable: true,
  18951. configurable: true
  18952. });
  18953. UIElement.prototype.dispose = function () {
  18954. if (this.isDisposed) {
  18955. return false;
  18956. }
  18957. if (this._renderingTemplate) {
  18958. this._renderingTemplate.detach();
  18959. this._renderingTemplate = null;
  18960. }
  18961. _super.prototype.dispose.call(this);
  18962. // Don't set to null, it may upset somebody...
  18963. this.animations.splice(0);
  18964. return true;
  18965. };
  18966. /**
  18967. * Returns as a new array populated with the Animatable used by the primitive. Must be overloaded by derived primitives.
  18968. * Look at Sprite2D for more information
  18969. */
  18970. UIElement.prototype.getAnimatables = function () {
  18971. return new Array();
  18972. };
  18973. // TODO
  18974. // PROPERTIES
  18975. // Style
  18976. // Id
  18977. // Parent/Children
  18978. // ActualWidth/Height, MinWidth/Height, MaxWidth/Height,
  18979. // Alignment/Margin
  18980. // Visibility, IsVisible
  18981. // IsEnabled (is false, control is disabled, no interaction and a specific render state)
  18982. // CacheMode of Visual Elements
  18983. // Focusable/IsFocused
  18984. // IsPointerCaptured, CapturePointer, IsPointerDirectlyOver, IsPointerOver. De-correlate mouse, stylus, touch?
  18985. // ContextMenu
  18986. // Cursor
  18987. // DesiredSize
  18988. // IsInputEnable ?
  18989. // Opacity, OpacityMask ?
  18990. // SnapToDevicePixels
  18991. // Tag
  18992. // ToolTip
  18993. // METHODS
  18994. // BringIntoView (for scrollable content, to move the scroll to bring the given element visible in the parent's area)
  18995. // Capture/ReleaseCapture (mouse, touch, stylus)
  18996. // Focus
  18997. // PointFrom/ToScreen to translate coordinates
  18998. // EVENTS
  18999. // ContextMenuOpening/Closing/Changed
  19000. // DragEnter/LeaveOver, Drop
  19001. // Got/LostFocus
  19002. // IsEnabledChanged
  19003. // IsPointerOver/DirectlyOverChanged
  19004. // IsVisibleChanged
  19005. // KeyDown/Up
  19006. // LayoutUpdated ?
  19007. // Pointer related events
  19008. // SizeChanged
  19009. // ToolTipOpening/Closing
  19010. UIElement.prototype.findById = function (id) {
  19011. if (this._id === id) {
  19012. return this;
  19013. }
  19014. var children = this._getChildren();
  19015. for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
  19016. var child = children_1[_i];
  19017. var r = child.findById(id);
  19018. if (r != null) {
  19019. return r;
  19020. }
  19021. }
  19022. };
  19023. Object.defineProperty(UIElement.prototype, "ownerWindow", {
  19024. get: function () {
  19025. return this._ownerWindow;
  19026. },
  19027. enumerable: true,
  19028. configurable: true
  19029. });
  19030. Object.defineProperty(UIElement.prototype, "style", {
  19031. get: function () {
  19032. if (!this.style) {
  19033. return GUIManager.DefaultStyleName;
  19034. }
  19035. return this._style.name;
  19036. },
  19037. set: function (value) {
  19038. if (this._style && (this._style.name === value)) {
  19039. return;
  19040. }
  19041. var newStyle = null;
  19042. if (value) {
  19043. newStyle = GUIManager.getStyle(BABYLON.Tools.getFullClassName(this), value);
  19044. if (!newStyle) {
  19045. throw Error("Couldn't find Style " + value + " for UIElement " + BABYLON.Tools.getFullClassName(this));
  19046. }
  19047. }
  19048. if (this._style) {
  19049. this._style.removeStyle(this);
  19050. }
  19051. if (newStyle) {
  19052. newStyle.applyStyle(this);
  19053. }
  19054. this._style = newStyle;
  19055. },
  19056. enumerable: true,
  19057. configurable: true
  19058. });
  19059. Object.defineProperty(UIElement.prototype, "id", {
  19060. /**
  19061. * A string that identifies the UIElement.
  19062. * The id is optional and there's possible collision with other UIElement's id as the uniqueness is not supported.
  19063. */
  19064. get: function () {
  19065. return this._id;
  19066. },
  19067. set: function (value) {
  19068. if (this._id === value) {
  19069. return;
  19070. }
  19071. this._id = value;
  19072. },
  19073. enumerable: true,
  19074. configurable: true
  19075. });
  19076. Object.defineProperty(UIElement.prototype, "uid", {
  19077. /**
  19078. * Return a unique id automatically generated.
  19079. * This property is mainly used for serialization to ensure a perfect way of identifying a UIElement
  19080. */
  19081. get: function () {
  19082. if (!this._uid) {
  19083. this._uid = BABYLON.Tools.RandomId();
  19084. }
  19085. return this._uid;
  19086. },
  19087. enumerable: true,
  19088. configurable: true
  19089. });
  19090. Object.defineProperty(UIElement.prototype, "hierarchyDepth", {
  19091. get: function () {
  19092. return this._hierarchyDepth;
  19093. },
  19094. enumerable: true,
  19095. configurable: true
  19096. });
  19097. Object.defineProperty(UIElement.prototype, "parent", {
  19098. get: function () {
  19099. return this._parent;
  19100. },
  19101. set: function (value) {
  19102. this._parent = value;
  19103. },
  19104. enumerable: true,
  19105. configurable: true
  19106. });
  19107. Object.defineProperty(UIElement.prototype, "width", {
  19108. get: function () {
  19109. return this._width;
  19110. },
  19111. set: function (value) {
  19112. this._width = value;
  19113. },
  19114. enumerable: true,
  19115. configurable: true
  19116. });
  19117. Object.defineProperty(UIElement.prototype, "height", {
  19118. get: function () {
  19119. return this._height;
  19120. },
  19121. set: function (value) {
  19122. this._height = value;
  19123. },
  19124. enumerable: true,
  19125. configurable: true
  19126. });
  19127. Object.defineProperty(UIElement.prototype, "minWidth", {
  19128. get: function () {
  19129. return this._minWidth;
  19130. },
  19131. set: function (value) {
  19132. this._minWidth = value;
  19133. },
  19134. enumerable: true,
  19135. configurable: true
  19136. });
  19137. Object.defineProperty(UIElement.prototype, "minHheight", {
  19138. get: function () {
  19139. return this._minHeight;
  19140. },
  19141. enumerable: true,
  19142. configurable: true
  19143. });
  19144. Object.defineProperty(UIElement.prototype, "minHeight", {
  19145. set: function (value) {
  19146. this._minHeight = value;
  19147. },
  19148. enumerable: true,
  19149. configurable: true
  19150. });
  19151. Object.defineProperty(UIElement.prototype, "maxWidth", {
  19152. get: function () {
  19153. return this._maxWidth;
  19154. },
  19155. set: function (value) {
  19156. this._maxWidth = value;
  19157. },
  19158. enumerable: true,
  19159. configurable: true
  19160. });
  19161. Object.defineProperty(UIElement.prototype, "maxHeight", {
  19162. get: function () {
  19163. return this._maxHeight;
  19164. },
  19165. set: function (value) {
  19166. this._maxHeight = value;
  19167. },
  19168. enumerable: true,
  19169. configurable: true
  19170. });
  19171. Object.defineProperty(UIElement.prototype, "actualWidth", {
  19172. get: function () {
  19173. return this._actualWidth;
  19174. },
  19175. set: function (value) {
  19176. this._actualWidth = value;
  19177. },
  19178. enumerable: true,
  19179. configurable: true
  19180. });
  19181. Object.defineProperty(UIElement.prototype, "actualHeight", {
  19182. get: function () {
  19183. return this._actualHeight;
  19184. },
  19185. set: function (value) {
  19186. this._actualHeight = value;
  19187. },
  19188. enumerable: true,
  19189. configurable: true
  19190. });
  19191. Object.defineProperty(UIElement.prototype, "margin", {
  19192. get: function () {
  19193. var _this = this;
  19194. if (!this._margin) {
  19195. this._margin = new BABYLON.PrimitiveThickness(function () {
  19196. if (!_this.parent) {
  19197. return null;
  19198. }
  19199. return _this.parent.margin;
  19200. });
  19201. }
  19202. return this._margin;
  19203. },
  19204. set: function (value) {
  19205. this.margin.copyFrom(value);
  19206. },
  19207. enumerable: true,
  19208. configurable: true
  19209. });
  19210. Object.defineProperty(UIElement.prototype, "_hasMargin", {
  19211. get: function () {
  19212. return (this._margin !== null && !this._margin.isDefault) || (this._marginAlignment !== null && !this._marginAlignment.isDefault);
  19213. },
  19214. enumerable: true,
  19215. configurable: true
  19216. });
  19217. Object.defineProperty(UIElement.prototype, "padding", {
  19218. get: function () {
  19219. var _this = this;
  19220. if (!this._padding) {
  19221. this._padding = new BABYLON.PrimitiveThickness(function () {
  19222. if (!_this.parent) {
  19223. return null;
  19224. }
  19225. return _this.parent.padding;
  19226. });
  19227. }
  19228. return this._padding;
  19229. },
  19230. set: function (value) {
  19231. this.padding.copyFrom(value);
  19232. },
  19233. enumerable: true,
  19234. configurable: true
  19235. });
  19236. Object.defineProperty(UIElement.prototype, "_hasPadding", {
  19237. get: function () {
  19238. return this._padding !== null && !this._padding.isDefault;
  19239. },
  19240. enumerable: true,
  19241. configurable: true
  19242. });
  19243. Object.defineProperty(UIElement.prototype, "marginAlignment", {
  19244. get: function () {
  19245. if (!this._marginAlignment) {
  19246. this._marginAlignment = new BABYLON.PrimitiveAlignment();
  19247. }
  19248. return this._marginAlignment;
  19249. },
  19250. set: function (value) {
  19251. this.marginAlignment.copyFrom(value);
  19252. },
  19253. enumerable: true,
  19254. configurable: true
  19255. });
  19256. Object.defineProperty(UIElement.prototype, "_hasMarginAlignment", {
  19257. /**
  19258. * Check if there a marginAlignment specified (non null and not default)
  19259. */
  19260. get: function () {
  19261. return (this._marginAlignment !== null && !this._marginAlignment.isDefault);
  19262. },
  19263. enumerable: true,
  19264. configurable: true
  19265. });
  19266. Object.defineProperty(UIElement.prototype, "paddingAlignment", {
  19267. get: function () {
  19268. if (!this._paddingAlignment) {
  19269. this._paddingAlignment = new BABYLON.PrimitiveAlignment();
  19270. }
  19271. return this._paddingAlignment;
  19272. },
  19273. set: function (value) {
  19274. this.paddingAlignment.copyFrom(value);
  19275. },
  19276. enumerable: true,
  19277. configurable: true
  19278. });
  19279. Object.defineProperty(UIElement.prototype, "_hasPaddingAlignment", {
  19280. /**
  19281. * Check if there a marginAlignment specified (non null and not default)
  19282. */
  19283. get: function () {
  19284. return (this._paddingAlignment !== null && !this._paddingAlignment.isDefault);
  19285. },
  19286. enumerable: true,
  19287. configurable: true
  19288. });
  19289. Object.defineProperty(UIElement.prototype, "isVisible", {
  19290. get: function () {
  19291. return this._isFlagSet(UIElement.flagIsVisible);
  19292. },
  19293. set: function (value) {
  19294. if (this.isVisible === value) {
  19295. return;
  19296. }
  19297. this._visualPlaceholder.levelVisible = value;
  19298. this._changeFlags(UIElement.flagIsVisible, value);
  19299. },
  19300. enumerable: true,
  19301. configurable: true
  19302. });
  19303. Object.defineProperty(UIElement.prototype, "isEnabled", {
  19304. get: function () {
  19305. return this._isFlagSet(UIElement.flagIsEnabled);
  19306. },
  19307. set: function (value) {
  19308. this._changeFlags(UIElement.flagIsEnabled, value);
  19309. },
  19310. enumerable: true,
  19311. configurable: true
  19312. });
  19313. Object.defineProperty(UIElement.prototype, "isFocused", {
  19314. get: function () {
  19315. return this._isFlagSet(UIElement.flagIsFocus);
  19316. },
  19317. set: function (value) {
  19318. // If the UIElement doesn't accept focus, set it on its parent
  19319. if (!this.isFocusable) {
  19320. var p = this.parent;
  19321. if (!p) {
  19322. return;
  19323. }
  19324. p.isFocused = value;
  19325. }
  19326. // If the focus is being set, notify the Focus Manager
  19327. if (value) {
  19328. this.ownerWindow.focusManager.setFocusOn(this, this.getFocusScope());
  19329. }
  19330. this._changeFlags(UIElement.flagIsFocus, value);
  19331. },
  19332. enumerable: true,
  19333. configurable: true
  19334. });
  19335. Object.defineProperty(UIElement.prototype, "isMouseOver", {
  19336. get: function () {
  19337. return this._isFlagSet(UIElement.flagIsMouseOver);
  19338. },
  19339. set: function (value) {
  19340. this._changeFlags(UIElement.flagIsMouseOver, value);
  19341. },
  19342. enumerable: true,
  19343. configurable: true
  19344. });
  19345. Object.defineProperty(UIElement.prototype, "isFocusScope", {
  19346. get: function () {
  19347. return this._isFlagSet(UIElement.flagIsFocusScope);
  19348. },
  19349. set: function (value) {
  19350. this._changeFlags(UIElement.flagIsFocusScope, value);
  19351. },
  19352. enumerable: true,
  19353. configurable: true
  19354. });
  19355. Object.defineProperty(UIElement.prototype, "isFocusable", {
  19356. get: function () {
  19357. return this._isFlagSet(UIElement.flagIsFocusable);
  19358. },
  19359. set: function (value) {
  19360. this._changeFlags(UIElement.flagIsFocusable, value);
  19361. },
  19362. enumerable: true,
  19363. configurable: true
  19364. });
  19365. // Look for the nearest parent which is the focus scope. Should always return something as the Window UIElement which is the root of all UI Tree is focus scope (unless the user disable it)
  19366. UIElement.prototype.getFocusScope = function () {
  19367. if (this.isFocusScope) {
  19368. return this;
  19369. }
  19370. var p = this.parent;
  19371. if (!p) {
  19372. return null;
  19373. }
  19374. return p.getFocusScope();
  19375. };
  19376. /**
  19377. * Check if a given flag is set
  19378. * @param flag the flag value
  19379. * @return true if set, false otherwise
  19380. */
  19381. UIElement.prototype._isFlagSet = function (flag) {
  19382. return (this._flags & flag) !== 0;
  19383. };
  19384. /**
  19385. * Check if all given flags are set
  19386. * @param flags the flags ORed
  19387. * @return true if all the flags are set, false otherwise
  19388. */
  19389. UIElement.prototype._areAllFlagsSet = function (flags) {
  19390. return (this._flags & flags) === flags;
  19391. };
  19392. /**
  19393. * Check if at least one flag of the given flags is set
  19394. * @param flags the flags ORed
  19395. * @return true if at least one flag is set, false otherwise
  19396. */
  19397. UIElement.prototype._areSomeFlagsSet = function (flags) {
  19398. return (this._flags & flags) !== 0;
  19399. };
  19400. /**
  19401. * Clear the given flags
  19402. * @param flags the flags to clear
  19403. */
  19404. UIElement.prototype._clearFlags = function (flags) {
  19405. this._flags &= ~flags;
  19406. };
  19407. /**
  19408. * Set the given flags to true state
  19409. * @param flags the flags ORed to set
  19410. * @return the flags state before this call
  19411. */
  19412. UIElement.prototype._setFlags = function (flags) {
  19413. var cur = this._flags;
  19414. this._flags |= flags;
  19415. return cur;
  19416. };
  19417. /**
  19418. * Change the state of the given flags
  19419. * @param flags the flags ORed to change
  19420. * @param state true to set them, false to clear them
  19421. */
  19422. UIElement.prototype._changeFlags = function (flags, state) {
  19423. if (state) {
  19424. this._flags |= flags;
  19425. }
  19426. else {
  19427. this._flags &= ~flags;
  19428. }
  19429. };
  19430. UIElement.prototype._assignTemplate = function (templateName) {
  19431. if (!templateName) {
  19432. templateName = GUIManager.DefaultTemplateName;
  19433. }
  19434. var className = BABYLON.Tools.getFullClassName(this);
  19435. if (!className) {
  19436. throw Error("Couldn't access class name of this UIElement, you have to decorate the type with the className decorator");
  19437. }
  19438. var factory = GUIManager.getRenderingTemplate(className, templateName);
  19439. if (!factory) {
  19440. throw Error("Couldn't get the renderingTemplate " + templateName + " of class " + className);
  19441. }
  19442. this._renderingTemplateName = templateName;
  19443. this._renderingTemplate = factory();
  19444. this._renderingTemplate.attach(this);
  19445. };
  19446. UIElement.prototype._createVisualTree = function () {
  19447. var parentPrim = this.ownerWindow.canvas;
  19448. if (this.parent) {
  19449. parentPrim = this.parent.visualChildrenPlaceholder;
  19450. }
  19451. if (!this._renderingTemplate) {
  19452. this._assignTemplate(this._renderingTemplateName);
  19453. }
  19454. this._visualPlaceholder = new BABYLON.Group2D({ parent: parentPrim, id: "GUI " + BABYLON.Tools.getClassName(this) + " RootGroup of " + this.id });
  19455. var p = this._visualPlaceholder;
  19456. p.addExternalData("_GUIOwnerElement_", this);
  19457. p.dataSource = this;
  19458. p.createSimpleDataBinding(BABYLON.Prim2DBase.widthProperty, "width", BABYLON.DataBinding.MODE_ONEWAY);
  19459. p.createSimpleDataBinding(BABYLON.Prim2DBase.heightProperty, "height", BABYLON.DataBinding.MODE_ONEWAY);
  19460. p.createSimpleDataBinding(BABYLON.Prim2DBase.actualWidthProperty, "actualWidth", BABYLON.DataBinding.MODE_ONEWAYTOSOURCE);
  19461. p.createSimpleDataBinding(BABYLON.Prim2DBase.actualHeightProperty, "actualHeight", BABYLON.DataBinding.MODE_ONEWAYTOSOURCE);
  19462. p.createSimpleDataBinding(BABYLON.Prim2DBase.marginProperty, "margin", BABYLON.DataBinding.MODE_ONEWAY);
  19463. p.createSimpleDataBinding(BABYLON.Prim2DBase.marginAlignmentProperty, "marginAlignment", BABYLON.DataBinding.MODE_ONEWAY);
  19464. this.createVisualTree();
  19465. };
  19466. UIElement.prototype._patchUIElement = function (ownerWindow, parent) {
  19467. if (ownerWindow) {
  19468. if (!this._ownerWindow) {
  19469. ownerWindow._registerVisualToBuild(this);
  19470. }
  19471. this._ownerWindow = ownerWindow;
  19472. }
  19473. this._parent = parent;
  19474. if (parent) {
  19475. this._hierarchyDepth = parent.hierarchyDepth + 1;
  19476. }
  19477. var children = this._getChildren();
  19478. if (children) {
  19479. for (var _i = 0, children_2 = children; _i < children_2.length; _i++) {
  19480. var curChild = children_2[_i];
  19481. curChild._patchUIElement(ownerWindow, this);
  19482. }
  19483. }
  19484. };
  19485. // Overload the SmartPropertyBase's method to provide the additional logic of returning the parent's dataSource if there's no dataSource specified at this level.
  19486. UIElement.prototype._getDataSource = function () {
  19487. var levelDS = _super.prototype._getDataSource.call(this);
  19488. if (levelDS != null) {
  19489. return levelDS;
  19490. }
  19491. var p = this.parent;
  19492. if (p != null) {
  19493. return p.dataSource;
  19494. }
  19495. return null;
  19496. };
  19497. UIElement.prototype.createVisualTree = function () {
  19498. var res = this._renderingTemplate.createVisualTree(this, this._visualPlaceholder);
  19499. this._visualTemplateRoot = res.root;
  19500. this._visualChildrenPlaceholder = res.contentPlaceholder;
  19501. };
  19502. Object.defineProperty(UIElement.prototype, "visualPlaceholder", {
  19503. get: function () {
  19504. return this._visualPlaceholder;
  19505. },
  19506. enumerable: true,
  19507. configurable: true
  19508. });
  19509. Object.defineProperty(UIElement.prototype, "visualTemplateRoot", {
  19510. get: function () {
  19511. return this._visualTemplateRoot;
  19512. },
  19513. enumerable: true,
  19514. configurable: true
  19515. });
  19516. Object.defineProperty(UIElement.prototype, "visualChildrenPlaceholder", {
  19517. get: function () {
  19518. return this._visualChildrenPlaceholder;
  19519. },
  19520. enumerable: true,
  19521. configurable: true
  19522. });
  19523. Object.defineProperty(UIElement.prototype, "_position", {
  19524. get: function () { return null; } // TODO use abstract keyword when TS 2.0 will be approved
  19525. ,
  19526. enumerable: true,
  19527. configurable: true
  19528. });
  19529. return UIElement;
  19530. }(BABYLON.SmartPropertyBase));
  19531. UIElement.UIELEMENT_PROPCOUNT = 16;
  19532. UIElement.flagVisualToBuild = 0x0000001;
  19533. UIElement.flagIsVisible = 0x0000002;
  19534. UIElement.flagIsFocus = 0x0000004;
  19535. UIElement.flagIsFocusScope = 0x0000008;
  19536. UIElement.flagIsFocusable = 0x0000010;
  19537. UIElement.flagIsEnabled = 0x0000020;
  19538. UIElement.flagIsMouseOver = 0x0000040;
  19539. UIElement._enableState = "Enabled";
  19540. UIElement._disabledState = "Disabled";
  19541. UIElement._mouseOverState = "MouseOver";
  19542. __decorate([
  19543. BABYLON.dependencyProperty(0, function (pi) { return UIElement.parentProperty = pi; })
  19544. ], UIElement.prototype, "parent", null);
  19545. __decorate([
  19546. BABYLON.dependencyProperty(1, function (pi) { return UIElement.widthProperty = pi; })
  19547. ], UIElement.prototype, "width", null);
  19548. __decorate([
  19549. BABYLON.dependencyProperty(2, function (pi) { return UIElement.heightProperty = pi; })
  19550. ], UIElement.prototype, "height", null);
  19551. __decorate([
  19552. BABYLON.dependencyProperty(3, function (pi) { return UIElement.minWidthProperty = pi; })
  19553. ], UIElement.prototype, "minWidth", null);
  19554. __decorate([
  19555. BABYLON.dependencyProperty(4, function (pi) { return UIElement.minHeightProperty = pi; })
  19556. ], UIElement.prototype, "minHheight", null);
  19557. __decorate([
  19558. BABYLON.dependencyProperty(5, function (pi) { return UIElement.maxWidthProperty = pi; })
  19559. ], UIElement.prototype, "maxWidth", null);
  19560. __decorate([
  19561. BABYLON.dependencyProperty(6, function (pi) { return UIElement.maxHeightProperty = pi; })
  19562. ], UIElement.prototype, "maxHeight", null);
  19563. __decorate([
  19564. BABYLON.dependencyProperty(7, function (pi) { return UIElement.actualWidthProperty = pi; })
  19565. ], UIElement.prototype, "actualWidth", null);
  19566. __decorate([
  19567. BABYLON.dependencyProperty(8, function (pi) { return UIElement.actualHeightProperty = pi; })
  19568. ], UIElement.prototype, "actualHeight", null);
  19569. __decorate([
  19570. BABYLON.dynamicLevelProperty(9, function (pi) { return UIElement.marginProperty = pi; })
  19571. /**
  19572. * You can get/set a margin on the primitive through this property
  19573. * @returns the margin object, if there was none, a default one is created and returned
  19574. */
  19575. ], UIElement.prototype, "margin", null);
  19576. __decorate([
  19577. BABYLON.dynamicLevelProperty(10, function (pi) { return UIElement.paddingProperty = pi; })
  19578. /**
  19579. * You can get/set a margin on the primitive through this property
  19580. * @returns the margin object, if there was none, a default one is created and returned
  19581. */
  19582. ], UIElement.prototype, "padding", null);
  19583. __decorate([
  19584. BABYLON.dynamicLevelProperty(11, function (pi) { return UIElement.marginAlignmentProperty = pi; })
  19585. /**
  19586. * You can get/set the margin alignment through this property
  19587. */
  19588. ], UIElement.prototype, "marginAlignment", null);
  19589. __decorate([
  19590. BABYLON.dynamicLevelProperty(12, function (pi) { return UIElement.paddingAlignmentProperty = pi; })
  19591. /**
  19592. * You can get/set the margin alignment through this property
  19593. */
  19594. ], UIElement.prototype, "paddingAlignment", null);
  19595. __decorate([
  19596. BABYLON.dynamicLevelProperty(13, function (pi) { return UIElement.isEnabledProperty = pi; })
  19597. /**
  19598. * True if the UIElement is enabled, false if it's disabled.
  19599. * User interaction is not possible if the UIElement is not enabled
  19600. */
  19601. ], UIElement.prototype, "isEnabled", null);
  19602. __decorate([
  19603. BABYLON.dynamicLevelProperty(14, function (pi) { return UIElement.isFocusedProperty = pi; })
  19604. /**
  19605. * True if the UIElement has the focus, false if it doesn't
  19606. */
  19607. ], UIElement.prototype, "isFocused", null);
  19608. __decorate([
  19609. BABYLON.dynamicLevelProperty(15, function (pi) { return UIElement.isMouseOverProperty = pi; })
  19610. /**
  19611. * True if the UIElement has the mouse over it
  19612. */
  19613. ], UIElement.prototype, "isMouseOver", null);
  19614. BABYLON.UIElement = UIElement;
  19615. var UIElementStyle = (function () {
  19616. function UIElementStyle() {
  19617. }
  19618. Object.defineProperty(UIElementStyle.prototype, "name", {
  19619. get: function () { return null; } // TODO use abstract keyword when TS 2.0 will be approved
  19620. ,
  19621. enumerable: true,
  19622. configurable: true
  19623. });
  19624. return UIElementStyle;
  19625. }());
  19626. BABYLON.UIElementStyle = UIElementStyle;
  19627. var GUIManager = (function () {
  19628. function GUIManager() {
  19629. }
  19630. /////////////////////////////////////////////////////////////////////////////////////////////////////
  19631. // DATA TEMPLATE MANAGER
  19632. GUIManager.registerDataTemplate = function (className, factory) {
  19633. };
  19634. // DATA TEMPLATE MANAGER
  19635. /////////////////////////////////////////////////////////////////////////////////////////////////////
  19636. /////////////////////////////////////////////////////////////////////////////////////////////////////
  19637. // STYLE MANAGER
  19638. GUIManager.getStyle = function (uiElType, styleName) {
  19639. var styles = GUIManager.stylesByUIElement.get(uiElType);
  19640. if (!styles) {
  19641. throw Error("The type " + uiElType + " is unknown, no style were registered for it.");
  19642. }
  19643. var style = styles.get(styleName);
  19644. if (!style) {
  19645. throw Error("Couldn't find Template " + styleName + " of UIElement type " + uiElType);
  19646. }
  19647. return style;
  19648. };
  19649. GUIManager.registerStyle = function (uiElType, templateName, style) {
  19650. var templates = GUIManager.stylesByUIElement.getOrAddWithFactory(uiElType, function () { return new BABYLON.StringDictionary(); });
  19651. if (templates.contains(templateName)) {
  19652. templates[templateName] = style;
  19653. }
  19654. else {
  19655. templates.add(templateName, style);
  19656. }
  19657. };
  19658. Object.defineProperty(GUIManager, "DefaultStyleName", {
  19659. get: function () {
  19660. return GUIManager._defaultStyleName;
  19661. },
  19662. set: function (value) {
  19663. GUIManager._defaultStyleName = value;
  19664. },
  19665. enumerable: true,
  19666. configurable: true
  19667. });
  19668. // STYLE MANAGER
  19669. /////////////////////////////////////////////////////////////////////////////////////////////////////
  19670. /////////////////////////////////////////////////////////////////////////////////////////////////////
  19671. // RENDERING TEMPLATE MANAGER
  19672. GUIManager.getRenderingTemplate = function (uiElType, templateName) {
  19673. var templates = GUIManager.renderingTemplatesByUIElement.get(uiElType);
  19674. if (!templates) {
  19675. throw Error("The type " + uiElType + " is unknown, no Rendering Template were registered for it.");
  19676. }
  19677. var templateFactory = templates.get(templateName);
  19678. if (!templateFactory) {
  19679. throw Error("Couldn't find Template " + templateName + " of UI Element type " + uiElType);
  19680. }
  19681. return templateFactory;
  19682. };
  19683. GUIManager.registerRenderingTemplate = function (uiElType, templateName, factory) {
  19684. var templates = GUIManager.renderingTemplatesByUIElement.getOrAddWithFactory(uiElType, function () { return new BABYLON.StringDictionary(); });
  19685. if (templates.contains(templateName)) {
  19686. templates[templateName] = factory;
  19687. }
  19688. else {
  19689. templates.add(templateName, factory);
  19690. }
  19691. };
  19692. Object.defineProperty(GUIManager, "DefaultTemplateName", {
  19693. get: function () {
  19694. return GUIManager._defaultTemplateName;
  19695. },
  19696. set: function (value) {
  19697. GUIManager._defaultTemplateName = value;
  19698. },
  19699. enumerable: true,
  19700. configurable: true
  19701. });
  19702. return GUIManager;
  19703. }());
  19704. GUIManager.stylesByUIElement = new BABYLON.StringDictionary();
  19705. GUIManager.renderingTemplatesByUIElement = new BABYLON.StringDictionary();
  19706. // RENDERING TEMPLATE MANAGER
  19707. /////////////////////////////////////////////////////////////////////////////////////////////////////
  19708. GUIManager._defaultTemplateName = "Default";
  19709. GUIManager._defaultStyleName = "Default";
  19710. BABYLON.GUIManager = GUIManager;
  19711. var UIElementRenderingTemplateBase = (function () {
  19712. function UIElementRenderingTemplateBase() {
  19713. }
  19714. UIElementRenderingTemplateBase.prototype.attach = function (owner) {
  19715. this._owner = owner;
  19716. };
  19717. UIElementRenderingTemplateBase.prototype.detach = function () {
  19718. };
  19719. Object.defineProperty(UIElementRenderingTemplateBase.prototype, "owner", {
  19720. get: function () {
  19721. return this._owner;
  19722. },
  19723. enumerable: true,
  19724. configurable: true
  19725. });
  19726. return UIElementRenderingTemplateBase;
  19727. }());
  19728. BABYLON.UIElementRenderingTemplateBase = UIElementRenderingTemplateBase;
  19729. function registerWindowRenderingTemplate(uiElType, templateName, factory) {
  19730. return function () {
  19731. GUIManager.registerRenderingTemplate(uiElType, templateName, factory);
  19732. };
  19733. }
  19734. BABYLON.registerWindowRenderingTemplate = registerWindowRenderingTemplate;
  19735. })(BABYLON || (BABYLON = {}));
  19736. var __extends = (this && this.__extends) || (function () {
  19737. var extendStatics = Object.setPrototypeOf ||
  19738. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  19739. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  19740. return function (d, b) {
  19741. extendStatics(d, b);
  19742. function __() { this.constructor = d; }
  19743. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  19744. };
  19745. })();
  19746. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  19747. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  19748. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  19749. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  19750. return c > 3 && r && Object.defineProperty(target, key, r), r;
  19751. };
  19752. var BABYLON;
  19753. (function (BABYLON) {
  19754. var StackPanel = StackPanel_1 = (function (_super) {
  19755. __extends(StackPanel, _super);
  19756. function StackPanel(settings) {
  19757. var _this = this;
  19758. if (!settings) {
  19759. settings = {};
  19760. }
  19761. _this = _super.call(this, settings) || this;
  19762. _this.isOrientationHorizontal = (settings.isOrientationHorizontal == null) ? true : settings.isOrientationHorizontal;
  19763. _this._children = new Array();
  19764. if (settings.children != null) {
  19765. for (var _i = 0, _a = settings.children; _i < _a.length; _i++) {
  19766. var child = _a[_i];
  19767. _this._children.push(child);
  19768. }
  19769. }
  19770. return _this;
  19771. }
  19772. Object.defineProperty(StackPanel.prototype, "isOrientationHorizontal", {
  19773. get: function () {
  19774. return this._isOrientationHorizontal;
  19775. },
  19776. set: function (value) {
  19777. this._isOrientationHorizontal = value;
  19778. },
  19779. enumerable: true,
  19780. configurable: true
  19781. });
  19782. StackPanel.prototype.createVisualTree = function () {
  19783. _super.prototype.createVisualTree.call(this);
  19784. // A StackPanel Control has a Group2D, child of the visualPlaceHolder, which is the Children placeholder.
  19785. // The Children UIElement Tree will be create inside this placeholder.
  19786. this._childrenPlaceholder = new BABYLON.Group2D({ parent: this._visualPlaceholder, id: "StackPanel Children Placeholder of " + this.id });
  19787. var p = this._childrenPlaceholder;
  19788. p.layoutEngine = this.isOrientationHorizontal ? BABYLON.StackPanelLayoutEngine.Horizontal : BABYLON.StackPanelLayoutEngine.Vertical;
  19789. // The UIElement padding properties (padding and paddingAlignment) are bound to the Group2D Children placeholder, we bound to the Margin properties as the Group2D acts as an inner element already, so margin of inner is padding.
  19790. p.dataSource = this;
  19791. p.createSimpleDataBinding(BABYLON.Prim2DBase.marginProperty, "padding", BABYLON.DataBinding.MODE_ONEWAY);
  19792. p.createSimpleDataBinding(BABYLON.Prim2DBase.marginAlignmentProperty, "paddingAlignment", BABYLON.DataBinding.MODE_ONEWAY);
  19793. // The UIElement set the childrenPlaceholder with the visual returned by the renderingTemplate.
  19794. // But it's not the case for a StackPanel, the placeholder of UIElement Children (the content)
  19795. this._visualChildrenPlaceholder = this._childrenPlaceholder;
  19796. };
  19797. Object.defineProperty(StackPanel.prototype, "children", {
  19798. get: function () {
  19799. return this._children;
  19800. },
  19801. enumerable: true,
  19802. configurable: true
  19803. });
  19804. StackPanel.prototype._getChildren = function () {
  19805. return this.children;
  19806. };
  19807. return StackPanel;
  19808. }(BABYLON.UIElement));
  19809. StackPanel.STACKPANEL_PROPCOUNT = BABYLON.UIElement.UIELEMENT_PROPCOUNT + 3;
  19810. __decorate([
  19811. BABYLON.dependencyProperty(StackPanel_1.STACKPANEL_PROPCOUNT + 0, function (pi) { return StackPanel_1.orientationHorizontalProperty = pi; })
  19812. ], StackPanel.prototype, "isOrientationHorizontal", null);
  19813. StackPanel = StackPanel_1 = __decorate([
  19814. BABYLON.className("StackPanel", "BABYLON")
  19815. ], StackPanel);
  19816. BABYLON.StackPanel = StackPanel;
  19817. var DefaultStackPanelRenderingTemplate = DefaultStackPanelRenderingTemplate_1 = (function (_super) {
  19818. __extends(DefaultStackPanelRenderingTemplate, _super);
  19819. function DefaultStackPanelRenderingTemplate() {
  19820. return _super !== null && _super.apply(this, arguments) || this;
  19821. }
  19822. DefaultStackPanelRenderingTemplate.prototype.createVisualTree = function (owner, visualPlaceholder) {
  19823. return { root: visualPlaceholder, contentPlaceholder: visualPlaceholder };
  19824. };
  19825. DefaultStackPanelRenderingTemplate.prototype.attach = function (owner) {
  19826. _super.prototype.attach.call(this, owner);
  19827. };
  19828. return DefaultStackPanelRenderingTemplate;
  19829. }(BABYLON.UIElementRenderingTemplateBase));
  19830. DefaultStackPanelRenderingTemplate = DefaultStackPanelRenderingTemplate_1 = __decorate([
  19831. BABYLON.registerWindowRenderingTemplate("BABYLON.StackPanel", "Default", function () { return new DefaultStackPanelRenderingTemplate_1(); })
  19832. ], DefaultStackPanelRenderingTemplate);
  19833. BABYLON.DefaultStackPanelRenderingTemplate = DefaultStackPanelRenderingTemplate;
  19834. var StackPanel_1, DefaultStackPanelRenderingTemplate_1;
  19835. })(BABYLON || (BABYLON = {}));
  19836. var __extends = (this && this.__extends) || (function () {
  19837. var extendStatics = Object.setPrototypeOf ||
  19838. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  19839. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  19840. return function (d, b) {
  19841. extendStatics(d, b);
  19842. function __() { this.constructor = d; }
  19843. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  19844. };
  19845. })();
  19846. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  19847. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  19848. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  19849. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  19850. return c > 3 && r && Object.defineProperty(target, key, r), r;
  19851. };
  19852. var BABYLON;
  19853. (function (BABYLON) {
  19854. var Control = Control_1 = (function (_super) {
  19855. __extends(Control, _super);
  19856. function Control(settings) {
  19857. return _super.call(this, settings) || this;
  19858. }
  19859. Object.defineProperty(Control.prototype, "background", {
  19860. get: function () {
  19861. if (!this._background) {
  19862. this._background = new BABYLON.ObservableStringDictionary(false);
  19863. }
  19864. return this._background;
  19865. },
  19866. set: function (value) {
  19867. this.background.copyFrom(value);
  19868. },
  19869. enumerable: true,
  19870. configurable: true
  19871. });
  19872. Object.defineProperty(Control.prototype, "border", {
  19873. get: function () {
  19874. return this._border;
  19875. },
  19876. set: function (value) {
  19877. this._border = value;
  19878. },
  19879. enumerable: true,
  19880. configurable: true
  19881. });
  19882. Object.defineProperty(Control.prototype, "borderThickness", {
  19883. get: function () {
  19884. return this._borderThickness;
  19885. },
  19886. set: function (value) {
  19887. this._borderThickness = value;
  19888. },
  19889. enumerable: true,
  19890. configurable: true
  19891. });
  19892. Object.defineProperty(Control.prototype, "fontName", {
  19893. get: function () {
  19894. return this._fontName;
  19895. },
  19896. set: function (value) {
  19897. this._fontName = value;
  19898. },
  19899. enumerable: true,
  19900. configurable: true
  19901. });
  19902. Object.defineProperty(Control.prototype, "foreground", {
  19903. get: function () {
  19904. return this._foreground;
  19905. },
  19906. set: function (value) {
  19907. this._foreground = value;
  19908. },
  19909. enumerable: true,
  19910. configurable: true
  19911. });
  19912. return Control;
  19913. }(BABYLON.UIElement));
  19914. Control.CONTROL_PROPCOUNT = BABYLON.UIElement.UIELEMENT_PROPCOUNT + 5;
  19915. __decorate([
  19916. BABYLON.dependencyProperty(BABYLON.UIElement.UIELEMENT_PROPCOUNT + 0, function (pi) { return Control_1.backgroundProperty = pi; })
  19917. ], Control.prototype, "background", null);
  19918. __decorate([
  19919. BABYLON.dependencyProperty(BABYLON.UIElement.UIELEMENT_PROPCOUNT + 1, function (pi) { return Control_1.borderProperty = pi; })
  19920. ], Control.prototype, "border", null);
  19921. __decorate([
  19922. BABYLON.dependencyProperty(BABYLON.UIElement.UIELEMENT_PROPCOUNT + 2, function (pi) { return Control_1.borderThicknessProperty = pi; })
  19923. ], Control.prototype, "borderThickness", null);
  19924. __decorate([
  19925. BABYLON.dependencyProperty(BABYLON.UIElement.UIELEMENT_PROPCOUNT + 3, function (pi) { return Control_1.fontNameProperty = pi; })
  19926. ], Control.prototype, "fontName", null);
  19927. __decorate([
  19928. BABYLON.dependencyProperty(BABYLON.UIElement.UIELEMENT_PROPCOUNT + 4, function (pi) { return Control_1.foregroundProperty = pi; })
  19929. ], Control.prototype, "foreground", null);
  19930. Control = Control_1 = __decorate([
  19931. BABYLON.className("Control", "BABYLON")
  19932. ], Control);
  19933. BABYLON.Control = Control;
  19934. var Control_1;
  19935. })(BABYLON || (BABYLON = {}));
  19936. var __extends = (this && this.__extends) || (function () {
  19937. var extendStatics = Object.setPrototypeOf ||
  19938. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  19939. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  19940. return function (d, b) {
  19941. extendStatics(d, b);
  19942. function __() { this.constructor = d; }
  19943. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  19944. };
  19945. })();
  19946. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  19947. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  19948. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  19949. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  19950. return c > 3 && r && Object.defineProperty(target, key, r), r;
  19951. };
  19952. var BABYLON;
  19953. (function (BABYLON) {
  19954. var ContentControl = ContentControl_1 = (function (_super) {
  19955. __extends(ContentControl, _super);
  19956. function ContentControl(settings) {
  19957. var _this = this;
  19958. if (!settings) {
  19959. settings = {};
  19960. }
  19961. _this = _super.call(this, settings) || this;
  19962. if (settings.content != null) {
  19963. _this._content = settings.content;
  19964. }
  19965. return _this;
  19966. }
  19967. ContentControl.prototype.dispose = function () {
  19968. if (this.isDisposed) {
  19969. return false;
  19970. }
  19971. if (this.content && this.content.dispose) {
  19972. this.content.dispose();
  19973. this.content = null;
  19974. }
  19975. if (this.__contentUIElement) {
  19976. this.__contentUIElement.dispose();
  19977. this.__contentUIElement = null;
  19978. }
  19979. _super.prototype.dispose.call(this);
  19980. return true;
  19981. };
  19982. Object.defineProperty(ContentControl.prototype, "content", {
  19983. get: function () {
  19984. return this._content;
  19985. },
  19986. set: function (value) {
  19987. this._content = value;
  19988. },
  19989. enumerable: true,
  19990. configurable: true
  19991. });
  19992. Object.defineProperty(ContentControl.prototype, "_contentUIElement", {
  19993. get: function () {
  19994. if (!this.__contentUIElement) {
  19995. this._buildContentUIElement();
  19996. }
  19997. return this.__contentUIElement;
  19998. },
  19999. enumerable: true,
  20000. configurable: true
  20001. });
  20002. ContentControl.prototype._createVisualTree = function () {
  20003. // Base implementation will create the Group2D for the Visual Placeholder and its Visual Tree
  20004. _super.prototype._createVisualTree.call(this);
  20005. // A Content Control has a Group2D, child of the visualPlaceHolder, which is the Content placeholder.
  20006. // The Content UIElement Tree will be create inside this placeholder.
  20007. this._contentPlaceholder = new BABYLON.Group2D({ parent: this._visualPlaceholder, id: "ContentControl Content Placeholder of " + this.id });
  20008. var p = this._contentPlaceholder;
  20009. // The UIElement padding properties (padding and paddingAlignment) are bound to the Group2D Content placeholder, we bound to the Margin properties as the Group2D acts as an inner element already, so margin of inner is padding.
  20010. p.dataSource = this;
  20011. p.createSimpleDataBinding(BABYLON.Prim2DBase.marginProperty, "padding", BABYLON.DataBinding.MODE_ONEWAY);
  20012. p.createSimpleDataBinding(BABYLON.Prim2DBase.marginAlignmentProperty, "paddingAlignment", BABYLON.DataBinding.MODE_ONEWAY);
  20013. // The UIElement set the childrenPlaceholder with the visual returned by the renderingTemplate.
  20014. // But it's not the case for a ContentControl, the placeholder of UIElement Children (the content)
  20015. this._visualChildrenPlaceholder = this._contentPlaceholder;
  20016. };
  20017. ContentControl.prototype._buildContentUIElement = function () {
  20018. var c = this._content;
  20019. this.__contentUIElement = null;
  20020. // Already a UIElement
  20021. if (c instanceof BABYLON.UIElement) {
  20022. this.__contentUIElement = c;
  20023. }
  20024. else if ((typeof c === "string") || (typeof c === "boolean") || (typeof c === "number")) {
  20025. var l = new BABYLON.Label({ parent: this, id: "Content of " + this.id });
  20026. var binding = new BABYLON.DataBinding();
  20027. binding.propertyPathName = "content";
  20028. binding.stringFormat = function (v) { return "" + v; };
  20029. binding.dataSource = this;
  20030. l.createDataBinding(BABYLON.Label.textProperty, binding);
  20031. this.__contentUIElement = l;
  20032. }
  20033. else {
  20034. // TODO: DataTemplate lookup and create instance
  20035. }
  20036. if (this.__contentUIElement) {
  20037. this.__contentUIElement._patchUIElement(this.ownerWindow, this);
  20038. }
  20039. };
  20040. ContentControl.prototype._getChildren = function () {
  20041. var children = new Array();
  20042. if (this.content) {
  20043. children.push(this._contentUIElement);
  20044. }
  20045. return children;
  20046. };
  20047. return ContentControl;
  20048. }(BABYLON.Control));
  20049. ContentControl.CONTENTCONTROL_PROPCOUNT = BABYLON.Control.CONTROL_PROPCOUNT + 2;
  20050. __decorate([
  20051. BABYLON.dependencyProperty(BABYLON.Control.CONTROL_PROPCOUNT + 0, function (pi) { return ContentControl_1.contentProperty = pi; })
  20052. ], ContentControl.prototype, "content", null);
  20053. ContentControl = ContentControl_1 = __decorate([
  20054. BABYLON.className("ContentControl", "BABYLON")
  20055. ], ContentControl);
  20056. BABYLON.ContentControl = ContentControl;
  20057. var ContentControl_1;
  20058. })(BABYLON || (BABYLON = {}));
  20059. var __extends = (this && this.__extends) || (function () {
  20060. var extendStatics = Object.setPrototypeOf ||
  20061. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  20062. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  20063. return function (d, b) {
  20064. extendStatics(d, b);
  20065. function __() { this.constructor = d; }
  20066. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  20067. };
  20068. })();
  20069. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  20070. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  20071. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  20072. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  20073. return c > 3 && r && Object.defineProperty(target, key, r), r;
  20074. };
  20075. var BABYLON;
  20076. (function (BABYLON) {
  20077. var FocusScopeData = (function () {
  20078. function FocusScopeData(focusScope) {
  20079. this.focusScope = focusScope;
  20080. this.focusedElement = null;
  20081. }
  20082. return FocusScopeData;
  20083. }());
  20084. var FocusManager = (function () {
  20085. function FocusManager() {
  20086. this._focusScopes = new BABYLON.StringDictionary();
  20087. this._rootScope = new FocusScopeData(null);
  20088. this._activeScope = null;
  20089. }
  20090. FocusManager.prototype.setFocusOn = function (el, focusScope) {
  20091. var fsd = (focusScope != null) ? this._focusScopes.getOrAddWithFactory(focusScope.uid, function (k) { return new FocusScopeData(focusScope); }) : this._rootScope;
  20092. if (fsd.focusedElement !== el) {
  20093. // Remove focus from current
  20094. if (fsd.focusedElement) {
  20095. fsd.focusedElement.isFocused = false;
  20096. }
  20097. fsd.focusedElement = el;
  20098. }
  20099. if (this._activeScope !== fsd) {
  20100. this._activeScope = fsd;
  20101. }
  20102. };
  20103. return FocusManager;
  20104. }());
  20105. BABYLON.FocusManager = FocusManager;
  20106. var GUISceneData = (function () {
  20107. function GUISceneData(scene) {
  20108. this.scene = scene;
  20109. this.screenSpaceCanvas = new BABYLON.ScreenSpaceCanvas2D(scene, { id: "GUI Canvas", cachingStrategy: BABYLON.Canvas2D.CACHESTRATEGY_DONTCACHE });
  20110. this.focusManager = new FocusManager();
  20111. }
  20112. return GUISceneData;
  20113. }());
  20114. var Window = Window_1 = (function (_super) {
  20115. __extends(Window, _super);
  20116. function Window(scene, settings) {
  20117. var _this = this;
  20118. if (!settings) {
  20119. settings = {};
  20120. }
  20121. _this = _super.call(this, settings) || this;
  20122. // Per default a Window is focus scope
  20123. _this.isFocusScope = true;
  20124. _this.isActive = false;
  20125. if (!_this._UIElementVisualToBuildList) {
  20126. _this._UIElementVisualToBuildList = new Array();
  20127. }
  20128. // Patch the owner and also the parent property through the whole tree
  20129. _this._patchUIElement(_this, null);
  20130. // Screen Space UI
  20131. if (!settings.worldPosition && !settings.worldRotation) {
  20132. _this._sceneData = Window_1.getSceneData(scene);
  20133. _this._canvas = _this._sceneData.screenSpaceCanvas;
  20134. _this._isWorldSpaceCanvas = false;
  20135. _this._left = (settings.left != null) ? settings.left : 0;
  20136. _this._bottom = (settings.bottom != null) ? settings.bottom : 0;
  20137. }
  20138. else {
  20139. var w = (settings.width == null) ? 100 : settings.width;
  20140. var h = (settings.height == null) ? 100 : settings.height;
  20141. var wpos = (settings.worldPosition == null) ? BABYLON.Vector3.Zero() : settings.worldPosition;
  20142. var wrot = (settings.worldRotation == null) ? BABYLON.Quaternion.Identity() : settings.worldRotation;
  20143. _this._canvas = new BABYLON.WorldSpaceCanvas2D(scene, new BABYLON.Size(w, h), { id: "GUI Canvas", cachingStrategy: BABYLON.Canvas2D.CACHESTRATEGY_DONTCACHE, worldPosition: wpos, worldRotation: wrot });
  20144. _this._isWorldSpaceCanvas = true;
  20145. }
  20146. _this._renderObserver = _this._canvas.renderObservable.add(function (e, s) { return _this._canvasPreRender(); }, BABYLON.Canvas2D.RENDEROBSERVABLE_PRE);
  20147. _this._disposeObserver = _this._canvas.disposeObservable.add(function (e, s) { return _this._canvasDisposed(); });
  20148. _this._canvas.propertyChanged.add(function (e, s) {
  20149. if (e.propertyName === "overPrim") {
  20150. _this._overPrimChanged(e.oldValue, e.newValue);
  20151. }
  20152. });
  20153. _this._mouseOverUIElement = null;
  20154. return _this;
  20155. }
  20156. Object.defineProperty(Window.prototype, "canvas", {
  20157. get: function () {
  20158. return this._canvas;
  20159. },
  20160. enumerable: true,
  20161. configurable: true
  20162. });
  20163. Object.defineProperty(Window.prototype, "left", {
  20164. get: function () {
  20165. return this._left;
  20166. },
  20167. set: function (value) {
  20168. var old = new BABYLON.Vector2(this._left, this._bottom);
  20169. this._left = value;
  20170. this.onPropertyChanged("_position", old, this._position);
  20171. },
  20172. enumerable: true,
  20173. configurable: true
  20174. });
  20175. Object.defineProperty(Window.prototype, "bottom", {
  20176. get: function () {
  20177. return this._bottom;
  20178. },
  20179. set: function (value) {
  20180. var old = new BABYLON.Vector2(this._left, this._bottom);
  20181. this._bottom = value;
  20182. this.onPropertyChanged("_position", old, this._position);
  20183. },
  20184. enumerable: true,
  20185. configurable: true
  20186. });
  20187. Object.defineProperty(Window.prototype, "position", {
  20188. get: function () {
  20189. return this._position;
  20190. },
  20191. set: function (value) {
  20192. this._left = value.x;
  20193. this._bottom = value.y;
  20194. },
  20195. enumerable: true,
  20196. configurable: true
  20197. });
  20198. Object.defineProperty(Window.prototype, "isActive", {
  20199. get: function () {
  20200. return this._isActive;
  20201. },
  20202. set: function (value) {
  20203. this._isActive = value;
  20204. },
  20205. enumerable: true,
  20206. configurable: true
  20207. });
  20208. Object.defineProperty(Window.prototype, "focusManager", {
  20209. get: function () {
  20210. return this._sceneData.focusManager;
  20211. },
  20212. enumerable: true,
  20213. configurable: true
  20214. });
  20215. Object.defineProperty(Window.prototype, "_position", {
  20216. get: function () {
  20217. return new BABYLON.Vector2(this.left, this.bottom);
  20218. },
  20219. enumerable: true,
  20220. configurable: true
  20221. });
  20222. Window.prototype.createVisualTree = function () {
  20223. _super.prototype.createVisualTree.call(this);
  20224. var p = this._visualPlaceholder;
  20225. p.createSimpleDataBinding(BABYLON.Group2D.positionProperty, "position");
  20226. };
  20227. Window.prototype._registerVisualToBuild = function (uiel) {
  20228. if (uiel._isFlagSet(BABYLON.UIElement.flagVisualToBuild)) {
  20229. return;
  20230. }
  20231. if (!this._UIElementVisualToBuildList) {
  20232. this._UIElementVisualToBuildList = new Array();
  20233. }
  20234. this._UIElementVisualToBuildList.push(uiel);
  20235. uiel._setFlags(BABYLON.UIElement.flagVisualToBuild);
  20236. };
  20237. Window.prototype._overPrimChanged = function (oldPrim, newPrim) {
  20238. var curOverEl = this._mouseOverUIElement;
  20239. var newOverEl = null;
  20240. var curGroup = newPrim ? newPrim.traverseUp(function (p) { return p instanceof BABYLON.Group2D; }) : null;
  20241. while (curGroup) {
  20242. var uiel = curGroup.getExternalData("_GUIOwnerElement_");
  20243. if (uiel) {
  20244. newOverEl = uiel;
  20245. break;
  20246. }
  20247. curGroup = curGroup.parent ? curGroup.parent.traverseUp(function (p) { return p instanceof BABYLON.Group2D; }) : null;
  20248. }
  20249. if (curOverEl === newOverEl) {
  20250. return;
  20251. }
  20252. if (curOverEl) {
  20253. curOverEl.isMouseOver = false;
  20254. }
  20255. if (newOverEl) {
  20256. newOverEl.isMouseOver = true;
  20257. }
  20258. this._mouseOverUIElement = newOverEl;
  20259. };
  20260. Window.prototype._canvasPreRender = function () {
  20261. // Check if we have visual to create
  20262. if (this._UIElementVisualToBuildList.length > 0) {
  20263. // Sort the UI Element to get the highest (so lowest hierarchy depth) in the hierarchy tree first
  20264. var sortedElementList = this._UIElementVisualToBuildList.sort(function (a, b) { return a.hierarchyDepth - b.hierarchyDepth; });
  20265. for (var _i = 0, sortedElementList_1 = sortedElementList; _i < sortedElementList_1.length; _i++) {
  20266. var el = sortedElementList_1[_i];
  20267. el._createVisualTree();
  20268. }
  20269. this._UIElementVisualToBuildList.splice(0);
  20270. }
  20271. };
  20272. Window.prototype._canvasDisposed = function () {
  20273. this._canvas.disposeObservable.remove(this._disposeObserver);
  20274. this._canvas.renderObservable.remove(this._renderObserver);
  20275. };
  20276. Window.getSceneData = function (scene) {
  20277. return Window_1._sceneData.getOrAddWithFactory(scene.uid, function (k) { return new GUISceneData(scene); });
  20278. };
  20279. return Window;
  20280. }(BABYLON.ContentControl));
  20281. Window.WINDOW_PROPCOUNT = BABYLON.ContentControl.CONTENTCONTROL_PROPCOUNT + 4;
  20282. Window._sceneData = new BABYLON.StringDictionary();
  20283. __decorate([
  20284. BABYLON.dependencyProperty(BABYLON.ContentControl.CONTENTCONTROL_PROPCOUNT + 0, function (pi) { return Window_1.leftProperty = pi; })
  20285. ], Window.prototype, "left", null);
  20286. __decorate([
  20287. BABYLON.dependencyProperty(BABYLON.ContentControl.CONTENTCONTROL_PROPCOUNT + 1, function (pi) { return Window_1.bottomProperty = pi; })
  20288. ], Window.prototype, "bottom", null);
  20289. __decorate([
  20290. BABYLON.dependencyProperty(BABYLON.ContentControl.CONTENTCONTROL_PROPCOUNT + 2, function (pi) { return Window_1.positionProperty = pi; })
  20291. ], Window.prototype, "position", null);
  20292. __decorate([
  20293. BABYLON.dependencyProperty(BABYLON.ContentControl.CONTENTCONTROL_PROPCOUNT + 3, function (pi) { return Window_1.isActiveProperty = pi; })
  20294. ], Window.prototype, "isActive", null);
  20295. Window = Window_1 = __decorate([
  20296. BABYLON.className("Window", "BABYLON")
  20297. ], Window);
  20298. BABYLON.Window = Window;
  20299. var DefaultWindowRenderingTemplate = DefaultWindowRenderingTemplate_1 = (function (_super) {
  20300. __extends(DefaultWindowRenderingTemplate, _super);
  20301. function DefaultWindowRenderingTemplate() {
  20302. return _super !== null && _super.apply(this, arguments) || this;
  20303. }
  20304. DefaultWindowRenderingTemplate.prototype.createVisualTree = function (owner, visualPlaceholder) {
  20305. var r = new BABYLON.Rectangle2D({ parent: visualPlaceholder, fill: "#808080FF" });
  20306. return { root: r, contentPlaceholder: r };
  20307. };
  20308. return DefaultWindowRenderingTemplate;
  20309. }(BABYLON.UIElementRenderingTemplateBase));
  20310. DefaultWindowRenderingTemplate = DefaultWindowRenderingTemplate_1 = __decorate([
  20311. BABYLON.registerWindowRenderingTemplate("BABYLON.Window", "Default", function () { return new DefaultWindowRenderingTemplate_1(); })
  20312. ], DefaultWindowRenderingTemplate);
  20313. BABYLON.DefaultWindowRenderingTemplate = DefaultWindowRenderingTemplate;
  20314. var Window_1, DefaultWindowRenderingTemplate_1;
  20315. })(BABYLON || (BABYLON = {}));
  20316. var __extends = (this && this.__extends) || (function () {
  20317. var extendStatics = Object.setPrototypeOf ||
  20318. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  20319. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  20320. return function (d, b) {
  20321. extendStatics(d, b);
  20322. function __() { this.constructor = d; }
  20323. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  20324. };
  20325. })();
  20326. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  20327. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  20328. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  20329. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  20330. return c > 3 && r && Object.defineProperty(target, key, r), r;
  20331. };
  20332. var BABYLON;
  20333. (function (BABYLON) {
  20334. var Label = Label_1 = (function (_super) {
  20335. __extends(Label, _super);
  20336. function Label(settings) {
  20337. var _this = this;
  20338. if (!settings) {
  20339. settings = {};
  20340. }
  20341. _this = _super.call(this, settings) || this;
  20342. if (settings.text != null) {
  20343. _this.text = settings.text;
  20344. }
  20345. return _this;
  20346. }
  20347. Object.defineProperty(Label.prototype, "_position", {
  20348. get: function () {
  20349. return BABYLON.Vector2.Zero();
  20350. },
  20351. enumerable: true,
  20352. configurable: true
  20353. });
  20354. Label.prototype._getChildren = function () {
  20355. return Label_1._emptyArray;
  20356. };
  20357. Label.prototype.createVisualTree = function () {
  20358. _super.prototype.createVisualTree.call(this);
  20359. var p = this._visualChildrenPlaceholder;
  20360. };
  20361. Object.defineProperty(Label.prototype, "text", {
  20362. get: function () {
  20363. return this._text;
  20364. },
  20365. set: function (value) {
  20366. this._text = value;
  20367. },
  20368. enumerable: true,
  20369. configurable: true
  20370. });
  20371. return Label;
  20372. }(BABYLON.Control));
  20373. Label._emptyArray = new Array();
  20374. __decorate([
  20375. BABYLON.dependencyProperty(BABYLON.Control.CONTROL_PROPCOUNT + 0, function (pi) { return Label_1.textProperty = pi; })
  20376. ], Label.prototype, "text", null);
  20377. Label = Label_1 = __decorate([
  20378. BABYLON.className("Label", "BABYLON")
  20379. ], Label);
  20380. BABYLON.Label = Label;
  20381. var DefaultLabelRenderingTemplate = DefaultLabelRenderingTemplate_1 = (function (_super) {
  20382. __extends(DefaultLabelRenderingTemplate, _super);
  20383. function DefaultLabelRenderingTemplate() {
  20384. return _super !== null && _super.apply(this, arguments) || this;
  20385. }
  20386. DefaultLabelRenderingTemplate.prototype.createVisualTree = function (owner, visualPlaceholder) {
  20387. var r = new BABYLON.Text2D("", { parent: visualPlaceholder });
  20388. r.createSimpleDataBinding(BABYLON.Text2D.textProperty, "text");
  20389. r.dataSource = owner;
  20390. return { root: r, contentPlaceholder: r };
  20391. };
  20392. return DefaultLabelRenderingTemplate;
  20393. }(BABYLON.UIElementRenderingTemplateBase));
  20394. DefaultLabelRenderingTemplate = DefaultLabelRenderingTemplate_1 = __decorate([
  20395. BABYLON.registerWindowRenderingTemplate("BABYLON.Label", "Default", function () { return new DefaultLabelRenderingTemplate_1(); })
  20396. ], DefaultLabelRenderingTemplate);
  20397. BABYLON.DefaultLabelRenderingTemplate = DefaultLabelRenderingTemplate;
  20398. var Label_1, DefaultLabelRenderingTemplate_1;
  20399. })(BABYLON || (BABYLON = {}));
  20400. var __extends = (this && this.__extends) || (function () {
  20401. var extendStatics = Object.setPrototypeOf ||
  20402. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  20403. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  20404. return function (d, b) {
  20405. extendStatics(d, b);
  20406. function __() { this.constructor = d; }
  20407. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  20408. };
  20409. })();
  20410. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  20411. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  20412. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  20413. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  20414. return c > 3 && r && Object.defineProperty(target, key, r), r;
  20415. };
  20416. var BABYLON;
  20417. (function (BABYLON) {
  20418. var Button = Button_1 = (function (_super) {
  20419. __extends(Button, _super);
  20420. function Button(settings) {
  20421. var _this = this;
  20422. if (!settings) {
  20423. settings = {};
  20424. }
  20425. _this = _super.call(this, settings) || this;
  20426. if (settings.paddingAlignment == null) {
  20427. _this.paddingAlignment.horizontal = BABYLON.PrimitiveAlignment.AlignCenter;
  20428. _this.paddingAlignment.vertical = BABYLON.PrimitiveAlignment.AlignCenter;
  20429. }
  20430. _this._normalStateBackground = new BABYLON.ObservableStringDictionary(false);
  20431. _this._normalStateBorder = new BABYLON.ObservableStringDictionary(false);
  20432. _this._defaultStateBackground = new BABYLON.ObservableStringDictionary(false);
  20433. _this._defaultStateBorder = new BABYLON.ObservableStringDictionary(false);
  20434. _this._normalStateBackground.add(BABYLON.UIElement.enabledState, BABYLON.Canvas2D.GetSolidColorBrushFromHex("#337AB7FF"));
  20435. _this._normalStateBackground.add(BABYLON.UIElement.disabledState, BABYLON.Canvas2D.GetSolidColorBrushFromHex("#7BA9D0FF"));
  20436. _this._normalStateBackground.add(BABYLON.UIElement.mouseOverState, BABYLON.Canvas2D.GetSolidColorBrushFromHex("#286090FF"));
  20437. _this._normalStateBackground.add(Button_1.pushedState, BABYLON.Canvas2D.GetSolidColorBrushFromHex("#1E496EFF"));
  20438. _this._normalStateBorder.add(BABYLON.UIElement.enabledState, BABYLON.Canvas2D.GetSolidColorBrushFromHex("#2E6DA4FF"));
  20439. _this._normalStateBorder.add(BABYLON.UIElement.disabledState, BABYLON.Canvas2D.GetSolidColorBrushFromHex("#77A0C4FF"));
  20440. _this._normalStateBorder.add(BABYLON.UIElement.mouseOverState, BABYLON.Canvas2D.GetSolidColorBrushFromHex("#204D74FF"));
  20441. _this._normalStateBorder.add(Button_1.pushedState, BABYLON.Canvas2D.GetSolidColorBrushFromHex("#2E5D9EFF"));
  20442. _this._defaultStateBackground.add(BABYLON.UIElement.enabledState, BABYLON.Canvas2D.GetSolidColorBrushFromHex("#FFFFFFFF"));
  20443. _this._defaultStateBackground.add(BABYLON.UIElement.disabledState, BABYLON.Canvas2D.GetSolidColorBrushFromHex("#FFFFFFFF"));
  20444. _this._defaultStateBackground.add(BABYLON.UIElement.mouseOverState, BABYLON.Canvas2D.GetSolidColorBrushFromHex("#E6E6E6FF"));
  20445. _this._defaultStateBackground.add(Button_1.pushedState, BABYLON.Canvas2D.GetSolidColorBrushFromHex("#D4D4D4FF"));
  20446. _this._defaultStateBorder.add(BABYLON.UIElement.enabledState, BABYLON.Canvas2D.GetSolidColorBrushFromHex("#CCCCCCFF"));
  20447. _this._defaultStateBorder.add(BABYLON.UIElement.disabledState, BABYLON.Canvas2D.GetSolidColorBrushFromHex("#DEDEDEFF"));
  20448. _this._defaultStateBorder.add(BABYLON.UIElement.mouseOverState, BABYLON.Canvas2D.GetSolidColorBrushFromHex("#ADADADFF"));
  20449. _this._defaultStateBorder.add(Button_1.pushedState, BABYLON.Canvas2D.GetSolidColorBrushFromHex("#6C8EC5FF"));
  20450. return _this;
  20451. }
  20452. Object.defineProperty(Button, "pushedState", {
  20453. get: function () {
  20454. return Button_1._pushedState;
  20455. },
  20456. enumerable: true,
  20457. configurable: true
  20458. });
  20459. Object.defineProperty(Button.prototype, "isPushed", {
  20460. get: function () {
  20461. return this._isPushed;
  20462. },
  20463. set: function (value) {
  20464. this._isPushed = value;
  20465. },
  20466. enumerable: true,
  20467. configurable: true
  20468. });
  20469. Object.defineProperty(Button.prototype, "isDefault", {
  20470. get: function () {
  20471. return this._isDefault;
  20472. },
  20473. set: function (value) {
  20474. this._isDefault = value;
  20475. },
  20476. enumerable: true,
  20477. configurable: true
  20478. });
  20479. Object.defineProperty(Button.prototype, "isOutline", {
  20480. get: function () {
  20481. return this._isOutline;
  20482. },
  20483. set: function (value) {
  20484. this._isOutline = value;
  20485. },
  20486. enumerable: true,
  20487. configurable: true
  20488. });
  20489. Object.defineProperty(Button.prototype, "clickObservable", {
  20490. get: function () {
  20491. if (!this._clickObservable) {
  20492. this._clickObservable = new BABYLON.Observable();
  20493. }
  20494. return this._clickObservable;
  20495. },
  20496. enumerable: true,
  20497. configurable: true
  20498. });
  20499. Button.prototype._raiseClick = function () {
  20500. if (this._clickObservable && this._clickObservable.hasObservers()) {
  20501. this._clickObservable.notifyObservers(this);
  20502. }
  20503. };
  20504. Button.prototype.createVisualTree = function () {
  20505. var _this = this;
  20506. _super.prototype.createVisualTree.call(this);
  20507. var p = this._visualPlaceholder;
  20508. p.pointerEventObservable.add(function (e, s) {
  20509. // check if input must be discarded
  20510. if (!_this.isVisible || !_this.isEnabled) {
  20511. return;
  20512. }
  20513. // We reject an event coming from the placeholder because it means it's on an empty spot, so it's not valid.
  20514. if (e.relatedTarget === _this._visualPlaceholder) {
  20515. return;
  20516. }
  20517. if (s.mask === BABYLON.PrimitivePointerInfo.PointerUp) {
  20518. _this._raiseClick();
  20519. _this.isPushed = false;
  20520. }
  20521. else if (s.mask === BABYLON.PrimitivePointerInfo.PointerDown) {
  20522. _this.isPushed = true;
  20523. _this.isFocused = true;
  20524. }
  20525. }, BABYLON.PrimitivePointerInfo.PointerUp | BABYLON.PrimitivePointerInfo.PointerDown);
  20526. };
  20527. Object.defineProperty(Button.prototype, "normalStateBackground", {
  20528. get: function () {
  20529. return this._normalStateBackground;
  20530. },
  20531. enumerable: true,
  20532. configurable: true
  20533. });
  20534. Object.defineProperty(Button.prototype, "defaultStateBackground", {
  20535. get: function () {
  20536. return this._defaultStateBackground;
  20537. },
  20538. enumerable: true,
  20539. configurable: true
  20540. });
  20541. Object.defineProperty(Button.prototype, "normalStateBorder", {
  20542. get: function () {
  20543. return this._normalStateBorder;
  20544. },
  20545. enumerable: true,
  20546. configurable: true
  20547. });
  20548. Object.defineProperty(Button.prototype, "defaultStateBorder", {
  20549. get: function () {
  20550. return this._defaultStateBorder;
  20551. },
  20552. enumerable: true,
  20553. configurable: true
  20554. });
  20555. return Button;
  20556. }(BABYLON.ContentControl));
  20557. Button.BUTTON_PROPCOUNT = BABYLON.ContentControl.CONTENTCONTROL_PROPCOUNT + 3;
  20558. Button._pushedState = "Pushed";
  20559. __decorate([
  20560. BABYLON.dependencyProperty(BABYLON.ContentControl.CONTROL_PROPCOUNT + 0, function (pi) { return Button_1.isPushedProperty = pi; })
  20561. ], Button.prototype, "isPushed", null);
  20562. __decorate([
  20563. BABYLON.dependencyProperty(BABYLON.ContentControl.CONTROL_PROPCOUNT + 1, function (pi) { return Button_1.isDefaultProperty = pi; })
  20564. ], Button.prototype, "isDefault", null);
  20565. __decorate([
  20566. BABYLON.dependencyProperty(BABYLON.ContentControl.CONTROL_PROPCOUNT + 2, function (pi) { return Button_1.isOutlineProperty = pi; })
  20567. ], Button.prototype, "isOutline", null);
  20568. Button = Button_1 = __decorate([
  20569. BABYLON.className("Button", "BABYLON")
  20570. ], Button);
  20571. BABYLON.Button = Button;
  20572. var DefaultButtonRenderingTemplate = DefaultButtonRenderingTemplate_1 = (function (_super) {
  20573. __extends(DefaultButtonRenderingTemplate, _super);
  20574. function DefaultButtonRenderingTemplate() {
  20575. return _super !== null && _super.apply(this, arguments) || this;
  20576. }
  20577. DefaultButtonRenderingTemplate.prototype.createVisualTree = function (owner, visualPlaceholder) {
  20578. this._rect = new BABYLON.Rectangle2D({ parent: visualPlaceholder, fill: "#FF8080FF", border: "#FF8080FF", roundRadius: 10, borderThickness: 2 });
  20579. this.stateChange();
  20580. return { root: this._rect, contentPlaceholder: this._rect };
  20581. };
  20582. DefaultButtonRenderingTemplate.prototype.attach = function (owner) {
  20583. var _this = this;
  20584. _super.prototype.attach.call(this, owner);
  20585. this.owner.propertyChanged.add(function (e, s) { return _this.stateChange(); }, BABYLON.UIElement.isEnabledProperty.flagId |
  20586. BABYLON.UIElement.isFocusedProperty.flagId |
  20587. BABYLON.UIElement.isMouseOverProperty.flagId |
  20588. Button.isDefaultProperty.flagId |
  20589. Button.isOutlineProperty.flagId |
  20590. Button.isPushedProperty.flagId);
  20591. // Register for brush change and update the Visual
  20592. var button = owner;
  20593. button.normalStateBackground.dictionaryChanged.add(function (e, c) { return _this.stateChange(); });
  20594. button.normalStateBorder.dictionaryChanged.add(function (e, c) { return _this.stateChange(); });
  20595. button.defaultStateBackground.dictionaryChanged.add(function (e, c) { return _this.stateChange(); });
  20596. button.defaultStateBorder.dictionaryChanged.add(function (e, c) { return _this.stateChange(); });
  20597. };
  20598. DefaultButtonRenderingTemplate.prototype.stateChange = function () {
  20599. //console.log("state changed");
  20600. var b = this.owner;
  20601. var state = BABYLON.UIElement.enabledState;
  20602. var bg = b.isDefault ? b.defaultStateBackground.get(state) : b.normalStateBackground.get(state);
  20603. var bd = b.isDefault ? b.defaultStateBorder.get(state) : b.normalStateBorder.get(state);
  20604. if (b.isPushed) {
  20605. state = Button.pushedState;
  20606. if (b.isDefault) {
  20607. bg = b.defaultStateBackground.get(state);
  20608. bd = b.defaultStateBorder.get(state);
  20609. }
  20610. else {
  20611. bg = b.normalStateBackground.get(state);
  20612. bd = b.normalStateBorder.get(state);
  20613. }
  20614. }
  20615. else if (b.isMouseOver) {
  20616. state = BABYLON.UIElement.mouseOverState;
  20617. if (b.isDefault) {
  20618. bg = b.defaultStateBackground.get(state);
  20619. bd = b.defaultStateBorder.get(state);
  20620. }
  20621. else {
  20622. bg = b.normalStateBackground.get(state);
  20623. bd = b.normalStateBorder.get(state);
  20624. }
  20625. }
  20626. else if (!b.isEnabled) {
  20627. state = BABYLON.UIElement.disabledState;
  20628. if (b.isDefault) {
  20629. bg = b.defaultStateBackground.get(state);
  20630. bd = b.defaultStateBorder.get(state);
  20631. }
  20632. else {
  20633. bg = b.normalStateBackground.get(state);
  20634. bd = b.normalStateBorder.get(state);
  20635. }
  20636. }
  20637. this._rect.fill = bg;
  20638. this._rect.border = bd;
  20639. };
  20640. return DefaultButtonRenderingTemplate;
  20641. }(BABYLON.UIElementRenderingTemplateBase));
  20642. DefaultButtonRenderingTemplate = DefaultButtonRenderingTemplate_1 = __decorate([
  20643. BABYLON.registerWindowRenderingTemplate("BABYLON.Button", "Default", function () { return new DefaultButtonRenderingTemplate_1(); })
  20644. ], DefaultButtonRenderingTemplate);
  20645. BABYLON.DefaultButtonRenderingTemplate = DefaultButtonRenderingTemplate;
  20646. var Button_1, DefaultButtonRenderingTemplate_1;
  20647. })(BABYLON || (BABYLON = {}));