three.editor.unit.js 198 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory() :
  3. typeof define === 'function' && define.amd ? define(factory) :
  4. (factory());
  5. }(this, (function () { 'use strict';
  6. QUnit.module( "Editor", () => {
  7. /**
  8. * @author dforrer / https://github.com/dforrer
  9. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  10. */
  11. /**
  12. * @param editorRef pointer to main editor object used to initialize
  13. * each command object with a reference to the editor
  14. * @constructor
  15. */
  16. var Command$1 = function ( editorRef ) {
  17. this.id = - 1;
  18. this.inMemory = false;
  19. this.updatable = false;
  20. this.type = '';
  21. this.name = '';
  22. if ( editorRef !== undefined ) {
  23. Command$1.editor = editorRef;
  24. }
  25. this.editor = Command$1.editor;
  26. };
  27. Command$1.prototype.toJSON = function () {
  28. var output = {};
  29. output.type = this.type;
  30. output.id = this.id;
  31. output.name = this.name;
  32. return output;
  33. };
  34. Command$1.prototype.fromJSON = function ( json ) {
  35. this.inMemory = true;
  36. this.type = json.type;
  37. this.id = json.id;
  38. this.name = json.name;
  39. };
  40. /**
  41. * @author TristanVALCKE / https://github.com/Itee
  42. */
  43. /* global QUnit */
  44. QUnit.module( 'Editor', () => {
  45. QUnit.module.todo( 'Command', () => {
  46. QUnit.test( 'write me !', ( assert ) => {
  47. assert.ok( false, "everything's gonna be alright" );
  48. } );
  49. } );
  50. } );
  51. /**
  52. * @author mrdoob / http://mrdoob.com/
  53. */
  54. /**
  55. * @author TristanVALCKE / https://github.com/Itee
  56. */
  57. /* global QUnit */
  58. QUnit.module( 'Editor', () => {
  59. QUnit.module.todo( 'Config', () => {
  60. QUnit.test( 'write me !', ( assert ) => {
  61. assert.ok( false, "everything's gonna be alright" );
  62. } );
  63. } );
  64. } );
  65. /**
  66. * @author mrdoob / http://mrdoob.com/
  67. */
  68. var Editor = function () {
  69. this.DEFAULT_CAMERA = new THREE.PerspectiveCamera( 50, 1, 0.1, 10000 );
  70. this.DEFAULT_CAMERA.name = 'Camera';
  71. this.DEFAULT_CAMERA.position.set( 20, 10, 20 );
  72. this.DEFAULT_CAMERA.lookAt( new THREE.Vector3() );
  73. var Signal = signals.Signal;
  74. this.signals = {
  75. // script
  76. editScript: new Signal(),
  77. // player
  78. startPlayer: new Signal(),
  79. stopPlayer: new Signal(),
  80. // actions
  81. showModal: new Signal(),
  82. // notifications
  83. editorCleared: new Signal(),
  84. savingStarted: new Signal(),
  85. savingFinished: new Signal(),
  86. themeChanged: new Signal(),
  87. transformModeChanged: new Signal(),
  88. snapChanged: new Signal(),
  89. spaceChanged: new Signal(),
  90. rendererChanged: new Signal(),
  91. sceneBackgroundChanged: new Signal(),
  92. sceneFogChanged: new Signal(),
  93. sceneGraphChanged: new Signal(),
  94. cameraChanged: new Signal(),
  95. geometryChanged: new Signal(),
  96. objectSelected: new Signal(),
  97. objectFocused: new Signal(),
  98. objectAdded: new Signal(),
  99. objectChanged: new Signal(),
  100. objectRemoved: new Signal(),
  101. helperAdded: new Signal(),
  102. helperRemoved: new Signal(),
  103. materialChanged: new Signal(),
  104. scriptAdded: new Signal(),
  105. scriptChanged: new Signal(),
  106. scriptRemoved: new Signal(),
  107. windowResize: new Signal(),
  108. showGridChanged: new Signal(),
  109. refreshSidebarObject3D: new Signal(),
  110. historyChanged: new Signal()
  111. };
  112. this.config = new Config( 'threejs-editor' );
  113. this.history = new History( this );
  114. this.storage = new Storage();
  115. this.loader = new Loader( this );
  116. this.camera = this.DEFAULT_CAMERA.clone();
  117. this.scene = new THREE.Scene();
  118. this.scene.name = 'Scene';
  119. this.scene.background = new THREE.Color( 0xaaaaaa );
  120. this.sceneHelpers = new THREE.Scene();
  121. this.object = {};
  122. this.geometries = {};
  123. this.materials = {};
  124. this.textures = {};
  125. this.scripts = {};
  126. this.selected = null;
  127. this.helpers = {};
  128. };
  129. Editor.prototype = {
  130. setTheme: function ( value ) {
  131. document.getElementById( 'theme' ).href = value;
  132. this.signals.themeChanged.dispatch( value );
  133. },
  134. //
  135. setScene: function ( scene ) {
  136. this.scene.uuid = scene.uuid;
  137. this.scene.name = scene.name;
  138. if ( scene.background !== null ) this.scene.background = scene.background.clone();
  139. if ( scene.fog !== null ) this.scene.fog = scene.fog.clone();
  140. this.scene.userData = JSON.parse( JSON.stringify( scene.userData ) );
  141. // avoid render per object
  142. this.signals.sceneGraphChanged.active = false;
  143. while ( scene.children.length > 0 ) {
  144. this.addObject( scene.children[ 0 ] );
  145. }
  146. this.signals.sceneGraphChanged.active = true;
  147. this.signals.sceneGraphChanged.dispatch();
  148. },
  149. //
  150. addObject: function ( object ) {
  151. var scope = this;
  152. object.traverse( function ( child ) {
  153. if ( child.geometry !== undefined ) scope.addGeometry( child.geometry );
  154. if ( child.material !== undefined ) scope.addMaterial( child.material );
  155. scope.addHelper( child );
  156. } );
  157. this.scene.add( object );
  158. this.signals.objectAdded.dispatch( object );
  159. this.signals.sceneGraphChanged.dispatch();
  160. },
  161. moveObject: function ( object, parent, before ) {
  162. if ( parent === undefined ) {
  163. parent = this.scene;
  164. }
  165. parent.add( object );
  166. // sort children array
  167. if ( before !== undefined ) {
  168. var index = parent.children.indexOf( before );
  169. parent.children.splice( index, 0, object );
  170. parent.children.pop();
  171. }
  172. this.signals.sceneGraphChanged.dispatch();
  173. },
  174. nameObject: function ( object, name ) {
  175. object.name = name;
  176. this.signals.sceneGraphChanged.dispatch();
  177. },
  178. removeObject: function ( object ) {
  179. if ( object.parent === null ) return; // avoid deleting the camera or scene
  180. var scope = this;
  181. object.traverse( function ( child ) {
  182. scope.removeHelper( child );
  183. } );
  184. object.parent.remove( object );
  185. this.signals.objectRemoved.dispatch( object );
  186. this.signals.sceneGraphChanged.dispatch();
  187. },
  188. addGeometry: function ( geometry ) {
  189. this.geometries[ geometry.uuid ] = geometry;
  190. },
  191. setGeometryName: function ( geometry, name ) {
  192. geometry.name = name;
  193. this.signals.sceneGraphChanged.dispatch();
  194. },
  195. addMaterial: function ( material ) {
  196. this.materials[ material.uuid ] = material;
  197. },
  198. setMaterialName: function ( material, name ) {
  199. material.name = name;
  200. this.signals.sceneGraphChanged.dispatch();
  201. },
  202. addTexture: function ( texture ) {
  203. this.textures[ texture.uuid ] = texture;
  204. },
  205. //
  206. addHelper: function () {
  207. var geometry = new THREE.SphereBufferGeometry( 2, 4, 2 );
  208. var material = new THREE.MeshBasicMaterial( { color: 0xff0000, visible: false } );
  209. return function ( object ) {
  210. var helper;
  211. if ( object instanceof THREE.Camera ) {
  212. helper = new THREE.CameraHelper( object, 1 );
  213. } else if ( object instanceof THREE.PointLight ) {
  214. helper = new THREE.PointLightHelper( object, 1 );
  215. } else if ( object instanceof THREE.DirectionalLight ) {
  216. helper = new THREE.DirectionalLightHelper( object, 1 );
  217. } else if ( object instanceof THREE.SpotLight ) {
  218. helper = new THREE.SpotLightHelper( object, 1 );
  219. } else if ( object instanceof THREE.HemisphereLight ) {
  220. helper = new THREE.HemisphereLightHelper( object, 1 );
  221. } else if ( object instanceof THREE.SkinnedMesh ) {
  222. helper = new THREE.SkeletonHelper( object );
  223. } else {
  224. // no helper for this object type
  225. return;
  226. }
  227. var picker = new THREE.Mesh( geometry, material );
  228. picker.name = 'picker';
  229. picker.userData.object = object;
  230. helper.add( picker );
  231. this.sceneHelpers.add( helper );
  232. this.helpers[ object.id ] = helper;
  233. this.signals.helperAdded.dispatch( helper );
  234. };
  235. }(),
  236. removeHelper: function ( object ) {
  237. if ( this.helpers[ object.id ] !== undefined ) {
  238. var helper = this.helpers[ object.id ];
  239. helper.parent.remove( helper );
  240. delete this.helpers[ object.id ];
  241. this.signals.helperRemoved.dispatch( helper );
  242. }
  243. },
  244. //
  245. addScript: function ( object, script ) {
  246. if ( this.scripts[ object.uuid ] === undefined ) {
  247. this.scripts[ object.uuid ] = [];
  248. }
  249. this.scripts[ object.uuid ].push( script );
  250. this.signals.scriptAdded.dispatch( script );
  251. },
  252. removeScript: function ( object, script ) {
  253. if ( this.scripts[ object.uuid ] === undefined ) return;
  254. var index = this.scripts[ object.uuid ].indexOf( script );
  255. if ( index !== - 1 ) {
  256. this.scripts[ object.uuid ].splice( index, 1 );
  257. }
  258. this.signals.scriptRemoved.dispatch( script );
  259. },
  260. getObjectMaterial: function ( object, slot ) {
  261. var material = object.material;
  262. if ( Array.isArray( material ) ) {
  263. material = material[ slot ];
  264. }
  265. return material;
  266. },
  267. setObjectMaterial: function ( object, slot, newMaterial ) {
  268. if ( Array.isArray( object.material ) ) {
  269. object.material[ slot ] = newMaterial;
  270. } else {
  271. object.material = newMaterial;
  272. }
  273. },
  274. //
  275. select: function ( object ) {
  276. if ( this.selected === object ) return;
  277. var uuid = null;
  278. if ( object !== null ) {
  279. uuid = object.uuid;
  280. }
  281. this.selected = object;
  282. this.config.setKey( 'selected', uuid );
  283. this.signals.objectSelected.dispatch( object );
  284. },
  285. selectById: function ( id ) {
  286. if ( id === this.camera.id ) {
  287. this.select( this.camera );
  288. return;
  289. }
  290. this.select( this.scene.getObjectById( id, true ) );
  291. },
  292. selectByUuid: function ( uuid ) {
  293. var scope = this;
  294. this.scene.traverse( function ( child ) {
  295. if ( child.uuid === uuid ) {
  296. scope.select( child );
  297. }
  298. } );
  299. },
  300. deselect: function () {
  301. this.select( null );
  302. },
  303. focus: function ( object ) {
  304. this.signals.objectFocused.dispatch( object );
  305. },
  306. focusById: function ( id ) {
  307. this.focus( this.scene.getObjectById( id, true ) );
  308. },
  309. clear: function () {
  310. this.history.clear();
  311. this.storage.clear();
  312. this.camera.copy( this.DEFAULT_CAMERA );
  313. this.scene.background.setHex( 0xaaaaaa );
  314. this.scene.fog = null;
  315. var objects = this.scene.children;
  316. while ( objects.length > 0 ) {
  317. this.removeObject( objects[ 0 ] );
  318. }
  319. this.geometries = {};
  320. this.materials = {};
  321. this.textures = {};
  322. this.scripts = {};
  323. this.deselect();
  324. this.signals.editorCleared.dispatch();
  325. },
  326. //
  327. fromJSON: function ( json ) {
  328. var loader = new THREE.ObjectLoader();
  329. // backwards
  330. if ( json.scene === undefined ) {
  331. this.setScene( loader.parse( json ) );
  332. return;
  333. }
  334. var camera = loader.parse( json.camera );
  335. this.camera.copy( camera );
  336. this.camera.aspect = this.DEFAULT_CAMERA.aspect;
  337. this.camera.updateProjectionMatrix();
  338. this.history.fromJSON( json.history );
  339. this.scripts = json.scripts;
  340. this.setScene( loader.parse( json.scene ) );
  341. },
  342. toJSON: function () {
  343. // scripts clean up
  344. var scene = this.scene;
  345. var scripts = this.scripts;
  346. for ( var key in scripts ) {
  347. var script = scripts[ key ];
  348. if ( script.length === 0 || scene.getObjectByProperty( 'uuid', key ) === undefined ) {
  349. delete scripts[ key ];
  350. }
  351. }
  352. //
  353. return {
  354. metadata: {},
  355. project: {
  356. gammaInput: this.config.getKey( 'project/renderer/gammaInput' ),
  357. gammaOutput: this.config.getKey( 'project/renderer/gammaOutput' ),
  358. shadows: this.config.getKey( 'project/renderer/shadows' ),
  359. vr: this.config.getKey( 'project/vr' )
  360. },
  361. camera: this.camera.toJSON(),
  362. scene: this.scene.toJSON(),
  363. scripts: this.scripts,
  364. history: this.history.toJSON()
  365. };
  366. },
  367. objectByUuid: function ( uuid ) {
  368. return this.scene.getObjectByProperty( 'uuid', uuid, true );
  369. },
  370. execute: function ( cmd, optionalName ) {
  371. this.history.execute( cmd, optionalName );
  372. },
  373. undo: function () {
  374. this.history.undo();
  375. },
  376. redo: function () {
  377. this.history.redo();
  378. }
  379. };
  380. /**
  381. * @author TristanVALCKE / https://github.com/Itee
  382. */
  383. /* global QUnit */
  384. QUnit.module( 'Editor', () => {
  385. QUnit.module.todo( 'Editor', () => {
  386. QUnit.test( 'write me !', ( assert ) => {
  387. assert.ok( false, "everything's gonna be alright" );
  388. } );
  389. } );
  390. } );
  391. /**
  392. * @author dforrer / https://github.com/dforrer
  393. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  394. */
  395. History = function ( editor ) {
  396. this.editor = editor;
  397. this.undos = [];
  398. this.redos = [];
  399. this.lastCmdTime = new Date();
  400. this.idCounter = 0;
  401. this.historyDisabled = false;
  402. this.config = editor.config;
  403. //Set editor-reference in Command
  404. Command( editor );
  405. // signals
  406. var scope = this;
  407. this.editor.signals.startPlayer.add( function () {
  408. scope.historyDisabled = true;
  409. } );
  410. this.editor.signals.stopPlayer.add( function () {
  411. scope.historyDisabled = false;
  412. } );
  413. };
  414. History.prototype = {
  415. execute: function ( cmd, optionalName ) {
  416. var lastCmd = this.undos[ this.undos.length - 1 ];
  417. var timeDifference = new Date().getTime() - this.lastCmdTime.getTime();
  418. var isUpdatableCmd = lastCmd &&
  419. lastCmd.updatable &&
  420. cmd.updatable &&
  421. lastCmd.object === cmd.object &&
  422. lastCmd.type === cmd.type &&
  423. lastCmd.script === cmd.script &&
  424. lastCmd.attributeName === cmd.attributeName;
  425. if ( isUpdatableCmd && cmd.type === "SetScriptValueCommand" ) {
  426. // When the cmd.type is "SetScriptValueCommand" the timeDifference is ignored
  427. lastCmd.update( cmd );
  428. cmd = lastCmd;
  429. } else if ( isUpdatableCmd && timeDifference < 500 ) {
  430. lastCmd.update( cmd );
  431. cmd = lastCmd;
  432. } else {
  433. // the command is not updatable and is added as a new part of the history
  434. this.undos.push( cmd );
  435. cmd.id = ++ this.idCounter;
  436. }
  437. cmd.name = ( optionalName !== undefined ) ? optionalName : cmd.name;
  438. cmd.execute();
  439. cmd.inMemory = true;
  440. if ( this.config.getKey( 'settings/history' ) ) {
  441. cmd.json = cmd.toJSON(); // serialize the cmd immediately after execution and append the json to the cmd
  442. }
  443. this.lastCmdTime = new Date();
  444. // clearing all the redo-commands
  445. this.redos = [];
  446. this.editor.signals.historyChanged.dispatch( cmd );
  447. },
  448. undo: function () {
  449. if ( this.historyDisabled ) {
  450. alert( "Undo/Redo disabled while scene is playing." );
  451. return;
  452. }
  453. var cmd = undefined;
  454. if ( this.undos.length > 0 ) {
  455. cmd = this.undos.pop();
  456. if ( cmd.inMemory === false ) {
  457. cmd.fromJSON( cmd.json );
  458. }
  459. }
  460. if ( cmd !== undefined ) {
  461. cmd.undo();
  462. this.redos.push( cmd );
  463. this.editor.signals.historyChanged.dispatch( cmd );
  464. }
  465. return cmd;
  466. },
  467. redo: function () {
  468. if ( this.historyDisabled ) {
  469. alert( "Undo/Redo disabled while scene is playing." );
  470. return;
  471. }
  472. var cmd = undefined;
  473. if ( this.redos.length > 0 ) {
  474. cmd = this.redos.pop();
  475. if ( cmd.inMemory === false ) {
  476. cmd.fromJSON( cmd.json );
  477. }
  478. }
  479. if ( cmd !== undefined ) {
  480. cmd.execute();
  481. this.undos.push( cmd );
  482. this.editor.signals.historyChanged.dispatch( cmd );
  483. }
  484. return cmd;
  485. },
  486. toJSON: function () {
  487. var history = {};
  488. history.undos = [];
  489. history.redos = [];
  490. if ( ! this.config.getKey( 'settings/history' ) ) {
  491. return history;
  492. }
  493. // Append Undos to History
  494. for ( var i = 0 ; i < this.undos.length; i ++ ) {
  495. if ( this.undos[ i ].hasOwnProperty( "json" ) ) {
  496. history.undos.push( this.undos[ i ].json );
  497. }
  498. }
  499. // Append Redos to History
  500. for ( var i = 0 ; i < this.redos.length; i ++ ) {
  501. if ( this.redos[ i ].hasOwnProperty( "json" ) ) {
  502. history.redos.push( this.redos[ i ].json );
  503. }
  504. }
  505. return history;
  506. },
  507. fromJSON: function ( json ) {
  508. if ( json === undefined ) return;
  509. for ( var i = 0; i < json.undos.length; i ++ ) {
  510. var cmdJSON = json.undos[ i ];
  511. var cmd = new window[ cmdJSON.type ](); // creates a new object of type "json.type"
  512. cmd.json = cmdJSON;
  513. cmd.id = cmdJSON.id;
  514. cmd.name = cmdJSON.name;
  515. this.undos.push( cmd );
  516. this.idCounter = ( cmdJSON.id > this.idCounter ) ? cmdJSON.id : this.idCounter; // set last used idCounter
  517. }
  518. for ( var i = 0; i < json.redos.length; i ++ ) {
  519. var cmdJSON = json.redos[ i ];
  520. var cmd = new window[ cmdJSON.type ](); // creates a new object of type "json.type"
  521. cmd.json = cmdJSON;
  522. cmd.id = cmdJSON.id;
  523. cmd.name = cmdJSON.name;
  524. this.redos.push( cmd );
  525. this.idCounter = ( cmdJSON.id > this.idCounter ) ? cmdJSON.id : this.idCounter; // set last used idCounter
  526. }
  527. // Select the last executed undo-command
  528. this.editor.signals.historyChanged.dispatch( this.undos[ this.undos.length - 1 ] );
  529. },
  530. clear: function () {
  531. this.undos = [];
  532. this.redos = [];
  533. this.idCounter = 0;
  534. this.editor.signals.historyChanged.dispatch();
  535. },
  536. goToState: function ( id ) {
  537. if ( this.historyDisabled ) {
  538. alert( "Undo/Redo disabled while scene is playing." );
  539. return;
  540. }
  541. this.editor.signals.sceneGraphChanged.active = false;
  542. this.editor.signals.historyChanged.active = false;
  543. var cmd = this.undos.length > 0 ? this.undos[ this.undos.length - 1 ] : undefined; // next cmd to pop
  544. if ( cmd === undefined || id > cmd.id ) {
  545. cmd = this.redo();
  546. while ( cmd !== undefined && id > cmd.id ) {
  547. cmd = this.redo();
  548. }
  549. } else {
  550. while ( true ) {
  551. cmd = this.undos[ this.undos.length - 1 ]; // next cmd to pop
  552. if ( cmd === undefined || id === cmd.id ) break;
  553. this.undo();
  554. }
  555. }
  556. this.editor.signals.sceneGraphChanged.active = true;
  557. this.editor.signals.historyChanged.active = true;
  558. this.editor.signals.sceneGraphChanged.dispatch();
  559. this.editor.signals.historyChanged.dispatch( cmd );
  560. },
  561. enableSerialization: function ( id ) {
  562. /**
  563. * because there might be commands in this.undos and this.redos
  564. * which have not been serialized with .toJSON() we go back
  565. * to the oldest command and redo one command after the other
  566. * while also calling .toJSON() on them.
  567. */
  568. this.goToState( - 1 );
  569. this.editor.signals.sceneGraphChanged.active = false;
  570. this.editor.signals.historyChanged.active = false;
  571. var cmd = this.redo();
  572. while ( cmd !== undefined ) {
  573. if ( ! cmd.hasOwnProperty( "json" ) ) {
  574. cmd.json = cmd.toJSON();
  575. }
  576. cmd = this.redo();
  577. }
  578. this.editor.signals.sceneGraphChanged.active = true;
  579. this.editor.signals.historyChanged.active = true;
  580. this.goToState( id );
  581. }
  582. };
  583. /**
  584. * @author TristanVALCKE / https://github.com/Itee
  585. */
  586. /* global QUnit */
  587. QUnit.module( 'Editor', () => {
  588. QUnit.module.todo( 'History', () => {
  589. QUnit.test( 'write me !', ( assert ) => {
  590. assert.ok( false, "everything's gonna be alright" );
  591. } );
  592. } );
  593. } );
  594. /**
  595. * @author mrdoob / http://mrdoob.com/
  596. */
  597. /**
  598. * @author TristanVALCKE / https://github.com/Itee
  599. */
  600. /* global QUnit */
  601. QUnit.module( 'Editor', () => {
  602. QUnit.module.todo( 'Loader', () => {
  603. QUnit.test( 'write me !', ( assert ) => {
  604. assert.ok( false, "everything's gonna be alright" );
  605. } );
  606. } );
  607. } );
  608. /**
  609. * @author mrdoob / http://mrdoob.com/
  610. */
  611. /**
  612. * @author TristanVALCKE / https://github.com/Itee
  613. */
  614. /* global QUnit */
  615. QUnit.module( 'Editor', () => {
  616. QUnit.module.todo( 'Player', () => {
  617. QUnit.test( 'write me !', ( assert ) => {
  618. assert.ok( false, "everything's gonna be alright" );
  619. } );
  620. } );
  621. } );
  622. /**
  623. * @author mrdoob / http://mrdoob.com/
  624. */
  625. /**
  626. * @author TristanVALCKE / https://github.com/Itee
  627. */
  628. /* global QUnit */
  629. QUnit.module( 'Editor', () => {
  630. QUnit.module.todo( 'Script', () => {
  631. QUnit.test( 'write me !', ( assert ) => {
  632. assert.ok( false, "everything's gonna be alright" );
  633. } );
  634. } );
  635. } );
  636. /**
  637. * @author mrdoob / http://mrdoob.com/
  638. */
  639. /**
  640. * @author TristanVALCKE / https://github.com/Itee
  641. */
  642. /* global QUnit */
  643. QUnit.module( 'Editor', () => {
  644. QUnit.module.todo( 'Menubar', () => {
  645. QUnit.test( 'write me !', ( assert ) => {
  646. assert.ok( false, "everything's gonna be alright" );
  647. } );
  648. } );
  649. } );
  650. /**
  651. * @author mrdoob / http://mrdoob.com/
  652. */
  653. Menubar.Add = function ( editor ) {
  654. var container = new UI.Panel();
  655. container.setClass( 'menu' );
  656. var title = new UI.Panel();
  657. title.setClass( 'title' );
  658. title.setTextContent( 'Add' );
  659. container.add( title );
  660. var options = new UI.Panel();
  661. options.setClass( 'options' );
  662. container.add( options );
  663. //
  664. var meshCount = 0;
  665. var lightCount = 0;
  666. var cameraCount = 0;
  667. editor.signals.editorCleared.add( function () {
  668. meshCount = 0;
  669. lightCount = 0;
  670. cameraCount = 0;
  671. } );
  672. // Group
  673. var option = new UI.Row();
  674. option.setClass( 'option' );
  675. option.setTextContent( 'Group' );
  676. option.onClick( function () {
  677. var mesh = new THREE.Group();
  678. mesh.name = 'Group ' + ( ++ meshCount );
  679. editor.execute( new AddObjectCommand( mesh ) );
  680. } );
  681. options.add( option );
  682. //
  683. options.add( new UI.HorizontalRule() );
  684. // Plane
  685. var option = new UI.Row();
  686. option.setClass( 'option' );
  687. option.setTextContent( 'Plane' );
  688. option.onClick( function () {
  689. var geometry = new THREE.PlaneBufferGeometry( 1, 1, 1, 1 );
  690. var material = new THREE.MeshStandardMaterial();
  691. var mesh = new THREE.Mesh( geometry, material );
  692. mesh.name = 'Plane ' + ( ++ meshCount );
  693. editor.execute( new AddObjectCommand( mesh ) );
  694. } );
  695. options.add( option );
  696. // Box
  697. var option = new UI.Row();
  698. option.setClass( 'option' );
  699. option.setTextContent( 'Box' );
  700. option.onClick( function () {
  701. var geometry = new THREE.BoxBufferGeometry( 1, 1, 1, 1, 1, 1 );
  702. var mesh = new THREE.Mesh( geometry, new THREE.MeshStandardMaterial() );
  703. mesh.name = 'Box ' + ( ++ meshCount );
  704. editor.execute( new AddObjectCommand( mesh ) );
  705. } );
  706. options.add( option );
  707. // Circle
  708. var option = new UI.Row();
  709. option.setClass( 'option' );
  710. option.setTextContent( 'Circle' );
  711. option.onClick( function () {
  712. var geometry = new THREE.CircleBufferGeometry( 1, 8, 0, Math.PI * 2 );
  713. var mesh = new THREE.Mesh( geometry, new THREE.MeshStandardMaterial() );
  714. mesh.name = 'Circle ' + ( ++ meshCount );
  715. editor.execute( new AddObjectCommand( mesh ) );
  716. } );
  717. options.add( option );
  718. // Cylinder
  719. var option = new UI.Row();
  720. option.setClass( 'option' );
  721. option.setTextContent( 'Cylinder' );
  722. option.onClick( function () {
  723. var geometry = new THREE.CylinderBufferGeometry( 1, 1, 1, 8, 1, false, 0, Math.PI * 2 );
  724. var mesh = new THREE.Mesh( geometry, new THREE.MeshStandardMaterial() );
  725. mesh.name = 'Cylinder ' + ( ++ meshCount );
  726. editor.execute( new AddObjectCommand( mesh ) );
  727. } );
  728. options.add( option );
  729. // Sphere
  730. var option = new UI.Row();
  731. option.setClass( 'option' );
  732. option.setTextContent( 'Sphere' );
  733. option.onClick( function () {
  734. var geometry = new THREE.SphereBufferGeometry( 1, 8, 6, 0, Math.PI * 2, 0, Math.PI );
  735. var mesh = new THREE.Mesh( geometry, new THREE.MeshStandardMaterial() );
  736. mesh.name = 'Sphere ' + ( ++ meshCount );
  737. editor.execute( new AddObjectCommand( mesh ) );
  738. } );
  739. options.add( option );
  740. // Icosahedron
  741. var option = new UI.Row();
  742. option.setClass( 'option' );
  743. option.setTextContent( 'Icosahedron' );
  744. option.onClick( function () {
  745. var geometry = new THREE.IcosahedronGeometry( 1, 0 );
  746. var mesh = new THREE.Mesh( geometry, new THREE.MeshStandardMaterial() );
  747. mesh.name = 'Icosahedron ' + ( ++ meshCount );
  748. editor.execute( new AddObjectCommand( mesh ) );
  749. } );
  750. options.add( option );
  751. // Torus
  752. var option = new UI.Row();
  753. option.setClass( 'option' );
  754. option.setTextContent( 'Torus' );
  755. option.onClick( function () {
  756. var geometry = new THREE.TorusBufferGeometry( 1, 0.4, 8, 6, Math.PI * 2 );
  757. var mesh = new THREE.Mesh( geometry, new THREE.MeshStandardMaterial() );
  758. mesh.name = 'Torus ' + ( ++ meshCount );
  759. editor.execute( new AddObjectCommand( mesh ) );
  760. } );
  761. options.add( option );
  762. // TorusKnot
  763. var option = new UI.Row();
  764. option.setClass( 'option' );
  765. option.setTextContent( 'TorusKnot' );
  766. option.onClick( function () {
  767. var geometry = new THREE.TorusKnotBufferGeometry( 1, 0.4, 64, 8, 2, 3 );
  768. var mesh = new THREE.Mesh( geometry, new THREE.MeshStandardMaterial() );
  769. mesh.name = 'TorusKnot ' + ( ++ meshCount );
  770. editor.execute( new AddObjectCommand( mesh ) );
  771. } );
  772. options.add( option );
  773. /*
  774. // Teapot
  775. var option = new UI.Row();
  776. option.setClass( 'option' );
  777. option.setTextContent( 'Teapot' );
  778. option.onClick( function () {
  779. var size = 50;
  780. var segments = 10;
  781. var bottom = true;
  782. var lid = true;
  783. var body = true;
  784. var fitLid = false;
  785. var blinnScale = true;
  786. var material = new THREE.MeshStandardMaterial();
  787. var geometry = new THREE.TeapotBufferGeometry( size, segments, bottom, lid, body, fitLid, blinnScale );
  788. var mesh = new THREE.Mesh( geometry, material );
  789. mesh.name = 'Teapot ' + ( ++ meshCount );
  790. editor.addObject( mesh );
  791. editor.select( mesh );
  792. } );
  793. options.add( option );
  794. */
  795. // Lathe
  796. var option = new UI.Row();
  797. option.setClass( 'option' );
  798. option.setTextContent( 'Lathe' );
  799. option.onClick( function() {
  800. var points = [
  801. new THREE.Vector2( 0, 0 ),
  802. new THREE.Vector2( 0.4, 0 ),
  803. new THREE.Vector2( 0.35, 0.05 ),
  804. new THREE.Vector2( 0.1, 0.075 ),
  805. new THREE.Vector2( 0.08, 0.1 ),
  806. new THREE.Vector2( 0.08, 0.4 ),
  807. new THREE.Vector2( 0.1, 0.42 ),
  808. new THREE.Vector2( 0.14, 0.48 ),
  809. new THREE.Vector2( 0.2, 0.5 ),
  810. new THREE.Vector2( 0.25, 0.54 ),
  811. new THREE.Vector2( 0.3, 1.2 )
  812. ];
  813. var geometry = new THREE.LatheBufferGeometry( points, 12, 0, Math.PI * 2 );
  814. var mesh = new THREE.Mesh( geometry, new THREE.MeshStandardMaterial( { side: THREE.DoubleSide } ) );
  815. mesh.name = 'Lathe ' + ( ++ meshCount );
  816. editor.execute( new AddObjectCommand( mesh ) );
  817. } );
  818. options.add( option );
  819. // Sprite
  820. var option = new UI.Row();
  821. option.setClass( 'option' );
  822. option.setTextContent( 'Sprite' );
  823. option.onClick( function () {
  824. var sprite = new THREE.Sprite( new THREE.SpriteMaterial() );
  825. sprite.name = 'Sprite ' + ( ++ meshCount );
  826. editor.execute( new AddObjectCommand( sprite ) );
  827. } );
  828. options.add( option );
  829. //
  830. options.add( new UI.HorizontalRule() );
  831. // PointLight
  832. var option = new UI.Row();
  833. option.setClass( 'option' );
  834. option.setTextContent( 'PointLight' );
  835. option.onClick( function () {
  836. var color = 0xffffff;
  837. var intensity = 1;
  838. var distance = 0;
  839. var light = new THREE.PointLight( color, intensity, distance );
  840. light.name = 'PointLight ' + ( ++ lightCount );
  841. editor.execute( new AddObjectCommand( light ) );
  842. } );
  843. options.add( option );
  844. // SpotLight
  845. var option = new UI.Row();
  846. option.setClass( 'option' );
  847. option.setTextContent( 'SpotLight' );
  848. option.onClick( function () {
  849. var color = 0xffffff;
  850. var intensity = 1;
  851. var distance = 0;
  852. var angle = Math.PI * 0.1;
  853. var penumbra = 0;
  854. var light = new THREE.SpotLight( color, intensity, distance, angle, penumbra );
  855. light.name = 'SpotLight ' + ( ++ lightCount );
  856. light.target.name = 'SpotLight ' + ( lightCount ) + ' Target';
  857. light.position.set( 5, 10, 7.5 );
  858. editor.execute( new AddObjectCommand( light ) );
  859. } );
  860. options.add( option );
  861. // DirectionalLight
  862. var option = new UI.Row();
  863. option.setClass( 'option' );
  864. option.setTextContent( 'DirectionalLight' );
  865. option.onClick( function () {
  866. var color = 0xffffff;
  867. var intensity = 1;
  868. var light = new THREE.DirectionalLight( color, intensity );
  869. light.name = 'DirectionalLight ' + ( ++ lightCount );
  870. light.target.name = 'DirectionalLight ' + ( lightCount ) + ' Target';
  871. light.position.set( 5, 10, 7.5 );
  872. editor.execute( new AddObjectCommand( light ) );
  873. } );
  874. options.add( option );
  875. // HemisphereLight
  876. var option = new UI.Row();
  877. option.setClass( 'option' );
  878. option.setTextContent( 'HemisphereLight' );
  879. option.onClick( function () {
  880. var skyColor = 0x00aaff;
  881. var groundColor = 0xffaa00;
  882. var intensity = 1;
  883. var light = new THREE.HemisphereLight( skyColor, groundColor, intensity );
  884. light.name = 'HemisphereLight ' + ( ++ lightCount );
  885. light.position.set( 0, 10, 0 );
  886. editor.execute( new AddObjectCommand( light ) );
  887. } );
  888. options.add( option );
  889. // AmbientLight
  890. var option = new UI.Row();
  891. option.setClass( 'option' );
  892. option.setTextContent( 'AmbientLight' );
  893. option.onClick( function() {
  894. var color = 0x222222;
  895. var light = new THREE.AmbientLight( color );
  896. light.name = 'AmbientLight ' + ( ++ lightCount );
  897. editor.execute( new AddObjectCommand( light ) );
  898. } );
  899. options.add( option );
  900. //
  901. options.add( new UI.HorizontalRule() );
  902. // PerspectiveCamera
  903. var option = new UI.Row();
  904. option.setClass( 'option' );
  905. option.setTextContent( 'PerspectiveCamera' );
  906. option.onClick( function() {
  907. var camera = new THREE.PerspectiveCamera( 50, 1, 1, 10000 );
  908. camera.name = 'PerspectiveCamera ' + ( ++ cameraCount );
  909. editor.execute( new AddObjectCommand( camera ) );
  910. } );
  911. options.add( option );
  912. return container;
  913. };
  914. /**
  915. * @author TristanVALCKE / https://github.com/Itee
  916. */
  917. /* global QUnit */
  918. QUnit.module( 'Editor', () => {
  919. QUnit.module.todo( 'Menubar.Add', () => {
  920. QUnit.test( 'write me !', ( assert ) => {
  921. assert.ok( false, "everything's gonna be alright" );
  922. } );
  923. } );
  924. } );
  925. /**
  926. * @author mrdoob / http://mrdoob.com/
  927. */
  928. Menubar.Edit = function ( editor ) {
  929. var container = new UI.Panel();
  930. container.setClass( 'menu' );
  931. var title = new UI.Panel();
  932. title.setClass( 'title' );
  933. title.setTextContent( 'Edit' );
  934. container.add( title );
  935. var options = new UI.Panel();
  936. options.setClass( 'options' );
  937. container.add( options );
  938. // Undo
  939. var undo = new UI.Row();
  940. undo.setClass( 'option' );
  941. undo.setTextContent( 'Undo (Ctrl+Z)' );
  942. undo.onClick( function () {
  943. editor.undo();
  944. } );
  945. options.add( undo );
  946. // Redo
  947. var redo = new UI.Row();
  948. redo.setClass( 'option' );
  949. redo.setTextContent( 'Redo (Ctrl+Shift+Z)' );
  950. redo.onClick( function () {
  951. editor.redo();
  952. } );
  953. options.add( redo );
  954. // Clear History
  955. var option = new UI.Row();
  956. option.setClass( 'option' );
  957. option.setTextContent( 'Clear History' );
  958. option.onClick( function () {
  959. if ( confirm( 'The Undo/Redo History will be cleared. Are you sure?' ) ) {
  960. editor.history.clear();
  961. }
  962. } );
  963. options.add( option );
  964. editor.signals.historyChanged.add( function () {
  965. var history = editor.history;
  966. undo.setClass( 'option' );
  967. redo.setClass( 'option' );
  968. if ( history.undos.length == 0 ) {
  969. undo.setClass( 'inactive' );
  970. }
  971. if ( history.redos.length == 0 ) {
  972. redo.setClass( 'inactive' );
  973. }
  974. } );
  975. // ---
  976. options.add( new UI.HorizontalRule() );
  977. // Clone
  978. var option = new UI.Row();
  979. option.setClass( 'option' );
  980. option.setTextContent( 'Clone' );
  981. option.onClick( function () {
  982. var object = editor.selected;
  983. if ( object.parent === null ) return; // avoid cloning the camera or scene
  984. object = object.clone();
  985. editor.execute( new AddObjectCommand( object ) );
  986. } );
  987. options.add( option );
  988. // Delete
  989. var option = new UI.Row();
  990. option.setClass( 'option' );
  991. option.setTextContent( 'Delete (Del)' );
  992. option.onClick( function () {
  993. var object = editor.selected;
  994. if ( confirm( 'Delete ' + object.name + '?' ) === false ) return;
  995. var parent = object.parent;
  996. if ( parent === undefined ) return; // avoid deleting the camera or scene
  997. editor.execute( new RemoveObjectCommand( object ) );
  998. } );
  999. options.add( option );
  1000. // Minify shaders
  1001. var option = new UI.Row();
  1002. option.setClass( 'option' );
  1003. option.setTextContent( 'Minify Shaders' );
  1004. option.onClick( function() {
  1005. var root = editor.selected || editor.scene;
  1006. var errors = [];
  1007. var nMaterialsChanged = 0;
  1008. var path = [];
  1009. function getPath ( object ) {
  1010. path.length = 0;
  1011. var parent = object.parent;
  1012. if ( parent !== undefined ) getPath( parent );
  1013. path.push( object.name || object.uuid );
  1014. return path;
  1015. }
  1016. var cmds = [];
  1017. root.traverse( function ( object ) {
  1018. var material = object.material;
  1019. if ( material instanceof THREE.ShaderMaterial ) {
  1020. try {
  1021. var shader = glslprep.minifyGlsl( [
  1022. material.vertexShader, material.fragmentShader ] );
  1023. cmds.push( new SetMaterialValueCommand( object, 'vertexShader', shader[ 0 ] ) );
  1024. cmds.push( new SetMaterialValueCommand( object, 'fragmentShader', shader[ 1 ] ) );
  1025. ++nMaterialsChanged;
  1026. } catch ( e ) {
  1027. var path = getPath( object ).join( "/" );
  1028. if ( e instanceof glslprep.SyntaxError )
  1029. errors.push( path + ":" +
  1030. e.line + ":" + e.column + ": " + e.message );
  1031. else {
  1032. errors.push( path +
  1033. ": Unexpected error (see console for details)." );
  1034. console.error( e.stack || e );
  1035. }
  1036. }
  1037. }
  1038. } );
  1039. if ( nMaterialsChanged > 0 ) {
  1040. editor.execute( new MultiCmdsCommand( cmds ), 'Minify Shaders' );
  1041. }
  1042. window.alert( nMaterialsChanged +
  1043. " material(s) were changed.\n" + errors.join( "\n" ) );
  1044. } );
  1045. options.add( option );
  1046. return container;
  1047. };
  1048. /**
  1049. * @author TristanVALCKE / https://github.com/Itee
  1050. */
  1051. /* global QUnit */
  1052. QUnit.module( 'Editor', () => {
  1053. QUnit.module.todo( 'Menubar.Edit', () => {
  1054. QUnit.test( 'write me !', ( assert ) => {
  1055. assert.ok( false, "everything's gonna be alright" );
  1056. } );
  1057. } );
  1058. } );
  1059. /**
  1060. * @author mrdoob / http://mrdoob.com/
  1061. */
  1062. Menubar.Examples = function ( editor ) {
  1063. var container = new UI.Panel();
  1064. container.setClass( 'menu' );
  1065. var title = new UI.Panel();
  1066. title.setClass( 'title' );
  1067. title.setTextContent( 'Examples' );
  1068. container.add( title );
  1069. var options = new UI.Panel();
  1070. options.setClass( 'options' );
  1071. container.add( options );
  1072. // Examples
  1073. var items = [
  1074. { title: 'Arkanoid', file: 'arkanoid.app.json' },
  1075. { title: 'Camera', file: 'camera.app.json' },
  1076. { title: 'Particles', file: 'particles.app.json' },
  1077. { title: 'Pong', file: 'pong.app.json' },
  1078. { title: 'Shaders', file: 'shaders.app.json' }
  1079. ];
  1080. var loader = new THREE.FileLoader();
  1081. for ( var i = 0; i < items.length; i ++ ) {
  1082. ( function ( i ) {
  1083. var item = items[ i ];
  1084. var option = new UI.Row();
  1085. option.setClass( 'option' );
  1086. option.setTextContent( item.title );
  1087. option.onClick( function () {
  1088. if ( confirm( 'Any unsaved data will be lost. Are you sure?' ) ) {
  1089. loader.load( 'examples/' + item.file, function ( text ) {
  1090. editor.clear();
  1091. editor.fromJSON( JSON.parse( text ) );
  1092. } );
  1093. }
  1094. } );
  1095. options.add( option );
  1096. } )( i );
  1097. }
  1098. return container;
  1099. };
  1100. /**
  1101. * @author TristanVALCKE / https://github.com/Itee
  1102. */
  1103. /* global QUnit */
  1104. QUnit.module( 'Editor', () => {
  1105. QUnit.module.todo( 'Menubar.Examples', () => {
  1106. QUnit.test( 'write me !', ( assert ) => {
  1107. assert.ok( false, "everything's gonna be alright" );
  1108. } );
  1109. } );
  1110. } );
  1111. /**
  1112. * @author mrdoob / http://mrdoob.com/
  1113. */
  1114. Menubar.File = function ( editor ) {
  1115. var NUMBER_PRECISION = 6;
  1116. function parseNumber( key, value ) {
  1117. return typeof value === 'number' ? parseFloat( value.toFixed( NUMBER_PRECISION ) ) : value;
  1118. }
  1119. //
  1120. var container = new UI.Panel();
  1121. container.setClass( 'menu' );
  1122. var title = new UI.Panel();
  1123. title.setClass( 'title' );
  1124. title.setTextContent( 'File' );
  1125. container.add( title );
  1126. var options = new UI.Panel();
  1127. options.setClass( 'options' );
  1128. container.add( options );
  1129. // New
  1130. var option = new UI.Row();
  1131. option.setClass( 'option' );
  1132. option.setTextContent( 'New' );
  1133. option.onClick( function () {
  1134. if ( confirm( 'Any unsaved data will be lost. Are you sure?' ) ) {
  1135. editor.clear();
  1136. }
  1137. } );
  1138. options.add( option );
  1139. //
  1140. options.add( new UI.HorizontalRule() );
  1141. // Import
  1142. var form = document.createElement( 'form' );
  1143. form.style.display = 'none';
  1144. document.body.appendChild( form );
  1145. var fileInput = document.createElement( 'input' );
  1146. fileInput.type = 'file';
  1147. fileInput.addEventListener( 'change', function ( event ) {
  1148. editor.loader.loadFile( fileInput.files[ 0 ] );
  1149. form.reset();
  1150. } );
  1151. form.appendChild( fileInput );
  1152. var option = new UI.Row();
  1153. option.setClass( 'option' );
  1154. option.setTextContent( 'Import' );
  1155. option.onClick( function () {
  1156. fileInput.click();
  1157. } );
  1158. options.add( option );
  1159. //
  1160. options.add( new UI.HorizontalRule() );
  1161. // Export Geometry
  1162. var option = new UI.Row();
  1163. option.setClass( 'option' );
  1164. option.setTextContent( 'Export Geometry' );
  1165. option.onClick( function () {
  1166. var object = editor.selected;
  1167. if ( object === null ) {
  1168. alert( 'No object selected.' );
  1169. return;
  1170. }
  1171. var geometry = object.geometry;
  1172. if ( geometry === undefined ) {
  1173. alert( 'The selected object doesn\'t have geometry.' );
  1174. return;
  1175. }
  1176. var output = geometry.toJSON();
  1177. try {
  1178. output = JSON.stringify( output, parseNumber, '\t' );
  1179. output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
  1180. } catch ( e ) {
  1181. output = JSON.stringify( output );
  1182. }
  1183. saveString( output, 'geometry.json' );
  1184. } );
  1185. options.add( option );
  1186. // Export Object
  1187. var option = new UI.Row();
  1188. option.setClass( 'option' );
  1189. option.setTextContent( 'Export Object' );
  1190. option.onClick( function () {
  1191. var object = editor.selected;
  1192. if ( object === null ) {
  1193. alert( 'No object selected' );
  1194. return;
  1195. }
  1196. var output = object.toJSON();
  1197. try {
  1198. output = JSON.stringify( output, parseNumber, '\t' );
  1199. output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
  1200. } catch ( e ) {
  1201. output = JSON.stringify( output );
  1202. }
  1203. saveString( output, 'model.json' );
  1204. } );
  1205. options.add( option );
  1206. // Export Scene
  1207. var option = new UI.Row();
  1208. option.setClass( 'option' );
  1209. option.setTextContent( 'Export Scene' );
  1210. option.onClick( function () {
  1211. var output = editor.scene.toJSON();
  1212. try {
  1213. output = JSON.stringify( output, parseNumber, '\t' );
  1214. output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
  1215. } catch ( e ) {
  1216. output = JSON.stringify( output );
  1217. }
  1218. saveString( output, 'scene.json' );
  1219. } );
  1220. options.add( option );
  1221. //
  1222. options.add( new UI.HorizontalRule() );
  1223. // Export GLTF
  1224. var option = new UI.Row();
  1225. option.setClass( 'option' );
  1226. option.setTextContent( 'Export GLTF' );
  1227. option.onClick( function () {
  1228. var exporter = new THREE.GLTFExporter();
  1229. exporter.parse( editor.scene, function ( result ) {
  1230. saveString( JSON.stringify( result, null, 2 ), 'scene.gltf' );
  1231. } );
  1232. } );
  1233. options.add( option );
  1234. // Export OBJ
  1235. var option = new UI.Row();
  1236. option.setClass( 'option' );
  1237. option.setTextContent( 'Export OBJ' );
  1238. option.onClick( function () {
  1239. var object = editor.selected;
  1240. if ( object === null ) {
  1241. alert( 'No object selected.' );
  1242. return;
  1243. }
  1244. var exporter = new THREE.OBJExporter();
  1245. saveString( exporter.parse( object ), 'model.obj' );
  1246. } );
  1247. options.add( option );
  1248. // Export STL
  1249. var option = new UI.Row();
  1250. option.setClass( 'option' );
  1251. option.setTextContent( 'Export STL' );
  1252. option.onClick( function () {
  1253. var exporter = new THREE.STLExporter();
  1254. saveString( exporter.parse( editor.scene ), 'model.stl' );
  1255. } );
  1256. options.add( option );
  1257. //
  1258. options.add( new UI.HorizontalRule() );
  1259. // Publish
  1260. var option = new UI.Row();
  1261. option.setClass( 'option' );
  1262. option.setTextContent( 'Publish' );
  1263. option.onClick( function () {
  1264. var zip = new JSZip();
  1265. //
  1266. var output = editor.toJSON();
  1267. output.metadata.type = 'App';
  1268. delete output.history;
  1269. var vr = output.project.vr;
  1270. output = JSON.stringify( output, parseNumber, '\t' );
  1271. output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
  1272. zip.file( 'app.json', output );
  1273. //
  1274. var manager = new THREE.LoadingManager( function () {
  1275. save( zip.generate( { type: 'blob' } ), 'download.zip' );
  1276. } );
  1277. var loader = new THREE.FileLoader( manager );
  1278. loader.load( 'js/libs/app/index.html', function ( content ) {
  1279. var includes = [];
  1280. if ( vr ) {
  1281. includes.push( '<script src="js/WebVR.js"></script>' );
  1282. }
  1283. content = content.replace( '<!-- includes -->', includes.join( '\n\t\t' ) );
  1284. var editButton = '';
  1285. if ( editor.config.getKey( 'project/editable' ) ) {
  1286. editButton = `
  1287. var button = document.createElement( 'a' );
  1288. button.href = 'https://threejs.org/editor/#file=' + location.href.split( '/' ).slice( 0, - 1 ).join( '/' ) + '/app.json';
  1289. button.style.cssText = 'position: absolute; bottom: 20px; right: 20px; padding: 7px 10px 6px 10px; color: #fff; border: 1px solid #fff; text-decoration: none;';
  1290. button.target = '_blank';
  1291. button.textContent = 'EDIT';
  1292. document.body.appendChild( button );
  1293. `;
  1294. }
  1295. content = content.replace( '/* edit button */', editButton );
  1296. zip.file( 'index.html', content );
  1297. } );
  1298. loader.load( 'js/libs/app.js', function ( content ) {
  1299. zip.file( 'js/app.js', content );
  1300. } );
  1301. loader.load( '../build/three.min.js', function ( content ) {
  1302. zip.file( 'js/three.min.js', content );
  1303. } );
  1304. if ( vr ) {
  1305. loader.load( '../examples/js/vr/WebVR.js', function ( content ) {
  1306. zip.file( 'js/WebVR.js', content );
  1307. } );
  1308. }
  1309. } );
  1310. options.add( option );
  1311. /*
  1312. // Publish (Dropbox)
  1313. var option = new UI.Row();
  1314. option.setClass( 'option' );
  1315. option.setTextContent( 'Publish (Dropbox)' );
  1316. option.onClick( function () {
  1317. var parameters = {
  1318. files: [
  1319. { 'url': 'data:text/plain;base64,' + window.btoa( "Hello, World" ), 'filename': 'app/test.txt' }
  1320. ]
  1321. };
  1322. Dropbox.save( parameters );
  1323. } );
  1324. options.add( option );
  1325. */
  1326. //
  1327. var link = document.createElement( 'a' );
  1328. link.style.display = 'none';
  1329. document.body.appendChild( link ); // Firefox workaround, see #6594
  1330. function save( blob, filename ) {
  1331. link.href = URL.createObjectURL( blob );
  1332. link.download = filename || 'data.json';
  1333. link.click();
  1334. // URL.revokeObjectURL( url ); breaks Firefox...
  1335. }
  1336. function saveString( text, filename ) {
  1337. save( new Blob( [ text ], { type: 'text/plain' } ), filename );
  1338. }
  1339. return container;
  1340. };
  1341. /**
  1342. * @author TristanVALCKE / https://github.com/Itee
  1343. */
  1344. /* global QUnit */
  1345. QUnit.module( 'Editor', () => {
  1346. QUnit.module.todo( 'Menubar.File', () => {
  1347. QUnit.test( 'write me !', ( assert ) => {
  1348. assert.ok( false, "everything's gonna be alright" );
  1349. } );
  1350. } );
  1351. } );
  1352. /**
  1353. * @author mrdoob / http://mrdoob.com/
  1354. */
  1355. Menubar.Help = function ( editor ) {
  1356. var container = new UI.Panel();
  1357. container.setClass( 'menu' );
  1358. var title = new UI.Panel();
  1359. title.setClass( 'title' );
  1360. title.setTextContent( 'Help' );
  1361. container.add( title );
  1362. var options = new UI.Panel();
  1363. options.setClass( 'options' );
  1364. container.add( options );
  1365. // Source code
  1366. var option = new UI.Row();
  1367. option.setClass( 'option' );
  1368. option.setTextContent( 'Source code' );
  1369. option.onClick( function () {
  1370. window.open( 'https://github.com/mrdoob/three.js/tree/master/editor', '_blank' );
  1371. } );
  1372. options.add( option );
  1373. // About
  1374. var option = new UI.Row();
  1375. option.setClass( 'option' );
  1376. option.setTextContent( 'About' );
  1377. option.onClick( function () {
  1378. window.open( 'http://threejs.org', '_blank' );
  1379. } );
  1380. options.add( option );
  1381. return container;
  1382. };
  1383. /**
  1384. * @author TristanVALCKE / https://github.com/Itee
  1385. */
  1386. /* global QUnit */
  1387. QUnit.module( 'Editor', () => {
  1388. QUnit.module.todo( 'Menubar.Help', () => {
  1389. QUnit.test( 'write me !', ( assert ) => {
  1390. assert.ok( false, "everything's gonna be alright" );
  1391. } );
  1392. } );
  1393. } );
  1394. /**
  1395. * @author mrdoob / http://mrdoob.com/
  1396. */
  1397. Menubar.Play = function ( editor ) {
  1398. var signals = editor.signals;
  1399. var container = new UI.Panel();
  1400. container.setClass( 'menu' );
  1401. var isPlaying = false;
  1402. var title = new UI.Panel();
  1403. title.setClass( 'title' );
  1404. title.setTextContent( 'Play' );
  1405. title.onClick( function () {
  1406. if ( isPlaying === false ) {
  1407. isPlaying = true;
  1408. title.setTextContent( 'Stop' );
  1409. signals.startPlayer.dispatch();
  1410. } else {
  1411. isPlaying = false;
  1412. title.setTextContent( 'Play' );
  1413. signals.stopPlayer.dispatch();
  1414. }
  1415. } );
  1416. container.add( title );
  1417. return container;
  1418. };
  1419. /**
  1420. * @author TristanVALCKE / https://github.com/Itee
  1421. */
  1422. /* global QUnit */
  1423. QUnit.module( 'Editor', () => {
  1424. QUnit.module.todo( 'Menubar.Play', () => {
  1425. QUnit.test( 'write me !', ( assert ) => {
  1426. assert.ok( false, "everything's gonna be alright" );
  1427. } );
  1428. } );
  1429. } );
  1430. /**
  1431. * @author mrdoob / http://mrdoob.com/
  1432. */
  1433. Menubar.Status = function ( editor ) {
  1434. var container = new UI.Panel();
  1435. container.setClass( 'menu right' );
  1436. var autosave = new UI.THREE.Boolean( editor.config.getKey( 'autosave' ), 'autosave' );
  1437. autosave.text.setColor( '#888' );
  1438. autosave.onChange( function () {
  1439. var value = this.getValue();
  1440. editor.config.setKey( 'autosave', value );
  1441. if ( value === true ) {
  1442. editor.signals.sceneGraphChanged.dispatch();
  1443. }
  1444. } );
  1445. container.add( autosave );
  1446. editor.signals.savingStarted.add( function () {
  1447. autosave.text.setTextDecoration( 'underline' );
  1448. } );
  1449. editor.signals.savingFinished.add( function () {
  1450. autosave.text.setTextDecoration( 'none' );
  1451. } );
  1452. var version = new UI.Text( 'r' + THREE.REVISION );
  1453. version.setClass( 'title' );
  1454. version.setOpacity( 0.5 );
  1455. container.add( version );
  1456. return container;
  1457. };
  1458. /**
  1459. * @author TristanVALCKE / https://github.com/Itee
  1460. */
  1461. /* global QUnit */
  1462. QUnit.module( 'Editor', () => {
  1463. QUnit.module.todo( 'Menubar.Status', () => {
  1464. QUnit.test( 'write me !', ( assert ) => {
  1465. assert.ok( false, "everything's gonna be alright" );
  1466. } );
  1467. } );
  1468. } );
  1469. /**
  1470. * @author mrdoob / http://mrdoob.com/
  1471. */
  1472. Menubar.View = function ( editor ) {
  1473. var container = new UI.Panel();
  1474. container.setClass( 'menu' );
  1475. var title = new UI.Panel();
  1476. title.setClass( 'title' );
  1477. title.setTextContent( 'View' );
  1478. container.add( title );
  1479. var options = new UI.Panel();
  1480. options.setClass( 'options' );
  1481. container.add( options );
  1482. // VR mode
  1483. var option = new UI.Row();
  1484. option.setClass( 'option' );
  1485. option.setTextContent( 'VR mode' );
  1486. option.onClick( function () {
  1487. if ( WEBVR.isAvailable() === true ) {
  1488. editor.signals.enterVR.dispatch();
  1489. } else {
  1490. alert( 'WebVR not available' );
  1491. }
  1492. } );
  1493. options.add( option );
  1494. return container;
  1495. };
  1496. /**
  1497. * @author TristanVALCKE / https://github.com/Itee
  1498. */
  1499. /* global QUnit */
  1500. QUnit.module( 'Editor', () => {
  1501. QUnit.module.todo( 'Menubar.View', () => {
  1502. QUnit.test( 'write me !', ( assert ) => {
  1503. assert.ok( false, "everything's gonna be alright" );
  1504. } );
  1505. } );
  1506. } );
  1507. /**
  1508. * @author mrdoob / http://mrdoob.com/
  1509. */
  1510. /**
  1511. * @author TristanVALCKE / https://github.com/Itee
  1512. */
  1513. /* global QUnit */
  1514. QUnit.module( 'Editor', () => {
  1515. QUnit.module.todo( 'Sidebar', () => {
  1516. QUnit.test( 'write me !', ( assert ) => {
  1517. assert.ok( false, "everything's gonna be alright" );
  1518. } );
  1519. } );
  1520. } );
  1521. /**
  1522. * @author mrdoob / http://mrdoob.com/
  1523. */
  1524. Sidebar.Animation = function ( editor ) {
  1525. var signals = editor.signals;
  1526. var options = {};
  1527. var possibleAnimations = {};
  1528. var container = new UI.Panel();
  1529. container.setDisplay( 'none' );
  1530. container.add( new UI.Text( 'Animation' ).setTextTransform( 'uppercase' ) );
  1531. container.add( new UI.Break() );
  1532. container.add( new UI.Break() );
  1533. var animationsRow = new UI.Row();
  1534. container.add( animationsRow );
  1535. return container;
  1536. };
  1537. /**
  1538. * @author TristanVALCKE / https://github.com/Itee
  1539. */
  1540. /* global QUnit */
  1541. QUnit.module( 'Editor', () => {
  1542. QUnit.module.todo( 'Sidebar.Animation', () => {
  1543. QUnit.test( 'write me !', ( assert ) => {
  1544. assert.ok( false, "everything's gonna be alright" );
  1545. } );
  1546. } );
  1547. } );
  1548. /**
  1549. * @author mrdoob / http://mrdoob.com/
  1550. */
  1551. Sidebar.Geometry = function ( editor ) {
  1552. var signals = editor.signals;
  1553. var container = new UI.Panel();
  1554. container.setBorderTop( '0' );
  1555. container.setPaddingTop( '20px' );
  1556. // Actions
  1557. /*
  1558. var objectActions = new UI.Select().setPosition( 'absolute' ).setRight( '8px' ).setFontSize( '11px' );
  1559. objectActions.setOptions( {
  1560. 'Actions': 'Actions',
  1561. 'Center': 'Center',
  1562. 'Convert': 'Convert',
  1563. 'Flatten': 'Flatten'
  1564. } );
  1565. objectActions.onClick( function ( event ) {
  1566. event.stopPropagation(); // Avoid panel collapsing
  1567. } );
  1568. objectActions.onChange( function ( event ) {
  1569. var action = this.getValue();
  1570. var object = editor.selected;
  1571. var geometry = object.geometry;
  1572. if ( confirm( action + ' ' + object.name + '?' ) === false ) return;
  1573. switch ( action ) {
  1574. case 'Center':
  1575. var offset = geometry.center();
  1576. var newPosition = object.position.clone();
  1577. newPosition.sub( offset );
  1578. editor.execute( new SetPositionCommand( object, newPosition ) );
  1579. editor.signals.geometryChanged.dispatch( object );
  1580. break;
  1581. case 'Convert':
  1582. if ( geometry instanceof THREE.Geometry ) {
  1583. editor.execute( new SetGeometryCommand( object, new THREE.BufferGeometry().fromGeometry( geometry ) ) );
  1584. }
  1585. break;
  1586. case 'Flatten':
  1587. var newGeometry = geometry.clone();
  1588. newGeometry.uuid = geometry.uuid;
  1589. newGeometry.applyMatrix( object.matrix );
  1590. var cmds = [ new SetGeometryCommand( object, newGeometry ),
  1591. new SetPositionCommand( object, new THREE.Vector3( 0, 0, 0 ) ),
  1592. new SetRotationCommand( object, new THREE.Euler( 0, 0, 0 ) ),
  1593. new SetScaleCommand( object, new THREE.Vector3( 1, 1, 1 ) ) ];
  1594. editor.execute( new MultiCmdsCommand( cmds ), 'Flatten Geometry' );
  1595. break;
  1596. }
  1597. this.setValue( 'Actions' );
  1598. } );
  1599. container.addStatic( objectActions );
  1600. */
  1601. // type
  1602. var geometryTypeRow = new UI.Row();
  1603. var geometryType = new UI.Text();
  1604. geometryTypeRow.add( new UI.Text( 'Type' ).setWidth( '90px' ) );
  1605. geometryTypeRow.add( geometryType );
  1606. container.add( geometryTypeRow );
  1607. // uuid
  1608. var geometryUUIDRow = new UI.Row();
  1609. var geometryUUID = new UI.Input().setWidth( '102px' ).setFontSize( '12px' ).setDisabled( true );
  1610. var geometryUUIDRenew = new UI.Button( 'New' ).setMarginLeft( '7px' ).onClick( function () {
  1611. geometryUUID.setValue( THREE.Math.generateUUID() );
  1612. editor.execute( new SetGeometryValueCommand( editor.selected, 'uuid', geometryUUID.getValue() ) );
  1613. } );
  1614. geometryUUIDRow.add( new UI.Text( 'UUID' ).setWidth( '90px' ) );
  1615. geometryUUIDRow.add( geometryUUID );
  1616. geometryUUIDRow.add( geometryUUIDRenew );
  1617. container.add( geometryUUIDRow );
  1618. // name
  1619. var geometryNameRow = new UI.Row();
  1620. var geometryName = new UI.Input().setWidth( '150px' ).setFontSize( '12px' ).onChange( function () {
  1621. editor.execute( new SetGeometryValueCommand( editor.selected, 'name', geometryName.getValue() ) );
  1622. } );
  1623. geometryNameRow.add( new UI.Text( 'Name' ).setWidth( '90px' ) );
  1624. geometryNameRow.add( geometryName );
  1625. container.add( geometryNameRow );
  1626. // geometry
  1627. container.add( new Sidebar.Geometry.Geometry( editor ) );
  1628. // buffergeometry
  1629. container.add( new Sidebar.Geometry.BufferGeometry( editor ) );
  1630. // parameters
  1631. var parameters = new UI.Span();
  1632. container.add( parameters );
  1633. //
  1634. function build() {
  1635. var object = editor.selected;
  1636. if ( object && object.geometry ) {
  1637. var geometry = object.geometry;
  1638. container.setDisplay( 'block' );
  1639. geometryType.setValue( geometry.type );
  1640. geometryUUID.setValue( geometry.uuid );
  1641. geometryName.setValue( geometry.name );
  1642. //
  1643. parameters.clear();
  1644. if ( geometry.type === 'BufferGeometry' || geometry.type === 'Geometry' ) {
  1645. parameters.add( new Sidebar.Geometry.Modifiers( editor, object ) );
  1646. } else if ( Sidebar.Geometry[ geometry.type ] !== undefined ) {
  1647. parameters.add( new Sidebar.Geometry[ geometry.type ]( editor, object ) );
  1648. }
  1649. } else {
  1650. container.setDisplay( 'none' );
  1651. }
  1652. }
  1653. signals.objectSelected.add( build );
  1654. signals.geometryChanged.add( build );
  1655. return container;
  1656. };
  1657. /**
  1658. * @author TristanVALCKE / https://github.com/Itee
  1659. */
  1660. /* global QUnit */
  1661. QUnit.module( 'Editor', () => {
  1662. QUnit.module.todo( 'Sidebar.Geometry', () => {
  1663. QUnit.test( 'write me !', ( assert ) => {
  1664. assert.ok( false, "everything's gonna be alright" );
  1665. } );
  1666. } );
  1667. } );
  1668. /**
  1669. * @author mrdoob / http://mrdoob.com/
  1670. */
  1671. Sidebar.Geometry.BoxGeometry = function ( editor, object ) {
  1672. var signals = editor.signals;
  1673. var container = new UI.Row();
  1674. var geometry = object.geometry;
  1675. var parameters = geometry.parameters;
  1676. // width
  1677. var widthRow = new UI.Row();
  1678. var width = new UI.Number( parameters.width ).onChange( update );
  1679. widthRow.add( new UI.Text( 'Width' ).setWidth( '90px' ) );
  1680. widthRow.add( width );
  1681. container.add( widthRow );
  1682. // height
  1683. var heightRow = new UI.Row();
  1684. var height = new UI.Number( parameters.height ).onChange( update );
  1685. heightRow.add( new UI.Text( 'Height' ).setWidth( '90px' ) );
  1686. heightRow.add( height );
  1687. container.add( heightRow );
  1688. // depth
  1689. var depthRow = new UI.Row();
  1690. var depth = new UI.Number( parameters.depth ).onChange( update );
  1691. depthRow.add( new UI.Text( 'Depth' ).setWidth( '90px' ) );
  1692. depthRow.add( depth );
  1693. container.add( depthRow );
  1694. // widthSegments
  1695. var widthSegmentsRow = new UI.Row();
  1696. var widthSegments = new UI.Integer( parameters.widthSegments ).setRange( 1, Infinity ).onChange( update );
  1697. widthSegmentsRow.add( new UI.Text( 'Width segments' ).setWidth( '90px' ) );
  1698. widthSegmentsRow.add( widthSegments );
  1699. container.add( widthSegmentsRow );
  1700. // heightSegments
  1701. var heightSegmentsRow = new UI.Row();
  1702. var heightSegments = new UI.Integer( parameters.heightSegments ).setRange( 1, Infinity ).onChange( update );
  1703. heightSegmentsRow.add( new UI.Text( 'Height segments' ).setWidth( '90px' ) );
  1704. heightSegmentsRow.add( heightSegments );
  1705. container.add( heightSegmentsRow );
  1706. // depthSegments
  1707. var depthSegmentsRow = new UI.Row();
  1708. var depthSegments = new UI.Integer( parameters.depthSegments ).setRange( 1, Infinity ).onChange( update );
  1709. depthSegmentsRow.add( new UI.Text( 'Depth segments' ).setWidth( '90px' ) );
  1710. depthSegmentsRow.add( depthSegments );
  1711. container.add( depthSegmentsRow );
  1712. //
  1713. function update() {
  1714. editor.execute( new SetGeometryCommand( object, new THREE[ geometry.type ](
  1715. width.getValue(),
  1716. height.getValue(),
  1717. depth.getValue(),
  1718. widthSegments.getValue(),
  1719. heightSegments.getValue(),
  1720. depthSegments.getValue()
  1721. ) ) );
  1722. }
  1723. return container;
  1724. };
  1725. Sidebar.Geometry.BoxBufferGeometry = Sidebar.Geometry.BoxGeometry;
  1726. /**
  1727. * @author TristanVALCKE / https://github.com/Itee
  1728. */
  1729. /* global QUnit */
  1730. QUnit.module( 'Editor', () => {
  1731. QUnit.module.todo( 'Sidebar.Geometry.BoxGeometry', () => {
  1732. QUnit.test( 'write me !', ( assert ) => {
  1733. assert.ok( false, "everything's gonna be alright" );
  1734. } );
  1735. } );
  1736. } );
  1737. /**
  1738. * @author mrdoob / http://mrdoob.com/
  1739. */
  1740. Sidebar.Geometry.BufferGeometry = function ( editor ) {
  1741. var signals = editor.signals;
  1742. var container = new UI.Row();
  1743. function update( object ) {
  1744. if ( object === null ) return; // objectSelected.dispatch( null )
  1745. if ( object === undefined ) return;
  1746. var geometry = object.geometry;
  1747. if ( geometry instanceof THREE.BufferGeometry ) {
  1748. container.clear();
  1749. container.setDisplay( 'block' );
  1750. var index = geometry.index;
  1751. if ( index !== null ) {
  1752. var panel = new UI.Row();
  1753. panel.add( new UI.Text( 'index' ).setWidth( '90px' ) );
  1754. panel.add( new UI.Text( ( index.count ).format() ).setFontSize( '12px' ) );
  1755. container.add( panel );
  1756. }
  1757. var attributes = geometry.attributes;
  1758. for ( var name in attributes ) {
  1759. var attribute = attributes[ name ];
  1760. var panel = new UI.Row();
  1761. panel.add( new UI.Text( name ).setWidth( '90px' ) );
  1762. panel.add( new UI.Text( ( attribute.count ).format() + ' (' + attribute.itemSize + ')' ).setFontSize( '12px' ) );
  1763. container.add( panel );
  1764. }
  1765. } else {
  1766. container.setDisplay( 'none' );
  1767. }
  1768. }
  1769. signals.objectSelected.add( update );
  1770. signals.geometryChanged.add( update );
  1771. return container;
  1772. };
  1773. /**
  1774. * @author TristanVALCKE / https://github.com/Itee
  1775. */
  1776. /* global QUnit */
  1777. QUnit.module( 'Editor', () => {
  1778. QUnit.module.todo( 'Sidebar.Geometry.BufferGeometry', () => {
  1779. QUnit.test( 'write me !', ( assert ) => {
  1780. assert.ok( false, "everything's gonna be alright" );
  1781. } );
  1782. } );
  1783. } );
  1784. /**
  1785. * @author mrdoob / http://mrdoob.com/
  1786. */
  1787. Sidebar.Geometry.CircleGeometry = function ( editor, object ) {
  1788. var signals = editor.signals;
  1789. var container = new UI.Row();
  1790. var geometry = object.geometry;
  1791. var parameters = geometry.parameters;
  1792. // radius
  1793. var radiusRow = new UI.Row();
  1794. var radius = new UI.Number( parameters.radius ).onChange( update );
  1795. radiusRow.add( new UI.Text( 'Radius' ).setWidth( '90px' ) );
  1796. radiusRow.add( radius );
  1797. container.add( radiusRow );
  1798. // segments
  1799. var segmentsRow = new UI.Row();
  1800. var segments = new UI.Integer( parameters.segments ).setRange( 3, Infinity ).onChange( update );
  1801. segmentsRow.add( new UI.Text( 'Segments' ).setWidth( '90px' ) );
  1802. segmentsRow.add( segments );
  1803. container.add( segmentsRow );
  1804. // thetaStart
  1805. var thetaStartRow = new UI.Row();
  1806. var thetaStart = new UI.Number( parameters.thetaStart ).onChange( update );
  1807. thetaStartRow.add( new UI.Text( 'Theta start' ).setWidth( '90px' ) );
  1808. thetaStartRow.add( thetaStart );
  1809. container.add( thetaStartRow );
  1810. // thetaLength
  1811. var thetaLengthRow = new UI.Row();
  1812. var thetaLength = new UI.Number( parameters.thetaLength ).onChange( update );
  1813. thetaLengthRow.add( new UI.Text( 'Theta length' ).setWidth( '90px' ) );
  1814. thetaLengthRow.add( thetaLength );
  1815. container.add( thetaLengthRow );
  1816. //
  1817. function update() {
  1818. editor.execute( new SetGeometryCommand( object, new THREE[ geometry.type ](
  1819. radius.getValue(),
  1820. segments.getValue(),
  1821. thetaStart.getValue(),
  1822. thetaLength.getValue()
  1823. ) ) );
  1824. }
  1825. return container;
  1826. };
  1827. Sidebar.Geometry.CircleBufferGeometry = Sidebar.Geometry.CircleGeometry;
  1828. /**
  1829. * @author TristanVALCKE / https://github.com/Itee
  1830. */
  1831. /* global QUnit */
  1832. QUnit.module( 'Editor', () => {
  1833. QUnit.module.todo( 'Sidebar.Geometry.CircleGeometry', () => {
  1834. QUnit.test( 'write me !', ( assert ) => {
  1835. assert.ok( false, "everything's gonna be alright" );
  1836. } );
  1837. } );
  1838. } );
  1839. /**
  1840. * @author mrdoob / http://mrdoob.com/
  1841. */
  1842. Sidebar.Geometry.CylinderGeometry = function ( editor, object ) {
  1843. var signals = editor.signals;
  1844. var container = new UI.Row();
  1845. var geometry = object.geometry;
  1846. var parameters = geometry.parameters;
  1847. // radiusTop
  1848. var radiusTopRow = new UI.Row();
  1849. var radiusTop = new UI.Number( parameters.radiusTop ).onChange( update );
  1850. radiusTopRow.add( new UI.Text( 'Radius top' ).setWidth( '90px' ) );
  1851. radiusTopRow.add( radiusTop );
  1852. container.add( radiusTopRow );
  1853. // radiusBottom
  1854. var radiusBottomRow = new UI.Row();
  1855. var radiusBottom = new UI.Number( parameters.radiusBottom ).onChange( update );
  1856. radiusBottomRow.add( new UI.Text( 'Radius bottom' ).setWidth( '90px' ) );
  1857. radiusBottomRow.add( radiusBottom );
  1858. container.add( radiusBottomRow );
  1859. // height
  1860. var heightRow = new UI.Row();
  1861. var height = new UI.Number( parameters.height ).onChange( update );
  1862. heightRow.add( new UI.Text( 'Height' ).setWidth( '90px' ) );
  1863. heightRow.add( height );
  1864. container.add( heightRow );
  1865. // radialSegments
  1866. var radialSegmentsRow = new UI.Row();
  1867. var radialSegments = new UI.Integer( parameters.radialSegments ).setRange( 1, Infinity ).onChange( update );
  1868. radialSegmentsRow.add( new UI.Text( 'Radial segments' ).setWidth( '90px' ) );
  1869. radialSegmentsRow.add( radialSegments );
  1870. container.add( radialSegmentsRow );
  1871. // heightSegments
  1872. var heightSegmentsRow = new UI.Row();
  1873. var heightSegments = new UI.Integer( parameters.heightSegments ).setRange( 1, Infinity ).onChange( update );
  1874. heightSegmentsRow.add( new UI.Text( 'Height segments' ).setWidth( '90px' ) );
  1875. heightSegmentsRow.add( heightSegments );
  1876. container.add( heightSegmentsRow );
  1877. // openEnded
  1878. var openEndedRow = new UI.Row();
  1879. var openEnded = new UI.Checkbox( parameters.openEnded ).onChange( update );
  1880. openEndedRow.add( new UI.Text( 'Open ended' ).setWidth( '90px' ) );
  1881. openEndedRow.add( openEnded );
  1882. container.add( openEndedRow );
  1883. //
  1884. function update() {
  1885. editor.execute( new SetGeometryCommand( object, new THREE[ geometry.type ](
  1886. radiusTop.getValue(),
  1887. radiusBottom.getValue(),
  1888. height.getValue(),
  1889. radialSegments.getValue(),
  1890. heightSegments.getValue(),
  1891. openEnded.getValue()
  1892. ) ) );
  1893. }
  1894. return container;
  1895. };
  1896. Sidebar.Geometry.CylinderBufferGeometry = Sidebar.Geometry.CylinderGeometry;
  1897. /**
  1898. * @author TristanVALCKE / https://github.com/Itee
  1899. */
  1900. /* global QUnit */
  1901. QUnit.module( 'Editor', () => {
  1902. QUnit.module.todo( 'Sidebar.Geometry.CylinderGeometry', () => {
  1903. QUnit.test( 'write me !', ( assert ) => {
  1904. assert.ok( false, "everything's gonna be alright" );
  1905. } );
  1906. } );
  1907. } );
  1908. /**
  1909. * @author TristanVALCKE / https://github.com/Itee
  1910. */
  1911. /* global QUnit */
  1912. QUnit.module( 'Editor', () => {
  1913. QUnit.module.todo( 'Sidebar.Geometry', () => {
  1914. QUnit.test( 'write me !', ( assert ) => {
  1915. assert.ok( false, "everything's gonna be alright" );
  1916. } );
  1917. } );
  1918. } );
  1919. /**
  1920. * @author mrdoob / http://mrdoob.com/
  1921. */
  1922. Sidebar.Geometry.IcosahedronGeometry = function ( editor, object ) {
  1923. var signals = editor.signals;
  1924. var container = new UI.Row();
  1925. var geometry = object.geometry;
  1926. var parameters = geometry.parameters;
  1927. // radius
  1928. var radiusRow = new UI.Row();
  1929. var radius = new UI.Number( parameters.radius ).onChange( update );
  1930. radiusRow.add( new UI.Text( 'Radius' ).setWidth( '90px' ) );
  1931. radiusRow.add( radius );
  1932. container.add( radiusRow );
  1933. // detail
  1934. var detailRow = new UI.Row();
  1935. var detail = new UI.Integer( parameters.detail ).setRange( 0, Infinity ).onChange( update );
  1936. detailRow.add( new UI.Text( 'Detail' ).setWidth( '90px' ) );
  1937. detailRow.add( detail );
  1938. container.add( detailRow );
  1939. //
  1940. function update() {
  1941. editor.execute( new SetGeometryCommand( object, new THREE[ geometry.type ](
  1942. radius.getValue(),
  1943. detail.getValue()
  1944. ) ) );
  1945. signals.objectChanged.dispatch( object );
  1946. }
  1947. return container;
  1948. };
  1949. Sidebar.Geometry.IcosahedronBufferGeometry = Sidebar.Geometry.IcosahedronGeometry;
  1950. /**
  1951. * @author TristanVALCKE / https://github.com/Itee
  1952. */
  1953. /* global QUnit */
  1954. QUnit.module( 'Editor', () => {
  1955. QUnit.module.todo( 'Sidebar.Geometry.IcosahedronGeometry', () => {
  1956. QUnit.test( 'write me !', ( assert ) => {
  1957. assert.ok( false, "everything's gonna be alright" );
  1958. } );
  1959. } );
  1960. } );
  1961. /**
  1962. * @author rfm1201
  1963. */
  1964. Sidebar.Geometry.LatheGeometry = function( editor, object ) {
  1965. var signals = editor.signals;
  1966. var container = new UI.Row();
  1967. var geometry = object.geometry;
  1968. var parameters = geometry.parameters;
  1969. // segments
  1970. var segmentsRow = new UI.Row();
  1971. var segments = new UI.Integer( parameters.segments ).onChange( update );
  1972. segmentsRow.add( new UI.Text( 'Segments' ).setWidth( '90px' ) );
  1973. segmentsRow.add( segments );
  1974. container.add( segmentsRow );
  1975. // phiStart
  1976. var phiStartRow = new UI.Row();
  1977. var phiStart = new UI.Number( parameters.phiStart * 180 / Math.PI ).onChange( update );
  1978. phiStartRow.add( new UI.Text( 'Phi start (°)' ).setWidth( '90px' ) );
  1979. phiStartRow.add( phiStart );
  1980. container.add( phiStartRow );
  1981. // phiLength
  1982. var phiLengthRow = new UI.Row();
  1983. var phiLength = new UI.Number( parameters.phiLength * 180 / Math.PI ).onChange( update );
  1984. phiLengthRow.add( new UI.Text( 'Phi length (°)' ).setWidth( '90px' ) );
  1985. phiLengthRow.add( phiLength );
  1986. container.add( phiLengthRow );
  1987. // points
  1988. var lastPointIdx = 0;
  1989. var pointsUI = [];
  1990. var pointsRow = new UI.Row();
  1991. pointsRow.add( new UI.Text( 'Points' ).setWidth( '90px' ) );
  1992. var points = new UI.Span().setDisplay( 'inline-block' );
  1993. pointsRow.add( points );
  1994. var pointsList = new UI.Div();
  1995. points.add( pointsList );
  1996. for ( var i = 0; i < parameters.points.length; i ++ ) {
  1997. var point = parameters.points[ i ];
  1998. pointsList.add( createPointRow( point.x, point.y ) );
  1999. }
  2000. var addPointButton = new UI.Button( '+' ).onClick( function() {
  2001. if( pointsUI.length === 0 ){
  2002. pointsList.add( createPointRow( 0, 0 ) );
  2003. } else {
  2004. var point = pointsUI[ pointsUI.length - 1 ];
  2005. pointsList.add( createPointRow( point.x.getValue(), point.y.getValue() ) );
  2006. }
  2007. update();
  2008. } );
  2009. points.add( addPointButton );
  2010. container.add( pointsRow );
  2011. //
  2012. function createPointRow( x, y ) {
  2013. var pointRow = new UI.Div();
  2014. var lbl = new UI.Text( lastPointIdx + 1 ).setWidth( '20px' );
  2015. var txtX = new UI.Number( x ).setRange( 0, Infinity ).setWidth( '40px' ).onChange( update );
  2016. var txtY = new UI.Number( y ).setWidth( '40px' ).onChange( update );
  2017. var idx = lastPointIdx;
  2018. var btn = new UI.Button( '-' ).onClick( function() {
  2019. deletePointRow( idx );
  2020. } );
  2021. pointsUI.push( { row: pointRow, lbl: lbl, x: txtX, y: txtY } );
  2022. lastPointIdx ++;
  2023. pointRow.add( lbl, txtX, txtY, btn );
  2024. return pointRow;
  2025. }
  2026. function deletePointRow( idx ) {
  2027. if ( ! pointsUI[ idx ] ) return;
  2028. pointsList.remove( pointsUI[ idx ].row );
  2029. pointsUI[ idx ] = null;
  2030. update();
  2031. }
  2032. function update() {
  2033. var points = [];
  2034. var count = 0;
  2035. for ( var i = 0; i < pointsUI.length; i ++ ) {
  2036. var pointUI = pointsUI[ i ];
  2037. if ( ! pointUI ) continue;
  2038. points.push( new THREE.Vector2( pointUI.x.getValue(), pointUI.y.getValue() ) );
  2039. count ++;
  2040. pointUI.lbl.setValue( count );
  2041. }
  2042. editor.execute( new SetGeometryCommand( object, new THREE[ geometry.type ](
  2043. points,
  2044. segments.getValue(),
  2045. phiStart.getValue() / 180 * Math.PI,
  2046. phiLength.getValue() / 180 * Math.PI
  2047. ) ) );
  2048. }
  2049. return container;
  2050. };
  2051. Sidebar.Geometry.LatheBufferGeometry = Sidebar.Geometry.LatheGeometry;
  2052. /**
  2053. * @author TristanVALCKE / https://github.com/Itee
  2054. */
  2055. /* global QUnit */
  2056. QUnit.module( 'Editor', () => {
  2057. QUnit.module.todo( 'Sidebar.Geometry.LatheGeometry', () => {
  2058. QUnit.test( 'write me !', ( assert ) => {
  2059. assert.ok( false, "everything's gonna be alright" );
  2060. } );
  2061. } );
  2062. } );
  2063. /**
  2064. * @author mrdoob / http://mrdoob.com/
  2065. */
  2066. Sidebar.Geometry.Modifiers = function ( editor, object ) {
  2067. var signals = editor.signals;
  2068. var container = new UI.Row().setPaddingLeft( '90px' );
  2069. var geometry = object.geometry;
  2070. // Compute Vertex Normals
  2071. var button = new UI.Button( 'Compute Vertex Normals' );
  2072. button.onClick( function () {
  2073. geometry.computeVertexNormals();
  2074. if ( geometry instanceof THREE.BufferGeometry ) {
  2075. geometry.attributes.normal.needsUpdate = true;
  2076. } else {
  2077. geometry.normalsNeedUpdate = true;
  2078. }
  2079. signals.geometryChanged.dispatch( object );
  2080. } );
  2081. container.add( button );
  2082. //
  2083. return container;
  2084. };
  2085. /**
  2086. * @author TristanVALCKE / https://github.com/Itee
  2087. */
  2088. /* global QUnit */
  2089. QUnit.module( 'Editor', () => {
  2090. QUnit.module.todo( 'Sidebar.Geometry.Modifiers', () => {
  2091. QUnit.test( 'write me !', ( assert ) => {
  2092. assert.ok( false, "everything's gonna be alright" );
  2093. } );
  2094. } );
  2095. } );
  2096. /**
  2097. * @author mrdoob / http://mrdoob.com/
  2098. */
  2099. Sidebar.Geometry.PlaneGeometry = function ( editor, object ) {
  2100. var signals = editor.signals;
  2101. var container = new UI.Row();
  2102. var geometry = object.geometry;
  2103. var parameters = geometry.parameters;
  2104. // width
  2105. var widthRow = new UI.Row();
  2106. var width = new UI.Number( parameters.width ).onChange( update );
  2107. widthRow.add( new UI.Text( 'Width' ).setWidth( '90px' ) );
  2108. widthRow.add( width );
  2109. container.add( widthRow );
  2110. // height
  2111. var heightRow = new UI.Row();
  2112. var height = new UI.Number( parameters.height ).onChange( update );
  2113. heightRow.add( new UI.Text( 'Height' ).setWidth( '90px' ) );
  2114. heightRow.add( height );
  2115. container.add( heightRow );
  2116. // widthSegments
  2117. var widthSegmentsRow = new UI.Row();
  2118. var widthSegments = new UI.Integer( parameters.widthSegments ).setRange( 1, Infinity ).onChange( update );
  2119. widthSegmentsRow.add( new UI.Text( 'Width segments' ).setWidth( '90px' ) );
  2120. widthSegmentsRow.add( widthSegments );
  2121. container.add( widthSegmentsRow );
  2122. // heightSegments
  2123. var heightSegmentsRow = new UI.Row();
  2124. var heightSegments = new UI.Integer( parameters.heightSegments ).setRange( 1, Infinity ).onChange( update );
  2125. heightSegmentsRow.add( new UI.Text( 'Height segments' ).setWidth( '90px' ) );
  2126. heightSegmentsRow.add( heightSegments );
  2127. container.add( heightSegmentsRow );
  2128. //
  2129. function update() {
  2130. editor.execute( new SetGeometryCommand( object, new THREE[ geometry.type ](
  2131. width.getValue(),
  2132. height.getValue(),
  2133. widthSegments.getValue(),
  2134. heightSegments.getValue()
  2135. ) ) );
  2136. }
  2137. return container;
  2138. };
  2139. Sidebar.Geometry.PlaneBufferGeometry = Sidebar.Geometry.PlaneGeometry;
  2140. /**
  2141. * @author TristanVALCKE / https://github.com/Itee
  2142. */
  2143. /* global QUnit */
  2144. QUnit.module( 'Editor', () => {
  2145. QUnit.module.todo( 'Sidebar.Geometry.PlaneGeometry', () => {
  2146. QUnit.test( 'write me !', ( assert ) => {
  2147. assert.ok( false, "everything's gonna be alright" );
  2148. } );
  2149. } );
  2150. } );
  2151. /**
  2152. * @author mrdoob / http://mrdoob.com/
  2153. */
  2154. Sidebar.Geometry.SphereGeometry = function ( editor, object ) {
  2155. var signals = editor.signals;
  2156. var container = new UI.Row();
  2157. var geometry = object.geometry;
  2158. var parameters = geometry.parameters;
  2159. // radius
  2160. var radiusRow = new UI.Row();
  2161. var radius = new UI.Number( parameters.radius ).onChange( update );
  2162. radiusRow.add( new UI.Text( 'Radius' ).setWidth( '90px' ) );
  2163. radiusRow.add( radius );
  2164. container.add( radiusRow );
  2165. // widthSegments
  2166. var widthSegmentsRow = new UI.Row();
  2167. var widthSegments = new UI.Integer( parameters.widthSegments ).setRange( 1, Infinity ).onChange( update );
  2168. widthSegmentsRow.add( new UI.Text( 'Width segments' ).setWidth( '90px' ) );
  2169. widthSegmentsRow.add( widthSegments );
  2170. container.add( widthSegmentsRow );
  2171. // heightSegments
  2172. var heightSegmentsRow = new UI.Row();
  2173. var heightSegments = new UI.Integer( parameters.heightSegments ).setRange( 1, Infinity ).onChange( update );
  2174. heightSegmentsRow.add( new UI.Text( 'Height segments' ).setWidth( '90px' ) );
  2175. heightSegmentsRow.add( heightSegments );
  2176. container.add( heightSegmentsRow );
  2177. // phiStart
  2178. var phiStartRow = new UI.Row();
  2179. var phiStart = new UI.Number( parameters.phiStart ).onChange( update );
  2180. phiStartRow.add( new UI.Text( 'Phi start' ).setWidth( '90px' ) );
  2181. phiStartRow.add( phiStart );
  2182. container.add( phiStartRow );
  2183. // phiLength
  2184. var phiLengthRow = new UI.Row();
  2185. var phiLength = new UI.Number( parameters.phiLength ).onChange( update );
  2186. phiLengthRow.add( new UI.Text( 'Phi length' ).setWidth( '90px' ) );
  2187. phiLengthRow.add( phiLength );
  2188. container.add( phiLengthRow );
  2189. // thetaStart
  2190. var thetaStartRow = new UI.Row();
  2191. var thetaStart = new UI.Number( parameters.thetaStart ).onChange( update );
  2192. thetaStartRow.add( new UI.Text( 'Theta start' ).setWidth( '90px' ) );
  2193. thetaStartRow.add( thetaStart );
  2194. container.add( thetaStartRow );
  2195. // thetaLength
  2196. var thetaLengthRow = new UI.Row();
  2197. var thetaLength = new UI.Number( parameters.thetaLength ).onChange( update );
  2198. thetaLengthRow.add( new UI.Text( 'Theta length' ).setWidth( '90px' ) );
  2199. thetaLengthRow.add( thetaLength );
  2200. container.add( thetaLengthRow );
  2201. //
  2202. function update() {
  2203. editor.execute( new SetGeometryCommand( object, new THREE[ geometry.type ](
  2204. radius.getValue(),
  2205. widthSegments.getValue(),
  2206. heightSegments.getValue(),
  2207. phiStart.getValue(),
  2208. phiLength.getValue(),
  2209. thetaStart.getValue(),
  2210. thetaLength.getValue()
  2211. ) ) );
  2212. }
  2213. return container;
  2214. };
  2215. Sidebar.Geometry.SphereBufferGeometry = Sidebar.Geometry.SphereGeometry;
  2216. /**
  2217. * @author TristanVALCKE / https://github.com/Itee
  2218. */
  2219. /* global QUnit */
  2220. QUnit.module( 'Editor', () => {
  2221. QUnit.module.todo( 'Sidebar.Geometry.SphereGeometry', () => {
  2222. QUnit.test( 'write me !', ( assert ) => {
  2223. assert.ok( false, "everything's gonna be alright" );
  2224. } );
  2225. } );
  2226. } );
  2227. /**
  2228. * @author tschw
  2229. */
  2230. Sidebar.Geometry.TeapotBufferGeometry = function ( signals, object ) {
  2231. var container = new UI.Row();
  2232. var parameters = object.geometry.parameters;
  2233. // size
  2234. var sizeRow = new UI.Row();
  2235. var size = new UI.Number( parameters.size ).onChange( update );
  2236. sizeRow.add( new UI.Text( 'Size' ).setWidth( '90px' ) );
  2237. sizeRow.add( size );
  2238. container.add( sizeRow );
  2239. // segments
  2240. var segmentsRow = new UI.Row();
  2241. var segments = new UI.Integer( parameters.segments ).setRange( 1, Infinity ).onChange( update );
  2242. segmentsRow.add( new UI.Text( 'Segments' ).setWidth( '90px' ) );
  2243. segmentsRow.add( segments );
  2244. container.add( segmentsRow );
  2245. // bottom
  2246. var bottomRow = new UI.Row();
  2247. var bottom = new UI.Checkbox( parameters.bottom ).onChange( update );
  2248. bottomRow.add( new UI.Text( 'Bottom' ).setWidth( '90px' ) );
  2249. bottomRow.add( bottom );
  2250. container.add( bottomRow );
  2251. // lid
  2252. var lidRow = new UI.Row();
  2253. var lid = new UI.Checkbox( parameters.lid ).onChange( update );
  2254. lidRow.add( new UI.Text( 'Lid' ).setWidth( '90px' ) );
  2255. lidRow.add( lid );
  2256. container.add( lidRow );
  2257. // body
  2258. var bodyRow = new UI.Row();
  2259. var body = new UI.Checkbox( parameters.body ).onChange( update );
  2260. bodyRow.add( new UI.Text( 'Body' ).setWidth( '90px' ) );
  2261. bodyRow.add( body );
  2262. container.add( bodyRow );
  2263. // fitted lid
  2264. var fitLidRow = new UI.Row();
  2265. var fitLid = new UI.Checkbox( parameters.fitLid ).onChange( update );
  2266. fitLidRow.add( new UI.Text( 'Fitted Lid' ).setWidth( '90px' ) );
  2267. fitLidRow.add( fitLid );
  2268. container.add( fitLidRow );
  2269. // blinn-sized
  2270. var blinnRow = new UI.Row();
  2271. var blinn = new UI.Checkbox( parameters.blinn ).onChange( update );
  2272. blinnRow.add( new UI.Text( 'Blinn-scaled' ).setWidth( '90px' ) );
  2273. blinnRow.add( blinn );
  2274. container.add( blinnRow );
  2275. function update() {
  2276. object.geometry.dispose();
  2277. object.geometry = new THREE.TeapotBufferGeometry(
  2278. size.getValue(),
  2279. segments.getValue(),
  2280. bottom.getValue(),
  2281. lid.getValue(),
  2282. body.getValue(),
  2283. fitLid.getValue(),
  2284. blinn.getValue()
  2285. );
  2286. object.geometry.computeBoundingSphere();
  2287. signals.geometryChanged.dispatch( object );
  2288. }
  2289. return container;
  2290. };
  2291. /**
  2292. * @author TristanVALCKE / https://github.com/Itee
  2293. */
  2294. /* global QUnit */
  2295. QUnit.module( 'Editor', () => {
  2296. QUnit.module.todo( 'Sidebar.Geometry.TeapotBufferGeometry', () => {
  2297. QUnit.test( 'write me !', ( assert ) => {
  2298. assert.ok( false, "everything's gonna be alright" );
  2299. } );
  2300. } );
  2301. } );
  2302. /**
  2303. * @author mrdoob / http://mrdoob.com/
  2304. */
  2305. Sidebar.Geometry.TorusGeometry = function ( editor, object ) {
  2306. var signals = editor.signals;
  2307. var container = new UI.Row();
  2308. var geometry = object.geometry;
  2309. var parameters = geometry.parameters;
  2310. // radius
  2311. var radiusRow = new UI.Row();
  2312. var radius = new UI.Number( parameters.radius ).onChange( update );
  2313. radiusRow.add( new UI.Text( 'Radius' ).setWidth( '90px' ) );
  2314. radiusRow.add( radius );
  2315. container.add( radiusRow );
  2316. // tube
  2317. var tubeRow = new UI.Row();
  2318. var tube = new UI.Number( parameters.tube ).onChange( update );
  2319. tubeRow.add( new UI.Text( 'Tube' ).setWidth( '90px' ) );
  2320. tubeRow.add( tube );
  2321. container.add( tubeRow );
  2322. // radialSegments
  2323. var radialSegmentsRow = new UI.Row();
  2324. var radialSegments = new UI.Integer( parameters.radialSegments ).setRange( 1, Infinity ).onChange( update );
  2325. radialSegmentsRow.add( new UI.Text( 'Radial segments' ).setWidth( '90px' ) );
  2326. radialSegmentsRow.add( radialSegments );
  2327. container.add( radialSegmentsRow );
  2328. // tubularSegments
  2329. var tubularSegmentsRow = new UI.Row();
  2330. var tubularSegments = new UI.Integer( parameters.tubularSegments ).setRange( 1, Infinity ).onChange( update );
  2331. tubularSegmentsRow.add( new UI.Text( 'Tubular segments' ).setWidth( '90px' ) );
  2332. tubularSegmentsRow.add( tubularSegments );
  2333. container.add( tubularSegmentsRow );
  2334. // arc
  2335. var arcRow = new UI.Row();
  2336. var arc = new UI.Number( parameters.arc ).onChange( update );
  2337. arcRow.add( new UI.Text( 'Arc' ).setWidth( '90px' ) );
  2338. arcRow.add( arc );
  2339. container.add( arcRow );
  2340. //
  2341. function update() {
  2342. editor.execute( new SetGeometryCommand( object, new THREE[ geometry.type ](
  2343. radius.getValue(),
  2344. tube.getValue(),
  2345. radialSegments.getValue(),
  2346. tubularSegments.getValue(),
  2347. arc.getValue()
  2348. ) ) );
  2349. }
  2350. return container;
  2351. };
  2352. Sidebar.Geometry.TorusBufferGeometry = Sidebar.Geometry.TorusGeometry;
  2353. /**
  2354. * @author TristanVALCKE / https://github.com/Itee
  2355. */
  2356. /* global QUnit */
  2357. QUnit.module( 'Editor', () => {
  2358. QUnit.module.todo( 'Sidebar.Geometry.TorusGeometry', () => {
  2359. QUnit.test( 'write me !', ( assert ) => {
  2360. assert.ok( false, "everything's gonna be alright" );
  2361. } );
  2362. } );
  2363. } );
  2364. /**
  2365. * @author mrdoob / http://mrdoob.com/
  2366. */
  2367. Sidebar.Geometry.TorusKnotGeometry = function ( editor, object ) {
  2368. var signals = editor.signals;
  2369. var container = new UI.Row();
  2370. var geometry = object.geometry;
  2371. var parameters = geometry.parameters;
  2372. // radius
  2373. var radiusRow = new UI.Row();
  2374. var radius = new UI.Number( parameters.radius ).onChange( update );
  2375. radiusRow.add( new UI.Text( 'Radius' ).setWidth( '90px' ) );
  2376. radiusRow.add( radius );
  2377. container.add( radiusRow );
  2378. // tube
  2379. var tubeRow = new UI.Row();
  2380. var tube = new UI.Number( parameters.tube ).onChange( update );
  2381. tubeRow.add( new UI.Text( 'Tube' ).setWidth( '90px' ) );
  2382. tubeRow.add( tube );
  2383. container.add( tubeRow );
  2384. // tubularSegments
  2385. var tubularSegmentsRow = new UI.Row();
  2386. var tubularSegments = new UI.Integer( parameters.tubularSegments ).setRange( 1, Infinity ).onChange( update );
  2387. tubularSegmentsRow.add( new UI.Text( 'Tubular segments' ).setWidth( '90px' ) );
  2388. tubularSegmentsRow.add( tubularSegments );
  2389. container.add( tubularSegmentsRow );
  2390. // radialSegments
  2391. var radialSegmentsRow = new UI.Row();
  2392. var radialSegments = new UI.Integer( parameters.radialSegments ).setRange( 1, Infinity ).onChange( update );
  2393. radialSegmentsRow.add( new UI.Text( 'Radial segments' ).setWidth( '90px' ) );
  2394. radialSegmentsRow.add( radialSegments );
  2395. container.add( radialSegmentsRow );
  2396. // p
  2397. var pRow = new UI.Row();
  2398. var p = new UI.Number( parameters.p ).onChange( update );
  2399. pRow.add( new UI.Text( 'P' ).setWidth( '90px' ) );
  2400. pRow.add( p );
  2401. container.add( pRow );
  2402. // q
  2403. var qRow = new UI.Row();
  2404. var q = new UI.Number( parameters.q ).onChange( update );
  2405. pRow.add( new UI.Text( 'Q' ).setWidth( '90px' ) );
  2406. pRow.add( q );
  2407. container.add( qRow );
  2408. //
  2409. function update() {
  2410. editor.execute( new SetGeometryCommand( object, new THREE[ geometry.type ](
  2411. radius.getValue(),
  2412. tube.getValue(),
  2413. tubularSegments.getValue(),
  2414. radialSegments.getValue(),
  2415. p.getValue(),
  2416. q.getValue()
  2417. ) ) );
  2418. }
  2419. return container;
  2420. };
  2421. Sidebar.Geometry.TorusKnotBufferGeometry = Sidebar.Geometry.TorusKnotGeometry;
  2422. /**
  2423. * @author TristanVALCKE / https://github.com/Itee
  2424. */
  2425. /* global QUnit */
  2426. QUnit.module( 'Editor', () => {
  2427. QUnit.module.todo( 'Sidebar.Geometry.TorusKnotGeometry', () => {
  2428. QUnit.test( 'write me !', ( assert ) => {
  2429. assert.ok( false, "everything's gonna be alright" );
  2430. } );
  2431. } );
  2432. } );
  2433. /**
  2434. * @author dforrer / https://github.com/dforrer
  2435. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  2436. */
  2437. Sidebar.History = function ( editor ) {
  2438. var signals = editor.signals;
  2439. var config = editor.config;
  2440. var history = editor.history;
  2441. var container = new UI.Panel();
  2442. container.add( new UI.Text( 'HISTORY' ) );
  2443. //
  2444. var persistent = new UI.THREE.Boolean( config.getKey( 'settings/history' ), 'persistent' );
  2445. persistent.setPosition( 'absolute' ).setRight( '8px' );
  2446. persistent.onChange( function () {
  2447. var value = this.getValue();
  2448. config.setKey( 'settings/history', value );
  2449. if ( value ) {
  2450. alert( 'The history will be preserved across sessions.\nThis can have an impact on performance when working with textures.' );
  2451. var lastUndoCmd = history.undos[ history.undos.length - 1 ];
  2452. var lastUndoId = ( lastUndoCmd !== undefined ) ? lastUndoCmd.id : 0;
  2453. editor.history.enableSerialization( lastUndoId );
  2454. } else {
  2455. signals.historyChanged.dispatch();
  2456. }
  2457. } );
  2458. container.add( persistent );
  2459. container.add( new UI.Break(), new UI.Break() );
  2460. var ignoreObjectSelectedSignal = false;
  2461. var outliner = new UI.Outliner( editor );
  2462. outliner.onChange( function () {
  2463. ignoreObjectSelectedSignal = true;
  2464. editor.history.goToState( parseInt( outliner.getValue() ) );
  2465. ignoreObjectSelectedSignal = false;
  2466. } );
  2467. container.add( outliner );
  2468. //
  2469. var refreshUI = function () {
  2470. var options = [];
  2471. var enumerator = 1;
  2472. function buildOption( object ) {
  2473. var option = document.createElement( 'div' );
  2474. option.value = object.id;
  2475. return option;
  2476. }
  2477. ( function addObjects( objects ) {
  2478. for ( var i = 0, l = objects.length; i < l; i ++ ) {
  2479. var object = objects[ i ];
  2480. var option = buildOption( object );
  2481. option.innerHTML = '&nbsp;' + object.name;
  2482. options.push( option );
  2483. }
  2484. } )( history.undos );
  2485. ( function addObjects( objects, pad ) {
  2486. for ( var i = objects.length - 1; i >= 0; i -- ) {
  2487. var object = objects[ i ];
  2488. var option = buildOption( object );
  2489. option.innerHTML = '&nbsp;' + object.name;
  2490. option.style.opacity = 0.3;
  2491. options.push( option );
  2492. }
  2493. } )( history.redos, '&nbsp;' );
  2494. outliner.setOptions( options );
  2495. };
  2496. refreshUI();
  2497. // events
  2498. signals.editorCleared.add( refreshUI );
  2499. signals.historyChanged.add( refreshUI );
  2500. signals.historyChanged.add( function ( cmd ) {
  2501. outliner.setValue( cmd !== undefined ? cmd.id : null );
  2502. } );
  2503. return container;
  2504. };
  2505. /**
  2506. * @author TristanVALCKE / https://github.com/Itee
  2507. */
  2508. /* global QUnit */
  2509. QUnit.module( 'Editor', () => {
  2510. QUnit.module.todo( 'Sidebar.History', () => {
  2511. QUnit.test( 'write me !', ( assert ) => {
  2512. assert.ok( false, "everything's gonna be alright" );
  2513. } );
  2514. } );
  2515. } );
  2516. /**
  2517. * @author mrdoob / http://mrdoob.com/
  2518. */
  2519. Sidebar.Material = function ( editor ) {
  2520. var signals = editor.signals;
  2521. var currentObject;
  2522. var currentMaterialSlot = 0;
  2523. var container = new UI.Panel();
  2524. container.setBorderTop( '0' );
  2525. container.setPaddingTop( '20px' );
  2526. // New / Copy / Paste
  2527. var copiedMaterial;
  2528. var managerRow = new UI.Row();
  2529. // Current material slot
  2530. var materialSlotRow = new UI.Row();
  2531. materialSlotRow.add( new UI.Text( 'Slot' ).setWidth( '90px' ) );
  2532. var materialSlotSelect = new UI.Select().setWidth( '170px' ).setFontSize( '12px' ).onChange( update );
  2533. materialSlotSelect.setOptions( { 0: '' } ).setValue( 0 );
  2534. materialSlotRow.add( materialSlotSelect );
  2535. container.add( materialSlotRow );
  2536. managerRow.add( new UI.Text( '' ).setWidth( '90px' ) );
  2537. managerRow.add( new UI.Button( 'New' ).onClick( function () {
  2538. var material = new THREE[ materialClass.getValue() ]();
  2539. editor.execute( new SetMaterialCommand( currentObject, material, currentMaterialSlot ), 'New Material: ' + materialClass.getValue() );
  2540. update();
  2541. } ) );
  2542. managerRow.add( new UI.Button( 'Copy' ).setMarginLeft( '4px' ).onClick( function () {
  2543. copiedMaterial = currentObject.material;
  2544. if ( Array.isArray( copiedMaterial ) ) {
  2545. if ( copiedMaterial.length === 0 ) return;
  2546. copiedMaterial = copiedMaterial[ currentMaterialSlot ];
  2547. }
  2548. } ) );
  2549. managerRow.add( new UI.Button( 'Paste' ).setMarginLeft( '4px' ).onClick( function () {
  2550. if ( copiedMaterial === undefined ) return;
  2551. editor.execute( new SetMaterialCommand( currentObject, copiedMaterial, currentMaterialSlot ), 'Pasted Material: ' + materialClass.getValue() );
  2552. refreshUI();
  2553. update();
  2554. } ) );
  2555. container.add( managerRow );
  2556. // type
  2557. var materialClassRow = new UI.Row();
  2558. var materialClass = new UI.Select().setOptions( {
  2559. 'LineBasicMaterial': 'LineBasicMaterial',
  2560. 'LineDashedMaterial': 'LineDashedMaterial',
  2561. 'MeshBasicMaterial': 'MeshBasicMaterial',
  2562. 'MeshDepthMaterial': 'MeshDepthMaterial',
  2563. 'MeshNormalMaterial': 'MeshNormalMaterial',
  2564. 'MeshLambertMaterial': 'MeshLambertMaterial',
  2565. 'MeshPhongMaterial': 'MeshPhongMaterial',
  2566. 'MeshStandardMaterial': 'MeshStandardMaterial',
  2567. 'MeshPhysicalMaterial': 'MeshPhysicalMaterial',
  2568. 'ShaderMaterial': 'ShaderMaterial',
  2569. 'SpriteMaterial': 'SpriteMaterial'
  2570. } ).setWidth( '150px' ).setFontSize( '12px' ).onChange( update );
  2571. materialClassRow.add( new UI.Text( 'Type' ).setWidth( '90px' ) );
  2572. materialClassRow.add( materialClass );
  2573. container.add( materialClassRow );
  2574. // uuid
  2575. var materialUUIDRow = new UI.Row();
  2576. var materialUUID = new UI.Input().setWidth( '102px' ).setFontSize( '12px' ).setDisabled( true );
  2577. var materialUUIDRenew = new UI.Button( 'New' ).setMarginLeft( '7px' ).onClick( function () {
  2578. materialUUID.setValue( THREE.Math.generateUUID() );
  2579. update();
  2580. } );
  2581. materialUUIDRow.add( new UI.Text( 'UUID' ).setWidth( '90px' ) );
  2582. materialUUIDRow.add( materialUUID );
  2583. materialUUIDRow.add( materialUUIDRenew );
  2584. container.add( materialUUIDRow );
  2585. // name
  2586. var materialNameRow = new UI.Row();
  2587. var materialName = new UI.Input().setWidth( '150px' ).setFontSize( '12px' ).onChange( function () {
  2588. editor.execute( new SetMaterialValueCommand( editor.selected, 'name', materialName.getValue(), currentMaterialSlot ) );
  2589. } );
  2590. materialNameRow.add( new UI.Text( 'Name' ).setWidth( '90px' ) );
  2591. materialNameRow.add( materialName );
  2592. container.add( materialNameRow );
  2593. // program
  2594. var materialProgramRow = new UI.Row();
  2595. materialProgramRow.add( new UI.Text( 'Program' ).setWidth( '90px' ) );
  2596. var materialProgramInfo = new UI.Button( 'Info' );
  2597. materialProgramInfo.setMarginLeft( '4px' );
  2598. materialProgramInfo.onClick( function () {
  2599. signals.editScript.dispatch( currentObject, 'programInfo' );
  2600. } );
  2601. materialProgramRow.add( materialProgramInfo );
  2602. var materialProgramVertex = new UI.Button( 'Vertex' );
  2603. materialProgramVertex.setMarginLeft( '4px' );
  2604. materialProgramVertex.onClick( function () {
  2605. signals.editScript.dispatch( currentObject, 'vertexShader' );
  2606. } );
  2607. materialProgramRow.add( materialProgramVertex );
  2608. var materialProgramFragment = new UI.Button( 'Fragment' );
  2609. materialProgramFragment.setMarginLeft( '4px' );
  2610. materialProgramFragment.onClick( function () {
  2611. signals.editScript.dispatch( currentObject, 'fragmentShader' );
  2612. } );
  2613. materialProgramRow.add( materialProgramFragment );
  2614. container.add( materialProgramRow );
  2615. // color
  2616. var materialColorRow = new UI.Row();
  2617. var materialColor = new UI.Color().onChange( update );
  2618. materialColorRow.add( new UI.Text( 'Color' ).setWidth( '90px' ) );
  2619. materialColorRow.add( materialColor );
  2620. container.add( materialColorRow );
  2621. // roughness
  2622. var materialRoughnessRow = new UI.Row();
  2623. var materialRoughness = new UI.Number( 0.5 ).setWidth( '60px' ).setRange( 0, 1 ).onChange( update );
  2624. materialRoughnessRow.add( new UI.Text( 'Roughness' ).setWidth( '90px' ) );
  2625. materialRoughnessRow.add( materialRoughness );
  2626. container.add( materialRoughnessRow );
  2627. // metalness
  2628. var materialMetalnessRow = new UI.Row();
  2629. var materialMetalness = new UI.Number( 0.5 ).setWidth( '60px' ).setRange( 0, 1 ).onChange( update );
  2630. materialMetalnessRow.add( new UI.Text( 'Metalness' ).setWidth( '90px' ) );
  2631. materialMetalnessRow.add( materialMetalness );
  2632. container.add( materialMetalnessRow );
  2633. // emissive
  2634. var materialEmissiveRow = new UI.Row();
  2635. var materialEmissive = new UI.Color().setHexValue( 0x000000 ).onChange( update );
  2636. materialEmissiveRow.add( new UI.Text( 'Emissive' ).setWidth( '90px' ) );
  2637. materialEmissiveRow.add( materialEmissive );
  2638. container.add( materialEmissiveRow );
  2639. // specular
  2640. var materialSpecularRow = new UI.Row();
  2641. var materialSpecular = new UI.Color().setHexValue( 0x111111 ).onChange( update );
  2642. materialSpecularRow.add( new UI.Text( 'Specular' ).setWidth( '90px' ) );
  2643. materialSpecularRow.add( materialSpecular );
  2644. container.add( materialSpecularRow );
  2645. // shininess
  2646. var materialShininessRow = new UI.Row();
  2647. var materialShininess = new UI.Number( 30 ).onChange( update );
  2648. materialShininessRow.add( new UI.Text( 'Shininess' ).setWidth( '90px' ) );
  2649. materialShininessRow.add( materialShininess );
  2650. container.add( materialShininessRow );
  2651. // clearCoat
  2652. var materialClearCoatRow = new UI.Row();
  2653. var materialClearCoat = new UI.Number( 1 ).setWidth( '60px' ).setRange( 0, 1 ).onChange( update );
  2654. materialClearCoatRow.add( new UI.Text( 'ClearCoat' ).setWidth( '90px' ) );
  2655. materialClearCoatRow.add( materialClearCoat );
  2656. container.add( materialClearCoatRow );
  2657. // clearCoatRoughness
  2658. var materialClearCoatRoughnessRow = new UI.Row();
  2659. var materialClearCoatRoughness = new UI.Number( 1 ).setWidth( '60px' ).setRange( 0, 1 ).onChange( update );
  2660. materialClearCoatRoughnessRow.add( new UI.Text( 'ClearCoat Roughness' ).setWidth( '90px' ) );
  2661. materialClearCoatRoughnessRow.add( materialClearCoatRoughness );
  2662. container.add( materialClearCoatRoughnessRow );
  2663. // vertex colors
  2664. var materialVertexColorsRow = new UI.Row();
  2665. var materialVertexColors = new UI.Select().setOptions( {
  2666. 0: 'No',
  2667. 1: 'Face',
  2668. 2: 'Vertex'
  2669. } ).onChange( update );
  2670. materialVertexColorsRow.add( new UI.Text( 'Vertex Colors' ).setWidth( '90px' ) );
  2671. materialVertexColorsRow.add( materialVertexColors );
  2672. container.add( materialVertexColorsRow );
  2673. // skinning
  2674. var materialSkinningRow = new UI.Row();
  2675. var materialSkinning = new UI.Checkbox( false ).onChange( update );
  2676. materialSkinningRow.add( new UI.Text( 'Skinning' ).setWidth( '90px' ) );
  2677. materialSkinningRow.add( materialSkinning );
  2678. container.add( materialSkinningRow );
  2679. // map
  2680. var materialMapRow = new UI.Row();
  2681. var materialMapEnabled = new UI.Checkbox( false ).onChange( update );
  2682. var materialMap = new UI.Texture().onChange( update );
  2683. materialMapRow.add( new UI.Text( 'Map' ).setWidth( '90px' ) );
  2684. materialMapRow.add( materialMapEnabled );
  2685. materialMapRow.add( materialMap );
  2686. container.add( materialMapRow );
  2687. // alpha map
  2688. var materialAlphaMapRow = new UI.Row();
  2689. var materialAlphaMapEnabled = new UI.Checkbox( false ).onChange( update );
  2690. var materialAlphaMap = new UI.Texture().onChange( update );
  2691. materialAlphaMapRow.add( new UI.Text( 'Alpha Map' ).setWidth( '90px' ) );
  2692. materialAlphaMapRow.add( materialAlphaMapEnabled );
  2693. materialAlphaMapRow.add( materialAlphaMap );
  2694. container.add( materialAlphaMapRow );
  2695. // bump map
  2696. var materialBumpMapRow = new UI.Row();
  2697. var materialBumpMapEnabled = new UI.Checkbox( false ).onChange( update );
  2698. var materialBumpMap = new UI.Texture().onChange( update );
  2699. var materialBumpScale = new UI.Number( 1 ).setWidth( '30px' ).onChange( update );
  2700. materialBumpMapRow.add( new UI.Text( 'Bump Map' ).setWidth( '90px' ) );
  2701. materialBumpMapRow.add( materialBumpMapEnabled );
  2702. materialBumpMapRow.add( materialBumpMap );
  2703. materialBumpMapRow.add( materialBumpScale );
  2704. container.add( materialBumpMapRow );
  2705. // normal map
  2706. var materialNormalMapRow = new UI.Row();
  2707. var materialNormalMapEnabled = new UI.Checkbox( false ).onChange( update );
  2708. var materialNormalMap = new UI.Texture().onChange( update );
  2709. materialNormalMapRow.add( new UI.Text( 'Normal Map' ).setWidth( '90px' ) );
  2710. materialNormalMapRow.add( materialNormalMapEnabled );
  2711. materialNormalMapRow.add( materialNormalMap );
  2712. container.add( materialNormalMapRow );
  2713. // displacement map
  2714. var materialDisplacementMapRow = new UI.Row();
  2715. var materialDisplacementMapEnabled = new UI.Checkbox( false ).onChange( update );
  2716. var materialDisplacementMap = new UI.Texture().onChange( update );
  2717. var materialDisplacementScale = new UI.Number( 1 ).setWidth( '30px' ).onChange( update );
  2718. materialDisplacementMapRow.add( new UI.Text( 'Displace Map' ).setWidth( '90px' ) );
  2719. materialDisplacementMapRow.add( materialDisplacementMapEnabled );
  2720. materialDisplacementMapRow.add( materialDisplacementMap );
  2721. materialDisplacementMapRow.add( materialDisplacementScale );
  2722. container.add( materialDisplacementMapRow );
  2723. // roughness map
  2724. var materialRoughnessMapRow = new UI.Row();
  2725. var materialRoughnessMapEnabled = new UI.Checkbox( false ).onChange( update );
  2726. var materialRoughnessMap = new UI.Texture().onChange( update );
  2727. materialRoughnessMapRow.add( new UI.Text( 'Rough. Map' ).setWidth( '90px' ) );
  2728. materialRoughnessMapRow.add( materialRoughnessMapEnabled );
  2729. materialRoughnessMapRow.add( materialRoughnessMap );
  2730. container.add( materialRoughnessMapRow );
  2731. // metalness map
  2732. var materialMetalnessMapRow = new UI.Row();
  2733. var materialMetalnessMapEnabled = new UI.Checkbox( false ).onChange( update );
  2734. var materialMetalnessMap = new UI.Texture().onChange( update );
  2735. materialMetalnessMapRow.add( new UI.Text( 'Metal. Map' ).setWidth( '90px' ) );
  2736. materialMetalnessMapRow.add( materialMetalnessMapEnabled );
  2737. materialMetalnessMapRow.add( materialMetalnessMap );
  2738. container.add( materialMetalnessMapRow );
  2739. // specular map
  2740. var materialSpecularMapRow = new UI.Row();
  2741. var materialSpecularMapEnabled = new UI.Checkbox( false ).onChange( update );
  2742. var materialSpecularMap = new UI.Texture().onChange( update );
  2743. materialSpecularMapRow.add( new UI.Text( 'Specular Map' ).setWidth( '90px' ) );
  2744. materialSpecularMapRow.add( materialSpecularMapEnabled );
  2745. materialSpecularMapRow.add( materialSpecularMap );
  2746. container.add( materialSpecularMapRow );
  2747. // env map
  2748. var materialEnvMapRow = new UI.Row();
  2749. var materialEnvMapEnabled = new UI.Checkbox( false ).onChange( update );
  2750. var materialEnvMap = new UI.Texture( THREE.SphericalReflectionMapping ).onChange( update );
  2751. var materialReflectivity = new UI.Number( 1 ).setWidth( '30px' ).onChange( update );
  2752. materialEnvMapRow.add( new UI.Text( 'Env Map' ).setWidth( '90px' ) );
  2753. materialEnvMapRow.add( materialEnvMapEnabled );
  2754. materialEnvMapRow.add( materialEnvMap );
  2755. materialEnvMapRow.add( materialReflectivity );
  2756. container.add( materialEnvMapRow );
  2757. // light map
  2758. var materialLightMapRow = new UI.Row();
  2759. var materialLightMapEnabled = new UI.Checkbox( false ).onChange( update );
  2760. var materialLightMap = new UI.Texture().onChange( update );
  2761. materialLightMapRow.add( new UI.Text( 'Light Map' ).setWidth( '90px' ) );
  2762. materialLightMapRow.add( materialLightMapEnabled );
  2763. materialLightMapRow.add( materialLightMap );
  2764. container.add( materialLightMapRow );
  2765. // ambient occlusion map
  2766. var materialAOMapRow = new UI.Row();
  2767. var materialAOMapEnabled = new UI.Checkbox( false ).onChange( update );
  2768. var materialAOMap = new UI.Texture().onChange( update );
  2769. var materialAOScale = new UI.Number( 1 ).setRange( 0, 1 ).setWidth( '30px' ).onChange( update );
  2770. materialAOMapRow.add( new UI.Text( 'AO Map' ).setWidth( '90px' ) );
  2771. materialAOMapRow.add( materialAOMapEnabled );
  2772. materialAOMapRow.add( materialAOMap );
  2773. materialAOMapRow.add( materialAOScale );
  2774. container.add( materialAOMapRow );
  2775. // emissive map
  2776. var materialEmissiveMapRow = new UI.Row();
  2777. var materialEmissiveMapEnabled = new UI.Checkbox( false ).onChange( update );
  2778. var materialEmissiveMap = new UI.Texture().onChange( update );
  2779. materialEmissiveMapRow.add( new UI.Text( 'Emissive Map' ).setWidth( '90px' ) );
  2780. materialEmissiveMapRow.add( materialEmissiveMapEnabled );
  2781. materialEmissiveMapRow.add( materialEmissiveMap );
  2782. container.add( materialEmissiveMapRow );
  2783. // side
  2784. var materialSideRow = new UI.Row();
  2785. var materialSide = new UI.Select().setOptions( {
  2786. 0: 'Front',
  2787. 1: 'Back',
  2788. 2: 'Double'
  2789. } ).setWidth( '150px' ).setFontSize( '12px' ).onChange( update );
  2790. materialSideRow.add( new UI.Text( 'Side' ).setWidth( '90px' ) );
  2791. materialSideRow.add( materialSide );
  2792. container.add( materialSideRow );
  2793. // shading
  2794. var materialShadingRow = new UI.Row();
  2795. var materialShading = new UI.Checkbox(false).setLeft( '100px' ).onChange( update );
  2796. materialShadingRow.add( new UI.Text( 'Flat Shaded' ).setWidth( '90px' ) );
  2797. materialShadingRow.add( materialShading );
  2798. container.add( materialShadingRow );
  2799. // blending
  2800. var materialBlendingRow = new UI.Row();
  2801. var materialBlending = new UI.Select().setOptions( {
  2802. 0: 'No',
  2803. 1: 'Normal',
  2804. 2: 'Additive',
  2805. 3: 'Subtractive',
  2806. 4: 'Multiply',
  2807. 5: 'Custom'
  2808. } ).setWidth( '150px' ).setFontSize( '12px' ).onChange( update );
  2809. materialBlendingRow.add( new UI.Text( 'Blending' ).setWidth( '90px' ) );
  2810. materialBlendingRow.add( materialBlending );
  2811. container.add( materialBlendingRow );
  2812. // opacity
  2813. var materialOpacityRow = new UI.Row();
  2814. var materialOpacity = new UI.Number( 1 ).setWidth( '60px' ).setRange( 0, 1 ).onChange( update );
  2815. materialOpacityRow.add( new UI.Text( 'Opacity' ).setWidth( '90px' ) );
  2816. materialOpacityRow.add( materialOpacity );
  2817. container.add( materialOpacityRow );
  2818. // transparent
  2819. var materialTransparentRow = new UI.Row();
  2820. var materialTransparent = new UI.Checkbox().setLeft( '100px' ).onChange( update );
  2821. materialTransparentRow.add( new UI.Text( 'Transparent' ).setWidth( '90px' ) );
  2822. materialTransparentRow.add( materialTransparent );
  2823. container.add( materialTransparentRow );
  2824. // alpha test
  2825. var materialAlphaTestRow = new UI.Row();
  2826. var materialAlphaTest = new UI.Number().setWidth( '60px' ).setRange( 0, 1 ).onChange( update );
  2827. materialAlphaTestRow.add( new UI.Text( 'Alpha Test' ).setWidth( '90px' ) );
  2828. materialAlphaTestRow.add( materialAlphaTest );
  2829. container.add( materialAlphaTestRow );
  2830. // wireframe
  2831. var materialWireframeRow = new UI.Row();
  2832. var materialWireframe = new UI.Checkbox( false ).onChange( update );
  2833. var materialWireframeLinewidth = new UI.Number( 1 ).setWidth( '60px' ).setRange( 0, 100 ).onChange( update );
  2834. materialWireframeRow.add( new UI.Text( 'Wireframe' ).setWidth( '90px' ) );
  2835. materialWireframeRow.add( materialWireframe );
  2836. materialWireframeRow.add( materialWireframeLinewidth );
  2837. container.add( materialWireframeRow );
  2838. //
  2839. function update() {
  2840. var object = currentObject;
  2841. var geometry = object.geometry;
  2842. var previousSelectedSlot = currentMaterialSlot;
  2843. currentMaterialSlot = parseInt( materialSlotSelect.getValue() );
  2844. if ( currentMaterialSlot !== previousSelectedSlot ) refreshUI( true );
  2845. var material = editor.getObjectMaterial( currentObject, currentMaterialSlot );
  2846. var textureWarning = false;
  2847. var objectHasUvs = false;
  2848. if ( object instanceof THREE.Sprite ) objectHasUvs = true;
  2849. if ( geometry instanceof THREE.Geometry && geometry.faceVertexUvs[ 0 ].length > 0 ) objectHasUvs = true;
  2850. if ( geometry instanceof THREE.BufferGeometry && geometry.attributes.uv !== undefined ) objectHasUvs = true;
  2851. if ( material ) {
  2852. if ( material.uuid !== undefined && material.uuid !== materialUUID.getValue() ) {
  2853. editor.execute( new SetMaterialValueCommand( currentObject, 'uuid', materialUUID.getValue(), currentMaterialSlot ) );
  2854. }
  2855. if ( material instanceof THREE[ materialClass.getValue() ] === false ) {
  2856. material = new THREE[ materialClass.getValue() ]();
  2857. editor.execute( new SetMaterialCommand( currentObject, material, currentMaterialSlot ), 'New Material: ' + materialClass.getValue() );
  2858. // TODO Copy other references in the scene graph
  2859. // keeping name and UUID then.
  2860. // Also there should be means to create a unique
  2861. // copy for the current object explicitly and to
  2862. // attach the current material to other objects.
  2863. }
  2864. if ( material.color !== undefined && material.color.getHex() !== materialColor.getHexValue() ) {
  2865. editor.execute( new SetMaterialColorCommand( currentObject, 'color', materialColor.getHexValue(), currentMaterialSlot ) );
  2866. }
  2867. if ( material.roughness !== undefined && Math.abs( material.roughness - materialRoughness.getValue() ) >= 0.01 ) {
  2868. editor.execute( new SetMaterialValueCommand( currentObject, 'roughness', materialRoughness.getValue(), currentMaterialSlot ) );
  2869. }
  2870. if ( material.metalness !== undefined && Math.abs( material.metalness - materialMetalness.getValue() ) >= 0.01 ) {
  2871. editor.execute( new SetMaterialValueCommand( currentObject, 'metalness', materialMetalness.getValue(), currentMaterialSlot ) );
  2872. }
  2873. if ( material.emissive !== undefined && material.emissive.getHex() !== materialEmissive.getHexValue() ) {
  2874. editor.execute( new SetMaterialColorCommand( currentObject, 'emissive', materialEmissive.getHexValue(), currentMaterialSlot ) );
  2875. }
  2876. if ( material.specular !== undefined && material.specular.getHex() !== materialSpecular.getHexValue() ) {
  2877. editor.execute( new SetMaterialColorCommand( currentObject, 'specular', materialSpecular.getHexValue(), currentMaterialSlot ) );
  2878. }
  2879. if ( material.shininess !== undefined && Math.abs( material.shininess - materialShininess.getValue() ) >= 0.01 ) {
  2880. editor.execute( new SetMaterialValueCommand( currentObject, 'shininess', materialShininess.getValue(), currentMaterialSlot ) );
  2881. }
  2882. if ( material.clearCoat !== undefined && Math.abs( material.clearCoat - materialClearCoat.getValue() ) >= 0.01 ) {
  2883. editor.execute( new SetMaterialValueCommand( currentObject, 'clearCoat', materialClearCoat.getValue(), currentMaterialSlot ) );
  2884. }
  2885. if ( material.clearCoatRoughness !== undefined && Math.abs( material.clearCoatRoughness - materialClearCoatRoughness.getValue() ) >= 0.01 ) {
  2886. editor.execute( new SetMaterialValueCommand( currentObject, 'clearCoatRoughness', materialClearCoatRoughness.getValue(), currentMaterialSlot ) );
  2887. }
  2888. if ( material.vertexColors !== undefined ) {
  2889. var vertexColors = parseInt( materialVertexColors.getValue() );
  2890. if ( material.vertexColors !== vertexColors ) {
  2891. editor.execute( new SetMaterialValueCommand( currentObject, 'vertexColors', vertexColors, currentMaterialSlot ) );
  2892. }
  2893. }
  2894. if ( material.skinning !== undefined && material.skinning !== materialSkinning.getValue() ) {
  2895. editor.execute( new SetMaterialValueCommand( currentObject, 'skinning', materialSkinning.getValue(), currentMaterialSlot ) );
  2896. }
  2897. if ( material.map !== undefined ) {
  2898. var mapEnabled = materialMapEnabled.getValue() === true;
  2899. if ( objectHasUvs ) {
  2900. var map = mapEnabled ? materialMap.getValue() : null;
  2901. if ( material.map !== map ) {
  2902. editor.execute( new SetMaterialMapCommand( currentObject, 'map', map, currentMaterialSlot ) );
  2903. }
  2904. } else {
  2905. if ( mapEnabled ) textureWarning = true;
  2906. }
  2907. }
  2908. if ( material.alphaMap !== undefined ) {
  2909. var mapEnabled = materialAlphaMapEnabled.getValue() === true;
  2910. if ( objectHasUvs ) {
  2911. var alphaMap = mapEnabled ? materialAlphaMap.getValue() : null;
  2912. if ( material.alphaMap !== alphaMap ) {
  2913. editor.execute( new SetMaterialMapCommand( currentObject, 'alphaMap', alphaMap, currentMaterialSlot ) );
  2914. }
  2915. } else {
  2916. if ( mapEnabled ) textureWarning = true;
  2917. }
  2918. }
  2919. if ( material.bumpMap !== undefined ) {
  2920. var bumpMapEnabled = materialBumpMapEnabled.getValue() === true;
  2921. if ( objectHasUvs ) {
  2922. var bumpMap = bumpMapEnabled ? materialBumpMap.getValue() : null;
  2923. if ( material.bumpMap !== bumpMap ) {
  2924. editor.execute( new SetMaterialMapCommand( currentObject, 'bumpMap', bumpMap, currentMaterialSlot ) );
  2925. }
  2926. if ( material.bumpScale !== materialBumpScale.getValue() ) {
  2927. editor.execute( new SetMaterialValueCommand( currentObject, 'bumpScale', materialBumpScale.getValue(), currentMaterialSlot ) );
  2928. }
  2929. } else {
  2930. if ( bumpMapEnabled ) textureWarning = true;
  2931. }
  2932. }
  2933. if ( material.normalMap !== undefined ) {
  2934. var normalMapEnabled = materialNormalMapEnabled.getValue() === true;
  2935. if ( objectHasUvs ) {
  2936. var normalMap = normalMapEnabled ? materialNormalMap.getValue() : null;
  2937. if ( material.normalMap !== normalMap ) {
  2938. editor.execute( new SetMaterialMapCommand( currentObject, 'normalMap', normalMap, currentMaterialSlot ) );
  2939. }
  2940. } else {
  2941. if ( normalMapEnabled ) textureWarning = true;
  2942. }
  2943. }
  2944. if ( material.displacementMap !== undefined ) {
  2945. var displacementMapEnabled = materialDisplacementMapEnabled.getValue() === true;
  2946. if ( objectHasUvs ) {
  2947. var displacementMap = displacementMapEnabled ? materialDisplacementMap.getValue() : null;
  2948. if ( material.displacementMap !== displacementMap ) {
  2949. editor.execute( new SetMaterialMapCommand( currentObject, 'displacementMap', displacementMap, currentMaterialSlot ) );
  2950. }
  2951. if ( material.displacementScale !== materialDisplacementScale.getValue() ) {
  2952. editor.execute( new SetMaterialValueCommand( currentObject, 'displacementScale', materialDisplacementScale.getValue(), currentMaterialSlot ) );
  2953. }
  2954. } else {
  2955. if ( displacementMapEnabled ) textureWarning = true;
  2956. }
  2957. }
  2958. if ( material.roughnessMap !== undefined ) {
  2959. var roughnessMapEnabled = materialRoughnessMapEnabled.getValue() === true;
  2960. if ( objectHasUvs ) {
  2961. var roughnessMap = roughnessMapEnabled ? materialRoughnessMap.getValue() : null;
  2962. if ( material.roughnessMap !== roughnessMap ) {
  2963. editor.execute( new SetMaterialMapCommand( currentObject, 'roughnessMap', roughnessMap, currentMaterialSlot ) );
  2964. }
  2965. } else {
  2966. if ( roughnessMapEnabled ) textureWarning = true;
  2967. }
  2968. }
  2969. if ( material.metalnessMap !== undefined ) {
  2970. var metalnessMapEnabled = materialMetalnessMapEnabled.getValue() === true;
  2971. if ( objectHasUvs ) {
  2972. var metalnessMap = metalnessMapEnabled ? materialMetalnessMap.getValue() : null;
  2973. if ( material.metalnessMap !== metalnessMap ) {
  2974. editor.execute( new SetMaterialMapCommand( currentObject, 'metalnessMap', metalnessMap, currentMaterialSlot ) );
  2975. }
  2976. } else {
  2977. if ( metalnessMapEnabled ) textureWarning = true;
  2978. }
  2979. }
  2980. if ( material.specularMap !== undefined ) {
  2981. var specularMapEnabled = materialSpecularMapEnabled.getValue() === true;
  2982. if ( objectHasUvs ) {
  2983. var specularMap = specularMapEnabled ? materialSpecularMap.getValue() : null;
  2984. if ( material.specularMap !== specularMap ) {
  2985. editor.execute( new SetMaterialMapCommand( currentObject, 'specularMap', specularMap, currentMaterialSlot ) );
  2986. }
  2987. } else {
  2988. if ( specularMapEnabled ) textureWarning = true;
  2989. }
  2990. }
  2991. if ( material.envMap !== undefined ) {
  2992. var envMapEnabled = materialEnvMapEnabled.getValue() === true;
  2993. var envMap = envMapEnabled ? materialEnvMap.getValue() : null;
  2994. if ( material.envMap !== envMap ) {
  2995. editor.execute( new SetMaterialMapCommand( currentObject, 'envMap', envMap, currentMaterialSlot ) );
  2996. }
  2997. }
  2998. if ( material.reflectivity !== undefined ) {
  2999. var reflectivity = materialReflectivity.getValue();
  3000. if ( material.reflectivity !== reflectivity ) {
  3001. editor.execute( new SetMaterialValueCommand( currentObject, 'reflectivity', reflectivity, currentMaterialSlot ) );
  3002. }
  3003. }
  3004. if ( material.lightMap !== undefined ) {
  3005. var lightMapEnabled = materialLightMapEnabled.getValue() === true;
  3006. if ( objectHasUvs ) {
  3007. var lightMap = lightMapEnabled ? materialLightMap.getValue() : null;
  3008. if ( material.lightMap !== lightMap ) {
  3009. editor.execute( new SetMaterialMapCommand( currentObject, 'lightMap', lightMap, currentMaterialSlot ) );
  3010. }
  3011. } else {
  3012. if ( lightMapEnabled ) textureWarning = true;
  3013. }
  3014. }
  3015. if ( material.aoMap !== undefined ) {
  3016. var aoMapEnabled = materialAOMapEnabled.getValue() === true;
  3017. if ( objectHasUvs ) {
  3018. var aoMap = aoMapEnabled ? materialAOMap.getValue() : null;
  3019. if ( material.aoMap !== aoMap ) {
  3020. editor.execute( new SetMaterialMapCommand( currentObject, 'aoMap', aoMap, currentMaterialSlot ) );
  3021. }
  3022. if ( material.aoMapIntensity !== materialAOScale.getValue() ) {
  3023. editor.execute( new SetMaterialValueCommand( currentObject, 'aoMapIntensity', materialAOScale.getValue(), currentMaterialSlot ) );
  3024. }
  3025. } else {
  3026. if ( aoMapEnabled ) textureWarning = true;
  3027. }
  3028. }
  3029. if ( material.emissiveMap !== undefined ) {
  3030. var emissiveMapEnabled = materialEmissiveMapEnabled.getValue() === true;
  3031. if ( objectHasUvs ) {
  3032. var emissiveMap = emissiveMapEnabled ? materialEmissiveMap.getValue() : null;
  3033. if ( material.emissiveMap !== emissiveMap ) {
  3034. editor.execute( new SetMaterialMapCommand( currentObject, 'emissiveMap', emissiveMap, currentMaterialSlot ) );
  3035. }
  3036. } else {
  3037. if ( emissiveMapEnabled ) textureWarning = true;
  3038. }
  3039. }
  3040. if ( material.side !== undefined ) {
  3041. var side = parseInt( materialSide.getValue() );
  3042. if ( material.side !== side ) {
  3043. editor.execute( new SetMaterialValueCommand( currentObject, 'side', side, currentMaterialSlot ) );
  3044. }
  3045. }
  3046. if ( material.flatShading !== undefined ) {
  3047. var flatShading = materialShading.getValue();
  3048. if ( material.flatShading != flatShading ) {
  3049. editor.execute( new SetMaterialValueCommand( currentObject, 'flatShading', flatShading, currentMaterialSlot ) );
  3050. }
  3051. }
  3052. if ( material.blending !== undefined ) {
  3053. var blending = parseInt( materialBlending.getValue() );
  3054. if ( material.blending !== blending ) {
  3055. editor.execute( new SetMaterialValueCommand( currentObject, 'blending', blending, currentMaterialSlot ) );
  3056. }
  3057. }
  3058. if ( material.opacity !== undefined && Math.abs( material.opacity - materialOpacity.getValue() ) >= 0.01 ) {
  3059. editor.execute( new SetMaterialValueCommand( currentObject, 'opacity', materialOpacity.getValue(), currentMaterialSlot ) );
  3060. }
  3061. if ( material.transparent !== undefined && material.transparent !== materialTransparent.getValue() ) {
  3062. editor.execute( new SetMaterialValueCommand( currentObject, 'transparent', materialTransparent.getValue(), currentMaterialSlot ) );
  3063. }
  3064. if ( material.alphaTest !== undefined && Math.abs( material.alphaTest - materialAlphaTest.getValue() ) >= 0.01 ) {
  3065. editor.execute( new SetMaterialValueCommand( currentObject, 'alphaTest', materialAlphaTest.getValue(), currentMaterialSlot ) );
  3066. }
  3067. if ( material.wireframe !== undefined && material.wireframe !== materialWireframe.getValue() ) {
  3068. editor.execute( new SetMaterialValueCommand( currentObject, 'wireframe', materialWireframe.getValue(), currentMaterialSlot) );
  3069. }
  3070. if ( material.wireframeLinewidth !== undefined && Math.abs( material.wireframeLinewidth - materialWireframeLinewidth.getValue() ) >= 0.01 ) {
  3071. editor.execute( new SetMaterialValueCommand( currentObject, 'wireframeLinewidth', materialWireframeLinewidth.getValue(), currentMaterialSlot ) );
  3072. }
  3073. refreshUI();
  3074. }
  3075. if ( textureWarning ) {
  3076. console.warn( "Can't set texture, model doesn't have texture coordinates" );
  3077. }
  3078. }
  3079. //
  3080. function setRowVisibility() {
  3081. var properties = {
  3082. 'name': materialNameRow,
  3083. 'color': materialColorRow,
  3084. 'roughness': materialRoughnessRow,
  3085. 'metalness': materialMetalnessRow,
  3086. 'emissive': materialEmissiveRow,
  3087. 'specular': materialSpecularRow,
  3088. 'shininess': materialShininessRow,
  3089. 'clearCoat': materialClearCoatRow,
  3090. 'clearCoatRoughness': materialClearCoatRoughnessRow,
  3091. 'vertexShader': materialProgramRow,
  3092. 'vertexColors': materialVertexColorsRow,
  3093. 'skinning': materialSkinningRow,
  3094. 'map': materialMapRow,
  3095. 'alphaMap': materialAlphaMapRow,
  3096. 'bumpMap': materialBumpMapRow,
  3097. 'normalMap': materialNormalMapRow,
  3098. 'displacementMap': materialDisplacementMapRow,
  3099. 'roughnessMap': materialRoughnessMapRow,
  3100. 'metalnessMap': materialMetalnessMapRow,
  3101. 'specularMap': materialSpecularMapRow,
  3102. 'envMap': materialEnvMapRow,
  3103. 'lightMap': materialLightMapRow,
  3104. 'aoMap': materialAOMapRow,
  3105. 'emissiveMap': materialEmissiveMapRow,
  3106. 'side': materialSideRow,
  3107. 'flatShading': materialShadingRow,
  3108. 'blending': materialBlendingRow,
  3109. 'opacity': materialOpacityRow,
  3110. 'transparent': materialTransparentRow,
  3111. 'alphaTest': materialAlphaTestRow,
  3112. 'wireframe': materialWireframeRow
  3113. };
  3114. var material = currentObject.material;
  3115. if ( Array.isArray( material ) ) {
  3116. materialSlotRow.setDisplay( '' );
  3117. if ( material.length === 0 ) return;
  3118. material = material[ currentMaterialSlot ];
  3119. } else {
  3120. materialSlotRow.setDisplay( 'none' );
  3121. }
  3122. for ( var property in properties ) {
  3123. properties[ property ].setDisplay( material[ property ] !== undefined ? '' : 'none' );
  3124. }
  3125. }
  3126. function refreshUI( resetTextureSelectors ) {
  3127. if ( ! currentObject ) return;
  3128. var material = currentObject.material;
  3129. if ( Array.isArray( material ) ) {
  3130. var slotOptions = {};
  3131. currentMaterialSlot = Math.max( 0, Math.min( material.length, currentMaterialSlot ) );
  3132. for ( var i = 0; i < material.length; i ++ ) {
  3133. slotOptions[ i ] = String( i + 1 ) + ': ' + material[ i ].name;
  3134. }
  3135. materialSlotSelect.setOptions( slotOptions ).setValue( currentMaterialSlot );
  3136. }
  3137. material = editor.getObjectMaterial( currentObject, currentMaterialSlot );
  3138. if ( material.uuid !== undefined ) {
  3139. materialUUID.setValue( material.uuid );
  3140. }
  3141. if ( material.name !== undefined ) {
  3142. materialName.setValue( material.name );
  3143. }
  3144. materialClass.setValue( material.type );
  3145. if ( material.color !== undefined ) {
  3146. materialColor.setHexValue( material.color.getHexString() );
  3147. }
  3148. if ( material.roughness !== undefined ) {
  3149. materialRoughness.setValue( material.roughness );
  3150. }
  3151. if ( material.metalness !== undefined ) {
  3152. materialMetalness.setValue( material.metalness );
  3153. }
  3154. if ( material.emissive !== undefined ) {
  3155. materialEmissive.setHexValue( material.emissive.getHexString() );
  3156. }
  3157. if ( material.specular !== undefined ) {
  3158. materialSpecular.setHexValue( material.specular.getHexString() );
  3159. }
  3160. if ( material.shininess !== undefined ) {
  3161. materialShininess.setValue( material.shininess );
  3162. }
  3163. if ( material.clearCoat !== undefined ) {
  3164. materialClearCoat.setValue( material.clearCoat );
  3165. }
  3166. if ( material.clearCoatRoughness !== undefined ) {
  3167. materialClearCoatRoughness.setValue( material.clearCoatRoughness );
  3168. }
  3169. if ( material.vertexColors !== undefined ) {
  3170. materialVertexColors.setValue( material.vertexColors );
  3171. }
  3172. if ( material.skinning !== undefined ) {
  3173. materialSkinning.setValue( material.skinning );
  3174. }
  3175. if ( material.map !== undefined ) {
  3176. materialMapEnabled.setValue( material.map !== null );
  3177. if ( material.map !== null || resetTextureSelectors ) {
  3178. materialMap.setValue( material.map );
  3179. }
  3180. }
  3181. if ( material.alphaMap !== undefined ) {
  3182. materialAlphaMapEnabled.setValue( material.alphaMap !== null );
  3183. if ( material.alphaMap !== null || resetTextureSelectors ) {
  3184. materialAlphaMap.setValue( material.alphaMap );
  3185. }
  3186. }
  3187. if ( material.bumpMap !== undefined ) {
  3188. materialBumpMapEnabled.setValue( material.bumpMap !== null );
  3189. if ( material.bumpMap !== null || resetTextureSelectors ) {
  3190. materialBumpMap.setValue( material.bumpMap );
  3191. }
  3192. materialBumpScale.setValue( material.bumpScale );
  3193. }
  3194. if ( material.normalMap !== undefined ) {
  3195. materialNormalMapEnabled.setValue( material.normalMap !== null );
  3196. if ( material.normalMap !== null || resetTextureSelectors ) {
  3197. materialNormalMap.setValue( material.normalMap );
  3198. }
  3199. }
  3200. if ( material.displacementMap !== undefined ) {
  3201. materialDisplacementMapEnabled.setValue( material.displacementMap !== null );
  3202. if ( material.displacementMap !== null || resetTextureSelectors ) {
  3203. materialDisplacementMap.setValue( material.displacementMap );
  3204. }
  3205. materialDisplacementScale.setValue( material.displacementScale );
  3206. }
  3207. if ( material.roughnessMap !== undefined ) {
  3208. materialRoughnessMapEnabled.setValue( material.roughnessMap !== null );
  3209. if ( material.roughnessMap !== null || resetTextureSelectors ) {
  3210. materialRoughnessMap.setValue( material.roughnessMap );
  3211. }
  3212. }
  3213. if ( material.metalnessMap !== undefined ) {
  3214. materialMetalnessMapEnabled.setValue( material.metalnessMap !== null );
  3215. if ( material.metalnessMap !== null || resetTextureSelectors ) {
  3216. materialMetalnessMap.setValue( material.metalnessMap );
  3217. }
  3218. }
  3219. if ( material.specularMap !== undefined ) {
  3220. materialSpecularMapEnabled.setValue( material.specularMap !== null );
  3221. if ( material.specularMap !== null || resetTextureSelectors ) {
  3222. materialSpecularMap.setValue( material.specularMap );
  3223. }
  3224. }
  3225. if ( material.envMap !== undefined ) {
  3226. materialEnvMapEnabled.setValue( material.envMap !== null );
  3227. if ( material.envMap !== null || resetTextureSelectors ) {
  3228. materialEnvMap.setValue( material.envMap );
  3229. }
  3230. }
  3231. if ( material.reflectivity !== undefined ) {
  3232. materialReflectivity.setValue( material.reflectivity );
  3233. }
  3234. if ( material.lightMap !== undefined ) {
  3235. materialLightMapEnabled.setValue( material.lightMap !== null );
  3236. if ( material.lightMap !== null || resetTextureSelectors ) {
  3237. materialLightMap.setValue( material.lightMap );
  3238. }
  3239. }
  3240. if ( material.aoMap !== undefined ) {
  3241. materialAOMapEnabled.setValue( material.aoMap !== null );
  3242. if ( material.aoMap !== null || resetTextureSelectors ) {
  3243. materialAOMap.setValue( material.aoMap );
  3244. }
  3245. materialAOScale.setValue( material.aoMapIntensity );
  3246. }
  3247. if ( material.emissiveMap !== undefined ) {
  3248. materialEmissiveMapEnabled.setValue( material.emissiveMap !== null );
  3249. if ( material.emissiveMap !== null || resetTextureSelectors ) {
  3250. materialEmissiveMap.setValue( material.emissiveMap );
  3251. }
  3252. }
  3253. if ( material.side !== undefined ) {
  3254. materialSide.setValue( material.side );
  3255. }
  3256. if ( material.flatShading !== undefined ) {
  3257. materialShading.setValue( material.flatShading );
  3258. }
  3259. if ( material.blending !== undefined ) {
  3260. materialBlending.setValue( material.blending );
  3261. }
  3262. if ( material.opacity !== undefined ) {
  3263. materialOpacity.setValue( material.opacity );
  3264. }
  3265. if ( material.transparent !== undefined ) {
  3266. materialTransparent.setValue( material.transparent );
  3267. }
  3268. if ( material.alphaTest !== undefined ) {
  3269. materialAlphaTest.setValue( material.alphaTest );
  3270. }
  3271. if ( material.wireframe !== undefined ) {
  3272. materialWireframe.setValue( material.wireframe );
  3273. }
  3274. if ( material.wireframeLinewidth !== undefined ) {
  3275. materialWireframeLinewidth.setValue( material.wireframeLinewidth );
  3276. }
  3277. setRowVisibility();
  3278. }
  3279. // events
  3280. signals.objectSelected.add( function ( object ) {
  3281. var hasMaterial = false;
  3282. if ( object && object.material ) {
  3283. hasMaterial = true;
  3284. if ( Array.isArray( object.material ) && object.material.length === 0 ) {
  3285. hasMaterial = false;
  3286. }
  3287. }
  3288. if ( hasMaterial ) {
  3289. var objectChanged = object !== currentObject;
  3290. currentObject = object;
  3291. refreshUI( objectChanged );
  3292. container.setDisplay( '' );
  3293. } else {
  3294. currentObject = null;
  3295. container.setDisplay( 'none' );
  3296. }
  3297. } );
  3298. signals.materialChanged.add( function () {
  3299. refreshUI();
  3300. } );
  3301. return container;
  3302. };
  3303. /**
  3304. * @author TristanVALCKE / https://github.com/Itee
  3305. */
  3306. /* global QUnit */
  3307. QUnit.module( 'Editor', () => {
  3308. QUnit.module.todo( 'Sidebar.Material', () => {
  3309. QUnit.test( 'write me !', ( assert ) => {
  3310. assert.ok( false, "everything's gonna be alright" );
  3311. } );
  3312. } );
  3313. } );
  3314. /**
  3315. * @author mrdoob / http://mrdoob.com/
  3316. */
  3317. Sidebar.Object = function ( editor ) {
  3318. var signals = editor.signals;
  3319. var container = new UI.Panel();
  3320. container.setBorderTop( '0' );
  3321. container.setPaddingTop( '20px' );
  3322. container.setDisplay( 'none' );
  3323. // Actions
  3324. var objectActions = new UI.Select().setPosition( 'absolute' ).setRight( '8px' ).setFontSize( '11px' );
  3325. objectActions.setOptions( {
  3326. 'Actions': 'Actions',
  3327. 'Reset Position': 'Reset Position',
  3328. 'Reset Rotation': 'Reset Rotation',
  3329. 'Reset Scale': 'Reset Scale'
  3330. } );
  3331. objectActions.onClick( function ( event ) {
  3332. event.stopPropagation(); // Avoid panel collapsing
  3333. } );
  3334. objectActions.onChange( function ( event ) {
  3335. var object = editor.selected;
  3336. switch ( this.getValue() ) {
  3337. case 'Reset Position':
  3338. editor.execute( new SetPositionCommand( object, new THREE.Vector3( 0, 0, 0 ) ) );
  3339. break;
  3340. case 'Reset Rotation':
  3341. editor.execute( new SetRotationCommand( object, new THREE.Euler( 0, 0, 0 ) ) );
  3342. break;
  3343. case 'Reset Scale':
  3344. editor.execute( new SetScaleCommand( object, new THREE.Vector3( 1, 1, 1 ) ) );
  3345. break;
  3346. }
  3347. this.setValue( 'Actions' );
  3348. } );
  3349. // container.addStatic( objectActions );
  3350. // type
  3351. var objectTypeRow = new UI.Row();
  3352. var objectType = new UI.Text();
  3353. objectTypeRow.add( new UI.Text( 'Type' ).setWidth( '90px' ) );
  3354. objectTypeRow.add( objectType );
  3355. container.add( objectTypeRow );
  3356. // uuid
  3357. var objectUUIDRow = new UI.Row();
  3358. var objectUUID = new UI.Input().setWidth( '102px' ).setFontSize( '12px' ).setDisabled( true );
  3359. var objectUUIDRenew = new UI.Button( 'New' ).setMarginLeft( '7px' ).onClick( function () {
  3360. objectUUID.setValue( THREE.Math.generateUUID() );
  3361. editor.execute( new SetUuidCommand( editor.selected, objectUUID.getValue() ) );
  3362. } );
  3363. objectUUIDRow.add( new UI.Text( 'UUID' ).setWidth( '90px' ) );
  3364. objectUUIDRow.add( objectUUID );
  3365. objectUUIDRow.add( objectUUIDRenew );
  3366. container.add( objectUUIDRow );
  3367. // name
  3368. var objectNameRow = new UI.Row();
  3369. var objectName = new UI.Input().setWidth( '150px' ).setFontSize( '12px' ).onChange( function () {
  3370. editor.execute( new SetValueCommand( editor.selected, 'name', objectName.getValue() ) );
  3371. } );
  3372. objectNameRow.add( new UI.Text( 'Name' ).setWidth( '90px' ) );
  3373. objectNameRow.add( objectName );
  3374. container.add( objectNameRow );
  3375. // position
  3376. var objectPositionRow = new UI.Row();
  3377. var objectPositionX = new UI.Number().setWidth( '50px' ).onChange( update );
  3378. var objectPositionY = new UI.Number().setWidth( '50px' ).onChange( update );
  3379. var objectPositionZ = new UI.Number().setWidth( '50px' ).onChange( update );
  3380. objectPositionRow.add( new UI.Text( 'Position' ).setWidth( '90px' ) );
  3381. objectPositionRow.add( objectPositionX, objectPositionY, objectPositionZ );
  3382. container.add( objectPositionRow );
  3383. // rotation
  3384. var objectRotationRow = new UI.Row();
  3385. var objectRotationX = new UI.Number().setStep( 10 ).setUnit( '°' ).setWidth( '50px' ).onChange( update );
  3386. var objectRotationY = new UI.Number().setStep( 10 ).setUnit( '°' ).setWidth( '50px' ).onChange( update );
  3387. var objectRotationZ = new UI.Number().setStep( 10 ).setUnit( '°' ).setWidth( '50px' ).onChange( update );
  3388. objectRotationRow.add( new UI.Text( 'Rotation' ).setWidth( '90px' ) );
  3389. objectRotationRow.add( objectRotationX, objectRotationY, objectRotationZ );
  3390. container.add( objectRotationRow );
  3391. // scale
  3392. var objectScaleRow = new UI.Row();
  3393. var objectScaleLock = new UI.Checkbox( true ).setPosition( 'absolute' ).setLeft( '75px' );
  3394. var objectScaleX = new UI.Number( 1 ).setRange( 0.01, Infinity ).setWidth( '50px' ).onChange( updateScaleX );
  3395. var objectScaleY = new UI.Number( 1 ).setRange( 0.01, Infinity ).setWidth( '50px' ).onChange( updateScaleY );
  3396. var objectScaleZ = new UI.Number( 1 ).setRange( 0.01, Infinity ).setWidth( '50px' ).onChange( updateScaleZ );
  3397. objectScaleRow.add( new UI.Text( 'Scale' ).setWidth( '90px' ) );
  3398. objectScaleRow.add( objectScaleLock );
  3399. objectScaleRow.add( objectScaleX, objectScaleY, objectScaleZ );
  3400. container.add( objectScaleRow );
  3401. // fov
  3402. var objectFovRow = new UI.Row();
  3403. var objectFov = new UI.Number().onChange( update );
  3404. objectFovRow.add( new UI.Text( 'Fov' ).setWidth( '90px' ) );
  3405. objectFovRow.add( objectFov );
  3406. container.add( objectFovRow );
  3407. // near
  3408. var objectNearRow = new UI.Row();
  3409. var objectNear = new UI.Number().onChange( update );
  3410. objectNearRow.add( new UI.Text( 'Near' ).setWidth( '90px' ) );
  3411. objectNearRow.add( objectNear );
  3412. container.add( objectNearRow );
  3413. // far
  3414. var objectFarRow = new UI.Row();
  3415. var objectFar = new UI.Number().onChange( update );
  3416. objectFarRow.add( new UI.Text( 'Far' ).setWidth( '90px' ) );
  3417. objectFarRow.add( objectFar );
  3418. container.add( objectFarRow );
  3419. // intensity
  3420. var objectIntensityRow = new UI.Row();
  3421. var objectIntensity = new UI.Number().setRange( 0, Infinity ).onChange( update );
  3422. objectIntensityRow.add( new UI.Text( 'Intensity' ).setWidth( '90px' ) );
  3423. objectIntensityRow.add( objectIntensity );
  3424. container.add( objectIntensityRow );
  3425. // color
  3426. var objectColorRow = new UI.Row();
  3427. var objectColor = new UI.Color().onChange( update );
  3428. objectColorRow.add( new UI.Text( 'Color' ).setWidth( '90px' ) );
  3429. objectColorRow.add( objectColor );
  3430. container.add( objectColorRow );
  3431. // ground color
  3432. var objectGroundColorRow = new UI.Row();
  3433. var objectGroundColor = new UI.Color().onChange( update );
  3434. objectGroundColorRow.add( new UI.Text( 'Ground color' ).setWidth( '90px' ) );
  3435. objectGroundColorRow.add( objectGroundColor );
  3436. container.add( objectGroundColorRow );
  3437. // distance
  3438. var objectDistanceRow = new UI.Row();
  3439. var objectDistance = new UI.Number().setRange( 0, Infinity ).onChange( update );
  3440. objectDistanceRow.add( new UI.Text( 'Distance' ).setWidth( '90px' ) );
  3441. objectDistanceRow.add( objectDistance );
  3442. container.add( objectDistanceRow );
  3443. // angle
  3444. var objectAngleRow = new UI.Row();
  3445. var objectAngle = new UI.Number().setPrecision( 3 ).setRange( 0, Math.PI / 2 ).onChange( update );
  3446. objectAngleRow.add( new UI.Text( 'Angle' ).setWidth( '90px' ) );
  3447. objectAngleRow.add( objectAngle );
  3448. container.add( objectAngleRow );
  3449. // penumbra
  3450. var objectPenumbraRow = new UI.Row();
  3451. var objectPenumbra = new UI.Number().setRange( 0, 1 ).onChange( update );
  3452. objectPenumbraRow.add( new UI.Text( 'Penumbra' ).setWidth( '90px' ) );
  3453. objectPenumbraRow.add( objectPenumbra );
  3454. container.add( objectPenumbraRow );
  3455. // decay
  3456. var objectDecayRow = new UI.Row();
  3457. var objectDecay = new UI.Number().setRange( 0, Infinity ).onChange( update );
  3458. objectDecayRow.add( new UI.Text( 'Decay' ).setWidth( '90px' ) );
  3459. objectDecayRow.add( objectDecay );
  3460. container.add( objectDecayRow );
  3461. // shadow
  3462. var objectShadowRow = new UI.Row();
  3463. objectShadowRow.add( new UI.Text( 'Shadow' ).setWidth( '90px' ) );
  3464. var objectCastShadow = new UI.THREE.Boolean( false, 'cast' ).onChange( update );
  3465. objectShadowRow.add( objectCastShadow );
  3466. var objectReceiveShadow = new UI.THREE.Boolean( false, 'receive' ).onChange( update );
  3467. objectShadowRow.add( objectReceiveShadow );
  3468. var objectShadowRadius = new UI.Number( 1 ).onChange( update );
  3469. objectShadowRow.add( objectShadowRadius );
  3470. container.add( objectShadowRow );
  3471. // visible
  3472. var objectVisibleRow = new UI.Row();
  3473. var objectVisible = new UI.Checkbox().onChange( update );
  3474. objectVisibleRow.add( new UI.Text( 'Visible' ).setWidth( '90px' ) );
  3475. objectVisibleRow.add( objectVisible );
  3476. container.add( objectVisibleRow );
  3477. // user data
  3478. var timeout;
  3479. var objectUserDataRow = new UI.Row();
  3480. var objectUserData = new UI.TextArea().setWidth( '150px' ).setHeight( '40px' ).setFontSize( '12px' ).onChange( update );
  3481. objectUserData.onKeyUp( function () {
  3482. try {
  3483. JSON.parse( objectUserData.getValue() );
  3484. objectUserData.dom.classList.add( 'success' );
  3485. objectUserData.dom.classList.remove( 'fail' );
  3486. } catch ( error ) {
  3487. objectUserData.dom.classList.remove( 'success' );
  3488. objectUserData.dom.classList.add( 'fail' );
  3489. }
  3490. } );
  3491. objectUserDataRow.add( new UI.Text( 'User data' ).setWidth( '90px' ) );
  3492. objectUserDataRow.add( objectUserData );
  3493. container.add( objectUserDataRow );
  3494. //
  3495. function updateScaleX() {
  3496. var object = editor.selected;
  3497. if ( objectScaleLock.getValue() === true ) {
  3498. var scale = objectScaleX.getValue() / object.scale.x;
  3499. objectScaleY.setValue( objectScaleY.getValue() * scale );
  3500. objectScaleZ.setValue( objectScaleZ.getValue() * scale );
  3501. }
  3502. update();
  3503. }
  3504. function updateScaleY() {
  3505. var object = editor.selected;
  3506. if ( objectScaleLock.getValue() === true ) {
  3507. var scale = objectScaleY.getValue() / object.scale.y;
  3508. objectScaleX.setValue( objectScaleX.getValue() * scale );
  3509. objectScaleZ.setValue( objectScaleZ.getValue() * scale );
  3510. }
  3511. update();
  3512. }
  3513. function updateScaleZ() {
  3514. var object = editor.selected;
  3515. if ( objectScaleLock.getValue() === true ) {
  3516. var scale = objectScaleZ.getValue() / object.scale.z;
  3517. objectScaleX.setValue( objectScaleX.getValue() * scale );
  3518. objectScaleY.setValue( objectScaleY.getValue() * scale );
  3519. }
  3520. update();
  3521. }
  3522. function update() {
  3523. var object = editor.selected;
  3524. if ( object !== null ) {
  3525. var newPosition = new THREE.Vector3( objectPositionX.getValue(), objectPositionY.getValue(), objectPositionZ.getValue() );
  3526. if ( object.position.distanceTo( newPosition ) >= 0.01 ) {
  3527. editor.execute( new SetPositionCommand( object, newPosition ) );
  3528. }
  3529. var newRotation = new THREE.Euler( objectRotationX.getValue() * THREE.Math.DEG2RAD, objectRotationY.getValue() * THREE.Math.DEG2RAD, objectRotationZ.getValue() * THREE.Math.DEG2RAD );
  3530. if ( object.rotation.toVector3().distanceTo( newRotation.toVector3() ) >= 0.01 ) {
  3531. editor.execute( new SetRotationCommand( object, newRotation ) );
  3532. }
  3533. var newScale = new THREE.Vector3( objectScaleX.getValue(), objectScaleY.getValue(), objectScaleZ.getValue() );
  3534. if ( object.scale.distanceTo( newScale ) >= 0.01 ) {
  3535. editor.execute( new SetScaleCommand( object, newScale ) );
  3536. }
  3537. if ( object.fov !== undefined && Math.abs( object.fov - objectFov.getValue() ) >= 0.01 ) {
  3538. editor.execute( new SetValueCommand( object, 'fov', objectFov.getValue() ) );
  3539. object.updateProjectionMatrix();
  3540. }
  3541. if ( object.near !== undefined && Math.abs( object.near - objectNear.getValue() ) >= 0.01 ) {
  3542. editor.execute( new SetValueCommand( object, 'near', objectNear.getValue() ) );
  3543. }
  3544. if ( object.far !== undefined && Math.abs( object.far - objectFar.getValue() ) >= 0.01 ) {
  3545. editor.execute( new SetValueCommand( object, 'far', objectFar.getValue() ) );
  3546. }
  3547. if ( object.intensity !== undefined && Math.abs( object.intensity - objectIntensity.getValue() ) >= 0.01 ) {
  3548. editor.execute( new SetValueCommand( object, 'intensity', objectIntensity.getValue() ) );
  3549. }
  3550. if ( object.color !== undefined && object.color.getHex() !== objectColor.getHexValue() ) {
  3551. editor.execute( new SetColorCommand( object, 'color', objectColor.getHexValue() ) );
  3552. }
  3553. if ( object.groundColor !== undefined && object.groundColor.getHex() !== objectGroundColor.getHexValue() ) {
  3554. editor.execute( new SetColorCommand( object, 'groundColor', objectGroundColor.getHexValue() ) );
  3555. }
  3556. if ( object.distance !== undefined && Math.abs( object.distance - objectDistance.getValue() ) >= 0.01 ) {
  3557. editor.execute( new SetValueCommand( object, 'distance', objectDistance.getValue() ) );
  3558. }
  3559. if ( object.angle !== undefined && Math.abs( object.angle - objectAngle.getValue() ) >= 0.01 ) {
  3560. editor.execute( new SetValueCommand( object, 'angle', objectAngle.getValue() ) );
  3561. }
  3562. if ( object.penumbra !== undefined && Math.abs( object.penumbra - objectPenumbra.getValue() ) >= 0.01 ) {
  3563. editor.execute( new SetValueCommand( object, 'penumbra', objectPenumbra.getValue() ) );
  3564. }
  3565. if ( object.decay !== undefined && Math.abs( object.decay - objectDecay.getValue() ) >= 0.01 ) {
  3566. editor.execute( new SetValueCommand( object, 'decay', objectDecay.getValue() ) );
  3567. }
  3568. if ( object.visible !== objectVisible.getValue() ) {
  3569. editor.execute( new SetValueCommand( object, 'visible', objectVisible.getValue() ) );
  3570. }
  3571. if ( object.castShadow !== undefined && object.castShadow !== objectCastShadow.getValue() ) {
  3572. editor.execute( new SetValueCommand( object, 'castShadow', objectCastShadow.getValue() ) );
  3573. }
  3574. if ( object.receiveShadow !== undefined && object.receiveShadow !== objectReceiveShadow.getValue() ) {
  3575. editor.execute( new SetValueCommand( object, 'receiveShadow', objectReceiveShadow.getValue() ) );
  3576. object.material.needsUpdate = true;
  3577. }
  3578. if ( object.shadow !== undefined ) {
  3579. if ( object.shadow.radius !== objectShadowRadius.getValue() ) {
  3580. editor.execute( new SetValueCommand( object.shadow, 'radius', objectShadowRadius.getValue() ) );
  3581. }
  3582. }
  3583. try {
  3584. var userData = JSON.parse( objectUserData.getValue() );
  3585. if ( JSON.stringify( object.userData ) != JSON.stringify( userData ) ) {
  3586. editor.execute( new SetValueCommand( object, 'userData', userData ) );
  3587. }
  3588. } catch ( exception ) {
  3589. console.warn( exception );
  3590. }
  3591. }
  3592. }
  3593. function updateRows( object ) {
  3594. var properties = {
  3595. 'fov': objectFovRow,
  3596. 'near': objectNearRow,
  3597. 'far': objectFarRow,
  3598. 'intensity': objectIntensityRow,
  3599. 'color': objectColorRow,
  3600. 'groundColor': objectGroundColorRow,
  3601. 'distance' : objectDistanceRow,
  3602. 'angle' : objectAngleRow,
  3603. 'penumbra' : objectPenumbraRow,
  3604. 'decay' : objectDecayRow,
  3605. 'castShadow' : objectShadowRow,
  3606. 'receiveShadow' : objectReceiveShadow,
  3607. 'shadow': objectShadowRadius
  3608. };
  3609. for ( var property in properties ) {
  3610. properties[ property ].setDisplay( object[ property ] !== undefined ? '' : 'none' );
  3611. }
  3612. }
  3613. function updateTransformRows( object ) {
  3614. if ( object instanceof THREE.Light ||
  3615. ( object instanceof THREE.Object3D && object.userData.targetInverse ) ) {
  3616. objectRotationRow.setDisplay( 'none' );
  3617. objectScaleRow.setDisplay( 'none' );
  3618. } else {
  3619. objectRotationRow.setDisplay( '' );
  3620. objectScaleRow.setDisplay( '' );
  3621. }
  3622. }
  3623. // events
  3624. signals.objectSelected.add( function ( object ) {
  3625. if ( object !== null ) {
  3626. container.setDisplay( 'block' );
  3627. updateRows( object );
  3628. updateUI( object );
  3629. } else {
  3630. container.setDisplay( 'none' );
  3631. }
  3632. } );
  3633. signals.objectChanged.add( function ( object ) {
  3634. if ( object !== editor.selected ) return;
  3635. updateUI( object );
  3636. } );
  3637. signals.refreshSidebarObject3D.add( function ( object ) {
  3638. if ( object !== editor.selected ) return;
  3639. updateUI( object );
  3640. } );
  3641. function updateUI( object ) {
  3642. objectType.setValue( object.type );
  3643. objectUUID.setValue( object.uuid );
  3644. objectName.setValue( object.name );
  3645. objectPositionX.setValue( object.position.x );
  3646. objectPositionY.setValue( object.position.y );
  3647. objectPositionZ.setValue( object.position.z );
  3648. objectRotationX.setValue( object.rotation.x * THREE.Math.RAD2DEG );
  3649. objectRotationY.setValue( object.rotation.y * THREE.Math.RAD2DEG );
  3650. objectRotationZ.setValue( object.rotation.z * THREE.Math.RAD2DEG );
  3651. objectScaleX.setValue( object.scale.x );
  3652. objectScaleY.setValue( object.scale.y );
  3653. objectScaleZ.setValue( object.scale.z );
  3654. if ( object.fov !== undefined ) {
  3655. objectFov.setValue( object.fov );
  3656. }
  3657. if ( object.near !== undefined ) {
  3658. objectNear.setValue( object.near );
  3659. }
  3660. if ( object.far !== undefined ) {
  3661. objectFar.setValue( object.far );
  3662. }
  3663. if ( object.intensity !== undefined ) {
  3664. objectIntensity.setValue( object.intensity );
  3665. }
  3666. if ( object.color !== undefined ) {
  3667. objectColor.setHexValue( object.color.getHexString() );
  3668. }
  3669. if ( object.groundColor !== undefined ) {
  3670. objectGroundColor.setHexValue( object.groundColor.getHexString() );
  3671. }
  3672. if ( object.distance !== undefined ) {
  3673. objectDistance.setValue( object.distance );
  3674. }
  3675. if ( object.angle !== undefined ) {
  3676. objectAngle.setValue( object.angle );
  3677. }
  3678. if ( object.penumbra !== undefined ) {
  3679. objectPenumbra.setValue( object.penumbra );
  3680. }
  3681. if ( object.decay !== undefined ) {
  3682. objectDecay.setValue( object.decay );
  3683. }
  3684. if ( object.castShadow !== undefined ) {
  3685. objectCastShadow.setValue( object.castShadow );
  3686. }
  3687. if ( object.receiveShadow !== undefined ) {
  3688. objectReceiveShadow.setValue( object.receiveShadow );
  3689. }
  3690. if ( object.shadow !== undefined ) {
  3691. objectShadowRadius.setValue( object.shadow.radius );
  3692. }
  3693. objectVisible.setValue( object.visible );
  3694. try {
  3695. objectUserData.setValue( JSON.stringify( object.userData, null, ' ' ) );
  3696. } catch ( error ) {
  3697. console.log( error );
  3698. }
  3699. objectUserData.setBorderColor( 'transparent' );
  3700. objectUserData.setBackgroundColor( '' );
  3701. updateTransformRows( object );
  3702. }
  3703. return container;
  3704. };
  3705. /**
  3706. * @author TristanVALCKE / https://github.com/Itee
  3707. */
  3708. /* global QUnit */
  3709. QUnit.module( 'Editor', () => {
  3710. QUnit.module.todo( 'Sidebar.Object', () => {
  3711. QUnit.test( 'write me !', ( assert ) => {
  3712. assert.ok( false, "everything's gonna be alright" );
  3713. } );
  3714. } );
  3715. } );
  3716. /**
  3717. * @author mrdoob / http://mrdoob.com/
  3718. */
  3719. Sidebar.Project = function ( editor ) {
  3720. var config = editor.config;
  3721. var signals = editor.signals;
  3722. var rendererTypes = {
  3723. 'WebGLRenderer': THREE.WebGLRenderer,
  3724. 'CanvasRenderer': THREE.CanvasRenderer,
  3725. 'SVGRenderer': THREE.SVGRenderer,
  3726. 'SoftwareRenderer': THREE.SoftwareRenderer,
  3727. 'RaytracingRenderer': THREE.RaytracingRenderer
  3728. };
  3729. var container = new UI.Panel();
  3730. container.setBorderTop( '0' );
  3731. container.setPaddingTop( '20px' );
  3732. // class
  3733. var options = {};
  3734. for ( var key in rendererTypes ) {
  3735. if ( key.indexOf( 'WebGL' ) >= 0 && System.support.webgl === false ) continue;
  3736. options[ key ] = key;
  3737. }
  3738. var rendererTypeRow = new UI.Row();
  3739. var rendererType = new UI.Select().setOptions( options ).setWidth( '150px' ).onChange( function () {
  3740. var value = this.getValue();
  3741. config.setKey( 'project/renderer', value );
  3742. updateRenderer();
  3743. } );
  3744. rendererTypeRow.add( new UI.Text( 'Renderer' ).setWidth( '90px' ) );
  3745. rendererTypeRow.add( rendererType );
  3746. container.add( rendererTypeRow );
  3747. if ( config.getKey( 'project/renderer' ) !== undefined ) {
  3748. rendererType.setValue( config.getKey( 'project/renderer' ) );
  3749. }
  3750. // antialiasing
  3751. var rendererPropertiesRow = new UI.Row().setMarginLeft( '90px' );
  3752. var rendererAntialias = new UI.THREE.Boolean( config.getKey( 'project/renderer/antialias' ), 'antialias' ).onChange( function () {
  3753. config.setKey( 'project/renderer/antialias', this.getValue() );
  3754. updateRenderer();
  3755. } );
  3756. rendererPropertiesRow.add( rendererAntialias );
  3757. // shadow
  3758. var rendererShadows = new UI.THREE.Boolean( config.getKey( 'project/renderer/shadows' ), 'shadows' ).onChange( function () {
  3759. config.setKey( 'project/renderer/shadows', this.getValue() );
  3760. updateRenderer();
  3761. } );
  3762. rendererPropertiesRow.add( rendererShadows );
  3763. rendererPropertiesRow.add( new UI.Break() );
  3764. // gamma input
  3765. var rendererGammaInput = new UI.THREE.Boolean( config.getKey( 'project/renderer/gammaInput' ), 'γ input' ).onChange( function () {
  3766. config.setKey( 'project/renderer/gammaInput', this.getValue() );
  3767. updateRenderer();
  3768. } );
  3769. rendererPropertiesRow.add( rendererGammaInput );
  3770. // gamma output
  3771. var rendererGammaOutput = new UI.THREE.Boolean( config.getKey( 'project/renderer/gammaOutput' ), 'γ output' ).onChange( function () {
  3772. config.setKey( 'project/renderer/gammaOutput', this.getValue() );
  3773. updateRenderer();
  3774. } );
  3775. rendererPropertiesRow.add( rendererGammaOutput );
  3776. container.add( rendererPropertiesRow );
  3777. // Editable
  3778. var editableRow = new UI.Row();
  3779. var editable = new UI.Checkbox( config.getKey( 'project/editable' ) ).setLeft( '100px' ).onChange( function () {
  3780. config.setKey( 'project/editable', this.getValue() );
  3781. } );
  3782. editableRow.add( new UI.Text( 'Editable' ).setWidth( '90px' ) );
  3783. editableRow.add( editable );
  3784. container.add( editableRow );
  3785. // VR
  3786. var vrRow = new UI.Row();
  3787. var vr = new UI.Checkbox( config.getKey( 'project/vr' ) ).setLeft( '100px' ).onChange( function () {
  3788. config.setKey( 'project/vr', this.getValue() );
  3789. } );
  3790. vrRow.add( new UI.Text( 'VR' ).setWidth( '90px' ) );
  3791. vrRow.add( vr );
  3792. container.add( vrRow );
  3793. //
  3794. function updateRenderer() {
  3795. createRenderer( rendererType.getValue(), rendererAntialias.getValue(), rendererShadows.getValue(), rendererGammaInput.getValue(), rendererGammaOutput.getValue() );
  3796. }
  3797. function createRenderer( type, antialias, shadows, gammaIn, gammaOut ) {
  3798. if ( type === 'WebGLRenderer' && System.support.webgl === false ) {
  3799. type = 'CanvasRenderer';
  3800. }
  3801. rendererPropertiesRow.setDisplay( type === 'WebGLRenderer' ? '' : 'none' );
  3802. var renderer = new rendererTypes[ type ]( { antialias: antialias} );
  3803. renderer.gammaInput = gammaIn;
  3804. renderer.gammaOutput = gammaOut;
  3805. if ( shadows && renderer.shadowMap ) {
  3806. renderer.shadowMap.enabled = true;
  3807. // renderer.shadowMap.type = THREE.PCFSoftShadowMap;
  3808. }
  3809. signals.rendererChanged.dispatch( renderer );
  3810. }
  3811. createRenderer( config.getKey( 'project/renderer' ), config.getKey( 'project/renderer/antialias' ), config.getKey( 'project/renderer/shadows' ), config.getKey( 'project/renderer/gammaInput' ), config.getKey( 'project/renderer/gammaOutput' ) );
  3812. return container;
  3813. };
  3814. /**
  3815. * @author TristanVALCKE / https://github.com/Itee
  3816. */
  3817. /* global QUnit */
  3818. QUnit.module( 'Editor', () => {
  3819. QUnit.module.todo( 'Sidebar.Project', () => {
  3820. QUnit.test( 'write me !', ( assert ) => {
  3821. assert.ok( false, "everything's gonna be alright" );
  3822. } );
  3823. } );
  3824. } );
  3825. /**
  3826. * @author mrdoob / http://mrdoob.com/
  3827. */
  3828. Sidebar.Properties = function ( editor ) {
  3829. var signals = editor.signals;
  3830. var container = new UI.Span();
  3831. var objectTab = new UI.Text( 'OBJECT' ).onClick( onClick );
  3832. var geometryTab = new UI.Text( 'GEOMETRY' ).onClick( onClick );
  3833. var materialTab = new UI.Text( 'MATERIAL' ).onClick( onClick );
  3834. var tabs = new UI.Div();
  3835. tabs.setId( 'tabs' );
  3836. tabs.add( objectTab, geometryTab, materialTab );
  3837. container.add( tabs );
  3838. function onClick( event ) {
  3839. select( event.target.textContent );
  3840. }
  3841. //
  3842. var object = new UI.Span().add(
  3843. new Sidebar.Object( editor )
  3844. );
  3845. container.add( object );
  3846. var geometry = new UI.Span().add(
  3847. new Sidebar.Geometry( editor )
  3848. );
  3849. container.add( geometry );
  3850. var material = new UI.Span().add(
  3851. new Sidebar.Material( editor )
  3852. );
  3853. container.add( material );
  3854. //
  3855. function select( section ) {
  3856. objectTab.setClass( '' );
  3857. geometryTab.setClass( '' );
  3858. materialTab.setClass( '' );
  3859. object.setDisplay( 'none' );
  3860. geometry.setDisplay( 'none' );
  3861. material.setDisplay( 'none' );
  3862. switch ( section ) {
  3863. case 'OBJECT':
  3864. objectTab.setClass( 'selected' );
  3865. object.setDisplay( '' );
  3866. break;
  3867. case 'GEOMETRY':
  3868. geometryTab.setClass( 'selected' );
  3869. geometry.setDisplay( '' );
  3870. break;
  3871. case 'MATERIAL':
  3872. materialTab.setClass( 'selected' );
  3873. material.setDisplay( '' );
  3874. break;
  3875. }
  3876. }
  3877. select( 'OBJECT' );
  3878. return container;
  3879. };
  3880. /**
  3881. * @author TristanVALCKE / https://github.com/Itee
  3882. */
  3883. /* global QUnit */
  3884. QUnit.module( 'Editor', () => {
  3885. QUnit.module.todo( 'Sidebar.Properties', () => {
  3886. QUnit.test( 'write me !', ( assert ) => {
  3887. assert.ok( false, "everything's gonna be alright" );
  3888. } );
  3889. } );
  3890. } );
  3891. /**
  3892. * @author mrdoob / http://mrdoob.com/
  3893. */
  3894. Sidebar.Scene = function ( editor ) {
  3895. var signals = editor.signals;
  3896. var container = new UI.Panel();
  3897. container.setBorderTop( '0' );
  3898. container.setPaddingTop( '20px' );
  3899. // outliner
  3900. function buildOption( object, draggable ) {
  3901. var option = document.createElement( 'div' );
  3902. option.draggable = draggable;
  3903. option.innerHTML = buildHTML( object );
  3904. option.value = object.id;
  3905. return option;
  3906. }
  3907. function getMaterialName( material ) {
  3908. if ( Array.isArray( material ) ) {
  3909. var array = [];
  3910. for ( var i = 0; i < material.length; i ++ ) {
  3911. array.push( material[ i ].name );
  3912. }
  3913. return array.join( ',' );
  3914. }
  3915. return material.name;
  3916. }
  3917. function buildHTML( object ) {
  3918. var html = '<span class="type ' + object.type + '"></span> ' + object.name;
  3919. if ( object instanceof THREE.Mesh ) {
  3920. var geometry = object.geometry;
  3921. var material = object.material;
  3922. html += ' <span class="type ' + geometry.type + '"></span> ' + geometry.name;
  3923. html += ' <span class="type ' + material.type + '"></span> ' + getMaterialName( material );
  3924. }
  3925. html += getScript( object.uuid );
  3926. return html;
  3927. }
  3928. function getScript( uuid ) {
  3929. if ( editor.scripts[ uuid ] !== undefined ) {
  3930. return ' <span class="type Script"></span>';
  3931. }
  3932. return '';
  3933. }
  3934. var ignoreObjectSelectedSignal = false;
  3935. var outliner = new UI.Outliner( editor );
  3936. outliner.setId( 'outliner' );
  3937. outliner.onChange( function () {
  3938. ignoreObjectSelectedSignal = true;
  3939. editor.selectById( parseInt( outliner.getValue() ) );
  3940. ignoreObjectSelectedSignal = false;
  3941. } );
  3942. outliner.onDblClick( function () {
  3943. editor.focusById( parseInt( outliner.getValue() ) );
  3944. } );
  3945. container.add( outliner );
  3946. container.add( new UI.Break() );
  3947. // background
  3948. function onBackgroundChanged() {
  3949. signals.sceneBackgroundChanged.dispatch( backgroundColor.getHexValue() );
  3950. }
  3951. var backgroundRow = new UI.Row();
  3952. var backgroundColor = new UI.Color().setValue( '#aaaaaa' ).onChange( onBackgroundChanged );
  3953. backgroundRow.add( new UI.Text( 'Background' ).setWidth( '90px' ) );
  3954. backgroundRow.add( backgroundColor );
  3955. container.add( backgroundRow );
  3956. // fog
  3957. function onFogChanged() {
  3958. signals.sceneFogChanged.dispatch(
  3959. fogType.getValue(),
  3960. fogColor.getHexValue(),
  3961. fogNear.getValue(),
  3962. fogFar.getValue(),
  3963. fogDensity.getValue()
  3964. );
  3965. }
  3966. var fogTypeRow = new UI.Row();
  3967. var fogType = new UI.Select().setOptions( {
  3968. 'None': 'None',
  3969. 'Fog': 'Linear',
  3970. 'FogExp2': 'Exponential'
  3971. } ).setWidth( '150px' );
  3972. fogType.onChange( function () {
  3973. onFogChanged();
  3974. refreshFogUI();
  3975. } );
  3976. fogTypeRow.add( new UI.Text( 'Fog' ).setWidth( '90px' ) );
  3977. fogTypeRow.add( fogType );
  3978. container.add( fogTypeRow );
  3979. // fog color
  3980. var fogPropertiesRow = new UI.Row();
  3981. fogPropertiesRow.setDisplay( 'none' );
  3982. fogPropertiesRow.setMarginLeft( '90px' );
  3983. container.add( fogPropertiesRow );
  3984. var fogColor = new UI.Color().setValue( '#aaaaaa' );
  3985. fogColor.onChange( onFogChanged );
  3986. fogPropertiesRow.add( fogColor );
  3987. // fog near
  3988. var fogNear = new UI.Number( 0.1 ).setWidth( '40px' ).setRange( 0, Infinity ).onChange( onFogChanged );
  3989. fogPropertiesRow.add( fogNear );
  3990. // fog far
  3991. var fogFar = new UI.Number( 50 ).setWidth( '40px' ).setRange( 0, Infinity ).onChange( onFogChanged );
  3992. fogPropertiesRow.add( fogFar );
  3993. // fog density
  3994. var fogDensity = new UI.Number( 0.05 ).setWidth( '40px' ).setRange( 0, 0.1 ).setPrecision( 3 ).onChange( onFogChanged );
  3995. fogPropertiesRow.add( fogDensity );
  3996. //
  3997. function refreshUI() {
  3998. var camera = editor.camera;
  3999. var scene = editor.scene;
  4000. var options = [];
  4001. options.push( buildOption( camera, false ) );
  4002. options.push( buildOption( scene, false ) );
  4003. ( function addObjects( objects, pad ) {
  4004. for ( var i = 0, l = objects.length; i < l; i ++ ) {
  4005. var object = objects[ i ];
  4006. var option = buildOption( object, true );
  4007. option.style.paddingLeft = ( pad * 10 ) + 'px';
  4008. options.push( option );
  4009. addObjects( object.children, pad + 1 );
  4010. }
  4011. } )( scene.children, 1 );
  4012. outliner.setOptions( options );
  4013. if ( editor.selected !== null ) {
  4014. outliner.setValue( editor.selected.id );
  4015. }
  4016. if ( scene.background ) {
  4017. backgroundColor.setHexValue( scene.background.getHex() );
  4018. }
  4019. if ( scene.fog ) {
  4020. fogColor.setHexValue( scene.fog.color.getHex() );
  4021. if ( scene.fog instanceof THREE.Fog ) {
  4022. fogType.setValue( "Fog" );
  4023. fogNear.setValue( scene.fog.near );
  4024. fogFar.setValue( scene.fog.far );
  4025. } else if ( scene.fog instanceof THREE.FogExp2 ) {
  4026. fogType.setValue( "FogExp2" );
  4027. fogDensity.setValue( scene.fog.density );
  4028. }
  4029. } else {
  4030. fogType.setValue( "None" );
  4031. }
  4032. refreshFogUI();
  4033. }
  4034. function refreshFogUI() {
  4035. var type = fogType.getValue();
  4036. fogPropertiesRow.setDisplay( type === 'None' ? 'none' : '' );
  4037. fogNear.setDisplay( type === 'Fog' ? '' : 'none' );
  4038. fogFar.setDisplay( type === 'Fog' ? '' : 'none' );
  4039. fogDensity.setDisplay( type === 'FogExp2' ? '' : 'none' );
  4040. }
  4041. refreshUI();
  4042. // events
  4043. signals.editorCleared.add( refreshUI );
  4044. signals.sceneGraphChanged.add( refreshUI );
  4045. signals.objectChanged.add( function ( object ) {
  4046. var options = outliner.options;
  4047. for ( var i = 0; i < options.length; i ++ ) {
  4048. var option = options[ i ];
  4049. if ( option.value === object.id ) {
  4050. option.innerHTML = buildHTML( object );
  4051. return;
  4052. }
  4053. }
  4054. } );
  4055. signals.objectSelected.add( function ( object ) {
  4056. if ( ignoreObjectSelectedSignal === true ) return;
  4057. outliner.setValue( object !== null ? object.id : null );
  4058. } );
  4059. return container;
  4060. };
  4061. /**
  4062. * @author TristanVALCKE / https://github.com/Itee
  4063. */
  4064. /* global QUnit */
  4065. QUnit.module( 'Editor', () => {
  4066. QUnit.module.todo( 'Sidebar.Scene', () => {
  4067. QUnit.test( 'write me !', ( assert ) => {
  4068. assert.ok( false, "everything's gonna be alright" );
  4069. } );
  4070. } );
  4071. } );
  4072. /**
  4073. * @author mrdoob / http://mrdoob.com/
  4074. */
  4075. Sidebar.Script = function ( editor ) {
  4076. var signals = editor.signals;
  4077. var container = new UI.Panel();
  4078. container.setDisplay( 'none' );
  4079. container.add( new UI.Text( 'Script' ).setTextTransform( 'uppercase' ) );
  4080. container.add( new UI.Break() );
  4081. container.add( new UI.Break() );
  4082. //
  4083. var scriptsContainer = new UI.Row();
  4084. container.add( scriptsContainer );
  4085. var newScript = new UI.Button( 'New' );
  4086. newScript.onClick( function () {
  4087. var script = { name: '', source: 'function update( event ) {}' };
  4088. editor.execute( new AddScriptCommand( editor.selected, script ) );
  4089. } );
  4090. container.add( newScript );
  4091. /*
  4092. var loadScript = new UI.Button( 'Load' );
  4093. loadScript.setMarginLeft( '4px' );
  4094. container.add( loadScript );
  4095. */
  4096. //
  4097. function update() {
  4098. scriptsContainer.clear();
  4099. scriptsContainer.setDisplay( 'none' );
  4100. var object = editor.selected;
  4101. if ( object === null ) {
  4102. return;
  4103. }
  4104. var scripts = editor.scripts[ object.uuid ];
  4105. if ( scripts !== undefined ) {
  4106. scriptsContainer.setDisplay( 'block' );
  4107. for ( var i = 0; i < scripts.length; i ++ ) {
  4108. ( function ( object, script ) {
  4109. var name = new UI.Input( script.name ).setWidth( '130px' ).setFontSize( '12px' );
  4110. name.onChange( function () {
  4111. editor.execute( new SetScriptValueCommand( editor.selected, script, 'name', this.getValue() ) );
  4112. } );
  4113. scriptsContainer.add( name );
  4114. var edit = new UI.Button( 'Edit' );
  4115. edit.setMarginLeft( '4px' );
  4116. edit.onClick( function () {
  4117. signals.editScript.dispatch( object, script );
  4118. } );
  4119. scriptsContainer.add( edit );
  4120. var remove = new UI.Button( 'Remove' );
  4121. remove.setMarginLeft( '4px' );
  4122. remove.onClick( function () {
  4123. if ( confirm( 'Are you sure?' ) ) {
  4124. editor.execute( new RemoveScriptCommand( editor.selected, script ) );
  4125. }
  4126. } );
  4127. scriptsContainer.add( remove );
  4128. scriptsContainer.add( new UI.Break() );
  4129. } )( object, scripts[ i ] );
  4130. }
  4131. }
  4132. }
  4133. // signals
  4134. signals.objectSelected.add( function ( object ) {
  4135. if ( object !== null && editor.camera !== object ) {
  4136. container.setDisplay( 'block' );
  4137. update();
  4138. } else {
  4139. container.setDisplay( 'none' );
  4140. }
  4141. } );
  4142. signals.scriptAdded.add( update );
  4143. signals.scriptRemoved.add( update );
  4144. signals.scriptChanged.add( update );
  4145. return container;
  4146. };
  4147. /**
  4148. * @author TristanVALCKE / https://github.com/Itee
  4149. */
  4150. /* global QUnit */
  4151. QUnit.module( 'Editor', () => {
  4152. QUnit.module.todo( 'Sidebar.Script', () => {
  4153. QUnit.test( 'write me !', ( assert ) => {
  4154. assert.ok( false, "everything's gonna be alright" );
  4155. } );
  4156. } );
  4157. } );
  4158. /**
  4159. * @author mrdoob / http://mrdoob.com/
  4160. */
  4161. Sidebar.Settings = function ( editor ) {
  4162. var config = editor.config;
  4163. var signals = editor.signals;
  4164. var container = new UI.Panel();
  4165. container.setBorderTop( '0' );
  4166. container.setPaddingTop( '20px' );
  4167. // class
  4168. var options = {
  4169. 'css/light.css': 'light',
  4170. 'css/dark.css': 'dark'
  4171. };
  4172. var themeRow = new UI.Row();
  4173. var theme = new UI.Select().setWidth( '150px' );
  4174. theme.setOptions( options );
  4175. if ( config.getKey( 'theme' ) !== undefined ) {
  4176. theme.setValue( config.getKey( 'theme' ) );
  4177. }
  4178. theme.onChange( function () {
  4179. var value = this.getValue();
  4180. editor.setTheme( value );
  4181. editor.config.setKey( 'theme', value );
  4182. } );
  4183. themeRow.add( new UI.Text( 'Theme' ).setWidth( '90px' ) );
  4184. themeRow.add( theme );
  4185. container.add( themeRow );
  4186. return container;
  4187. };
  4188. /**
  4189. * @author TristanVALCKE / https://github.com/Itee
  4190. */
  4191. /* global QUnit */
  4192. QUnit.module( 'Editor', () => {
  4193. QUnit.module.todo( 'Sidebar.Settings', () => {
  4194. QUnit.test( 'write me !', ( assert ) => {
  4195. assert.ok( false, "everything's gonna be alright" );
  4196. } );
  4197. } );
  4198. } );
  4199. /**
  4200. * @author mrdoob / http://mrdoob.com/
  4201. */
  4202. /**
  4203. * @author TristanVALCKE / https://github.com/Itee
  4204. */
  4205. /* global QUnit */
  4206. QUnit.module( 'Editor', () => {
  4207. QUnit.module.todo( 'Storage', () => {
  4208. QUnit.test( 'write me !', ( assert ) => {
  4209. assert.ok( false, "everything's gonna be alright" );
  4210. } );
  4211. } );
  4212. } );
  4213. /**
  4214. * @author mrdoob / http://mrdoob.com/
  4215. */
  4216. /**
  4217. * @author TristanVALCKE / https://github.com/Itee
  4218. */
  4219. /* global QUnit */
  4220. QUnit.module( 'Editor', () => {
  4221. QUnit.module.todo( 'Toolbar', () => {
  4222. QUnit.test( 'write me !', ( assert ) => {
  4223. assert.ok( false, "everything's gonna be alright" );
  4224. } );
  4225. } );
  4226. } );
  4227. /**
  4228. * @author mrdoob / http://mrdoob.com/
  4229. */
  4230. /**
  4231. * @author TristanVALCKE / https://github.com/Itee
  4232. */
  4233. /* global QUnit */
  4234. QUnit.module( 'Editor', () => {
  4235. QUnit.module.todo( 'Viewport', () => {
  4236. QUnit.test( 'write me !', ( assert ) => {
  4237. assert.ok( false, "everything's gonna be alright" );
  4238. } );
  4239. } );
  4240. } );
  4241. /**
  4242. * @author mrdoob / http://mrdoob.com/
  4243. */
  4244. Viewport.Info = function ( editor ) {
  4245. var signals = editor.signals;
  4246. var container = new UI.Panel();
  4247. container.setId( 'info' );
  4248. container.setPosition( 'absolute' );
  4249. container.setLeft( '10px' );
  4250. container.setBottom( '10px' );
  4251. container.setFontSize( '12px' );
  4252. container.setColor( '#fff' );
  4253. var objectsText = new UI.Text( '0' ).setMarginLeft( '6px' );
  4254. var verticesText = new UI.Text( '0' ).setMarginLeft( '6px' );
  4255. var trianglesText = new UI.Text( '0' ).setMarginLeft( '6px' );
  4256. container.add( new UI.Text( 'objects' ), objectsText, new UI.Break() );
  4257. container.add( new UI.Text( 'vertices' ), verticesText, new UI.Break() );
  4258. container.add( new UI.Text( 'triangles' ), trianglesText, new UI.Break() );
  4259. signals.objectAdded.add( update );
  4260. signals.objectRemoved.add( update );
  4261. signals.geometryChanged.add( update );
  4262. //
  4263. function update() {
  4264. var scene = editor.scene;
  4265. var objects = 0, vertices = 0, triangles = 0;
  4266. for ( var i = 0, l = scene.children.length; i < l; i ++ ) {
  4267. var object = scene.children[ i ];
  4268. object.traverseVisible( function ( object ) {
  4269. objects ++;
  4270. if ( object instanceof THREE.Mesh ) {
  4271. var geometry = object.geometry;
  4272. if ( geometry instanceof THREE.Geometry ) {
  4273. vertices += geometry.vertices.length;
  4274. triangles += geometry.faces.length;
  4275. } else if ( geometry instanceof THREE.BufferGeometry ) {
  4276. if ( geometry.index !== null ) {
  4277. vertices += geometry.index.count * 3;
  4278. triangles += geometry.index.count;
  4279. } else {
  4280. vertices += geometry.attributes.position.count;
  4281. triangles += geometry.attributes.position.count / 3;
  4282. }
  4283. }
  4284. }
  4285. } );
  4286. }
  4287. objectsText.setValue( objects.format() );
  4288. verticesText.setValue( vertices.format() );
  4289. trianglesText.setValue( triangles.format() );
  4290. }
  4291. return container;
  4292. };
  4293. /**
  4294. * @author TristanVALCKE / https://github.com/Itee
  4295. */
  4296. /* global QUnit */
  4297. QUnit.module( 'Editor', () => {
  4298. QUnit.module.todo( 'Viewport.Info', () => {
  4299. QUnit.test( 'write me !', ( assert ) => {
  4300. assert.ok( false, "everything's gonna be alright" );
  4301. } );
  4302. } );
  4303. } );
  4304. /**
  4305. * @author dforrer / https://github.com/dforrer
  4306. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  4307. */
  4308. /**
  4309. * @param object THREE.Object3D
  4310. * @constructor
  4311. */
  4312. var AddObjectCommand$1 = function ( object ) {
  4313. Command.call( this );
  4314. this.type = 'AddObjectCommand';
  4315. this.object = object;
  4316. if ( object !== undefined ) {
  4317. this.name = 'Add Object: ' + object.name;
  4318. }
  4319. };
  4320. AddObjectCommand$1.prototype = {
  4321. execute: function () {
  4322. this.editor.addObject( this.object );
  4323. this.editor.select( this.object );
  4324. },
  4325. undo: function () {
  4326. this.editor.removeObject( this.object );
  4327. this.editor.deselect();
  4328. },
  4329. toJSON: function () {
  4330. var output = Command.prototype.toJSON.call( this );
  4331. output.object = this.object.toJSON();
  4332. return output;
  4333. },
  4334. fromJSON: function ( json ) {
  4335. Command.prototype.fromJSON.call( this, json );
  4336. this.object = this.editor.objectByUuid( json.object.object.uuid );
  4337. if ( this.object === undefined ) {
  4338. var loader = new THREE.ObjectLoader();
  4339. this.object = loader.parse( json.object );
  4340. }
  4341. }
  4342. };
  4343. /**
  4344. * @author TristanVALCKE / https://github.com/Itee
  4345. */
  4346. /* global QUnit */
  4347. QUnit.module( 'Editor', () => {
  4348. QUnit.module( 'Commands', () => {
  4349. QUnit.module.todo( 'AddObjectCommand', () => {
  4350. QUnit.test( 'write me !', ( assert ) => {
  4351. assert.ok( false, "everything's gonna be alright" );
  4352. } );
  4353. } );
  4354. } );
  4355. } );
  4356. /**
  4357. * @author dforrer / https://github.com/dforrer
  4358. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  4359. */
  4360. /**
  4361. * @param object THREE.Object3D
  4362. * @param script javascript object
  4363. * @constructor
  4364. */
  4365. var AddScriptCommand$1 = function ( object, script ) {
  4366. Command.call( this );
  4367. this.type = 'AddScriptCommand';
  4368. this.name = 'Add Script';
  4369. this.object = object;
  4370. this.script = script;
  4371. };
  4372. AddScriptCommand$1.prototype = {
  4373. execute: function () {
  4374. if ( this.editor.scripts[ this.object.uuid ] === undefined ) {
  4375. this.editor.scripts[ this.object.uuid ] = [];
  4376. }
  4377. this.editor.scripts[ this.object.uuid ].push( this.script );
  4378. this.editor.signals.scriptAdded.dispatch( this.script );
  4379. },
  4380. undo: function () {
  4381. if ( this.editor.scripts[ this.object.uuid ] === undefined ) return;
  4382. var index = this.editor.scripts[ this.object.uuid ].indexOf( this.script );
  4383. if ( index !== - 1 ) {
  4384. this.editor.scripts[ this.object.uuid ].splice( index, 1 );
  4385. }
  4386. this.editor.signals.scriptRemoved.dispatch( this.script );
  4387. },
  4388. toJSON: function () {
  4389. var output = Command.prototype.toJSON.call( this );
  4390. output.objectUuid = this.object.uuid;
  4391. output.script = this.script;
  4392. return output;
  4393. },
  4394. fromJSON: function ( json ) {
  4395. Command.prototype.fromJSON.call( this, json );
  4396. this.script = json.script;
  4397. this.object = this.editor.objectByUuid( json.objectUuid );
  4398. }
  4399. };
  4400. /**
  4401. * @author TristanVALCKE / https://github.com/Itee
  4402. */
  4403. /* global QUnit */
  4404. QUnit.module( 'Editor', () => {
  4405. QUnit.module( 'Commands', () => {
  4406. QUnit.module.todo( 'AddScriptCommand', () => {
  4407. QUnit.test( 'write me !', ( assert ) => {
  4408. assert.ok( false, "everything's gonna be alright" );
  4409. } );
  4410. } );
  4411. } );
  4412. } );
  4413. /**
  4414. * @author dforrer / https://github.com/dforrer
  4415. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  4416. */
  4417. /**
  4418. * @param object THREE.Object3D
  4419. * @param newParent THREE.Object3D
  4420. * @param newBefore THREE.Object3D
  4421. * @constructor
  4422. */
  4423. var MoveObjectCommand = function ( object, newParent, newBefore ) {
  4424. Command.call( this );
  4425. this.type = 'MoveObjectCommand';
  4426. this.name = 'Move Object';
  4427. this.object = object;
  4428. this.oldParent = ( object !== undefined ) ? object.parent : undefined;
  4429. this.oldIndex = ( this.oldParent !== undefined ) ? this.oldParent.children.indexOf( this.object ) : undefined;
  4430. this.newParent = newParent;
  4431. if ( newBefore !== undefined ) {
  4432. this.newIndex = ( newParent !== undefined ) ? newParent.children.indexOf( newBefore ) : undefined;
  4433. } else {
  4434. this.newIndex = ( newParent !== undefined ) ? newParent.children.length : undefined;
  4435. }
  4436. if ( this.oldParent === this.newParent && this.newIndex > this.oldIndex ) {
  4437. this.newIndex --;
  4438. }
  4439. this.newBefore = newBefore;
  4440. };
  4441. MoveObjectCommand.prototype = {
  4442. execute: function () {
  4443. this.oldParent.remove( this.object );
  4444. var children = this.newParent.children;
  4445. children.splice( this.newIndex, 0, this.object );
  4446. this.object.parent = this.newParent;
  4447. this.editor.signals.sceneGraphChanged.dispatch();
  4448. },
  4449. undo: function () {
  4450. this.newParent.remove( this.object );
  4451. var children = this.oldParent.children;
  4452. children.splice( this.oldIndex, 0, this.object );
  4453. this.object.parent = this.oldParent;
  4454. this.editor.signals.sceneGraphChanged.dispatch();
  4455. },
  4456. toJSON: function () {
  4457. var output = Command.prototype.toJSON.call( this );
  4458. output.objectUuid = this.object.uuid;
  4459. output.newParentUuid = this.newParent.uuid;
  4460. output.oldParentUuid = this.oldParent.uuid;
  4461. output.newIndex = this.newIndex;
  4462. output.oldIndex = this.oldIndex;
  4463. return output;
  4464. },
  4465. fromJSON: function ( json ) {
  4466. Command.prototype.fromJSON.call( this, json );
  4467. this.object = this.editor.objectByUuid( json.objectUuid );
  4468. this.oldParent = this.editor.objectByUuid( json.oldParentUuid );
  4469. if ( this.oldParent === undefined ) {
  4470. this.oldParent = this.editor.scene;
  4471. }
  4472. this.newParent = this.editor.objectByUuid( json.newParentUuid );
  4473. if ( this.newParent === undefined ) {
  4474. this.newParent = this.editor.scene;
  4475. }
  4476. this.newIndex = json.newIndex;
  4477. this.oldIndex = json.oldIndex;
  4478. }
  4479. };
  4480. /**
  4481. * @author TristanVALCKE / https://github.com/Itee
  4482. */
  4483. /* global QUnit */
  4484. QUnit.module( 'Editor', () => {
  4485. QUnit.module( 'Commands', () => {
  4486. QUnit.module.todo( 'MoveObjectCommand', () => {
  4487. QUnit.test( 'write me !', ( assert ) => {
  4488. assert.ok( false, "everything's gonna be alright" );
  4489. } );
  4490. } );
  4491. } );
  4492. } );
  4493. /**
  4494. * @author dforrer / https://github.com/dforrer
  4495. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  4496. */
  4497. /**
  4498. * @param cmdArray array containing command objects
  4499. * @constructor
  4500. */
  4501. var MultiCmdsCommand$1 = function ( cmdArray ) {
  4502. Command.call( this );
  4503. this.type = 'MultiCmdsCommand';
  4504. this.name = 'Multiple Changes';
  4505. this.cmdArray = ( cmdArray !== undefined ) ? cmdArray : [];
  4506. };
  4507. MultiCmdsCommand$1.prototype = {
  4508. execute: function () {
  4509. this.editor.signals.sceneGraphChanged.active = false;
  4510. for ( var i = 0; i < this.cmdArray.length; i ++ ) {
  4511. this.cmdArray[ i ].execute();
  4512. }
  4513. this.editor.signals.sceneGraphChanged.active = true;
  4514. this.editor.signals.sceneGraphChanged.dispatch();
  4515. },
  4516. undo: function () {
  4517. this.editor.signals.sceneGraphChanged.active = false;
  4518. for ( var i = this.cmdArray.length - 1; i >= 0; i -- ) {
  4519. this.cmdArray[ i ].undo();
  4520. }
  4521. this.editor.signals.sceneGraphChanged.active = true;
  4522. this.editor.signals.sceneGraphChanged.dispatch();
  4523. },
  4524. toJSON: function () {
  4525. var output = Command.prototype.toJSON.call( this );
  4526. var cmds = [];
  4527. for ( var i = 0; i < this.cmdArray.length; i ++ ) {
  4528. cmds.push( this.cmdArray[ i ].toJSON() );
  4529. }
  4530. output.cmds = cmds;
  4531. return output;
  4532. },
  4533. fromJSON: function ( json ) {
  4534. Command.prototype.fromJSON.call( this, json );
  4535. var cmds = json.cmds;
  4536. for ( var i = 0; i < cmds.length; i ++ ) {
  4537. var cmd = new window[ cmds[ i ].type ](); // creates a new object of type "json.type"
  4538. cmd.fromJSON( cmds[ i ] );
  4539. this.cmdArray.push( cmd );
  4540. }
  4541. }
  4542. };
  4543. /**
  4544. * @author TristanVALCKE / https://github.com/Itee
  4545. */
  4546. /* global QUnit */
  4547. QUnit.module( 'Editor', () => {
  4548. QUnit.module( 'Commands', () => {
  4549. QUnit.module.todo( 'MultiCmdsCommand', () => {
  4550. QUnit.test( 'write me !', ( assert ) => {
  4551. assert.ok( false, "everything's gonna be alright" );
  4552. } );
  4553. } );
  4554. } );
  4555. } );
  4556. /**
  4557. * @author dforrer / https://github.com/dforrer
  4558. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  4559. */
  4560. /**
  4561. * @param object THREE.Object3D
  4562. * @constructor
  4563. */
  4564. var RemoveObjectCommand$1 = function ( object ) {
  4565. Command.call( this );
  4566. this.type = 'RemoveObjectCommand';
  4567. this.name = 'Remove Object';
  4568. this.object = object;
  4569. this.parent = ( object !== undefined ) ? object.parent : undefined;
  4570. if ( this.parent !== undefined ) {
  4571. this.index = this.parent.children.indexOf( this.object );
  4572. }
  4573. };
  4574. RemoveObjectCommand$1.prototype = {
  4575. execute: function () {
  4576. var scope = this.editor;
  4577. this.object.traverse( function ( child ) {
  4578. scope.removeHelper( child );
  4579. } );
  4580. this.parent.remove( this.object );
  4581. this.editor.select( this.parent );
  4582. this.editor.signals.objectRemoved.dispatch( this.object );
  4583. this.editor.signals.sceneGraphChanged.dispatch();
  4584. },
  4585. undo: function () {
  4586. var scope = this.editor;
  4587. this.object.traverse( function ( child ) {
  4588. if ( child.geometry !== undefined ) scope.addGeometry( child.geometry );
  4589. if ( child.material !== undefined ) scope.addMaterial( child.material );
  4590. scope.addHelper( child );
  4591. } );
  4592. this.parent.children.splice( this.index, 0, this.object );
  4593. this.object.parent = this.parent;
  4594. this.editor.select( this.object );
  4595. this.editor.signals.objectAdded.dispatch( this.object );
  4596. this.editor.signals.sceneGraphChanged.dispatch();
  4597. },
  4598. toJSON: function () {
  4599. var output = Command.prototype.toJSON.call( this );
  4600. output.object = this.object.toJSON();
  4601. output.index = this.index;
  4602. output.parentUuid = this.parent.uuid;
  4603. return output;
  4604. },
  4605. fromJSON: function ( json ) {
  4606. Command.prototype.fromJSON.call( this, json );
  4607. this.parent = this.editor.objectByUuid( json.parentUuid );
  4608. if ( this.parent === undefined ) {
  4609. this.parent = this.editor.scene;
  4610. }
  4611. this.index = json.index;
  4612. this.object = this.editor.objectByUuid( json.object.object.uuid );
  4613. if ( this.object === undefined ) {
  4614. var loader = new THREE.ObjectLoader();
  4615. this.object = loader.parse( json.object );
  4616. }
  4617. }
  4618. };
  4619. /**
  4620. * @author TristanVALCKE / https://github.com/Itee
  4621. */
  4622. /* global QUnit */
  4623. QUnit.module( 'Editor', () => {
  4624. QUnit.module( 'Commands', () => {
  4625. QUnit.module.todo( 'RemoveObjectCommand', () => {
  4626. QUnit.test( 'write me !', ( assert ) => {
  4627. assert.ok( false, "everything's gonna be alright" );
  4628. } );
  4629. } );
  4630. } );
  4631. } );
  4632. /**
  4633. * @author dforrer / https://github.com/dforrer
  4634. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  4635. */
  4636. /**
  4637. * @param object THREE.Object3D
  4638. * @param script javascript object
  4639. * @constructor
  4640. */
  4641. var RemoveScriptCommand$1 = function ( object, script ) {
  4642. Command.call( this );
  4643. this.type = 'RemoveScriptCommand';
  4644. this.name = 'Remove Script';
  4645. this.object = object;
  4646. this.script = script;
  4647. if ( this.object && this.script ) {
  4648. this.index = this.editor.scripts[ this.object.uuid ].indexOf( this.script );
  4649. }
  4650. };
  4651. RemoveScriptCommand$1.prototype = {
  4652. execute: function () {
  4653. if ( this.editor.scripts[ this.object.uuid ] === undefined ) return;
  4654. if ( this.index !== - 1 ) {
  4655. this.editor.scripts[ this.object.uuid ].splice( this.index, 1 );
  4656. }
  4657. this.editor.signals.scriptRemoved.dispatch( this.script );
  4658. },
  4659. undo: function () {
  4660. if ( this.editor.scripts[ this.object.uuid ] === undefined ) {
  4661. this.editor.scripts[ this.object.uuid ] = [];
  4662. }
  4663. this.editor.scripts[ this.object.uuid ].splice( this.index, 0, this.script );
  4664. this.editor.signals.scriptAdded.dispatch( this.script );
  4665. },
  4666. toJSON: function () {
  4667. var output = Command.prototype.toJSON.call( this );
  4668. output.objectUuid = this.object.uuid;
  4669. output.script = this.script;
  4670. output.index = this.index;
  4671. return output;
  4672. },
  4673. fromJSON: function ( json ) {
  4674. Command.prototype.fromJSON.call( this, json );
  4675. this.script = json.script;
  4676. this.index = json.index;
  4677. this.object = this.editor.objectByUuid( json.objectUuid );
  4678. }
  4679. };
  4680. /**
  4681. * @author TristanVALCKE / https://github.com/Itee
  4682. */
  4683. /* global QUnit */
  4684. QUnit.module( 'Editor', () => {
  4685. QUnit.module( 'Commands', () => {
  4686. QUnit.module.todo( 'RemoveScriptCommand', () => {
  4687. QUnit.test( 'write me !', ( assert ) => {
  4688. assert.ok( false, "everything's gonna be alright" );
  4689. } );
  4690. } );
  4691. } );
  4692. } );
  4693. /**
  4694. * @author dforrer / https://github.com/dforrer
  4695. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  4696. */
  4697. /**
  4698. * @param object THREE.Object3D
  4699. * @param attributeName string
  4700. * @param newValue integer representing a hex color value
  4701. * @constructor
  4702. */
  4703. var SetColorCommand$1 = function ( object, attributeName, newValue ) {
  4704. Command.call( this );
  4705. this.type = 'SetColorCommand';
  4706. this.name = 'Set ' + attributeName;
  4707. this.updatable = true;
  4708. this.object = object;
  4709. this.attributeName = attributeName;
  4710. this.oldValue = ( object !== undefined ) ? this.object[ this.attributeName ].getHex() : undefined;
  4711. this.newValue = newValue;
  4712. };
  4713. SetColorCommand$1.prototype = {
  4714. execute: function () {
  4715. this.object[ this.attributeName ].setHex( this.newValue );
  4716. this.editor.signals.objectChanged.dispatch( this.object );
  4717. },
  4718. undo: function () {
  4719. this.object[ this.attributeName ].setHex( this.oldValue );
  4720. this.editor.signals.objectChanged.dispatch( this.object );
  4721. },
  4722. update: function ( cmd ) {
  4723. this.newValue = cmd.newValue;
  4724. },
  4725. toJSON: function () {
  4726. var output = Command.prototype.toJSON.call( this );
  4727. output.objectUuid = this.object.uuid;
  4728. output.attributeName = this.attributeName;
  4729. output.oldValue = this.oldValue;
  4730. output.newValue = this.newValue;
  4731. return output;
  4732. },
  4733. fromJSON: function ( json ) {
  4734. Command.prototype.fromJSON.call( this, json );
  4735. this.object = this.editor.objectByUuid( json.objectUuid );
  4736. this.attributeName = json.attributeName;
  4737. this.oldValue = json.oldValue;
  4738. this.newValue = json.newValue;
  4739. }
  4740. };
  4741. /**
  4742. * @author TristanVALCKE / https://github.com/Itee
  4743. */
  4744. /* global QUnit */
  4745. QUnit.module( 'Editor', () => {
  4746. QUnit.module( 'Commands', () => {
  4747. QUnit.module.todo( 'SetColorCommand', () => {
  4748. QUnit.test( 'write me !', ( assert ) => {
  4749. assert.ok( false, "everything's gonna be alright" );
  4750. } );
  4751. } );
  4752. } );
  4753. } );
  4754. /**
  4755. * @author dforrer / https://github.com/dforrer
  4756. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  4757. */
  4758. /**
  4759. * @param object THREE.Object3D
  4760. * @param newGeometry THREE.Geometry
  4761. * @constructor
  4762. */
  4763. var SetGeometryCommand$1 = function ( object, newGeometry ) {
  4764. Command.call( this );
  4765. this.type = 'SetGeometryCommand';
  4766. this.name = 'Set Geometry';
  4767. this.updatable = true;
  4768. this.object = object;
  4769. this.oldGeometry = ( object !== undefined ) ? object.geometry : undefined;
  4770. this.newGeometry = newGeometry;
  4771. };
  4772. SetGeometryCommand$1.prototype = {
  4773. execute: function () {
  4774. this.object.geometry.dispose();
  4775. this.object.geometry = this.newGeometry;
  4776. this.object.geometry.computeBoundingSphere();
  4777. this.editor.signals.geometryChanged.dispatch( this.object );
  4778. this.editor.signals.sceneGraphChanged.dispatch();
  4779. },
  4780. undo: function () {
  4781. this.object.geometry.dispose();
  4782. this.object.geometry = this.oldGeometry;
  4783. this.object.geometry.computeBoundingSphere();
  4784. this.editor.signals.geometryChanged.dispatch( this.object );
  4785. this.editor.signals.sceneGraphChanged.dispatch();
  4786. },
  4787. update: function ( cmd ) {
  4788. this.newGeometry = cmd.newGeometry;
  4789. },
  4790. toJSON: function () {
  4791. var output = Command.prototype.toJSON.call( this );
  4792. output.objectUuid = this.object.uuid;
  4793. output.oldGeometry = this.object.geometry.toJSON();
  4794. output.newGeometry = this.newGeometry.toJSON();
  4795. return output;
  4796. },
  4797. fromJSON: function ( json ) {
  4798. Command.prototype.fromJSON.call( this, json );
  4799. this.object = this.editor.objectByUuid( json.objectUuid );
  4800. this.oldGeometry = parseGeometry( json.oldGeometry );
  4801. this.newGeometry = parseGeometry( json.newGeometry );
  4802. function parseGeometry ( data ) {
  4803. var loader = new THREE.ObjectLoader();
  4804. return loader.parseGeometries( [ data ] )[ data.uuid ];
  4805. }
  4806. }
  4807. };
  4808. /**
  4809. * @author TristanVALCKE / https://github.com/Itee
  4810. */
  4811. /* global QUnit */
  4812. QUnit.module( 'Editor', () => {
  4813. QUnit.module( 'Commands', () => {
  4814. QUnit.module.todo( 'SetGeometryCommand', () => {
  4815. QUnit.test( 'write me !', ( assert ) => {
  4816. assert.ok( false, "everything's gonna be alright" );
  4817. } );
  4818. } );
  4819. } );
  4820. } );
  4821. /**
  4822. * @author dforrer / https://github.com/dforrer
  4823. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  4824. */
  4825. /**
  4826. * @param object THREE.Object3D
  4827. * @param attributeName string
  4828. * @param newValue number, string, boolean or object
  4829. * @constructor
  4830. */
  4831. var SetGeometryValueCommand$1 = function ( object, attributeName, newValue ) {
  4832. Command.call( this );
  4833. this.type = 'SetGeometryValueCommand';
  4834. this.name = 'Set Geometry.' + attributeName;
  4835. this.object = object;
  4836. this.attributeName = attributeName;
  4837. this.oldValue = ( object !== undefined ) ? object.geometry[ attributeName ] : undefined;
  4838. this.newValue = newValue;
  4839. };
  4840. SetGeometryValueCommand$1.prototype = {
  4841. execute: function () {
  4842. this.object.geometry[ this.attributeName ] = this.newValue;
  4843. this.editor.signals.objectChanged.dispatch( this.object );
  4844. this.editor.signals.geometryChanged.dispatch();
  4845. this.editor.signals.sceneGraphChanged.dispatch();
  4846. },
  4847. undo: function () {
  4848. this.object.geometry[ this.attributeName ] = this.oldValue;
  4849. this.editor.signals.objectChanged.dispatch( this.object );
  4850. this.editor.signals.geometryChanged.dispatch();
  4851. this.editor.signals.sceneGraphChanged.dispatch();
  4852. },
  4853. toJSON: function () {
  4854. var output = Command.prototype.toJSON.call( this );
  4855. output.objectUuid = this.object.uuid;
  4856. output.attributeName = this.attributeName;
  4857. output.oldValue = this.oldValue;
  4858. output.newValue = this.newValue;
  4859. return output;
  4860. },
  4861. fromJSON: function ( json ) {
  4862. Command.prototype.fromJSON.call( this, json );
  4863. this.object = this.editor.objectByUuid( json.objectUuid );
  4864. this.attributeName = json.attributeName;
  4865. this.oldValue = json.oldValue;
  4866. this.newValue = json.newValue;
  4867. }
  4868. };
  4869. /**
  4870. * @author TristanVALCKE / https://github.com/Itee
  4871. */
  4872. /* global QUnit */
  4873. QUnit.module( 'Editor', () => {
  4874. QUnit.module( 'Commands', () => {
  4875. QUnit.module.todo( 'SetGeometryValueCommand', () => {
  4876. QUnit.test( 'write me !', ( assert ) => {
  4877. assert.ok( false, "everything's gonna be alright" );
  4878. } );
  4879. } );
  4880. } );
  4881. } );
  4882. /**
  4883. * @author dforrer / https://github.com/dforrer
  4884. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  4885. */
  4886. /**
  4887. * @param object THREE.Object3D
  4888. * @param attributeName string
  4889. * @param newValue integer representing a hex color value
  4890. * @constructor
  4891. */
  4892. var SetMaterialColorCommand$1 = function ( object, attributeName, newValue, materialSlot ) {
  4893. Command.call( this );
  4894. this.type = 'SetMaterialColorCommand';
  4895. this.name = 'Set Material.' + attributeName;
  4896. this.updatable = true;
  4897. this.object = object;
  4898. this.material = this.editor.getObjectMaterial( object, materialSlot );
  4899. this.oldValue = ( this.material !== undefined ) ? this.material[ attributeName ].getHex() : undefined;
  4900. this.newValue = newValue;
  4901. this.attributeName = attributeName;
  4902. };
  4903. SetMaterialColorCommand$1.prototype = {
  4904. execute: function () {
  4905. this.material[ this.attributeName ].setHex( this.newValue );
  4906. this.editor.signals.materialChanged.dispatch( this.material );
  4907. },
  4908. undo: function () {
  4909. this.material[ this.attributeName ].setHex( this.oldValue );
  4910. this.editor.signals.materialChanged.dispatch( this.material );
  4911. },
  4912. update: function ( cmd ) {
  4913. this.newValue = cmd.newValue;
  4914. },
  4915. toJSON: function () {
  4916. var output = Command.prototype.toJSON.call( this );
  4917. output.objectUuid = this.object.uuid;
  4918. output.attributeName = this.attributeName;
  4919. output.oldValue = this.oldValue;
  4920. output.newValue = this.newValue;
  4921. return output;
  4922. },
  4923. fromJSON: function ( json ) {
  4924. Command.prototype.fromJSON.call( this, json );
  4925. this.object = this.editor.objectByUuid( json.objectUuid );
  4926. this.attributeName = json.attributeName;
  4927. this.oldValue = json.oldValue;
  4928. this.newValue = json.newValue;
  4929. }
  4930. };
  4931. /**
  4932. * @author TristanVALCKE / https://github.com/Itee
  4933. */
  4934. /* global QUnit */
  4935. QUnit.module( 'Editor', () => {
  4936. QUnit.module( 'Commands', () => {
  4937. QUnit.module.todo( 'SetMaterialColorCommand', () => {
  4938. QUnit.test( 'write me !', ( assert ) => {
  4939. assert.ok( false, "everything's gonna be alright" );
  4940. } );
  4941. } );
  4942. } );
  4943. } );
  4944. /**
  4945. * @author dforrer / https://github.com/dforrer
  4946. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  4947. */
  4948. /**
  4949. * @param object THREE.Object3D
  4950. * @param newMaterial THREE.Material
  4951. * @constructor
  4952. */
  4953. var SetMaterialCommand$1 = function ( object, newMaterial, materialSlot ) {
  4954. Command.call( this );
  4955. this.type = 'SetMaterialCommand';
  4956. this.name = 'New Material';
  4957. this.object = object;
  4958. this.materialSlot = materialSlot;
  4959. this.oldMaterial = this.editor.getObjectMaterial( object, materialSlot );
  4960. this.newMaterial = newMaterial;
  4961. };
  4962. SetMaterialCommand$1.prototype = {
  4963. execute: function () {
  4964. this.editor.setObjectMaterial( this.object, this.materialSlot, this.newMaterial );
  4965. this.editor.signals.materialChanged.dispatch( this.newMaterial );
  4966. },
  4967. undo: function () {
  4968. this.editor.setObjectMaterial( this.object, this.materialSlot, this.oldMaterial );
  4969. this.editor.signals.materialChanged.dispatch( this.oldMaterial );
  4970. },
  4971. toJSON: function () {
  4972. var output = Command.prototype.toJSON.call( this );
  4973. output.objectUuid = this.object.uuid;
  4974. output.oldMaterial = this.oldMaterial.toJSON();
  4975. output.newMaterial = this.newMaterial.toJSON();
  4976. return output;
  4977. },
  4978. fromJSON: function ( json ) {
  4979. Command.prototype.fromJSON.call( this, json );
  4980. this.object = this.editor.objectByUuid( json.objectUuid );
  4981. this.oldMaterial = parseMaterial( json.oldMaterial );
  4982. this.newMaterial = parseMaterial( json.newMaterial );
  4983. function parseMaterial ( json ) {
  4984. var loader = new THREE.ObjectLoader();
  4985. var images = loader.parseImages( json.images );
  4986. var textures = loader.parseTextures( json.textures, images );
  4987. var materials = loader.parseMaterials( [ json ], textures );
  4988. return materials[ json.uuid ];
  4989. }
  4990. }
  4991. };
  4992. /**
  4993. * @author TristanVALCKE / https://github.com/Itee
  4994. */
  4995. /* global QUnit */
  4996. QUnit.module( 'Editor', () => {
  4997. QUnit.module( 'Commands', () => {
  4998. QUnit.module.todo( 'SetMaterialCommand', () => {
  4999. QUnit.test( 'write me !', ( assert ) => {
  5000. assert.ok( false, "everything's gonna be alright" );
  5001. } );
  5002. } );
  5003. } );
  5004. } );
  5005. /**
  5006. * @author dforrer / https://github.com/dforrer
  5007. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  5008. */
  5009. /**
  5010. * @param object THREE.Object3D
  5011. * @param mapName string
  5012. * @param newMap THREE.Texture
  5013. * @constructor
  5014. */
  5015. var SetMaterialMapCommand$1 = function ( object, mapName, newMap, materialSlot ) {
  5016. Command.call( this );
  5017. this.type = 'SetMaterialMapCommand';
  5018. this.name = 'Set Material.' + mapName;
  5019. this.object = object;
  5020. this.material = this.editor.getObjectMaterial( object, materialSlot );
  5021. this.oldMap = ( object !== undefined ) ? this.material[ mapName ] : undefined;
  5022. this.newMap = newMap;
  5023. this.mapName = mapName;
  5024. };
  5025. SetMaterialMapCommand$1.prototype = {
  5026. execute: function () {
  5027. this.material[ this.mapName ] = this.newMap;
  5028. this.material.needsUpdate = true;
  5029. this.editor.signals.materialChanged.dispatch( this.material );
  5030. },
  5031. undo: function () {
  5032. this.material[ this.mapName ] = this.oldMap;
  5033. this.material.needsUpdate = true;
  5034. this.editor.signals.materialChanged.dispatch( this.material );
  5035. },
  5036. toJSON: function () {
  5037. var output = Command.prototype.toJSON.call( this );
  5038. output.objectUuid = this.object.uuid;
  5039. output.mapName = this.mapName;
  5040. output.newMap = serializeMap( this.newMap );
  5041. output.oldMap = serializeMap( this.oldMap );
  5042. return output;
  5043. // serializes a map (THREE.Texture)
  5044. function serializeMap ( map ) {
  5045. if ( map === null || map === undefined ) return null;
  5046. var meta = {
  5047. geometries: {},
  5048. materials: {},
  5049. textures: {},
  5050. images: {}
  5051. };
  5052. var json = map.toJSON( meta );
  5053. var images = extractFromCache( meta.images );
  5054. if ( images.length > 0 ) json.images = images;
  5055. json.sourceFile = map.sourceFile;
  5056. return json;
  5057. }
  5058. // Note: The function 'extractFromCache' is copied from Object3D.toJSON()
  5059. // extract data from the cache hash
  5060. // remove metadata on each item
  5061. // and return as array
  5062. function extractFromCache ( cache ) {
  5063. var values = [];
  5064. for ( var key in cache ) {
  5065. var data = cache[ key ];
  5066. delete data.metadata;
  5067. values.push( data );
  5068. }
  5069. return values;
  5070. }
  5071. },
  5072. fromJSON: function ( json ) {
  5073. Command.prototype.fromJSON.call( this, json );
  5074. this.object = this.editor.objectByUuid( json.objectUuid );
  5075. this.mapName = json.mapName;
  5076. this.oldMap = parseTexture( json.oldMap );
  5077. this.newMap = parseTexture( json.newMap );
  5078. function parseTexture ( json ) {
  5079. var map = null;
  5080. if ( json !== null ) {
  5081. var loader = new THREE.ObjectLoader();
  5082. var images = loader.parseImages( json.images );
  5083. var textures = loader.parseTextures( [ json ], images );
  5084. map = textures[ json.uuid ];
  5085. map.sourceFile = json.sourceFile;
  5086. }
  5087. return map;
  5088. }
  5089. }
  5090. };
  5091. /**
  5092. * @author TristanVALCKE / https://github.com/Itee
  5093. */
  5094. /* global QUnit */
  5095. QUnit.module( 'Editor', () => {
  5096. QUnit.module( 'Commands', () => {
  5097. QUnit.module.todo( 'SetMaterialMapCommand', () => {
  5098. QUnit.test( 'write me !', ( assert ) => {
  5099. assert.ok( false, "everything's gonna be alright" );
  5100. } );
  5101. } );
  5102. } );
  5103. } );
  5104. /**
  5105. * @author dforrer / https://github.com/dforrer
  5106. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  5107. */
  5108. /**
  5109. * @param object THREE.Object3D
  5110. * @param attributeName string
  5111. * @param newValue number, string, boolean or object
  5112. * @constructor
  5113. */
  5114. var SetMaterialValueCommand$1 = function ( object, attributeName, newValue, materialSlot ) {
  5115. Command.call( this );
  5116. this.type = 'SetMaterialValueCommand';
  5117. this.name = 'Set Material.' + attributeName;
  5118. this.updatable = true;
  5119. this.object = object;
  5120. this.material = this.editor.getObjectMaterial( object, materialSlot );
  5121. this.oldValue = ( this.material !== undefined ) ? this.material[ attributeName ] : undefined;
  5122. this.newValue = newValue;
  5123. this.attributeName = attributeName;
  5124. };
  5125. SetMaterialValueCommand$1.prototype = {
  5126. execute: function () {
  5127. this.material[ this.attributeName ] = this.newValue;
  5128. this.material.needsUpdate = true;
  5129. this.editor.signals.objectChanged.dispatch( this.object );
  5130. this.editor.signals.materialChanged.dispatch( this.material );
  5131. },
  5132. undo: function () {
  5133. this.material[ this.attributeName ] = this.oldValue;
  5134. this.material.needsUpdate = true;
  5135. this.editor.signals.objectChanged.dispatch( this.object );
  5136. this.editor.signals.materialChanged.dispatch( this.material );
  5137. },
  5138. update: function ( cmd ) {
  5139. this.newValue = cmd.newValue;
  5140. },
  5141. toJSON: function () {
  5142. var output = Command.prototype.toJSON.call( this );
  5143. output.objectUuid = this.object.uuid;
  5144. output.attributeName = this.attributeName;
  5145. output.oldValue = this.oldValue;
  5146. output.newValue = this.newValue;
  5147. return output;
  5148. },
  5149. fromJSON: function ( json ) {
  5150. Command.prototype.fromJSON.call( this, json );
  5151. this.attributeName = json.attributeName;
  5152. this.oldValue = json.oldValue;
  5153. this.newValue = json.newValue;
  5154. this.object = this.editor.objectByUuid( json.objectUuid );
  5155. }
  5156. };
  5157. /**
  5158. * @author TristanVALCKE / https://github.com/Itee
  5159. */
  5160. /* global QUnit */
  5161. QUnit.module( 'Editor', () => {
  5162. QUnit.module( 'Commands', () => {
  5163. QUnit.module.todo( 'SetMaterialValueCommand', () => {
  5164. QUnit.test( 'write me !', ( assert ) => {
  5165. assert.ok( false, "everything's gonna be alright" );
  5166. } );
  5167. } );
  5168. } );
  5169. } );
  5170. /**
  5171. * @author dforrer / https://github.com/dforrer
  5172. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  5173. */
  5174. /**
  5175. * @param object THREE.Object3D
  5176. * @param newPosition THREE.Vector3
  5177. * @param optionalOldPosition THREE.Vector3
  5178. * @constructor
  5179. */
  5180. var SetPositionCommand$1 = function ( object, newPosition, optionalOldPosition ) {
  5181. Command.call( this );
  5182. this.type = 'SetPositionCommand';
  5183. this.name = 'Set Position';
  5184. this.updatable = true;
  5185. this.object = object;
  5186. if ( object !== undefined && newPosition !== undefined ) {
  5187. this.oldPosition = object.position.clone();
  5188. this.newPosition = newPosition.clone();
  5189. }
  5190. if ( optionalOldPosition !== undefined ) {
  5191. this.oldPosition = optionalOldPosition.clone();
  5192. }
  5193. };
  5194. SetPositionCommand$1.prototype = {
  5195. execute: function () {
  5196. this.object.position.copy( this.newPosition );
  5197. this.object.updateMatrixWorld( true );
  5198. this.editor.signals.objectChanged.dispatch( this.object );
  5199. },
  5200. undo: function () {
  5201. this.object.position.copy( this.oldPosition );
  5202. this.object.updateMatrixWorld( true );
  5203. this.editor.signals.objectChanged.dispatch( this.object );
  5204. },
  5205. update: function ( command ) {
  5206. this.newPosition.copy( command.newPosition );
  5207. },
  5208. toJSON: function () {
  5209. var output = Command.prototype.toJSON.call( this );
  5210. output.objectUuid = this.object.uuid;
  5211. output.oldPosition = this.oldPosition.toArray();
  5212. output.newPosition = this.newPosition.toArray();
  5213. return output;
  5214. },
  5215. fromJSON: function ( json ) {
  5216. Command.prototype.fromJSON.call( this, json );
  5217. this.object = this.editor.objectByUuid( json.objectUuid );
  5218. this.oldPosition = new THREE.Vector3().fromArray( json.oldPosition );
  5219. this.newPosition = new THREE.Vector3().fromArray( json.newPosition );
  5220. }
  5221. };
  5222. /**
  5223. * @author TristanVALCKE / https://github.com/Itee
  5224. */
  5225. /* global QUnit */
  5226. QUnit.module( 'Editor', () => {
  5227. QUnit.module( 'Commands', () => {
  5228. QUnit.module.todo( 'SetPositionCommand', () => {
  5229. QUnit.test( 'write me !', ( assert ) => {
  5230. assert.ok( false, "everything's gonna be alright" );
  5231. } );
  5232. } );
  5233. } );
  5234. } );
  5235. /**
  5236. * @author dforrer / https://github.com/dforrer
  5237. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  5238. */
  5239. /**
  5240. * @param object THREE.Object3D
  5241. * @param newRotation THREE.Euler
  5242. * @param optionalOldRotation THREE.Euler
  5243. * @constructor
  5244. */
  5245. var SetRotationCommand$1 = function ( object, newRotation, optionalOldRotation ) {
  5246. Command.call( this );
  5247. this.type = 'SetRotationCommand';
  5248. this.name = 'Set Rotation';
  5249. this.updatable = true;
  5250. this.object = object;
  5251. if ( object !== undefined && newRotation !== undefined ) {
  5252. this.oldRotation = object.rotation.clone();
  5253. this.newRotation = newRotation.clone();
  5254. }
  5255. if ( optionalOldRotation !== undefined ) {
  5256. this.oldRotation = optionalOldRotation.clone();
  5257. }
  5258. };
  5259. SetRotationCommand$1.prototype = {
  5260. execute: function () {
  5261. this.object.rotation.copy( this.newRotation );
  5262. this.object.updateMatrixWorld( true );
  5263. this.editor.signals.objectChanged.dispatch( this.object );
  5264. },
  5265. undo: function () {
  5266. this.object.rotation.copy( this.oldRotation );
  5267. this.object.updateMatrixWorld( true );
  5268. this.editor.signals.objectChanged.dispatch( this.object );
  5269. },
  5270. update: function ( command ) {
  5271. this.newRotation.copy( command.newRotation );
  5272. },
  5273. toJSON: function () {
  5274. var output = Command.prototype.toJSON.call( this );
  5275. output.objectUuid = this.object.uuid;
  5276. output.oldRotation = this.oldRotation.toArray();
  5277. output.newRotation = this.newRotation.toArray();
  5278. return output;
  5279. },
  5280. fromJSON: function ( json ) {
  5281. Command.prototype.fromJSON.call( this, json );
  5282. this.object = this.editor.objectByUuid( json.objectUuid );
  5283. this.oldRotation = new THREE.Euler().fromArray( json.oldRotation );
  5284. this.newRotation = new THREE.Euler().fromArray( json.newRotation );
  5285. }
  5286. };
  5287. /**
  5288. * @author TristanVALCKE / https://github.com/Itee
  5289. */
  5290. /* global QUnit */
  5291. QUnit.module( 'Editor', () => {
  5292. QUnit.module( 'Commands', () => {
  5293. QUnit.module.todo( 'SetRotationCommand', () => {
  5294. QUnit.test( 'write me !', ( assert ) => {
  5295. assert.ok( false, "everything's gonna be alright" );
  5296. } );
  5297. } );
  5298. } );
  5299. } );
  5300. /**
  5301. * @author dforrer / https://github.com/dforrer
  5302. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  5303. */
  5304. /**
  5305. * @param object THREE.Object3D
  5306. * @param newScale THREE.Vector3
  5307. * @param optionalOldScale THREE.Vector3
  5308. * @constructor
  5309. */
  5310. var SetScaleCommand$1 = function ( object, newScale, optionalOldScale ) {
  5311. Command.call( this );
  5312. this.type = 'SetScaleCommand';
  5313. this.name = 'Set Scale';
  5314. this.updatable = true;
  5315. this.object = object;
  5316. if ( object !== undefined && newScale !== undefined ) {
  5317. this.oldScale = object.scale.clone();
  5318. this.newScale = newScale.clone();
  5319. }
  5320. if ( optionalOldScale !== undefined ) {
  5321. this.oldScale = optionalOldScale.clone();
  5322. }
  5323. };
  5324. SetScaleCommand$1.prototype = {
  5325. execute: function () {
  5326. this.object.scale.copy( this.newScale );
  5327. this.object.updateMatrixWorld( true );
  5328. this.editor.signals.objectChanged.dispatch( this.object );
  5329. },
  5330. undo: function () {
  5331. this.object.scale.copy( this.oldScale );
  5332. this.object.updateMatrixWorld( true );
  5333. this.editor.signals.objectChanged.dispatch( this.object );
  5334. },
  5335. update: function ( command ) {
  5336. this.newScale.copy( command.newScale );
  5337. },
  5338. toJSON: function () {
  5339. var output = Command.prototype.toJSON.call( this );
  5340. output.objectUuid = this.object.uuid;
  5341. output.oldScale = this.oldScale.toArray();
  5342. output.newScale = this.newScale.toArray();
  5343. return output;
  5344. },
  5345. fromJSON: function ( json ) {
  5346. Command.prototype.fromJSON.call( this, json );
  5347. this.object = this.editor.objectByUuid( json.objectUuid );
  5348. this.oldScale = new THREE.Vector3().fromArray( json.oldScale );
  5349. this.newScale = new THREE.Vector3().fromArray( json.newScale );
  5350. }
  5351. };
  5352. /**
  5353. * @author TristanVALCKE / https://github.com/Itee
  5354. */
  5355. /* global QUnit */
  5356. QUnit.module( 'Editor', () => {
  5357. QUnit.module( 'Commands', () => {
  5358. QUnit.module.todo( 'SetScaleCommand', () => {
  5359. QUnit.test( 'write me !', ( assert ) => {
  5360. assert.ok( false, "everything's gonna be alright" );
  5361. } );
  5362. } );
  5363. } );
  5364. } );
  5365. /**
  5366. * @author dforrer / https://github.com/dforrer
  5367. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  5368. */
  5369. /**
  5370. * @param scene containing children to import
  5371. * @constructor
  5372. */
  5373. var SetSceneCommand$1 = function ( scene ) {
  5374. Command.call( this );
  5375. this.type = 'SetSceneCommand';
  5376. this.name = 'Set Scene';
  5377. this.cmdArray = [];
  5378. if ( scene !== undefined ) {
  5379. this.cmdArray.push( new SetUuidCommand( this.editor.scene, scene.uuid ) );
  5380. this.cmdArray.push( new SetValueCommand( this.editor.scene, 'name', scene.name ) );
  5381. this.cmdArray.push( new SetValueCommand( this.editor.scene, 'userData', JSON.parse( JSON.stringify( scene.userData ) ) ) );
  5382. while ( scene.children.length > 0 ) {
  5383. var child = scene.children.pop();
  5384. this.cmdArray.push( new AddObjectCommand( child ) );
  5385. }
  5386. }
  5387. };
  5388. SetSceneCommand$1.prototype = {
  5389. execute: function () {
  5390. this.editor.signals.sceneGraphChanged.active = false;
  5391. for ( var i = 0; i < this.cmdArray.length; i ++ ) {
  5392. this.cmdArray[ i ].execute();
  5393. }
  5394. this.editor.signals.sceneGraphChanged.active = true;
  5395. this.editor.signals.sceneGraphChanged.dispatch();
  5396. },
  5397. undo: function () {
  5398. this.editor.signals.sceneGraphChanged.active = false;
  5399. for ( var i = this.cmdArray.length - 1; i >= 0; i -- ) {
  5400. this.cmdArray[ i ].undo();
  5401. }
  5402. this.editor.signals.sceneGraphChanged.active = true;
  5403. this.editor.signals.sceneGraphChanged.dispatch();
  5404. },
  5405. toJSON: function () {
  5406. var output = Command.prototype.toJSON.call( this );
  5407. var cmds = [];
  5408. for ( var i = 0; i < this.cmdArray.length; i ++ ) {
  5409. cmds.push( this.cmdArray[ i ].toJSON() );
  5410. }
  5411. output.cmds = cmds;
  5412. return output;
  5413. },
  5414. fromJSON: function ( json ) {
  5415. Command.prototype.fromJSON.call( this, json );
  5416. var cmds = json.cmds;
  5417. for ( var i = 0; i < cmds.length; i ++ ) {
  5418. var cmd = new window[ cmds[ i ].type ](); // creates a new object of type "json.type"
  5419. cmd.fromJSON( cmds[ i ] );
  5420. this.cmdArray.push( cmd );
  5421. }
  5422. }
  5423. };
  5424. /**
  5425. * @author TristanVALCKE / https://github.com/Itee
  5426. */
  5427. /* global QUnit */
  5428. QUnit.module( 'Editor', () => {
  5429. QUnit.module( 'Commands', () => {
  5430. QUnit.module.todo( 'SetSceneCommand', () => {
  5431. QUnit.test( 'write me !', ( assert ) => {
  5432. assert.ok( false, "everything's gonna be alright" );
  5433. } );
  5434. } );
  5435. } );
  5436. } );
  5437. /**
  5438. * @author dforrer / https://github.com/dforrer
  5439. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  5440. */
  5441. /**
  5442. * @param object THREE.Object3D
  5443. * @param script javascript object
  5444. * @param attributeName string
  5445. * @param newValue string, object
  5446. * @constructor
  5447. */
  5448. var SetScriptValueCommand$1 = function ( object, script, attributeName, newValue ) {
  5449. Command.call( this );
  5450. this.type = 'SetScriptValueCommand';
  5451. this.name = 'Set Script.' + attributeName;
  5452. this.updatable = true;
  5453. this.object = object;
  5454. this.script = script;
  5455. this.attributeName = attributeName;
  5456. this.oldValue = ( script !== undefined ) ? script[ this.attributeName ] : undefined;
  5457. this.newValue = newValue;
  5458. };
  5459. SetScriptValueCommand$1.prototype = {
  5460. execute: function () {
  5461. this.script[ this.attributeName ] = this.newValue;
  5462. this.editor.signals.scriptChanged.dispatch();
  5463. },
  5464. undo: function () {
  5465. this.script[ this.attributeName ] = this.oldValue;
  5466. this.editor.signals.scriptChanged.dispatch();
  5467. },
  5468. update: function ( cmd ) {
  5469. this.newValue = cmd.newValue;
  5470. },
  5471. toJSON: function () {
  5472. var output = Command.prototype.toJSON.call( this );
  5473. output.objectUuid = this.object.uuid;
  5474. output.index = this.editor.scripts[ this.object.uuid ].indexOf( this.script );
  5475. output.attributeName = this.attributeName;
  5476. output.oldValue = this.oldValue;
  5477. output.newValue = this.newValue;
  5478. return output;
  5479. },
  5480. fromJSON: function ( json ) {
  5481. Command.prototype.fromJSON.call( this, json );
  5482. this.oldValue = json.oldValue;
  5483. this.newValue = json.newValue;
  5484. this.attributeName = json.attributeName;
  5485. this.object = this.editor.objectByUuid( json.objectUuid );
  5486. this.script = this.editor.scripts[ json.objectUuid ][ json.index ];
  5487. }
  5488. };
  5489. /**
  5490. * @author TristanVALCKE / https://github.com/Itee
  5491. */
  5492. /* global QUnit */
  5493. QUnit.module( 'Editor', () => {
  5494. QUnit.module( 'Commands', () => {
  5495. QUnit.module.todo( 'SetScriptValueCommand', () => {
  5496. QUnit.test( 'write me !', ( assert ) => {
  5497. assert.ok( false, "everything's gonna be alright" );
  5498. } );
  5499. } );
  5500. } );
  5501. } );
  5502. /**
  5503. * @author dforrer / https://github.com/dforrer
  5504. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  5505. */
  5506. /**
  5507. * @param object THREE.Object3D
  5508. * @param newUuid string
  5509. * @constructor
  5510. */
  5511. var SetUuidCommand$1 = function ( object, newUuid ) {
  5512. Command.call( this );
  5513. this.type = 'SetUuidCommand';
  5514. this.name = 'Update UUID';
  5515. this.object = object;
  5516. this.oldUuid = ( object !== undefined ) ? object.uuid : undefined;
  5517. this.newUuid = newUuid;
  5518. };
  5519. SetUuidCommand$1.prototype = {
  5520. execute: function () {
  5521. this.object.uuid = this.newUuid;
  5522. this.editor.signals.objectChanged.dispatch( this.object );
  5523. this.editor.signals.sceneGraphChanged.dispatch();
  5524. },
  5525. undo: function () {
  5526. this.object.uuid = this.oldUuid;
  5527. this.editor.signals.objectChanged.dispatch( this.object );
  5528. this.editor.signals.sceneGraphChanged.dispatch();
  5529. },
  5530. toJSON: function () {
  5531. var output = Command.prototype.toJSON.call( this );
  5532. output.oldUuid = this.oldUuid;
  5533. output.newUuid = this.newUuid;
  5534. return output;
  5535. },
  5536. fromJSON: function ( json ) {
  5537. Command.prototype.fromJSON.call( this, json );
  5538. this.oldUuid = json.oldUuid;
  5539. this.newUuid = json.newUuid;
  5540. this.object = this.editor.objectByUuid( json.oldUuid );
  5541. if ( this.object === undefined ) {
  5542. this.object = this.editor.objectByUuid( json.newUuid );
  5543. }
  5544. }
  5545. };
  5546. /**
  5547. * @author TristanVALCKE / https://github.com/Itee
  5548. */
  5549. /* global QUnit */
  5550. QUnit.module( 'Editor', () => {
  5551. QUnit.module( 'Commands', () => {
  5552. QUnit.module.todo( 'SetUuidCommand', () => {
  5553. QUnit.test( 'write me !', ( assert ) => {
  5554. assert.ok( false, "everything's gonna be alright" );
  5555. } );
  5556. } );
  5557. } );
  5558. } );
  5559. /**
  5560. * @author dforrer / https://github.com/dforrer
  5561. * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
  5562. */
  5563. /**
  5564. * @param object THREE.Object3D
  5565. * @param attributeName string
  5566. * @param newValue number, string, boolean or object
  5567. * @constructor
  5568. */
  5569. var SetValueCommand$1 = function ( object, attributeName, newValue ) {
  5570. Command.call( this );
  5571. this.type = 'SetValueCommand';
  5572. this.name = 'Set ' + attributeName;
  5573. this.updatable = true;
  5574. this.object = object;
  5575. this.attributeName = attributeName;
  5576. this.oldValue = ( object !== undefined ) ? object[ attributeName ] : undefined;
  5577. this.newValue = newValue;
  5578. };
  5579. SetValueCommand$1.prototype = {
  5580. execute: function () {
  5581. this.object[ this.attributeName ] = this.newValue;
  5582. this.editor.signals.objectChanged.dispatch( this.object );
  5583. // this.editor.signals.sceneGraphChanged.dispatch();
  5584. },
  5585. undo: function () {
  5586. this.object[ this.attributeName ] = this.oldValue;
  5587. this.editor.signals.objectChanged.dispatch( this.object );
  5588. // this.editor.signals.sceneGraphChanged.dispatch();
  5589. },
  5590. update: function ( cmd ) {
  5591. this.newValue = cmd.newValue;
  5592. },
  5593. toJSON: function () {
  5594. var output = Command.prototype.toJSON.call( this );
  5595. output.objectUuid = this.object.uuid;
  5596. output.attributeName = this.attributeName;
  5597. output.oldValue = this.oldValue;
  5598. output.newValue = this.newValue;
  5599. return output;
  5600. },
  5601. fromJSON: function ( json ) {
  5602. Command.prototype.fromJSON.call( this, json );
  5603. this.attributeName = json.attributeName;
  5604. this.oldValue = json.oldValue;
  5605. this.newValue = json.newValue;
  5606. this.object = this.editor.objectByUuid( json.objectUuid );
  5607. }
  5608. };
  5609. /**
  5610. * @author TristanVALCKE / https://github.com/Itee
  5611. */
  5612. /* global QUnit */
  5613. QUnit.module( 'Editor', () => {
  5614. QUnit.module( 'Commands', () => {
  5615. QUnit.module.todo( 'SetValueCommand', () => {
  5616. QUnit.test( 'write me !', ( assert ) => {
  5617. assert.ok( false, "everything's gonna be alright" );
  5618. } );
  5619. } );
  5620. } );
  5621. } );
  5622. /**
  5623. * @author TristanVALCKE / https://github.com/Itee
  5624. */
  5625. // TODO (Itee) Editor is not es6 module so care to include order !!!
  5626. // TODO: all views could not be testable, waiting modular code before implement units tests on them
  5627. //editor
  5628. //editor/commands
  5629. //editor/others
  5630. } );
  5631. })));