MegaShape.cs 128 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475
  1. using UnityEngine;
  2. using System.IO;
  3. using System.Collections.Generic;
  4. [System.Serializable]
  5. public class MegaKnotAnimCurve
  6. {
  7. public AnimationCurve px = new AnimationCurve(new Keyframe(0, 0));
  8. public AnimationCurve py = new AnimationCurve(new Keyframe(0, 0));
  9. public AnimationCurve pz = new AnimationCurve(new Keyframe(0, 0));
  10. public AnimationCurve ix = new AnimationCurve(new Keyframe(0, 0));
  11. public AnimationCurve iy = new AnimationCurve(new Keyframe(0, 0));
  12. public AnimationCurve iz = new AnimationCurve(new Keyframe(0, 0));
  13. public AnimationCurve ox = new AnimationCurve(new Keyframe(0, 0));
  14. public AnimationCurve oy = new AnimationCurve(new Keyframe(0, 0));
  15. public AnimationCurve oz = new AnimationCurve(new Keyframe(0, 0));
  16. public void GetState(MegaKnot knot, float t)
  17. {
  18. knot.p.x = px.Evaluate(t);
  19. knot.p.y = py.Evaluate(t);
  20. knot.p.z = pz.Evaluate(t);
  21. knot.invec.x = ix.Evaluate(t);
  22. knot.invec.y = iy.Evaluate(t);
  23. knot.invec.z = iz.Evaluate(t);
  24. knot.outvec.x = ox.Evaluate(t);
  25. knot.outvec.y = oy.Evaluate(t);
  26. knot.outvec.z = oz.Evaluate(t);
  27. }
  28. public void AddKey(MegaKnot knot, float t)
  29. {
  30. px.AddKey(new Keyframe(t, knot.p.x));
  31. py.AddKey(new Keyframe(t, knot.p.y));
  32. pz.AddKey(new Keyframe(t, knot.p.z));
  33. ix.AddKey(new Keyframe(t, knot.invec.x));
  34. iy.AddKey(new Keyframe(t, knot.invec.y));
  35. iz.AddKey(new Keyframe(t, knot.invec.z));
  36. ox.AddKey(new Keyframe(t, knot.outvec.x));
  37. oy.AddKey(new Keyframe(t, knot.outvec.y));
  38. oz.AddKey(new Keyframe(t, knot.outvec.z));
  39. }
  40. public void MoveKey(MegaKnot knot, float t, int k)
  41. {
  42. px.MoveKey(k, new Keyframe(t, knot.p.x));
  43. py.MoveKey(k, new Keyframe(t, knot.p.y));
  44. pz.MoveKey(k, new Keyframe(t, knot.p.z));
  45. ix.MoveKey(k, new Keyframe(t, knot.invec.x));
  46. iy.MoveKey(k, new Keyframe(t, knot.invec.y));
  47. iz.MoveKey(k, new Keyframe(t, knot.invec.z));
  48. ox.MoveKey(k, new Keyframe(t, knot.outvec.x));
  49. oy.MoveKey(k, new Keyframe(t, knot.outvec.y));
  50. oz.MoveKey(k, new Keyframe(t, knot.outvec.z));
  51. }
  52. public void RemoveKey(int k)
  53. {
  54. px.RemoveKey(k);
  55. py.RemoveKey(k);
  56. pz.RemoveKey(k);
  57. ix.RemoveKey(k);
  58. iy.RemoveKey(k);
  59. iz.RemoveKey(k);
  60. ox.RemoveKey(k);
  61. oy.RemoveKey(k);
  62. oz.RemoveKey(k);
  63. }
  64. }
  65. [System.Serializable]
  66. public class MegaSplineAnim
  67. {
  68. public bool Enabled = false;
  69. public List<MegaKnotAnimCurve> knots = new List<MegaKnotAnimCurve>();
  70. public void SetState(MegaSpline spline, float t)
  71. {
  72. }
  73. public void GetState1(MegaSpline spline, float t)
  74. {
  75. for ( int i = 0; i < knots.Count; i++ )
  76. {
  77. knots[i].GetState(spline.knots[i], t);
  78. }
  79. }
  80. int FindKey(float t)
  81. {
  82. if ( knots.Count > 0 )
  83. {
  84. Keyframe[] keys = knots[0].px.keys;
  85. for ( int i = 0; i < keys.Length; i++ )
  86. {
  87. if ( keys[i].time == t )
  88. return i;
  89. }
  90. }
  91. return -1;
  92. }
  93. public void AddState(MegaSpline spline, float t)
  94. {
  95. if ( knots.Count == 0 )
  96. {
  97. Init(spline);
  98. }
  99. // if we have a match for time then replace
  100. int k = FindKey(t);
  101. if ( k == -1 )
  102. {
  103. // add new keys
  104. for ( int i = 0; i < spline.knots.Count; i++ )
  105. knots[i].AddKey(spline.knots[i], t);
  106. }
  107. else
  108. {
  109. // Move existing key with new values
  110. for ( int i = 0; i < spline.knots.Count; i++ )
  111. knots[i].MoveKey(spline.knots[i], t, k);
  112. }
  113. }
  114. public void Remove(float t)
  115. {
  116. int k = FindKey(t);
  117. if ( k != -1 )
  118. {
  119. for ( int i = 0; i < knots.Count; i++ )
  120. knots[i].RemoveKey(k);
  121. }
  122. }
  123. public void RemoveKey(int k)
  124. {
  125. if ( k < NumKeys() )
  126. {
  127. for ( int i = 0; i < knots.Count; i++ )
  128. knots[i].RemoveKey(k);
  129. }
  130. }
  131. public void Init(MegaSpline spline)
  132. {
  133. knots.Clear();
  134. for ( int i = 0; i < spline.knots.Count; i++ )
  135. {
  136. MegaKnotAnimCurve kc = new MegaKnotAnimCurve();
  137. kc.MoveKey(spline.knots[i], 0.0f, 0);
  138. knots.Add(kc);
  139. }
  140. }
  141. public int NumKeys()
  142. {
  143. if ( knots == null || knots.Count == 0 )
  144. return 0;
  145. return knots[0].px.keys.Length;
  146. }
  147. public float GetKeyTime(int k)
  148. {
  149. if ( knots == null || knots.Count == 0 )
  150. return 0;
  151. Keyframe[] f = knots[0].px.keys;
  152. if ( k < f.Length )
  153. {
  154. return f[k].time;
  155. }
  156. return 0.0f;
  157. }
  158. public void SetKeyTime(MegaSpline spline, int k, float t)
  159. {
  160. if ( knots == null || knots.Count == 0 )
  161. return;
  162. for ( int i = 0; i < spline.knots.Count; i++ )
  163. knots[i].MoveKey(spline.knots[i], t, k);
  164. }
  165. public void GetKey(MegaSpline spline, int k)
  166. {
  167. float t = GetKeyTime(k);
  168. GetState1(spline, t);
  169. spline.CalcLength(); //(10); // could use less here
  170. }
  171. public void UpdateKey(MegaSpline spline, int k)
  172. {
  173. float t = GetKeyTime(k);
  174. for ( int i = 0; i < spline.knots.Count; i++ )
  175. knots[i].MoveKey(spline.knots[i], t, k);
  176. }
  177. }
  178. // option for spline profile for border?
  179. // TODO: Add option for border strip, so get edge, duplicate points, move originals in by amount and normal of tangent
  180. // if we do meshes with edge loops then easy to do borders, bevels, extrudes
  181. // TODO: Split code to shape, spline, knot, and same for edit code
  182. // TODO: Each spline in a shape should have its own transform
  183. // TODO: split knot and spline out to files
  184. // Need to draw and edit multiple splines, and work on them, then mesh needs to work on those indi
  185. [System.Serializable]
  186. public class MegaKnotAnim
  187. {
  188. public int p; // point index
  189. public int t; // handle or val
  190. public int s; // spline
  191. public MegaBezVector3KeyControl con;
  192. }
  193. public enum MegaHandleType
  194. {
  195. Position,
  196. Free,
  197. }
  198. [System.Serializable]
  199. public class MegaKnot
  200. {
  201. public Vector3 p;
  202. public Vector3 invec;
  203. public Vector3 outvec;
  204. public float seglength;
  205. public float length;
  206. public bool notlocked;
  207. public float twist;
  208. public int id;
  209. public float[] lengths;
  210. public Vector3[] points;
  211. public MegaKnot()
  212. {
  213. p = new Vector3();
  214. invec = new Vector3();
  215. outvec = new Vector3();
  216. length = 0.0f;
  217. seglength = 0.0f;
  218. }
  219. public Vector3 Interpolate(float t, MegaKnot k)
  220. {
  221. float omt = 1.0f - t;
  222. float omt2 = omt * omt;
  223. float omt3 = omt2 * omt;
  224. float t2 = t * t;
  225. float t3 = t2 * t;
  226. omt2 = 3.0f * omt2 * t;
  227. omt = 3.0f * omt * t2;
  228. Vector3 tp = Vector3.zero;
  229. tp.x = (omt3 * p.x) + (omt2 * outvec.x) + (omt * k.invec.x) + (t3 * k.p.x);
  230. tp.y = (omt3 * p.y) + (omt2 * outvec.y) + (omt * k.invec.y) + (t3 * k.p.y);
  231. tp.z = (omt3 * p.z) + (omt2 * outvec.z) + (omt * k.invec.z) + (t3 * k.p.z);
  232. return tp;
  233. }
  234. #if false
  235. public Vector3 InterpolateCS(float t, MegaKnot k)
  236. {
  237. if ( lengths == null || lengths.Length == 0 )
  238. return Interpolate(t, k);
  239. float u = (t * seglength) + lengths[0];
  240. int i = 0;
  241. for ( i = 0; i < lengths.Length - 1; i++ )
  242. {
  243. if ( u < lengths[i] )
  244. {
  245. break;
  246. }
  247. }
  248. float alpha = (u - lengths[i - 1]) / (lengths[i] - lengths[i - 1]);
  249. return Vector3.Lerp(points[i - 1], points[i], alpha);
  250. }
  251. #else
  252. public Vector3 InterpolateCS(float t, MegaKnot k)
  253. {
  254. if ( lengths == null || lengths.Length == 0 )
  255. return Interpolate(t, k);
  256. float u = (t * seglength) + lengths[0];
  257. int high = lengths.Length - 1;
  258. int low = -1;
  259. int probe = 0;
  260. //int i = lengths.Length / 2;
  261. while ( high - low > 1 )
  262. {
  263. probe = (high + low) / 2;
  264. if ( u >= lengths[probe] )
  265. {
  266. if ( u < lengths[probe + 1] )
  267. break;
  268. low = probe;
  269. }
  270. else
  271. high = probe;
  272. }
  273. //for ( i = 0; i < lengths.Length - 1; i++ )
  274. //{
  275. // if ( u < lengths[i] )
  276. // {
  277. // break;
  278. // }
  279. //}
  280. float alpha = (u - lengths[probe]) / (lengths[probe + 1] - lengths[probe]);
  281. return Vector3.Lerp(points[probe], points[probe + 1], alpha);
  282. }
  283. #endif
  284. public Vector3 Tangent(float t, MegaKnot k)
  285. {
  286. Vector3 vel;
  287. float a = t;
  288. float b = 1.0f - t;
  289. float b2 = b * b;
  290. float a2 = a * a;
  291. vel.x = (-3.0f * p.x * b2) + (3.0f * outvec.x * b * (b - 2.0f * a)) + (3.0f * k.invec.x * a * (2.0f * b - a)) + (k.p.x * 3.0f * a2);
  292. vel.y = (-3.0f * p.y * b2) + (3.0f * outvec.y * b * (b - 2.0f * a)) + (3.0f * k.invec.y * a * (2.0f * b - a)) + (k.p.y * 3.0f * a2);
  293. vel.z = (-3.0f * p.z * b2) + (3.0f * outvec.z * b * (b - 2.0f * a)) + (3.0f * k.invec.z * a * (2.0f * b - a)) + (k.p.z * 3.0f * a2);
  294. //float d = vel.sqrMagnitude;
  295. return vel;
  296. }
  297. }
  298. public enum MegaShapeEase
  299. {
  300. Linear,
  301. Sine,
  302. }
  303. public enum MegaShapeBezComputeMode
  304. {
  305. Old,
  306. New,
  307. }
  308. [System.Serializable]
  309. public class MegaSpline
  310. {
  311. public float length;
  312. public bool closed;
  313. public List<MegaKnot> knots = new List<MegaKnot>();
  314. public List<MegaKnotAnim> animations;
  315. public Vector3 offset = Vector3.zero;
  316. public Vector3 rotate = Vector3.zero;
  317. public Vector3 scale = Vector3.one;
  318. public bool reverse = false;
  319. public int outlineSpline = -1;
  320. public float outline = 0.0f;
  321. public bool constantSpeed = false;
  322. public int subdivs = 10;
  323. public MegaShapeEase twistmode = MegaShapeEase.Linear;
  324. // New animation
  325. public MegaSplineAnim splineanim = new MegaSplineAnim();
  326. static public MegaSpline Copy(MegaSpline src)
  327. {
  328. MegaSpline spl = new MegaSpline();
  329. spl.closed = src.closed;
  330. spl.offset = src.offset;
  331. spl.rotate = src.rotate;
  332. spl.scale = src.scale;
  333. spl.length = src.length;
  334. spl.knots = new List<MegaKnot>(); //src.knots);
  335. spl.constantSpeed = src.constantSpeed;
  336. spl.subdivs = src.subdivs;
  337. for ( int i = 0; i < src.knots.Count; i++ )
  338. {
  339. MegaKnot knot = new MegaKnot();
  340. knot.p = src.knots[i].p;
  341. knot.invec = src.knots[i].invec;
  342. knot.outvec = src.knots[i].outvec;
  343. knot.seglength = src.knots[i].seglength;
  344. knot.length = src.knots[i].length;
  345. knot.notlocked = src.knots[i].notlocked;
  346. spl.knots.Add(knot);
  347. }
  348. if ( src.animations != null )
  349. spl.animations = new List<MegaKnotAnim>(src.animations);
  350. return spl;
  351. }
  352. public float KnotDistance(int k, int k1)
  353. {
  354. if ( k >= 0 && k <= knots.Count - 1 && k1 >= 0 && k1 <= knots.Count - 1 )
  355. {
  356. return Vector3.Distance(knots[k].p, knots[k1].p);
  357. }
  358. return 0.0f;
  359. }
  360. public void AddKnot(Vector3 p, Vector3 invec, Vector3 outvec)
  361. {
  362. MegaKnot knot = new MegaKnot();
  363. knot.p = p;
  364. knot.invec = invec;
  365. knot.outvec = outvec;
  366. knots.Add(knot);
  367. }
  368. public void AddKnot(Vector3 p, Vector3 invec, Vector3 outvec, Matrix4x4 tm)
  369. {
  370. MegaKnot knot = new MegaKnot();
  371. knot.p = tm.MultiplyPoint3x4(p);
  372. knot.invec = tm.MultiplyPoint3x4(invec);
  373. knot.outvec = tm.MultiplyPoint3x4(outvec);
  374. knots.Add(knot);
  375. }
  376. // Assumes minor axis to be y
  377. public bool Contains(Vector3 p)
  378. {
  379. if ( !closed )
  380. return false;
  381. int j = knots.Count - 1;
  382. bool oddNodes = false;
  383. for ( int i = 0; i < knots.Count; i++ )
  384. {
  385. if ( knots[i].p.z < p.z && knots[j].p.z >= p.z || knots[j].p.z < p.z && knots[i].p.z >= p.z )
  386. {
  387. if ( knots[i].p.x + (p.z - knots[i].p.z) / (knots[j].p.z - knots[i].p.z) * (knots[j].p.x - knots[i].p.x) < p.x )
  388. oddNodes = !oddNodes;
  389. }
  390. j = i;
  391. }
  392. return oddNodes;
  393. }
  394. // Assumes minor axis to be y
  395. public float Area()
  396. {
  397. float area = 0.0f;
  398. if ( closed )
  399. {
  400. for ( int i = 0; i < knots.Count; i++ )
  401. {
  402. int i1 = (i + 1) % knots.Count;
  403. area += (knots[i].p.z + knots[i1].p.z) * (knots[i1].p.x - knots[i].p.x);
  404. }
  405. }
  406. return area * 0.5f;
  407. }
  408. // Should actually go through segments, what about scale?
  409. #if false // old
  410. public float CalcLength(int steps)
  411. {
  412. length = 0.0f;
  413. int kend = knots.Count - 1;
  414. if ( closed )
  415. kend++;
  416. for ( int knot = 0; knot < kend; knot++ )
  417. {
  418. int k1 = (knot + 1) % knots.Count;
  419. Vector3 p1 = knots[knot].p;
  420. float step = 1.0f / (float)steps;
  421. float pos = step;
  422. knots[knot].seglength = 0.0f;
  423. for ( int i = 1; i < steps; i++ )
  424. {
  425. Vector3 p2 = knots[knot].Interpolate(pos, knots[k1]);
  426. knots[knot].seglength += Vector3.Magnitude(p2 - p1);
  427. p1 = p2;
  428. pos += step;
  429. }
  430. knots[knot].seglength += Vector3.Magnitude(knots[k1].p - p1);
  431. length += knots[knot].seglength;
  432. knots[knot].length = length;
  433. length = knots[knot].length;
  434. }
  435. //AdjustSpline();
  436. return length;
  437. }
  438. #else
  439. public float CalcLength(int steps)
  440. {
  441. if ( steps < 1 )
  442. steps = 1;
  443. subdivs = steps;
  444. return CalcLength();
  445. }
  446. public float CalcLength()
  447. {
  448. length = 0.0f;
  449. int kend = knots.Count - 1;
  450. if ( closed )
  451. kend++;
  452. for ( int knot = 0; knot < kend; knot++ )
  453. {
  454. int k1 = (knot + 1) % knots.Count;
  455. Vector3 p1 = knots[knot].p;
  456. float step = 1.0f / (float)subdivs;
  457. float pos = step;
  458. knots[knot].seglength = 0.0f;
  459. if ( knots[knot].lengths == null || knots[knot].lengths.Length != subdivs + 1 )
  460. {
  461. knots[knot].lengths = new float[subdivs + 1];
  462. knots[knot].points = new Vector3[subdivs + 1];
  463. }
  464. knots[knot].lengths[0] = length;
  465. knots[knot].points[0] = knots[knot].p;
  466. float dist = 0.0f;
  467. for ( int i = 1; i < subdivs; i++ )
  468. {
  469. Vector3 p2 = knots[knot].Interpolate(pos, knots[k1]);
  470. knots[knot].points[i] = p2;
  471. dist = Vector3.Magnitude(p2 - p1);
  472. knots[knot].seglength += dist;
  473. p1 = p2;
  474. pos += step;
  475. length += dist;
  476. knots[knot].lengths[i] = length;
  477. }
  478. dist = Vector3.Magnitude(knots[k1].p - p1);
  479. knots[knot].seglength += dist; //Vector3.Magnitude(knots[k1].p - p1);
  480. length += dist; //knots[knot].seglength;
  481. knots[knot].lengths[subdivs] = length;
  482. knots[knot].points[subdivs] = knots[k1].p;
  483. knots[knot].length = length;
  484. length = knots[knot].length;
  485. }
  486. //AdjustSpline();
  487. return length;
  488. }
  489. #endif
  490. //List<Vector3> samples = new List<Vector3>();
  491. //public List<float> alphas = new List<float>();
  492. //public Vector3 InterpCurve3DSampled(float alpha)
  493. //{
  494. // if ( alpha == 1.0f )
  495. // return samples[samples.Count - 1];
  496. // if ( alpha == 0.0f )
  497. // return samples[0];
  498. // float findex = (float)samples.Count * alpha;
  499. // int index = (int)findex;
  500. // findex -= index;
  501. // return Vector3.Lerp(samples[index], samples[index + 1], findex);
  502. //}
  503. #if false
  504. public void AdjustSpline()
  505. {
  506. int k = 0;
  507. float lindist = length / 100.0f;
  508. float dist = 0.0f;
  509. Vector3 last = knots[0].p;
  510. alphas.Clear();
  511. alphas.Add(1.0f);
  512. for ( int i = 1; i < 100; i++ )
  513. {
  514. float alpha = (float)i / 100.0f;
  515. Vector3 p = InterpCurve3D(alpha, true, ref k);
  516. float d = (p - last).magnitude;
  517. dist += d;
  518. float sa = (length * alpha) / dist;
  519. float dev = alpha / sa;
  520. alphas.Add(sa); //dev);
  521. last = p;
  522. }
  523. alphas.Add(1.0f);
  524. }
  525. #endif
  526. #if false
  527. // Could pass start and end alpha
  528. public float CalcSampleTable(int steps)
  529. {
  530. float delta = length / (float)steps;
  531. samples.Clear();
  532. int k = 0;
  533. samples.Add(InterpCurve3D(0.0f, true, ref k));
  534. float alpha = 0.0f;
  535. Vector3 last = samples[0];
  536. while ( alpha < 1.0f )
  537. {
  538. float dist = 0.0f;
  539. }
  540. samples.Add(InterpCurve3D(1.0f, true, ref k));
  541. length = 0.0f;
  542. int kend = knots.Count - 1;
  543. if ( closed )
  544. kend++;
  545. for ( int knot = 0; knot < kend; knot++ )
  546. {
  547. int k1 = (knot + 1) % knots.Count;
  548. Vector3 p1 = knots[knot].p;
  549. float step = 1.0f / (float)steps;
  550. float pos = step;
  551. knots[knot].seglength = 0.0f;
  552. for ( int i = 1; i < steps; i++ )
  553. {
  554. Vector3 p2 = knots[knot].Interpolate(pos, knots[k1]);
  555. knots[knot].seglength += Vector3.Magnitude(p2 - p1);
  556. p1 = p2;
  557. pos += step;
  558. }
  559. knots[knot].seglength += Vector3.Magnitude(knots[k1].p - p1);
  560. length += knots[knot].seglength;
  561. knots[knot].length = length;
  562. length = knots[knot].length;
  563. }
  564. return length;
  565. }
  566. #endif
  567. public float GetTwist(float alpha)
  568. {
  569. int seg = 0;
  570. if ( closed )
  571. {
  572. alpha = Mathf.Repeat(alpha, 1.0f);
  573. float dist = alpha * length;
  574. if ( dist > knots[knots.Count - 1].length )
  575. {
  576. alpha = 1.0f - ((length - dist) / knots[knots.Count - 1].seglength);
  577. //return Mathf.LerpAngle(knots[knots.Count - 1].twist, knots[0].twist, alpha);
  578. //return Mathf.Lerp(knots[knots.Count - 1].twist, knots[0].twist, alpha);
  579. return TwistVal(knots[knots.Count - 1].twist, knots[0].twist, alpha);
  580. }
  581. else
  582. {
  583. for ( seg = 0; seg < knots.Count; seg++ )
  584. {
  585. if ( dist <= knots[seg].length )
  586. break;
  587. }
  588. }
  589. alpha = 1.0f - ((knots[seg].length - dist) / knots[seg].seglength);
  590. if ( seg < knots.Count - 1 )
  591. {
  592. //return Mathf.LerpAngle(knots[seg].twist, knots[seg + 1].twist, alpha);
  593. //return Mathf.Lerp(knots[seg].twist, knots[seg + 1].twist, alpha);
  594. return TwistVal(knots[seg].twist, knots[seg + 1].twist, alpha);
  595. }
  596. else
  597. {
  598. //return Mathf.LerpAngle(knots[seg].twist, knots[0].twist, alpha);
  599. //return Mathf.Lerp(knots[seg].twist, knots[0].twist, alpha);
  600. return TwistVal(knots[seg].twist, knots[0].twist, alpha);
  601. }
  602. }
  603. else
  604. {
  605. alpha = Mathf.Clamp(alpha, 0.0f, 0.9999f);
  606. float dist = alpha * length;
  607. for ( seg = 0; seg < knots.Count; seg++ )
  608. {
  609. if ( dist <= knots[seg].length )
  610. break;
  611. }
  612. alpha = 1.0f - ((knots[seg].length - dist) / knots[seg].seglength);
  613. // Should check alpha
  614. if ( seg < knots.Count - 1 )
  615. {
  616. //return Mathf.LerpAngle(knots[seg].twist, knots[seg + 1].twist, alpha);
  617. return TwistVal(knots[seg].twist, knots[seg + 1].twist, alpha);
  618. }
  619. else
  620. return knots[seg].twist;
  621. }
  622. }
  623. /* So this should work for curves or splines, no sep code for curve, derive from common base */
  624. /* Could save a hint for next time through, ie spline and seg */
  625. public Vector3 Interpolate(float alpha, bool type, ref int k)
  626. {
  627. int seg = 0;
  628. //if ( alphas != null && alphas.Count > 0 )
  629. //{
  630. // int ix = (int)(alpha * (float)alphas.Count);
  631. // alpha *= alphas[ix];
  632. // if ( alpha >= 1.0f )
  633. // alpha = 0.99999f;
  634. // if ( alpha < 0.0f )
  635. // alpha = 0.0f;
  636. //}
  637. if ( constantSpeed )
  638. return InterpolateCS(alpha, type, ref k);
  639. // Special case if closed
  640. if ( closed )
  641. {
  642. if ( type )
  643. {
  644. float dist = alpha * length;
  645. if ( dist > knots[knots.Count - 1].length )
  646. {
  647. k = knots.Count - 1;
  648. alpha = 1.0f - ((length - dist) / knots[knots.Count - 1].seglength);
  649. return knots[knots.Count - 1].Interpolate(alpha, knots[0]);
  650. }
  651. else
  652. {
  653. for ( seg = 0; seg < knots.Count; seg++ )
  654. {
  655. if ( dist <= knots[seg].length )
  656. break;
  657. }
  658. }
  659. alpha = 1.0f - ((knots[seg].length - dist) / knots[seg].seglength);
  660. }
  661. else
  662. {
  663. float segf = alpha * knots.Count;
  664. seg = (int)segf;
  665. if ( seg == knots.Count )
  666. {
  667. seg--;
  668. alpha = 1.0f;
  669. }
  670. else
  671. alpha = segf - seg;
  672. }
  673. if ( seg < knots.Count - 1 )
  674. {
  675. k = seg;
  676. return knots[seg].Interpolate(alpha, knots[seg + 1]);
  677. }
  678. else
  679. {
  680. k = seg;
  681. return knots[seg].Interpolate(alpha, knots[0]);
  682. }
  683. //return knots[0].p;
  684. }
  685. else
  686. {
  687. if ( type )
  688. {
  689. float dist = alpha * length;
  690. for ( seg = 0; seg < knots.Count; seg++ )
  691. {
  692. if ( dist <= knots[seg].length )
  693. break;
  694. }
  695. alpha = 1.0f - ((knots[seg].length - dist) / knots[seg].seglength);
  696. }
  697. else
  698. {
  699. float segf = alpha * knots.Count;
  700. seg = (int)segf;
  701. if ( seg == knots.Count )
  702. {
  703. seg--;
  704. alpha = 1.0f;
  705. }
  706. else
  707. alpha = segf - seg;
  708. }
  709. // Should check alpha
  710. if ( seg < knots.Count - 1 )
  711. {
  712. k = seg;
  713. return knots[seg].Interpolate(alpha, knots[seg + 1]);
  714. }
  715. else
  716. {
  717. k = seg; //knots.Length - 1;
  718. return knots[seg].p;
  719. //return knots[seg].Interpolate(alpha, knots[seg + 1]);
  720. }
  721. }
  722. }
  723. public Vector3 InterpolateCS(float alpha, bool type, ref int k)
  724. {
  725. int seg = 0;
  726. // Special case if closed
  727. if ( closed )
  728. {
  729. float dist = alpha * length;
  730. if ( dist > knots[knots.Count - 1].length )
  731. {
  732. k = knots.Count - 1;
  733. alpha = 1.0f - ((length - dist) / knots[knots.Count - 1].seglength);
  734. return knots[knots.Count - 1].InterpolateCS(alpha, knots[0]);
  735. }
  736. else
  737. {
  738. for ( seg = 0; seg < knots.Count; seg++ )
  739. {
  740. if ( dist <= knots[seg].length )
  741. break;
  742. }
  743. }
  744. alpha = 1.0f - ((knots[seg].length - dist) / knots[seg].seglength);
  745. if ( seg < knots.Count - 1 )
  746. {
  747. k = seg;
  748. return knots[seg].InterpolateCS(alpha, knots[seg + 1]);
  749. }
  750. else
  751. {
  752. k = seg;
  753. return knots[seg].InterpolateCS(alpha, knots[0]);
  754. }
  755. }
  756. else
  757. {
  758. if ( type )
  759. {
  760. float dist = alpha * length;
  761. for ( seg = 0; seg < knots.Count; seg++ )
  762. {
  763. if ( dist <= knots[seg].length )
  764. break;
  765. }
  766. alpha = 1.0f - ((knots[seg].length - dist) / knots[seg].seglength);
  767. }
  768. else
  769. {
  770. float segf = alpha * knots.Count;
  771. seg = (int)segf;
  772. if ( seg == knots.Count )
  773. {
  774. seg--;
  775. alpha = 1.0f;
  776. }
  777. else
  778. alpha = segf - seg;
  779. }
  780. // Should check alpha
  781. if ( seg < knots.Count - 1 )
  782. {
  783. k = seg;
  784. return knots[seg].InterpolateCS(alpha, knots[seg + 1]);
  785. }
  786. else
  787. {
  788. k = seg; //knots.Length - 1;
  789. return knots[seg].p;
  790. //return knots[seg].Interpolate(alpha, knots[seg + 1]);
  791. }
  792. #if false
  793. float dist = alpha * length;
  794. if ( dist > knots[knots.Count - 1].length )
  795. {
  796. k = knots.Count - 1;
  797. alpha = 1.0f - ((length - dist) / knots[knots.Count - 1].seglength);
  798. return knots[knots.Count - 1].InterpolateCS(alpha, knots[0]);
  799. }
  800. else
  801. {
  802. for ( seg = 0; seg < knots.Count; seg++ )
  803. {
  804. if ( dist <= knots[seg].length )
  805. break;
  806. }
  807. }
  808. alpha = 1.0f - ((knots[seg].length - dist) / knots[seg].seglength);
  809. // Should check alpha
  810. if ( seg < knots.Count - 1 )
  811. {
  812. k = seg;
  813. return knots[seg].InterpolateCS(alpha, knots[seg + 1]);
  814. }
  815. else
  816. {
  817. k = seg; //knots.Length - 1;
  818. return knots[seg].p;
  819. }
  820. #endif
  821. }
  822. }
  823. private float easeInOutSine(float start, float end, float value)
  824. {
  825. end -= start;
  826. return -end / 2.0f * (Mathf.Cos(Mathf.PI * value / 1.0f) - 1.0f) + start;
  827. }
  828. float TwistVal(float v1, float v2, float alpha)
  829. {
  830. if ( twistmode == MegaShapeEase.Linear )
  831. return Mathf.Lerp(v1, v2, alpha);
  832. return easeInOutSine(v1, v2, alpha);
  833. }
  834. #if false
  835. public Vector3 Interpolate(float alpha, bool type, ref int k, ref float twist)
  836. {
  837. int seg = 0;
  838. if ( constantSpeed )
  839. return InterpolateCS(alpha, type, ref k, ref twist);
  840. // Special case if closed
  841. if ( closed )
  842. {
  843. if ( type )
  844. {
  845. float dist = alpha * length;
  846. if ( dist > knots[knots.Count - 1].length )
  847. {
  848. k = knots.Count - 1;
  849. alpha = 1.0f - ((length - dist) / knots[knots.Count - 1].seglength);
  850. //twist = Mathf.LerpAngle(knots[knots.Count - 1].twist, knots[0].twist, alpha);
  851. //twist = Mathf.Lerp(knots[knots.Count - 1].twist, knots[0].twist, alpha);
  852. twist = TwistVal(knots[knots.Count - 1].twist, knots[0].twist, alpha);
  853. return knots[knots.Count - 1].Interpolate(alpha, knots[0]);
  854. }
  855. else
  856. {
  857. for ( seg = 0; seg < knots.Count; seg++ )
  858. {
  859. if ( dist <= knots[seg].length )
  860. break;
  861. }
  862. }
  863. alpha = 1.0f - ((knots[seg].length - dist) / knots[seg].seglength);
  864. }
  865. else
  866. {
  867. float segf = alpha * knots.Count;
  868. seg = (int)segf;
  869. if ( seg == knots.Count )
  870. {
  871. seg--;
  872. alpha = 1.0f;
  873. }
  874. else
  875. alpha = segf - seg;
  876. }
  877. if ( seg < knots.Count - 1 )
  878. {
  879. k = seg;
  880. //twist = Mathf.LerpAngle(knots[seg].twist, knots[seg + 1].twist, alpha);
  881. //twist = Mathf.Lerp(knots[seg].twist, knots[seg + 1].twist, alpha);
  882. twist = TwistVal(knots[seg].twist, knots[seg + 1].twist, alpha);
  883. return knots[seg].Interpolate(alpha, knots[seg + 1]);
  884. }
  885. else
  886. {
  887. k = seg;
  888. //twist = Mathf.LerpAngle(knots[seg].twist, knots[0].twist, alpha);
  889. //twist = Mathf.Lerp(knots[seg].twist, knots[0].twist, alpha);
  890. twist = TwistVal(knots[seg].twist, knots[0].twist, alpha);
  891. return knots[seg].Interpolate(alpha, knots[0]);
  892. }
  893. }
  894. else
  895. {
  896. if ( type )
  897. {
  898. float dist = alpha * length;
  899. for ( seg = 0; seg < knots.Count; seg++ )
  900. {
  901. if ( dist <= knots[seg].length )
  902. break;
  903. }
  904. alpha = 1.0f - ((knots[seg].length - dist) / knots[seg].seglength);
  905. }
  906. else
  907. {
  908. float segf = alpha * knots.Count;
  909. seg = (int)segf;
  910. if ( seg == knots.Count )
  911. {
  912. seg--;
  913. alpha = 1.0f;
  914. }
  915. else
  916. alpha = segf - seg;
  917. }
  918. // Should check alpha
  919. if ( seg < knots.Count - 1 )
  920. {
  921. k = seg;
  922. //twist = Mathf.LerpAngle(knots[seg].twist, knots[seg + 1].twist, alpha);
  923. //twist = Mathf.Lerp(knots[seg].twist, knots[seg + 1].twist, alpha);
  924. twist = TwistVal(knots[seg].twist, knots[seg + 1].twist, alpha);
  925. return knots[seg].Interpolate(alpha, knots[seg + 1]);
  926. }
  927. else
  928. {
  929. k = seg; //knots.Length - 1;
  930. twist = knots[seg].twist;
  931. return knots[seg].p;
  932. }
  933. }
  934. }
  935. #endif
  936. public Vector3 Interpolate(float alpha, bool type, ref int k, ref float twist)
  937. {
  938. int seg = 0;
  939. if ( knots == null || knots.Count == 0 )
  940. return Vector3.zero;
  941. if ( constantSpeed )
  942. return InterpolateCS(alpha, type, ref k, ref twist);
  943. // Special case if closed
  944. if ( closed )
  945. {
  946. if ( type )
  947. {
  948. float dist = alpha * length;
  949. if ( dist > knots[knots.Count - 1].length )
  950. {
  951. k = knots.Count - 1;
  952. alpha = 1.0f - ((length - dist) / knots[knots.Count - 1].seglength);
  953. //twist = Mathf.LerpAngle(knots[knots.Count - 1].twist, knots[0].twist, alpha);
  954. //twist = Mathf.Lerp(knots[knots.Count - 1].twist, knots[0].twist, alpha);
  955. twist = TwistVal(knots[knots.Count - 1].twist, knots[0].twist, alpha);
  956. return knots[knots.Count - 1].Interpolate(alpha, knots[0]);
  957. }
  958. else
  959. {
  960. for ( seg = 0; seg < knots.Count; seg++ )
  961. {
  962. if ( dist <= knots[seg].length )
  963. break;
  964. }
  965. }
  966. alpha = 1.0f - ((knots[seg].length - dist) / knots[seg].seglength);
  967. }
  968. else
  969. {
  970. float segf = alpha * knots.Count;
  971. seg = (int)segf;
  972. if ( seg == knots.Count )
  973. {
  974. seg--;
  975. alpha = 1.0f;
  976. }
  977. else
  978. alpha = segf - seg;
  979. }
  980. if ( seg < knots.Count - 1 )
  981. {
  982. k = seg;
  983. //twist = Mathf.LerpAngle(knots[seg].twist, knots[seg + 1].twist, alpha);
  984. //twist = Mathf.Lerp(knots[seg].twist, knots[seg + 1].twist, alpha);
  985. twist = TwistVal(knots[seg].twist, knots[seg + 1].twist, alpha);
  986. return knots[seg].Interpolate(alpha, knots[seg + 1]);
  987. }
  988. else
  989. {
  990. k = seg;
  991. //twist = Mathf.LerpAngle(knots[seg].twist, knots[0].twist, alpha);
  992. //twist = Mathf.Lerp(knots[seg].twist, knots[0].twist, alpha);
  993. twist = TwistVal(knots[seg].twist, knots[0].twist, alpha);
  994. return knots[seg].Interpolate(alpha, knots[0]);
  995. }
  996. }
  997. else
  998. {
  999. if ( type )
  1000. {
  1001. float dist = alpha * length;
  1002. for ( seg = 0; seg < knots.Count; seg++ )
  1003. {
  1004. if ( dist <= knots[seg].length )
  1005. break;
  1006. }
  1007. alpha = 1.0f - ((knots[seg].length - dist) / knots[seg].seglength);
  1008. }
  1009. else
  1010. {
  1011. float segf = alpha * knots.Count;
  1012. seg = (int)segf;
  1013. if ( seg == knots.Count )
  1014. {
  1015. seg--;
  1016. alpha = 1.0f;
  1017. }
  1018. else
  1019. alpha = segf - seg;
  1020. }
  1021. // Should check alpha
  1022. if ( seg < knots.Count - 1 )
  1023. {
  1024. k = seg;
  1025. twist = TwistVal(knots[seg].twist, knots[seg + 1].twist, alpha);
  1026. return knots[seg].Interpolate(alpha, knots[seg + 1]);
  1027. }
  1028. else
  1029. {
  1030. k = seg; //knots.Length - 1;
  1031. twist = knots[seg].twist;
  1032. return knots[seg].p;
  1033. }
  1034. }
  1035. }
  1036. #if false
  1037. public Vector3 InterpolateCS(float alpha, bool type, ref int k, ref float twist)
  1038. {
  1039. int seg = 0;
  1040. // Special case if closed
  1041. if ( closed )
  1042. {
  1043. float dist = alpha * length;
  1044. if ( dist > knots[knots.Count - 1].length )
  1045. {
  1046. k = knots.Count - 1;
  1047. alpha = 1.0f - ((length - dist) / knots[knots.Count - 1].seglength);
  1048. //twist = Mathf.LerpAngle(knots[knots.Count - 1].twist, knots[0].twist, alpha);
  1049. twist = TwistVal(knots[knots.Count - 1].twist, knots[0].twist, alpha);
  1050. return knots[knots.Count - 1].InterpolateCS(alpha, knots[0]);
  1051. }
  1052. else
  1053. {
  1054. for ( seg = 0; seg < knots.Count; seg++ )
  1055. {
  1056. if ( dist <= knots[seg].length )
  1057. break;
  1058. }
  1059. }
  1060. alpha = 1.0f - ((knots[seg].length - dist) / knots[seg].seglength);
  1061. if ( seg < knots.Count - 1 )
  1062. {
  1063. k = seg;
  1064. //twist = Mathf.LerpAngle(knots[seg].twist, knots[seg + 1].twist, alpha);
  1065. twist = TwistVal(knots[seg].twist, knots[seg + 1].twist, alpha);
  1066. return knots[seg].InterpolateCS(alpha, knots[seg + 1]);
  1067. }
  1068. else
  1069. {
  1070. k = seg;
  1071. //twist = Mathf.LerpAngle(knots[seg].twist, knots[0].twist, alpha);
  1072. twist = TwistVal(knots[seg].twist, knots[0].twist, alpha);
  1073. return knots[seg].InterpolateCS(alpha, knots[0]);
  1074. }
  1075. }
  1076. else
  1077. {
  1078. if ( type )
  1079. {
  1080. float dist = alpha * length;
  1081. for ( seg = 0; seg < knots.Count; seg++ )
  1082. {
  1083. if ( dist <= knots[seg].length )
  1084. break;
  1085. }
  1086. alpha = 1.0f - ((knots[seg].length - dist) / knots[seg].seglength);
  1087. }
  1088. else
  1089. {
  1090. float segf = alpha * knots.Count;
  1091. seg = (int)segf;
  1092. if ( seg == knots.Count )
  1093. {
  1094. seg--;
  1095. alpha = 1.0f;
  1096. }
  1097. else
  1098. alpha = segf - seg;
  1099. }
  1100. // Should check alpha
  1101. if ( seg < knots.Count - 1 )
  1102. {
  1103. k = seg;
  1104. //twist = Mathf.LerpAngle(knots[seg].twist, knots[seg + 1].twist, alpha);
  1105. twist = TwistVal(knots[seg].twist, knots[seg + 1].twist, alpha);
  1106. return knots[seg].InterpolateCS(alpha, knots[seg + 1]);
  1107. }
  1108. else
  1109. {
  1110. k = seg; //knots.Length - 1;
  1111. twist = knots[seg].twist;
  1112. return knots[seg].p;
  1113. //return knots[seg].Interpolate(alpha, knots[seg + 1]);
  1114. }
  1115. }
  1116. }
  1117. #endif
  1118. public Vector3 InterpolateCS(float alpha, bool type, ref int k, ref float twist)
  1119. {
  1120. int seg = 0;
  1121. // Special case if closed
  1122. if ( closed )
  1123. {
  1124. float dist = alpha * length;
  1125. if ( dist > knots[knots.Count - 1].length )
  1126. {
  1127. k = knots.Count - 1;
  1128. alpha = 1.0f - ((length - dist) / knots[knots.Count - 1].seglength);
  1129. twist = TwistVal(knots[knots.Count - 1].twist, knots[0].twist, alpha);
  1130. return knots[knots.Count - 1].InterpolateCS(alpha, knots[0]);
  1131. }
  1132. else
  1133. {
  1134. for ( seg = 0; seg < knots.Count; seg++ )
  1135. {
  1136. if ( dist <= knots[seg].length )
  1137. break;
  1138. }
  1139. }
  1140. if ( seg == knots.Count || knots[seg].seglength == 0.0f )
  1141. alpha = 0.0f;
  1142. else
  1143. alpha = 1.0f - ((knots[seg].length - dist) / knots[seg].seglength);
  1144. if ( seg < knots.Count - 1 )
  1145. {
  1146. k = seg;
  1147. twist = TwistVal(knots[seg].twist, knots[seg + 1].twist, alpha);
  1148. return knots[seg].InterpolateCS(alpha, knots[seg + 1]);
  1149. }
  1150. else
  1151. {
  1152. seg = knots.Count - 1;
  1153. k = seg;
  1154. twist = TwistVal(knots[seg].twist, knots[0].twist, alpha);
  1155. return knots[seg].InterpolateCS(alpha, knots[0]);
  1156. }
  1157. }
  1158. else
  1159. {
  1160. if ( type )
  1161. {
  1162. float dist = alpha * length;
  1163. for ( seg = 0; seg < knots.Count; seg++ )
  1164. {
  1165. if ( dist <= knots[seg].length )
  1166. break;
  1167. }
  1168. if ( seg == knots.Count || knots[seg].seglength == 0.0f )
  1169. alpha = 0.0f;
  1170. else
  1171. alpha = 1.0f - ((knots[seg].length - dist) / knots[seg].seglength);
  1172. }
  1173. else
  1174. {
  1175. float segf = alpha * knots.Count;
  1176. seg = (int)segf;
  1177. if ( seg == knots.Count )
  1178. {
  1179. seg--;
  1180. alpha = 1.0f;
  1181. }
  1182. else
  1183. alpha = segf - seg;
  1184. }
  1185. // Should check alpha
  1186. if ( seg < knots.Count - 1 )
  1187. {
  1188. k = seg;
  1189. twist = TwistVal(knots[seg].twist, knots[seg + 1].twist, alpha);
  1190. return knots[seg].InterpolateCS(alpha, knots[seg + 1]);
  1191. }
  1192. else
  1193. {
  1194. seg = knots.Count - 1;
  1195. k = seg; //knots.Length - 1;
  1196. twist = knots[seg].twist;
  1197. return knots[seg].p;
  1198. }
  1199. }
  1200. }
  1201. // New method that handles open splines better
  1202. public Vector3 InterpCurve3D(float alpha, bool type, ref int k)
  1203. {
  1204. Vector3 ret;
  1205. k = 0;
  1206. if ( knots == null || knots.Count == 0 )
  1207. return Vector3.zero;
  1208. if ( alpha < 0.0f )
  1209. {
  1210. if ( closed )
  1211. alpha = Mathf.Repeat(alpha, 1.0f);
  1212. else
  1213. {
  1214. Vector3 ps = Interpolate(0.0f, type, ref k);
  1215. // Need a proper tangent function
  1216. Vector3 ps1 = Interpolate(0.01f, type, ref k);
  1217. // Calc the spline in out vecs
  1218. Vector3 delta = ps1 - ps;
  1219. delta.Normalize();
  1220. return ps + ((length * alpha) * delta);
  1221. }
  1222. }
  1223. else
  1224. {
  1225. if ( alpha > 1.0f )
  1226. {
  1227. if ( closed )
  1228. alpha = alpha % 1.0f;
  1229. else
  1230. {
  1231. Vector3 ps = Interpolate(1.0f, type, ref k);
  1232. // Need a proper tangent function
  1233. Vector3 ps1 = Interpolate(0.99f, type, ref k);
  1234. // Calc the spline in out vecs
  1235. Vector3 delta = ps1 - ps;
  1236. delta.Normalize();
  1237. return ps + ((length * (1.0f - alpha)) * delta);
  1238. }
  1239. }
  1240. }
  1241. ret = Interpolate(alpha, type, ref k);
  1242. return ret;
  1243. }
  1244. public Vector3 InterpBezier3D(int knot, float a)
  1245. {
  1246. if ( knot < knots.Count )
  1247. {
  1248. int k1 = knot + 1;
  1249. if ( k1 == knots.Count && closed )
  1250. {
  1251. k1 = 0;
  1252. }
  1253. return knots[knot].Interpolate(a, knots[k1]);
  1254. }
  1255. return Vector3.zero;
  1256. }
  1257. // Should be spline methods
  1258. public void Centre(float scale)
  1259. {
  1260. Vector3 p = Vector3.zero;
  1261. for ( int i = 0; i < knots.Count; i++ )
  1262. p += knots[i].p;
  1263. p /= (float)knots.Count;
  1264. for ( int i = 0; i < knots.Count; i++ )
  1265. {
  1266. knots[i].p -= p;
  1267. knots[i].invec -= p;
  1268. knots[i].outvec -= p;
  1269. knots[i].p *= scale;
  1270. knots[i].invec *= scale;
  1271. knots[i].outvec *= scale;
  1272. }
  1273. }
  1274. public void Reverse()
  1275. {
  1276. List<MegaKnot> newknots = new List<MegaKnot>();
  1277. for ( int i = knots.Count - 1; i >= 0; i-- )
  1278. {
  1279. MegaKnot k = new MegaKnot();
  1280. k.p = knots[i].p;
  1281. k.invec = knots[i].outvec;
  1282. k.outvec = knots[i].invec;
  1283. newknots.Add(k);
  1284. }
  1285. knots = newknots;
  1286. CalcLength(); //(10);
  1287. }
  1288. public void SetHeight(float y)
  1289. {
  1290. for ( int i = 0; i < knots.Count; i++ )
  1291. {
  1292. knots[i].p.y = y;
  1293. knots[i].outvec.y = y;
  1294. knots[i].invec.y = y;
  1295. }
  1296. }
  1297. public void SetTwist(float twist)
  1298. {
  1299. for ( int i = 0; i < knots.Count; i++ )
  1300. {
  1301. knots[i].twist = twist;
  1302. }
  1303. }
  1304. public Vector3 FindNearestPoint(Vector3 p, int iterations, ref int kn, ref Vector3 tangent, ref float alpha)
  1305. {
  1306. //Vector3 np = Vector3.zero;
  1307. float positiveInfinity = float.PositiveInfinity;
  1308. float num2 = 0.0f;
  1309. iterations = Mathf.Clamp(iterations, 0, 5);
  1310. int kt = 0;
  1311. for ( float i = 0.0f; i <= 1.0f; i += 0.01f )
  1312. {
  1313. Vector3 vector = Interpolate(i, true, ref kt) - p;
  1314. float sqrMagnitude = vector.sqrMagnitude;
  1315. if ( positiveInfinity > sqrMagnitude )
  1316. {
  1317. positiveInfinity = sqrMagnitude;
  1318. num2 = i;
  1319. }
  1320. }
  1321. for ( int j = 0; j < iterations; j++ )
  1322. {
  1323. float num6 = 0.01f * Mathf.Pow(10.0f, -((float)j));
  1324. float num7 = num6 * 0.1f;
  1325. for ( float k = Mathf.Clamp01(num2 - num6); k <= Mathf.Clamp01(num2 + num6); k += num7 )
  1326. {
  1327. Vector3 vector2 = Interpolate(k, true, ref kt) - p;
  1328. float num9 = vector2.sqrMagnitude;
  1329. if ( positiveInfinity > num9 )
  1330. {
  1331. positiveInfinity = num9;
  1332. num2 = k;
  1333. }
  1334. }
  1335. }
  1336. kn = kt;
  1337. tangent = InterpCurve3D(num2 + 0.01f, true, ref kn);
  1338. alpha = num2;
  1339. return InterpCurve3D(num2, true, ref kn); //num2;
  1340. }
  1341. }
  1342. public enum MeshShapeType
  1343. {
  1344. Fill, // options, height, doublesided
  1345. Tube, // sides, cap ends, start, end, step
  1346. Box,
  1347. Ribbon,
  1348. //Line, // height, rotate, offset, segments for height
  1349. //Lathe, // segs
  1350. }
  1351. [ExecuteInEditMode]
  1352. public class MegaShape : MonoBehaviour
  1353. {
  1354. public MegaAxis axis = MegaAxis.Y;
  1355. public Color col1 = new Color(1.0f, 1.0f, 1.0f, 1.0f);
  1356. public Color col2 = new Color(0.1f, 0.1f, 0.1f, 1.0f);
  1357. public Color KnotCol = new Color(0.0f, 1.0f, 0.0f, 1.0f);
  1358. public Color HandleCol = new Color(1.0f, 0.0f, 0.0f, 1.0f);
  1359. public Color VecCol = new Color(0.1f, 0.1f, 0.2f, 0.5f);
  1360. public float KnotSize = 10.0f;
  1361. public float stepdist = 1.0f; // Distance along whole shape
  1362. public bool normalizedInterp = true;
  1363. public bool drawHandles = false;
  1364. public bool drawKnots = true;
  1365. public bool drawspline = true;
  1366. public bool drawTwist = false;
  1367. public bool lockhandles = true;
  1368. public bool showorigin = true;
  1369. public bool usesnap = false;
  1370. public bool usesnaphandles = false;
  1371. public Vector3 snap = Vector3.one;
  1372. public MegaHandleType handleType = MegaHandleType.Position;
  1373. public float CursorPos = 0.0f;
  1374. public List<MegaSpline> splines = new List<MegaSpline>();
  1375. public bool showanimations = false;
  1376. public float keytime = 0.0f;
  1377. public bool updateondrag = true;
  1378. // Lightmap
  1379. public float angleError = 0.08f;
  1380. public float areaError = 0.15f;
  1381. public float hardAngle = 88.0f;
  1382. public float packMargin = 0.0039f;
  1383. //public virtual void MakeShape() { }
  1384. public float defRadius = 1.0f;
  1385. public bool smoothonaddknot = true;
  1386. const float CIRCLE_VECTOR_LENGTH = 0.5517861843f;
  1387. public virtual void MakeShape()
  1388. {
  1389. Matrix4x4 tm = GetMatrix();
  1390. float vector = CIRCLE_VECTOR_LENGTH * defRadius;
  1391. MegaSpline spline = NewSpline();
  1392. for ( int ix = 0; ix < 4; ++ix )
  1393. {
  1394. float angle = (Mathf.PI * 2.0f) * (float)ix / (float)4;
  1395. float sinfac = Mathf.Sin(angle);
  1396. float cosfac = Mathf.Cos(angle);
  1397. Vector3 p = new Vector3(cosfac * defRadius, sinfac * defRadius, 0.0f);
  1398. Vector3 rotvec = new Vector3(sinfac * vector, -cosfac * vector, 0.0f);
  1399. spline.AddKnot(p, p + rotvec, p - rotvec, tm);
  1400. }
  1401. spline.closed = true;
  1402. CalcLength(); //10);
  1403. }
  1404. //public List<MegaKnotAnim> animations;
  1405. public float testtime = 0.0f;
  1406. public float time = 0.0f;
  1407. public bool animate;
  1408. public float speed = 1.0f;
  1409. public int selcurve = 0;
  1410. public bool imported = false;
  1411. //public int CurrentCurve = 0;
  1412. //public int CursorKnot = 0;
  1413. public float CursorPercent = 0.0f;
  1414. public virtual string GetHelpURL() { return "?page_id=390"; }
  1415. [ContextMenu("Help")]
  1416. public void Help()
  1417. {
  1418. Application.OpenURL("http://www.west-racing.com/mf/" + GetHelpURL());
  1419. }
  1420. [ContextMenu("Reset Mesh Info")]
  1421. public void ResetMesh()
  1422. {
  1423. shapemesh = null;
  1424. BuildMesh();
  1425. }
  1426. public Matrix4x4 GetMatrix()
  1427. {
  1428. Matrix4x4 tm = Matrix4x4.identity;
  1429. switch ( axis )
  1430. {
  1431. case MegaAxis.X: MegaMatrix.RotateY(ref tm, -Mathf.PI * 0.5f);
  1432. MegaMatrix.Scale(ref tm, -Vector3.one, false);
  1433. break;
  1434. //case MegaAxis.X: MegaMatrix.RotateY(ref tm, Mathf.PI * 0.5f); break;
  1435. case MegaAxis.Y: MegaMatrix.RotateX(ref tm, Mathf.PI * 0.5f); break;
  1436. case MegaAxis.Z: break; //Matrix.RotateY(ref tm, Mathf.PI * 0.5f); break;
  1437. }
  1438. return tm;
  1439. }
  1440. public void CopyIDS(int curve)
  1441. {
  1442. if ( curve > 0 && curve < splines.Count )
  1443. {
  1444. MegaSpline tospl = splines[curve];
  1445. MegaSpline fromspl = splines[curve - 1];
  1446. for ( int i = 0; i < fromspl.knots.Count && i < tospl.knots.Count; i++ )
  1447. {
  1448. tospl.knots[i].id = fromspl.knots[i].id;
  1449. }
  1450. }
  1451. }
  1452. public void Reverse(int c)
  1453. {
  1454. if ( c >= 0 && c < splines.Count )
  1455. {
  1456. splines[c].Reverse();
  1457. }
  1458. }
  1459. public void SetHeight(int c, float y)
  1460. {
  1461. if ( c >= 0 && c < splines.Count )
  1462. {
  1463. splines[c].SetHeight(y);
  1464. }
  1465. }
  1466. public void SetTwist(int c, float twist)
  1467. {
  1468. if ( c >= 0 && c < splines.Count )
  1469. {
  1470. splines[c].SetTwist(twist);
  1471. }
  1472. }
  1473. // Should be in MegaShape
  1474. public MegaSpline NewSpline()
  1475. {
  1476. if ( splines.Count == 0 )
  1477. {
  1478. MegaSpline newspline = new MegaSpline();
  1479. splines.Add(newspline);
  1480. }
  1481. MegaSpline spline = splines[0];
  1482. spline.knots.Clear();
  1483. spline.closed = false;
  1484. return spline;
  1485. }
  1486. void Reset()
  1487. {
  1488. MakeShape();
  1489. }
  1490. void Awake()
  1491. {
  1492. if ( splines.Count == 0 )
  1493. {
  1494. MakeShape();
  1495. }
  1496. }
  1497. float t = 0.0f;
  1498. public float MaxTime = 1.0f;
  1499. public MegaRepeatMode LoopMode;
  1500. public bool dolateupdate = false;
  1501. void Update()
  1502. {
  1503. if ( !dolateupdate )
  1504. {
  1505. DoUpdate();
  1506. }
  1507. }
  1508. void LateUpdate()
  1509. {
  1510. if ( dolateupdate )
  1511. {
  1512. DoUpdate();
  1513. }
  1514. }
  1515. void DoUpdate()
  1516. {
  1517. if ( animate )
  1518. {
  1519. BuildMesh();
  1520. time += Time.deltaTime * speed;
  1521. switch ( LoopMode )
  1522. {
  1523. case MegaRepeatMode.Loop: t = Mathf.Repeat(time, MaxTime); break;
  1524. case MegaRepeatMode.PingPong: t = Mathf.PingPong(time, MaxTime); break;
  1525. case MegaRepeatMode.Clamp: t = Mathf.Clamp(time, 0.0f, MaxTime); break;
  1526. }
  1527. for ( int s = 0; s < splines.Count; s++ )
  1528. {
  1529. if ( splines[s].splineanim != null && splines[s].splineanim.Enabled && splines[s].splineanim.NumKeys() > 1 )
  1530. {
  1531. //Debug.Log("getstate");
  1532. splines[s].splineanim.GetState1(splines[s], t);
  1533. splines[s].CalcLength(); //(10); // could use less here
  1534. }
  1535. else
  1536. {
  1537. if ( splines[s].animations != null && splines[s].animations.Count > 0 )
  1538. {
  1539. for ( int i = 0; i < splines[s].animations.Count; i++ )
  1540. {
  1541. Vector3 pos = splines[s].animations[i].con.GetVector3(t);
  1542. switch ( splines[s].animations[i].t )
  1543. {
  1544. case 0: splines[splines[s].animations[i].s].knots[splines[s].animations[i].p].invec = pos; break;
  1545. case 1: splines[splines[s].animations[i].s].knots[splines[s].animations[i].p].p = pos; break;
  1546. case 2: splines[splines[s].animations[i].s].knots[splines[s].animations[i].p].outvec = pos; break;
  1547. }
  1548. }
  1549. splines[s].CalcLength(); //(10); // could use less here
  1550. }
  1551. }
  1552. }
  1553. }
  1554. // Options here:
  1555. // Uv scale, offset, rotate, physuv, genuv
  1556. // Optimize
  1557. // recalcnorms
  1558. // tangents
  1559. // fill in shape
  1560. // pipe along shape
  1561. // wall along shape
  1562. // double sided
  1563. // extrude on fill
  1564. //BuildMesh();
  1565. #if false
  1566. if ( makeMesh )
  1567. {
  1568. //makeMesh = false;
  1569. List<Vector3> verts = new List<Vector3>();
  1570. List<Vector2> uvs = new List<Vector2>();
  1571. float sdist = stepdist * 0.1f;
  1572. if ( splines[0].length / sdist > 1500.0f )
  1573. sdist = splines[0].length / 1500.0f;
  1574. int[] tris = MegaTriangulator.Triangulate(this, splines[0], sdist, ref verts, ref uvs);
  1575. if ( shapemesh == null )
  1576. {
  1577. MeshFilter mf = gameObject.GetComponent<MeshFilter>();
  1578. if ( mf == null )
  1579. mf = gameObject.AddComponent<MeshFilter>();
  1580. mf.sharedMesh = new Mesh();
  1581. MeshRenderer mr = gameObject.GetComponent<MeshRenderer>();
  1582. if ( mr == null )
  1583. {
  1584. mr = gameObject.AddComponent<MeshRenderer>();
  1585. }
  1586. Material[] mats = new Material[1];
  1587. mr.sharedMaterials = mats;
  1588. shapemesh = mf.sharedMesh; //Utils.GetMesh(gameObject);
  1589. }
  1590. //Vector3[] verts = new Vector3[splines[0].knots.Count];
  1591. //for ( int i = 0; i < splines[0].knots.Count; i++ )
  1592. //{
  1593. // verts[i] = splines[0].knots[i].p;
  1594. //}
  1595. shapemesh.Clear();
  1596. shapemesh.vertices = verts.ToArray();
  1597. shapemesh.uv = uvs.ToArray();
  1598. shapemesh.triangles = tris;
  1599. shapemesh.RecalculateNormals();
  1600. shapemesh.RecalculateBounds();
  1601. }
  1602. #endif
  1603. }
  1604. // Meshing options
  1605. public bool makeMesh = false;
  1606. public MeshShapeType meshType = MeshShapeType.Fill;
  1607. public bool DoubleSided = true;
  1608. public bool CalcTangents = false;
  1609. public bool GenUV = true;
  1610. public bool PhysUV = false;
  1611. public float Height = 0.0f;
  1612. public int HeightSegs = 1;
  1613. public int Sides = 4;
  1614. public float TubeStep = 0.1f;
  1615. public float Start = 0.0f;
  1616. public float End = 100.0f;
  1617. public float Rotate = 0.0f;
  1618. public Vector3 Pivot = Vector3.zero;
  1619. // Material 1
  1620. public Vector2 UVOffset = Vector2.zero;
  1621. public Vector2 UVRotate = Vector2.zero;
  1622. public Vector2 UVScale = Vector2.one;
  1623. public Vector2 UVOffset1 = Vector2.zero;
  1624. public Vector2 UVRotate1 = Vector2.zero;
  1625. public Vector2 UVScale1 = Vector2.one;
  1626. public Vector2 UVOffset2 = Vector2.zero;
  1627. public Vector2 UVRotate3 = Vector2.zero;
  1628. public Vector2 UVScale3 = Vector2.one;
  1629. public bool autosmooth = false;
  1630. public float smoothness = 0.75f;
  1631. public bool flipNormals = false;
  1632. public MegaShapeBezComputeMode smoothMode = MegaShapeBezComputeMode.Old;
  1633. public bool smoothOnDrag = false;
  1634. public bool freezeX = false;
  1635. public bool freezeY = false;
  1636. public bool freezeZ = false;
  1637. // TODO:
  1638. // Pivot
  1639. // UV info per submesh
  1640. // work on multiple splines
  1641. // new poly to tri to handle holes
  1642. // merge to one mesh
  1643. // height segs
  1644. public Material mat1;
  1645. public Material mat2;
  1646. public Material mat3;
  1647. public bool UseHeightCurve = false;
  1648. public AnimationCurve heightCrv = new AnimationCurve(new Keyframe(0, 1), new Keyframe(1, 1));
  1649. public float heightOff = 0.0f;
  1650. // May need wall UV info as well
  1651. public Mesh shapemesh;
  1652. // New equal step system for faster interps etc
  1653. #if false
  1654. //Create table to convert u to distance
  1655. std::pair<float, float> u_distance_map[LENGTH_DIVISIONS + 1];
  1656. //Calculate u value and distance map
  1657. public void CreateDistMap(int divs)
  1658. {
  1659. for ( int i = 0; i <= divs; i++ )
  1660. {
  1661. float u = (float)i / (float)divs;
  1662. u_distance_map[i].first = u;
  1663. u_distance_map[i].second = track_path->Get_Path_Length(u);
  1664. }
  1665. //Determine the u values of the ties
  1666. std::vector<float> tie_u_values;
  1667. for ( int i = 0; i < num_ties; i++ )
  1668. {
  1669. bool found = false;
  1670. for ( int j = 1; j <= divs && !found; j++ )
  1671. {
  1672. /*The correct u value is less than this distance and greater than the last
  1673. so just interpolate from here.*/
  1674. if ( u_distance_map[j].second >= (i + 1) * tie_distance )
  1675. {
  1676. //Calculate percentage between u values
  1677. float distance_between_nodes = u_distance_map[j].second - u_distance_map[j - 1].second;
  1678. float distance_past_previous = ((i + 1) * tie_distance) - u_distance_map[j - 1].second;
  1679. float percent = distance_past_previous / distance_between_nodes;
  1680. //Calculate u value
  1681. float u = ((u_distance_map[j].first - u_distance_map[j - 1].first) * percent) + u_distance_map[j - 1].first;
  1682. found = true;
  1683. tie_u_values.push_back(u);
  1684. }
  1685. }
  1686. }
  1687. }
  1688. #endif
  1689. public void Centre(float scale, Vector3 axis)
  1690. {
  1691. Vector3 p = Vector3.zero;
  1692. int count = 0;
  1693. for ( int s = 0; s < splines.Count; s++ )
  1694. {
  1695. count += splines[s].knots.Count;
  1696. for ( int i = 0; i < splines[s].knots.Count; i++ )
  1697. p += splines[s].knots[i].p;
  1698. }
  1699. p /= (float)count; //knots.Count;
  1700. for ( int s = 0; s < splines.Count; s++ )
  1701. {
  1702. for ( int i = 0; i < splines[s].knots.Count; i++ )
  1703. {
  1704. splines[s].knots[i].p -= p;
  1705. splines[s].knots[i].invec -= p;
  1706. splines[s].knots[i].outvec -= p;
  1707. splines[s].knots[i].p *= scale;
  1708. splines[s].knots[i].invec *= scale;
  1709. splines[s].knots[i].outvec *= scale;
  1710. splines[s].knots[i].p = Vector3.Scale(splines[s].knots[i].p, axis);
  1711. splines[s].knots[i].invec = Vector3.Scale(splines[s].knots[i].invec, axis);
  1712. splines[s].knots[i].outvec = Vector3.Scale(splines[s].knots[i].outvec, axis);
  1713. }
  1714. }
  1715. }
  1716. public void Centre(float scale, Vector3 axis, int start)
  1717. {
  1718. Vector3 p = Vector3.zero;
  1719. int count = 0;
  1720. for ( int s = start; s < splines.Count; s++ )
  1721. {
  1722. count += splines[s].knots.Count;
  1723. for ( int i = 0; i < splines[s].knots.Count; i++ )
  1724. p += splines[s].knots[i].p;
  1725. }
  1726. p /= (float)count; //knots.Count;
  1727. for ( int s = start; s < splines.Count; s++ )
  1728. {
  1729. for ( int i = 0; i < splines[s].knots.Count; i++ )
  1730. {
  1731. splines[s].knots[i].p -= p;
  1732. splines[s].knots[i].invec -= p;
  1733. splines[s].knots[i].outvec -= p;
  1734. splines[s].knots[i].p *= scale;
  1735. splines[s].knots[i].invec *= scale;
  1736. splines[s].knots[i].outvec *= scale;
  1737. splines[s].knots[i].p = Vector3.Scale(splines[s].knots[i].p, axis);
  1738. splines[s].knots[i].invec = Vector3.Scale(splines[s].knots[i].invec, axis);
  1739. splines[s].knots[i].outvec = Vector3.Scale(splines[s].knots[i].outvec, axis);
  1740. }
  1741. }
  1742. }
  1743. public void CoordAdjust(float scale, Vector3 axis, int start)
  1744. {
  1745. for ( int s = start; s < splines.Count; s++ )
  1746. {
  1747. for ( int i = 0; i < splines[s].knots.Count; i++ )
  1748. {
  1749. splines[s].knots[i].p *= scale;
  1750. splines[s].knots[i].invec *= scale;
  1751. splines[s].knots[i].outvec *= scale;
  1752. splines[s].knots[i].p = Vector3.Scale(splines[s].knots[i].p, axis);
  1753. splines[s].knots[i].invec = Vector3.Scale(splines[s].knots[i].invec, axis);
  1754. splines[s].knots[i].outvec = Vector3.Scale(splines[s].knots[i].outvec, axis);
  1755. }
  1756. }
  1757. }
  1758. // Need a scale method?
  1759. public void Scale(float scale)
  1760. {
  1761. for ( int i = 0; i < splines.Count; i++ )
  1762. {
  1763. for ( int k = 0; k < splines[i].knots.Count; k++ )
  1764. {
  1765. splines[i].knots[k].invec *= scale;
  1766. splines[i].knots[k].p *= scale;
  1767. splines[i].knots[k].outvec *= scale;
  1768. }
  1769. if ( splines[i].animations != null )
  1770. {
  1771. for ( int a = 0; a < splines[i].animations.Count; a++ )
  1772. {
  1773. if ( splines[i].animations[a].con != null )
  1774. splines[i].animations[a].con.Scale(scale);
  1775. }
  1776. }
  1777. }
  1778. CalcLength(); //(10);
  1779. }
  1780. public void Scale(float scale, int start)
  1781. {
  1782. for ( int i = start; i < splines.Count; i++ )
  1783. {
  1784. for ( int k = 0; k < splines[i].knots.Count; k++ )
  1785. {
  1786. splines[i].knots[k].invec *= scale;
  1787. splines[i].knots[k].p *= scale;
  1788. splines[i].knots[k].outvec *= scale;
  1789. }
  1790. if ( splines[i].animations != null )
  1791. {
  1792. for ( int a = 0; a < splines[i].animations.Count; a++ )
  1793. {
  1794. if ( splines[i].animations[a].con != null )
  1795. splines[i].animations[a].con.Scale(scale);
  1796. }
  1797. }
  1798. }
  1799. CalcLength(); //(10);
  1800. }
  1801. public void Scale(Vector3 scale)
  1802. {
  1803. for ( int i = 0; i < splines.Count; i++ )
  1804. {
  1805. for ( int k = 0; k < splines[i].knots.Count; k++ )
  1806. {
  1807. splines[i].knots[k].invec.x *= scale.x;
  1808. splines[i].knots[k].invec.y *= scale.y;
  1809. splines[i].knots[k].invec.z *= scale.z;
  1810. splines[i].knots[k].p.x *= scale.x;
  1811. splines[i].knots[k].p.y *= scale.y;
  1812. splines[i].knots[k].p.z *= scale.z;
  1813. splines[i].knots[k].outvec.x *= scale.x;
  1814. splines[i].knots[k].outvec.y *= scale.y;
  1815. splines[i].knots[k].outvec.z *= scale.z;
  1816. }
  1817. if ( splines[i].animations != null )
  1818. {
  1819. for ( int a = 0; a < splines[i].animations.Count; a++ )
  1820. {
  1821. if ( splines[i].animations[a].con != null )
  1822. splines[i].animations[a].con.Scale(scale);
  1823. }
  1824. }
  1825. }
  1826. CalcLength(); //(10);
  1827. }
  1828. public void MoveSpline(Vector3 delta)
  1829. {
  1830. for ( int i = 0; i < splines.Count; i++ )
  1831. {
  1832. MoveSpline(delta, i, false);
  1833. }
  1834. CalcLength(); //(10);
  1835. }
  1836. public void MoveSpline(Vector3 delta, int c, bool calc)
  1837. {
  1838. for ( int k = 0; k < splines[c].knots.Count; k++ )
  1839. {
  1840. splines[c].knots[k].invec += delta;
  1841. splines[c].knots[k].p += delta;
  1842. splines[c].knots[k].outvec += delta;
  1843. }
  1844. if ( splines[c].animations != null )
  1845. {
  1846. for ( int a = 0; a < splines[c].animations.Count; a++ )
  1847. {
  1848. if ( splines[c].animations[a].con != null )
  1849. splines[c].animations[a].con.Move(delta);
  1850. }
  1851. }
  1852. if ( calc )
  1853. CalcLength(c); //(10);
  1854. }
  1855. public void RotateSpline(Vector3 rot, int c, bool calc)
  1856. {
  1857. Matrix4x4 tm = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(rot), Vector3.one);
  1858. for ( int k = 0; k < splines[c].knots.Count; k++ )
  1859. {
  1860. splines[c].knots[k].invec = tm.MultiplyPoint3x4(splines[c].knots[k].invec);
  1861. splines[c].knots[k].outvec = tm.MultiplyPoint3x4(splines[c].knots[k].outvec);
  1862. splines[c].knots[k].p = tm.MultiplyPoint3x4(splines[c].knots[k].p);
  1863. }
  1864. if ( splines[c].animations != null )
  1865. {
  1866. for ( int a = 0; a < splines[c].animations.Count; a++ )
  1867. {
  1868. if ( splines[c].animations[a].con != null )
  1869. splines[c].animations[a].con.Rotate(tm);
  1870. }
  1871. }
  1872. if ( calc )
  1873. CalcLength(c); //(10);
  1874. }
  1875. public int GetSpline(int p, ref MegaKnotAnim ma) //int spl, ref int sp, ref int pt)
  1876. {
  1877. int index = 0;
  1878. int pn = p / 3;
  1879. for ( int i = 0; i < splines.Count; i++ )
  1880. {
  1881. int nx = index + splines[i].knots.Count;
  1882. if ( pn < nx )
  1883. {
  1884. ma.s = i;
  1885. ma.p = pn - index;
  1886. ma.t = p % 3;
  1887. return i;
  1888. }
  1889. index = nx;
  1890. }
  1891. Debug.Log("Cant find point in spline");
  1892. return 0;
  1893. }
  1894. public float GetCurveLength(int curve)
  1895. {
  1896. if ( curve < splines.Count )
  1897. return splines[curve].length;
  1898. return splines[0].length;
  1899. }
  1900. public float CalcLength(int curve, int step)
  1901. {
  1902. if ( curve < splines.Count )
  1903. return splines[curve].CalcLength(step);
  1904. return 0.0f;
  1905. }
  1906. //public float CalcLength(int curve)
  1907. //{
  1908. // if ( curve < splines.Count )
  1909. // return splines[curve].CalcLength();
  1910. // return 0.0f;
  1911. //}
  1912. [ContextMenu("Recalc Length")]
  1913. public void ReCalcLength()
  1914. {
  1915. CalcLength(); //10);
  1916. }
  1917. //public float CalcLength(int step)
  1918. //{
  1919. // float length = 0.0f;
  1920. // for ( int i = 0; i < splines.Count; i++ )
  1921. // length += CalcLength(i, step);
  1922. // return length;
  1923. //}
  1924. public float CalcLength()
  1925. {
  1926. float length = 0.0f;
  1927. for ( int i = 0; i < splines.Count; i++ )
  1928. length += splines[i].CalcLength();
  1929. return length;
  1930. }
  1931. public float CalcLength(int curve)
  1932. {
  1933. return splines[curve].CalcLength();
  1934. }
  1935. public Vector3 GetKnotPos(int curve, int knot)
  1936. {
  1937. return splines[curve].knots[knot].p;
  1938. }
  1939. public Vector3 GetKnotInVec(int curve, int knot)
  1940. {
  1941. return splines[curve].knots[knot].invec;
  1942. }
  1943. public Vector3 GetKnotOutVec(int curve, int knot)
  1944. {
  1945. return splines[curve].knots[knot].outvec;
  1946. }
  1947. public void SetKnotPos(int curve, int knot, Vector3 p)
  1948. {
  1949. splines[curve].knots[knot].p = p;
  1950. CalcLength(); //10);
  1951. }
  1952. public void SetKnot(int curve, int knot, Vector3 p, Vector3 intan, Vector3 outtan)
  1953. {
  1954. splines[curve].knots[knot].p = p;
  1955. splines[curve].knots[knot].invec = intan;
  1956. splines[curve].knots[knot].outvec = outtan;
  1957. CalcLength(); //10);
  1958. }
  1959. public void SetHandles(int curve, int knot, Vector3 intan, Vector3 outtan)
  1960. {
  1961. splines[curve].knots[knot].invec = splines[curve].knots[knot].p + intan;
  1962. splines[curve].knots[knot].outvec = splines[curve].knots[knot].p + outtan;
  1963. CalcLength(); //10);
  1964. }
  1965. public void MoveKnot(int curve, int knot, Vector3 p)
  1966. {
  1967. Vector3 delta = p - splines[curve].knots[knot].p;
  1968. splines[curve].knots[knot].p = p;
  1969. splines[curve].knots[knot].invec += delta;
  1970. splines[curve].knots[knot].outvec += delta;
  1971. CalcLength();
  1972. }
  1973. public Quaternion GetRotate(int curve, float alpha)
  1974. {
  1975. Vector3 p = InterpCurve3D(curve, alpha, normalizedInterp);
  1976. Vector3 p1 = InterpCurve3D(curve, alpha + 0.001f, normalizedInterp);
  1977. return Quaternion.LookRotation(p - p1);
  1978. }
  1979. public Vector3 InterpCurve3D(int curve, float alpha, bool type)
  1980. {
  1981. Vector3 ret;
  1982. int k = 0;
  1983. if ( curve < splines.Count )
  1984. {
  1985. if ( alpha < 0.0f )
  1986. {
  1987. if ( splines[curve].closed )
  1988. alpha = Mathf.Repeat(alpha, 1.0f);
  1989. else
  1990. {
  1991. Vector3 ps = splines[curve].Interpolate(0.0f, type, ref k);
  1992. // Need a proper tangent function
  1993. Vector3 ps1 = splines[curve].Interpolate(0.01f, type, ref k);
  1994. // Calc the spline in out vecs
  1995. Vector3 delta = ps1 - ps;
  1996. delta.Normalize();
  1997. return ps + ((splines[curve].length * alpha) * delta);
  1998. }
  1999. }
  2000. else
  2001. {
  2002. if ( alpha > 1.0f )
  2003. {
  2004. if ( splines[curve].closed )
  2005. alpha = alpha % 1.0f;
  2006. else
  2007. {
  2008. Vector3 ps = splines[curve].Interpolate(1.0f, type, ref k);
  2009. // Need a proper tangent function
  2010. Vector3 ps1 = splines[curve].Interpolate(0.99f, type, ref k);
  2011. // Calc the spline in out vecs
  2012. Vector3 delta = ps1 - ps;
  2013. delta.Normalize();
  2014. return ps + ((splines[curve].length * (1.0f - alpha)) * delta);
  2015. }
  2016. }
  2017. }
  2018. ret = splines[curve].Interpolate(alpha, type, ref k);
  2019. }
  2020. else
  2021. {
  2022. if ( splines == null || splines.Count == 0 )
  2023. return Vector3.zero;
  2024. ret = splines[0].Interpolate(1.0f, type, ref k);
  2025. }
  2026. return ret;
  2027. }
  2028. public Vector3 InterpCurve3D(int curve, float alpha, bool type, ref float twist)
  2029. {
  2030. Vector3 ret;
  2031. int k = 0;
  2032. if ( curve < splines.Count )
  2033. {
  2034. if ( alpha < 0.0f )
  2035. {
  2036. if ( splines[curve].closed )
  2037. alpha = Mathf.Repeat(alpha, 1.0f);
  2038. else
  2039. {
  2040. Vector3 ps = splines[curve].Interpolate(0.0f, type, ref k, ref twist);
  2041. // Need a proper tangent function
  2042. Vector3 ps1 = splines[curve].Interpolate(0.01f, type, ref k, ref twist);
  2043. // Calc the spline in out vecs
  2044. Vector3 delta = ps1 - ps;
  2045. delta.Normalize();
  2046. return ps + ((splines[curve].length * alpha) * delta);
  2047. }
  2048. }
  2049. else
  2050. {
  2051. if ( alpha > 1.0f )
  2052. {
  2053. if ( splines[curve].closed )
  2054. alpha = alpha % 1.0f;
  2055. else
  2056. {
  2057. Vector3 ps = splines[curve].Interpolate(1.0f, type, ref k, ref twist);
  2058. // Need a proper tangent function
  2059. Vector3 ps1 = splines[curve].Interpolate(0.99f, type, ref k, ref twist);
  2060. // Calc the spline in out vecs
  2061. Vector3 delta = ps1 - ps;
  2062. delta.Normalize();
  2063. return ps + ((splines[curve].length * (1.0f - alpha)) * delta);
  2064. }
  2065. }
  2066. }
  2067. ret = splines[curve].Interpolate(alpha, type, ref k, ref twist);
  2068. }
  2069. else
  2070. {
  2071. if ( splines == null || splines.Count == 0 )
  2072. return Vector3.zero;
  2073. ret = splines[0].Interpolate(1.0f, type, ref k, ref twist);
  2074. }
  2075. return ret;
  2076. }
  2077. public Vector3 InterpCurve3D(int curve, float alpha, float tanalpha, bool type, ref float twist, ref Quaternion rot)
  2078. {
  2079. Vector3 ret;
  2080. int k = 0;
  2081. if ( curve < splines.Count )
  2082. {
  2083. if ( alpha < 0.0f )
  2084. {
  2085. if ( splines[curve].closed )
  2086. alpha = Mathf.Repeat(alpha, 1.0f);
  2087. else
  2088. {
  2089. Vector3 ps = splines[curve].Interpolate(0.0f, type, ref k, ref twist);
  2090. // Need a proper tangent function
  2091. Vector3 ps1 = splines[curve].Interpolate(0.01f, type, ref k, ref twist);
  2092. // Calc the spline in out vecs
  2093. Vector3 delta = ps1 - ps;
  2094. delta.Normalize();
  2095. ret = ps + ((splines[curve].length * alpha) * delta);
  2096. rot = Quaternion.LookRotation(delta) * Quaternion.Euler(0.0f, 0.0f, twist);
  2097. return ret;
  2098. }
  2099. }
  2100. else
  2101. {
  2102. if ( alpha > 1.0f )
  2103. {
  2104. if ( splines[curve].closed )
  2105. alpha = alpha % 1.0f;
  2106. else
  2107. {
  2108. Vector3 ps = splines[curve].Interpolate(1.0f, type, ref k, ref twist);
  2109. // Need a proper tangent function
  2110. Vector3 ps1 = splines[curve].Interpolate(0.99f, type, ref k, ref twist);
  2111. // Calc the spline in out vecs
  2112. Vector3 delta = ps1 - ps;
  2113. delta.Normalize();
  2114. ret = ps + ((splines[curve].length * (1.0f - alpha)) * delta);
  2115. rot = Quaternion.LookRotation(delta) * Quaternion.Euler(0.0f, 0.0f, twist);
  2116. return ret;
  2117. }
  2118. }
  2119. }
  2120. ret = splines[curve].Interpolate(alpha, type, ref k, ref twist);
  2121. Vector3 tpos = splines[curve].Interpolate(tanalpha, type, ref k, ref twist);
  2122. Vector3 dir = tpos - ret;
  2123. rot = Quaternion.LookRotation(dir) * Quaternion.Euler(0.0f, 0.0f, twist);
  2124. }
  2125. else
  2126. {
  2127. rot = Quaternion.identity;
  2128. if ( splines == null || splines.Count == 0 )
  2129. return Vector3.zero;
  2130. ret = splines[0].Interpolate(1.0f, type, ref k, ref twist);
  2131. }
  2132. return ret;
  2133. }
  2134. static float lastout = 0.0f;
  2135. static float lastin = -9999.0f;
  2136. static public float veccalc(float angstep)
  2137. {
  2138. if ( lastin == angstep )
  2139. return lastout;
  2140. float totdist;
  2141. float sinfac = Mathf.Sin(angstep);
  2142. float cosfac = Mathf.Cos(angstep);
  2143. float test;
  2144. int ix;
  2145. MegaSpline work = new MegaSpline();
  2146. Vector3 k1 = new Vector3(Mathf.Cos(0.0f), Mathf.Sin(0.0f), 0.0f);
  2147. Vector3 k2 = new Vector3(cosfac, sinfac, 0.0f);
  2148. float hi = 1.5f;
  2149. float lo = 0.0f;
  2150. int count = 200;
  2151. // Loop thru test vectors
  2152. loop:
  2153. work.knots.Clear();
  2154. test = (hi + lo) / 2.0f;
  2155. Vector3 outv = k1 + new Vector3(0.0f, test, 0.0f);
  2156. Vector3 inv = k2 + new Vector3(sinfac * test, -cosfac * test, 0.0f);
  2157. work.AddKnot(k1, k1, outv);
  2158. work.AddKnot(k2, inv, k2);
  2159. totdist = 0.0f;
  2160. int k = 0;
  2161. //totdist = work.CalcLength(10);
  2162. for ( ix = 0; ix < 10; ++ix )
  2163. {
  2164. Vector3 terp = work.Interpolate((float)ix / 10.0f, false, ref k);
  2165. totdist += Mathf.Sqrt(terp.x * terp.x + terp.y * terp.y);
  2166. }
  2167. totdist /= 10.0f;
  2168. count--;
  2169. if ( totdist == 1.0f || count <= 0 )
  2170. goto done;
  2171. if ( totdist > 1.0f )
  2172. {
  2173. hi = test;
  2174. goto loop;
  2175. }
  2176. lo = test;
  2177. goto loop;
  2178. done:
  2179. lastin = angstep;
  2180. lastout = test;
  2181. return test;
  2182. }
  2183. public Vector3 FindNearestPointWorld(Vector3 p, int iterations, ref int kn, ref Vector3 tangent, ref float alpha)
  2184. {
  2185. Vector3 pos = transform.TransformPoint(FindNearestPoint(transform.worldToLocalMatrix.MultiplyPoint(p), iterations, ref kn, ref tangent, ref alpha));
  2186. tangent = transform.TransformPoint(tangent);
  2187. return pos;
  2188. }
  2189. public Vector3 FindNearestPointWorldShape(Vector3 p, int iterations, ref int kn, ref Vector3 tangent, ref float alpha)
  2190. {
  2191. Vector3 pos = transform.TransformPoint(FindNearestPointShape(transform.worldToLocalMatrix.MultiplyPoint(p), iterations, ref kn, ref tangent, ref alpha));
  2192. tangent = transform.TransformPoint(tangent);
  2193. return pos;
  2194. }
  2195. public Vector3 FindNearestPointWorldXZ(Vector3 p, int iterations, ref int kn, ref Vector3 tangent, ref float alpha)
  2196. {
  2197. Vector3 pos = transform.TransformPoint(FindNearestPointXZ(transform.worldToLocalMatrix.MultiplyPoint(p), iterations, ref kn, ref tangent, ref alpha));
  2198. tangent = transform.TransformPoint(tangent);
  2199. return pos;
  2200. }
  2201. // Find nearest point
  2202. public Vector3 FindNearestPoint(Vector3 p, int iterations, ref int kn, ref Vector3 tangent, ref float alpha)
  2203. {
  2204. //Vector3 np = Vector3.zero;
  2205. float positiveInfinity = float.PositiveInfinity;
  2206. float num2 = 0.0f;
  2207. iterations = Mathf.Clamp(iterations, 0, 5);
  2208. int kt = 0;
  2209. int crv = selcurve;
  2210. if ( crv >= splines.Count )
  2211. crv = splines.Count - 1;
  2212. for ( float i = 0.0f; i <= 1.0f; i += 0.01f )
  2213. {
  2214. //Vector3 vector = this.GetPositionOnSpline(i) - p;
  2215. //Vector3 vector = InterpCurve3D(0, i, true) - p; //this.GetPositionOnSpline(i) - p;
  2216. Vector3 vector = splines[crv].Interpolate(i, true, ref kt) - p; //this.GetPositionOnSpline(i) - p;
  2217. float sqrMagnitude = vector.sqrMagnitude;
  2218. if ( positiveInfinity > sqrMagnitude )
  2219. {
  2220. positiveInfinity = sqrMagnitude;
  2221. num2 = i;
  2222. }
  2223. }
  2224. for ( int j = 0; j < iterations; j++ )
  2225. {
  2226. float num6 = 0.01f * Mathf.Pow(10.0f, -((float)j));
  2227. float num7 = num6 * 0.1f;
  2228. for ( float k = Mathf.Clamp01(num2 - num6); k <= Mathf.Clamp01(num2 + num6); k += num7 )
  2229. {
  2230. //Vector3 vector2 = InterpCurve3D(0, k, true) - p; //this.GetPositionOnSpline(k) - p;
  2231. Vector3 vector2 = splines[crv].Interpolate(k, true, ref kt) - p; //this.GetPositionOnSpline(k) - p;
  2232. float num9 = vector2.sqrMagnitude;
  2233. if ( positiveInfinity > num9 )
  2234. {
  2235. positiveInfinity = num9;
  2236. num2 = k;
  2237. }
  2238. }
  2239. }
  2240. kn = kt;
  2241. tangent = InterpCurve3D(crv, num2 + 0.01f, true);
  2242. alpha = num2;
  2243. return InterpCurve3D(crv, num2, true); //num2;
  2244. //return np;
  2245. }
  2246. public Vector3 FindNearestPointShape(Vector3 p, int iterations, ref int kn, ref Vector3 tangent, ref float alpha)
  2247. {
  2248. Vector3 tan = Vector3.zero;
  2249. float a = 0.0f;
  2250. int k = 0;
  2251. float dist = float.MaxValue;
  2252. Vector3 cp = Vector3.zero;
  2253. for ( int i = 0; i < splines.Count; i++ )
  2254. {
  2255. Vector3 np = splines[i].FindNearestPoint(p, iterations, ref k, ref tan, ref a);
  2256. float d = Vector3.Distance(np, p);
  2257. if ( d < dist )
  2258. {
  2259. dist = d;
  2260. kn = k;
  2261. tangent = tan;
  2262. alpha = a;
  2263. cp = np;
  2264. }
  2265. }
  2266. return cp;
  2267. }
  2268. public Vector3 FindNearestPointXZ(Vector3 p, int iterations, ref int kn, ref Vector3 tangent, ref float alpha)
  2269. {
  2270. //Vector3 np = Vector3.zero;
  2271. float positiveInfinity = float.PositiveInfinity;
  2272. float num2 = 0.0f;
  2273. iterations = Mathf.Clamp(iterations, 0, 5);
  2274. int kt = 0;
  2275. int crv = selcurve;
  2276. if ( crv >= splines.Count )
  2277. crv = splines.Count - 1;
  2278. for ( float i = 0.0f; i <= 1.0f; i += 0.01f )
  2279. {
  2280. //Vector3 vector = this.GetPositionOnSpline(i) - p;
  2281. //Vector3 vector = InterpCurve3D(0, i, true) - p; //this.GetPositionOnSpline(i) - p;
  2282. Vector3 vector = splines[crv].Interpolate(i, true, ref kt) - p; //this.GetPositionOnSpline(i) - p;
  2283. vector.y = 0.0f;
  2284. float sqrMagnitude = vector.sqrMagnitude;
  2285. if ( positiveInfinity > sqrMagnitude )
  2286. {
  2287. positiveInfinity = sqrMagnitude;
  2288. num2 = i;
  2289. }
  2290. }
  2291. for ( int j = 0; j < iterations; j++ )
  2292. {
  2293. float num6 = 0.01f * Mathf.Pow(10.0f, -((float)j));
  2294. float num7 = num6 * 0.1f;
  2295. for ( float k = Mathf.Clamp01(num2 - num6); k <= Mathf.Clamp01(num2 + num6); k += num7 )
  2296. {
  2297. //Vector3 vector2 = InterpCurve3D(0, k, true) - p; //this.GetPositionOnSpline(k) - p;
  2298. Vector3 vector2 = splines[crv].Interpolate(k, true, ref kt) - p; //this.GetPositionOnSpline(k) - p;
  2299. vector2.y = 0.0f;
  2300. float num9 = vector2.sqrMagnitude;
  2301. if ( positiveInfinity > num9 )
  2302. {
  2303. positiveInfinity = num9;
  2304. num2 = k;
  2305. }
  2306. }
  2307. }
  2308. kn = kt;
  2309. tangent = InterpCurve3D(crv, num2 + 0.01f, true);
  2310. alpha = num2;
  2311. Vector3 rval = InterpCurve3D(crv, num2, true);
  2312. rval.y = 0.0f;
  2313. return rval;
  2314. //return np;
  2315. }
  2316. public Vector3 FindNearestPoint(int crv, Vector3 p, int iterations, ref int kn, ref Vector3 tangent, ref float alpha)
  2317. {
  2318. //Vector3 np = Vector3.zero;
  2319. float positiveInfinity = float.PositiveInfinity;
  2320. float num2 = 0.0f;
  2321. iterations = Mathf.Clamp(iterations, 0, 5);
  2322. int kt = 0;
  2323. if ( crv >= splines.Count )
  2324. crv = splines.Count - 1;
  2325. for ( float i = 0.0f; i <= 1.0f; i += 0.01f )
  2326. {
  2327. //Vector3 vector = this.GetPositionOnSpline(i) - p;
  2328. //Vector3 vector = InterpCurve3D(0, i, true) - p; //this.GetPositionOnSpline(i) - p;
  2329. Vector3 vector = splines[crv].Interpolate(i, true, ref kt) - p; //this.GetPositionOnSpline(i) - p;
  2330. float sqrMagnitude = vector.sqrMagnitude;
  2331. if ( positiveInfinity > sqrMagnitude )
  2332. {
  2333. positiveInfinity = sqrMagnitude;
  2334. num2 = i;
  2335. }
  2336. }
  2337. for ( int j = 0; j < iterations; j++ )
  2338. {
  2339. float num6 = 0.01f * Mathf.Pow(10.0f, -((float)j));
  2340. float num7 = num6 * 0.1f;
  2341. for ( float k = Mathf.Clamp01(num2 - num6); k <= Mathf.Clamp01(num2 + num6); k += num7 )
  2342. {
  2343. //Vector3 vector2 = InterpCurve3D(0, k, true) - p; //this.GetPositionOnSpline(k) - p;
  2344. Vector3 vector2 = splines[crv].Interpolate(k, true, ref kt) - p; //this.GetPositionOnSpline(k) - p;
  2345. float num9 = vector2.sqrMagnitude;
  2346. if ( positiveInfinity > num9 )
  2347. {
  2348. positiveInfinity = num9;
  2349. num2 = k;
  2350. }
  2351. }
  2352. }
  2353. kn = kt;
  2354. tangent = InterpCurve3D(crv, num2 + 0.01f, true);
  2355. alpha = num2;
  2356. return InterpCurve3D(crv, num2, true); //num2;
  2357. //return np;
  2358. }
  2359. public void BuildSplineWorld(int curve, Vector3[] points, bool closed)
  2360. {
  2361. if ( curve >= 0 && curve < splines.Count )
  2362. {
  2363. MegaSpline spline = splines[curve];
  2364. spline.knots = new List<MegaKnot>(points.Length);
  2365. for ( int i = 0; i < points.Length; i++ )
  2366. {
  2367. MegaKnot knot = new MegaKnot();
  2368. knot.p = transform.worldToLocalMatrix.MultiplyPoint(points[i]);
  2369. spline.knots.Add(knot);
  2370. }
  2371. spline.closed = closed;
  2372. AutoCurve(spline);
  2373. }
  2374. }
  2375. public void BuildSpline(int curve, Vector3[] points, bool closed)
  2376. {
  2377. if ( curve >= 0 && curve < splines.Count )
  2378. {
  2379. MegaSpline spline = splines[curve];
  2380. spline.knots = new List<MegaKnot>(points.Length);
  2381. for ( int i = 0; i < points.Length; i++ )
  2382. {
  2383. MegaKnot knot = new MegaKnot();
  2384. knot.p = points[i];
  2385. spline.knots.Add(knot);
  2386. }
  2387. spline.closed = closed;
  2388. AutoCurve(spline);
  2389. }
  2390. }
  2391. public void BuildSpline(Vector3[] points, bool closed)
  2392. {
  2393. MegaSpline spline = new MegaSpline();
  2394. spline.knots = new List<MegaKnot>(points.Length);
  2395. for ( int i = 0; i < points.Length; i++ )
  2396. {
  2397. MegaKnot knot = new MegaKnot();
  2398. knot.p = points[i];
  2399. spline.knots.Add(knot);
  2400. }
  2401. spline.closed = closed;
  2402. splines.Add(spline);
  2403. AutoCurve(spline);
  2404. }
  2405. public void AddToSpline(int curve, Vector3[] points)
  2406. {
  2407. if ( curve >= 0 && curve < splines.Count )
  2408. {
  2409. MegaSpline spline = splines[curve];
  2410. int fk = spline.knots.Count;
  2411. for ( int i = 0; i < points.Length; i++ )
  2412. {
  2413. MegaKnot knot = new MegaKnot();
  2414. knot.p = points[i];
  2415. spline.knots.Add(knot);
  2416. }
  2417. AutoCurve(spline, fk, fk + points.Length);
  2418. }
  2419. }
  2420. public void AddToSpline(int curve, Vector3 point)
  2421. {
  2422. if ( curve >= 0 && curve < splines.Count )
  2423. {
  2424. MegaSpline spline = splines[curve];
  2425. MegaKnot knot = new MegaKnot();
  2426. knot.p = point;
  2427. spline.knots.Add(knot);
  2428. AutoCurve(spline, spline.knots.Count - 2, spline.knots.Count - 1);
  2429. }
  2430. }
  2431. public void AutoCurve(int s)
  2432. {
  2433. AutoCurve(splines[s]);
  2434. }
  2435. // Calc tangents for knots
  2436. public void AutoCurve(MegaSpline spline)
  2437. {
  2438. if ( smoothMode == MegaShapeBezComputeMode.Old )
  2439. ComputeControlPointsOld(spline);
  2440. else
  2441. ComputeControlPointsNew(spline);
  2442. }
  2443. public void ComputeControlPointsOld(MegaSpline spline)
  2444. {
  2445. if ( spline.closed )
  2446. {
  2447. Vector3 premid = (spline.knots[spline.knots.Count - 1].p + spline.knots[0].p) * 0.5f;
  2448. for ( int k = 0; k < spline.knots.Count; k++ )
  2449. {
  2450. int nk = (k + 1) % spline.knots.Count;
  2451. Vector3 mid = (spline.knots[nk].p + spline.knots[k].p) * 0.5f;
  2452. Vector3 mp = (mid + premid) * 0.5f;
  2453. spline.knots[k].invec = spline.knots[k].p + ((premid - mp) * smoothness);
  2454. spline.knots[k].outvec = spline.knots[k].p + ((mid - mp) * smoothness);
  2455. //SmoothHandles(spline, k, 0.5f);
  2456. premid = mid;
  2457. }
  2458. for ( int k = 0; k < spline.knots.Count; k++ )
  2459. {
  2460. //SmoothHandles(spline, k, 0.25f);
  2461. }
  2462. }
  2463. else
  2464. {
  2465. int kc = spline.knots.Count - 1;
  2466. Vector3 premid = spline.knots[0].p - ((spline.knots[1].p - spline.knots[0].p) * 0.5f);
  2467. Vector3 endmid = spline.knots[kc - 1].p + ((spline.knots[kc].p - spline.knots[kc - 1].p) * 0.5f);
  2468. //Vector3 delta = (spline.knots[1].p - spline.knots[0].p); * 0.5f;
  2469. for ( int k = 0; k < spline.knots.Count - 1; k++ )
  2470. {
  2471. Vector3 mid = (spline.knots[k + 1].p + spline.knots[k].p) * 0.5f;
  2472. Vector3 mp = (mid + premid) * 0.5f;
  2473. spline.knots[k].invec = spline.knots[k].p + ((premid - mp) * smoothness);
  2474. spline.knots[k].outvec = spline.knots[k].p + ((mid - mp) * smoothness);
  2475. //SmoothHandles(spline, k, 0.5f);
  2476. premid = mid;
  2477. }
  2478. //Vector3 mid = (spline.knots[k + 1].p + spline.knots[k].p) * 0.5f;
  2479. //Vector3 mp1 = (premid + endmid) * 0.5f;
  2480. spline.knots[kc].invec = spline.knots[kc].p - ((spline.knots[kc].p - endmid) * smoothness);
  2481. spline.knots[kc].outvec = spline.knots[kc].p + ((spline.knots[kc].p - endmid) * smoothness); //invec; //((mid - mp) * smoothness);
  2482. for ( int k = 1; k < spline.knots.Count; k++ )
  2483. {
  2484. //SmoothHandles(spline, k, 0.25f);
  2485. }
  2486. }
  2487. spline.CalcLength(); //10);
  2488. }
  2489. public void ComputeControlPointsNew(MegaSpline spline)
  2490. {
  2491. if ( spline.closed )
  2492. {
  2493. ComputeControlPointsNewClosed(spline);
  2494. return;
  2495. }
  2496. int n = spline.knots.Count - 1; //K.length - 1;
  2497. Vector3[] p1 = new Vector3[n + 1]; // Tans
  2498. Vector3[] p2 = new Vector3[n + 1];
  2499. // rhs vector
  2500. float[] a = new float[n + 1];
  2501. float[] b = new float[n + 1];
  2502. float[] c = new float[n + 1];
  2503. Vector3[] r = new Vector3[n + 1];
  2504. // left most segment
  2505. a[0] = 0.0f;
  2506. b[0] = 2.0f;
  2507. c[0] = 1.0f;
  2508. r[0] = spline.knots[0].p + 2.0f * spline.knots[1].p;
  2509. // internal segments
  2510. for ( int i = 1; i < n - 1; i++ )
  2511. {
  2512. a[i] = 1.0f;
  2513. b[i] = 4.0f;
  2514. c[i] = 1.0f;
  2515. r[i] = 4.0f * spline.knots[i].p + 2.0f * spline.knots[i + 1].p;
  2516. }
  2517. // right segment
  2518. a[n - 1] = 2.0f;
  2519. b[n - 1] = 7.0f;
  2520. c[n - 1] = 0.0f;
  2521. r[n - 1] = 8.0f * spline.knots[n - 1].p + spline.knots[n].p;
  2522. // solves Ax = b with the Thomas algorithm (from Wikipedia)
  2523. for ( int i = 1; i < n; i++ )
  2524. {
  2525. float m = a[i] / b[i - 1];
  2526. b[i] = b[i] - m * c[i - 1];
  2527. r[i] = r[i] - m * r[i - 1];
  2528. }
  2529. p1[n - 1] = r[n - 1] / b[n - 1];
  2530. for ( int i = n - 2; i >= 0; --i )
  2531. p1[i] = (r[i] - c[i] * p1[i + 1]) / b[i];
  2532. // we have p1, now compute p2
  2533. for ( int i = 0; i < n - 1; i++ )
  2534. p2[i] = 2.0f * spline.knots[i + 1].p - p1[i + 1];
  2535. p2[n - 1] = 0.5f * (spline.knots[n].p + p1[n - 1]);
  2536. // handles are p1 and p2
  2537. for ( int i = 0; i < n; i++ )
  2538. {
  2539. spline.knots[i].outvec = p1[i];
  2540. spline.knots[i + 1].invec = p2[i];
  2541. }
  2542. spline.CalcLength();
  2543. }
  2544. public void ComputeControlPointsNewClosed(MegaSpline spline)
  2545. {
  2546. int kn = spline.knots.Count;
  2547. Vector3[] k = new Vector3[kn + 3];
  2548. k[0] = spline.knots[kn - 1].p;
  2549. for ( int i = 0; i < kn; i++ )
  2550. k[i + 1] = spline.knots[i].p;
  2551. k[kn + 1] = spline.knots[0].p;
  2552. k[kn + 2] = spline.knots[1].p;
  2553. //k[kn + 3] = spline.knots[2].p;
  2554. int n = k.Length - 1; // - 1; //K.length - 1;
  2555. Vector3[] p1 = new Vector3[n + 1]; // Tans
  2556. Vector3[] p2 = new Vector3[n + 1];
  2557. // rhs vector
  2558. float[] a = new float[n + 1];
  2559. float[] b = new float[n + 1];
  2560. float[] c = new float[n + 1];
  2561. Vector3[] r = new Vector3[n + 1];
  2562. // left most segment
  2563. a[0] = 0.0f;
  2564. b[0] = 2.0f;
  2565. c[0] = 1.0f;
  2566. r[0] = k[0] + 2.0f * k[1];
  2567. // internal segments
  2568. for ( int i = 1; i < n - 1; i++ )
  2569. {
  2570. a[i] = 1.0f;
  2571. b[i] = 4.0f;
  2572. c[i] = 1.0f;
  2573. r[i] = 4.0f * k[i] + 2.0f * k[i + 1];
  2574. }
  2575. // right segment
  2576. a[n - 1] = 2.0f;
  2577. b[n - 1] = 7.0f;
  2578. c[n - 1] = 0.0f;
  2579. r[n - 1] = 8.0f * k[n - 1] + k[n];
  2580. // solves Ax = b with the Thomas algorithm (from Wikipedia)
  2581. for ( int i = 1; i < n; i++ )
  2582. {
  2583. float m = a[i] / b[i - 1];
  2584. b[i] = b[i] - m * c[i - 1];
  2585. r[i] = r[i] - m * r[i - 1];
  2586. }
  2587. p1[n - 1] = r[n - 1] / b[n - 1];
  2588. for ( int i = n - 2; i >= 0; --i )
  2589. {
  2590. p1[i] = (r[i] - c[i] * p1[i + 1]) / b[i];
  2591. }
  2592. // we have p1, now compute p2
  2593. for ( int i = 0; i < n - 1; i++ )
  2594. {
  2595. p2[i] = 2.0f * k[i + 1] - p1[i + 1];
  2596. }
  2597. p2[n - 1] = 0.5f * (k[n] + p1[n - 1]);
  2598. // handles are p1 and p2
  2599. for ( int i = 0; i < k.Length; i++ )
  2600. {
  2601. //Debug.Log("Knot " + k[i]);
  2602. }
  2603. for ( int i = 0; i < p1.Length; i++ )
  2604. {
  2605. //Debug.Log("p1 " + p1[i] + " p2 " + p2[i]);
  2606. }
  2607. spline.knots[0].invec = p2[0];
  2608. for ( int i = 0; i < kn - 1; i++ )
  2609. {
  2610. spline.knots[i].outvec = p1[i + 1];
  2611. spline.knots[i + 1].invec = p2[i + 1];
  2612. }
  2613. spline.knots[kn - 1].outvec = p1[kn];
  2614. spline.CalcLength();
  2615. }
  2616. public void AutoCurve(MegaSpline spline, int start, int end)
  2617. {
  2618. if ( spline.closed )
  2619. {
  2620. int pk = (start - 1) % spline.knots.Count;
  2621. Vector3 premid = (spline.knots[pk].p + spline.knots[start].p) * 0.5f;
  2622. for ( int k = start; k < end; k++ )
  2623. {
  2624. int nk = (k + 1) % spline.knots.Count;
  2625. Vector3 mid = (spline.knots[nk].p + spline.knots[k].p) * 0.5f;
  2626. Vector3 mp = (mid + premid) * 0.5f;
  2627. spline.knots[k].invec = spline.knots[k].p + ((premid - mp) * smoothness);
  2628. spline.knots[k].outvec = spline.knots[k].p + ((mid - mp) * smoothness);
  2629. premid = mid;
  2630. }
  2631. for ( int k = start; k < end; k++ )
  2632. {
  2633. //SmoothHandles(spline, k, 0.25f);
  2634. }
  2635. }
  2636. else
  2637. {
  2638. int pk = (start - 1) % spline.knots.Count;
  2639. Vector3 premid = (spline.knots[pk].p + spline.knots[start].p) * 0.5f;
  2640. for ( int k = start; k < end - 1; k++ )
  2641. {
  2642. Vector3 mid = (spline.knots[k + 1].p + spline.knots[k].p) * 0.5f;
  2643. Vector3 mp = (mid + premid) * 0.5f;
  2644. spline.knots[k].invec = spline.knots[k].p + ((premid - mp) * smoothness);
  2645. spline.knots[k].outvec = spline.knots[k].p + ((mid - mp) * smoothness);
  2646. premid = mid;
  2647. }
  2648. for ( int k = start; k < end; k++ )
  2649. {
  2650. //SmoothHandles(spline, k, 0.25f);
  2651. }
  2652. }
  2653. spline.CalcLength(); //10);
  2654. }
  2655. public void AutoCurve()
  2656. {
  2657. for ( int s = 0; s < splines.Count; s++ )
  2658. {
  2659. MegaSpline spline = splines[s];
  2660. AutoCurve(spline);
  2661. #if false
  2662. if ( spline.closed )
  2663. {
  2664. Vector3 premid = (spline.knots[spline.knots.Count - 1].p + spline.knots[0].p) * 0.5f;
  2665. for ( int k = 0; k < spline.knots.Count; k++ )
  2666. {
  2667. int nk = (k + 1) % spline.knots.Count;
  2668. Vector3 mid = (spline.knots[nk].p + spline.knots[k].p) * 0.5f;
  2669. Vector3 mp = (mid + premid) * 0.5f;
  2670. Vector3 delta = spline.knots[k].p - mp;
  2671. spline.knots[k].invec = spline.knots[k].p + (premid - mp); //premid + delta;
  2672. spline.knots[k].outvec = spline.knots[k].p + (mid - mp); //mid + delta;
  2673. premid = mid;
  2674. }
  2675. }
  2676. else
  2677. {
  2678. Vector3 premid = (spline.knots[1].p + spline.knots[0].p) * 0.5f;
  2679. for ( int k = 1; k < spline.knots.Count - 1; k++ )
  2680. {
  2681. Vector3 mid = (spline.knots[k + 1].p + spline.knots[k].p) * 0.5f;
  2682. Vector3 mp = (mid + premid) * 0.5f;
  2683. Vector3 delta = spline.knots[k].p - mp;
  2684. spline.knots[k].invec = spline.knots[k].p + (premid - mp); //premid + delta;
  2685. spline.knots[k].outvec = spline.knots[k].p + (mid - mp); //mid + delta;
  2686. premid = mid;
  2687. }
  2688. }
  2689. #endif
  2690. }
  2691. //CalcLength(10);
  2692. }
  2693. Vector3 SetVectorLength(Vector3 dir, float mag)
  2694. {
  2695. return dir * mag;
  2696. }
  2697. public void SmoothHandles(MegaSpline spline, int i, float lengthFactor) //start, end)
  2698. {
  2699. if ( i < spline.knots.Count - 1 )
  2700. {
  2701. int i1 = i + 1;
  2702. if ( i1 >= spline.knots.Count )
  2703. {
  2704. if ( spline.closed )
  2705. i1 = 0;
  2706. else
  2707. return;
  2708. }
  2709. //for( int i = 0; i < spline.knots.Count - 1; i++ )
  2710. {
  2711. //get the handle length
  2712. Vector3 currentOutDir = spline.knots[i].outvec - spline.knots[i].p;
  2713. Vector3 nextInDir = spline.knots[i1].invec - spline.knots[i1].p;
  2714. //get the distance between the knots
  2715. float knotDistance = Vector3.Magnitude(spline.knots[i1].p - spline.knots[i].p);
  2716. //are the handles overlapping?
  2717. if ( (currentOutDir.magnitude + nextInDir.magnitude) > knotDistance )
  2718. {
  2719. if ( currentOutDir.magnitude > nextInDir.magnitude )
  2720. {
  2721. //make the outvec handle smaller
  2722. Vector3 dir = spline.knots[i1].invec - spline.knots[i].p;
  2723. dir = SetVectorLength(dir, nextInDir.magnitude * lengthFactor);
  2724. spline.knots[i].outvec = spline.knots[i].p + dir;
  2725. //set the invec handle
  2726. dir = SetVectorLength(dir, currentOutDir.magnitude);
  2727. spline.knots[i].invec = spline.knots[i].p - dir;
  2728. //set the next invec handle
  2729. dir = spline.knots[i1].invec - spline.knots[i1].p;
  2730. dir = SetVectorLength(dir, dir.magnitude * lengthFactor);
  2731. spline.knots[i1].invec = spline.knots[i1].p + dir;
  2732. }
  2733. if ( currentOutDir.magnitude < nextInDir.magnitude )
  2734. {
  2735. //make the invec handle smaller
  2736. Vector3 dir = spline.knots[i].outvec - spline.knots[i1].p;
  2737. dir = SetVectorLength(dir, currentOutDir.magnitude * lengthFactor);
  2738. spline.knots[i1].invec = spline.knots[i1].p + dir;
  2739. //set the outvec handle
  2740. dir = SetVectorLength(dir, nextInDir.magnitude);
  2741. spline.knots[i1].outvec = spline.knots[i].p - dir;
  2742. //set the previous outvec handle
  2743. dir = spline.knots[i].outvec - spline.knots[i].p;
  2744. dir = SetVectorLength(dir, dir.magnitude * lengthFactor);
  2745. spline.knots[i].outvec = spline.knots[i].p + dir;
  2746. }
  2747. }
  2748. }
  2749. }
  2750. }
  2751. List<Vector3> verts = new List<Vector3>();
  2752. List<Vector2> uvs = new List<Vector2>();
  2753. List<int> tris = new List<int>();
  2754. List<int> tris1 = new List<int>();
  2755. List<int> tris2 = new List<int>();
  2756. #if true // tube mesh
  2757. //Vector3[] verts;
  2758. //Vector2[] uvs;
  2759. //int[] tris;
  2760. Vector3[] cross;
  2761. public int tsides = 8;
  2762. void BuildCrossSection(float rad)
  2763. {
  2764. if ( cross == null || cross.Length != tsides )
  2765. cross = new Vector3[tsides];
  2766. float sang = rotate * Mathf.Deg2Rad;
  2767. for ( int i = 0; i < tsides; i++ )
  2768. {
  2769. float ang = sang + (((float)i / (float)tsides) * Mathf.PI * 2.0f);
  2770. cross[i] = new Vector3(Mathf.Sin(ang) * rad, 0.0f, Mathf.Cos(ang) * rad);
  2771. }
  2772. }
  2773. public void BuildTubeMesh()
  2774. {
  2775. // Start, length
  2776. BuildMultiStrandMesh();
  2777. }
  2778. public enum CrossSectionType
  2779. {
  2780. Circle,
  2781. Box,
  2782. }
  2783. public CrossSectionType crossType = CrossSectionType.Circle;
  2784. public float Twist = 0.0f;
  2785. public int strands = 1;
  2786. public float tradius = 0.1f;
  2787. public float offset = 0.0f;
  2788. public float uvtilex = 1.0f;
  2789. public float uvtiley = 1.0f;
  2790. public float uvtwist = 0.0f;
  2791. public float TubeLength = 1.0f;
  2792. public float TubeStart = 0.0f;
  2793. public float SegsPerUnit = 20.0f;
  2794. public float TwistPerUnit = 0.0f;
  2795. public float strandRadius = 0.0f;
  2796. public float startAng = 0.0f;
  2797. public float rotate = 0.0f;
  2798. int segments = 0;
  2799. public bool cap = false;
  2800. Vector3[] tverts;
  2801. Vector2[] tuvs;
  2802. int[] ttris;
  2803. Matrix4x4 tm;
  2804. Matrix4x4 mat;
  2805. Matrix4x4 wtm;
  2806. public MegaAxis RopeUp = MegaAxis.Y;
  2807. Vector3 ropeup = Vector3.up;
  2808. public AnimationCurve scaleX = new AnimationCurve(new Keyframe(0, 1), new Keyframe(1, 1));
  2809. public AnimationCurve scaleY = new AnimationCurve(new Keyframe(0, 1), new Keyframe(1, 1));
  2810. public bool unlinkScale = false;
  2811. // Add in twist etc in here to get proper matrix
  2812. Matrix4x4 GetDeformMat(float percent)
  2813. {
  2814. float alpha = percent;
  2815. float twist = 0.0f;
  2816. Vector3 ps = InterpCurve3D(selcurve, alpha, normalizedInterp, ref twist);
  2817. Vector3 ps1 = InterpCurve3D(selcurve, alpha + 0.001f, normalizedInterp, ref twist);
  2818. Vector3 relativePos = ps1 - ps; // This is Vel?
  2819. //Vector3 scl = ps * 0.99f;
  2820. Quaternion rotation = Quaternion.identity;
  2821. if ( relativePos != Vector3.zero )
  2822. rotation = Quaternion.LookRotation(relativePos, ropeup); //vertices[p + 1].point - vertices[p].point);
  2823. //Quaternion rotation = Quaternion.LookRotation(relativePos, ropeup); //vertices[p + 1].point - vertices[p].point);
  2824. Quaternion twistrot = Quaternion.Euler(0.0f, 0.0f, twist);
  2825. //wtm.SetTRS(ps, rotation, Vector3.one);
  2826. MegaMatrix.SetTR(ref wtm, ps, rotation * twistrot);
  2827. wtm = mat * wtm; // * roll;
  2828. return wtm;
  2829. }
  2830. public float boxwidth = 0.2f;
  2831. public float boxheight = 0.2f;
  2832. float[] boxuv = new float[8];
  2833. public void BuildBoxCrossSection(float width, float height)
  2834. {
  2835. if ( cross == null || cross.Length != 8 )
  2836. cross = new Vector3[8];
  2837. float sang = rotate * Mathf.Deg2Rad;
  2838. Matrix4x4 mat = Matrix4x4.identity;
  2839. MegaMatrix.RotateY(ref mat, sang); //rotate);
  2840. cross[0] = new Vector3(width * 0.5f, 0.0f, height * 0.5f);
  2841. cross[1] = new Vector3(width * 0.5f, 0.0f, -height * 0.5f);
  2842. cross[2] = new Vector3(width * 0.5f, 0.0f, -height * 0.5f);
  2843. cross[3] = new Vector3(-width * 0.5f, 0.0f, -height * 0.5f);
  2844. cross[4] = new Vector3(-width * 0.5f, 0.0f, -height * 0.5f);
  2845. cross[5] = new Vector3(-width * 0.5f, 0.0f, height * 0.5f);
  2846. cross[6] = new Vector3(-width * 0.5f, 0.0f, height * 0.5f);
  2847. cross[7] = new Vector3(width * 0.5f, 0.0f, height * 0.5f);
  2848. for ( int i = 0; i < 8; i++ )
  2849. {
  2850. cross[i] = mat.MultiplyPoint(cross[i]);
  2851. }
  2852. float uvlen = (2.0f * boxwidth) + (2.0f * boxheight);
  2853. float ux = 0.0f;
  2854. boxuv[0] = 0.0f;
  2855. ux += boxheight;
  2856. boxuv[1] = ux / uvlen;
  2857. boxuv[2] = boxuv[1];
  2858. ux += boxwidth;
  2859. boxuv[3] = ux / uvlen;
  2860. boxuv[4] = boxuv[3];
  2861. ux += boxheight;
  2862. boxuv[5] = ux / uvlen;
  2863. boxuv[6] = boxuv[5];
  2864. ux += boxwidth;
  2865. boxuv[7] = ux / uvlen;
  2866. }
  2867. public MegaAxis raxis = MegaAxis.X;
  2868. public int ribsegs = 1;
  2869. public void BuildRibbonCrossSection(float width)
  2870. {
  2871. if ( cross == null || cross.Length != ribsegs + 1 )
  2872. cross = new Vector3[ribsegs + 1];
  2873. float sang = rotate * Mathf.Deg2Rad;
  2874. for ( int i = 0; i <= ribsegs; i++ )
  2875. {
  2876. float x = (((float)i / (float)ribsegs) * width) - (width * 0.5f);
  2877. switch ( raxis )
  2878. {
  2879. case MegaAxis.X: cross[i] = new Vector3(x, 0.0f, 0.0f); break;
  2880. case MegaAxis.Y: cross[i] = new Vector3(0.0f, x, 0.0f); break;
  2881. case MegaAxis.Z: cross[i] = new Vector3(0.0f, 0.0f, x); break;
  2882. }
  2883. }
  2884. Matrix4x4 mat = Matrix4x4.identity;
  2885. MegaMatrix.RotateY(ref mat, sang); //rotate);
  2886. for ( int i = 0; i < cross.Length; i++ )
  2887. {
  2888. cross[i] = mat.MultiplyPoint(cross[i]);
  2889. }
  2890. }
  2891. // Width, segs
  2892. void BuildRibbonMesh()
  2893. {
  2894. //float lengthuvtile = uvtiley * TubeLength;
  2895. TubeLength = Mathf.Clamp01(TubeLength);
  2896. if ( TubeLength == 0.0f || strands < 1 )
  2897. {
  2898. shapemesh.Clear();
  2899. return;
  2900. }
  2901. //float sradius = (tradius * 0.5f) + strandRadius;
  2902. BuildRibbonCrossSection(boxwidth);
  2903. segments = (int)((splines[0].length * TubeLength) / (stepdist * 0.1f));
  2904. Twist = TwistPerUnit; // * TubeLength;
  2905. float sang = startAng * Mathf.Deg2Rad;
  2906. int vcount = ((segments + 1) * (ribsegs + 1)) * strands;
  2907. int tcount = (ribsegs * 2 * segments) * strands;
  2908. //Debug.Log("segs " + segments);
  2909. //Debug.Log("verts " + vcount);
  2910. //Debug.Log("tris " + tcount);
  2911. float off = (tradius * 0.5f) + offset;
  2912. //float off = offset;
  2913. if ( strands == 1 )
  2914. {
  2915. off = offset;
  2916. }
  2917. if ( tverts == null || tverts.Length != vcount )
  2918. tverts = new Vector3[vcount];
  2919. //bool builduvs = false;
  2920. if ( GenUV && (tuvs == null || tuvs.Length != vcount) )
  2921. {
  2922. tuvs = new Vector2[vcount];
  2923. //builduvs = true;
  2924. }
  2925. if ( ttris == null || ttris.Length != tcount * 3 )
  2926. {
  2927. ttris = new int[tcount * 3];
  2928. }
  2929. mat = Matrix4x4.identity;
  2930. tm = Matrix4x4.identity;
  2931. switch ( axis )
  2932. {
  2933. case MegaAxis.X: MegaMatrix.RotateY(ref tm, -Mathf.PI * 0.5f); break;
  2934. case MegaAxis.Y: MegaMatrix.RotateX(ref tm, -Mathf.PI * 0.5f); break;
  2935. case MegaAxis.Z: break;
  2936. }
  2937. MegaMatrix.SetTrans(ref tm, Pivot);
  2938. switch ( RopeUp )
  2939. {
  2940. case MegaAxis.X: ropeup = Vector3.right; break;
  2941. case MegaAxis.Y: ropeup = Vector3.up; break;
  2942. case MegaAxis.Z: ropeup = Vector3.forward; break;
  2943. }
  2944. // We only need to refresh the verts, tris and uvs are done once
  2945. int vi = 0;
  2946. int ti = 0;
  2947. Vector2 uv = Vector2.zero;
  2948. Vector3 soff = Vector3.zero;
  2949. Vector3 scl = Vector3.one;
  2950. for ( int s = 0; s < strands; s++ )
  2951. {
  2952. //rollingquat = Quaternion.identity;
  2953. float ang = ((float)s / (float)strands) * Mathf.PI * 2.0f;
  2954. soff.x = Mathf.Sin(ang) * off;
  2955. soff.z = Mathf.Cos(ang) * off;
  2956. //Matrix.SetTrans(ref tm, soff);
  2957. int vo = vi;
  2958. vo = vi;
  2959. for ( int i = 0; i <= segments; i++ )
  2960. {
  2961. float alpha = TubeStart + (((float)i / (float)segments) * TubeLength);
  2962. wtm = GetDeformMat(alpha);
  2963. float uvt = alpha * uvtwist;
  2964. float tst = sang + ((alpha - TubeStart) * Twist * Mathf.PI * 2.0f); // + rollang;
  2965. soff.x = Mathf.Sin(ang + tst) * off;
  2966. soff.z = Mathf.Cos(ang + tst) * off;
  2967. scl.x = scaleX.Evaluate(alpha);
  2968. float cuv = (float)(cross.Length - 1);
  2969. for ( int v = 0; v < cross.Length; v++ )
  2970. {
  2971. Vector3 cp = cross[v];
  2972. cp.x *= scl.x;
  2973. Vector3 p = tm.MultiplyPoint3x4(cp + soff);
  2974. tverts[vi] = wtm.MultiplyPoint3x4(p); //cross[v]);
  2975. if ( GenUV ) //builduvs )
  2976. {
  2977. uv.y = ((alpha - TubeStart) * splines[0].length * uvtiley) + UVOffset.y;
  2978. uv.x = (((float)v / cuv) * uvtilex) + uvt + UVOffset.x;
  2979. tuvs[vi++] = uv;
  2980. }
  2981. else
  2982. vi++;
  2983. }
  2984. // Uv is - to 1 around and alpha along
  2985. }
  2986. if ( GenUV ) //builduvs )
  2987. {
  2988. int sc = ribsegs + 1;
  2989. if ( flipNormals )
  2990. {
  2991. for ( int i = 0; i < segments; i++ )
  2992. {
  2993. for ( int v = 0; v < cross.Length - 1; v++ )
  2994. {
  2995. ttris[ti++] = ((i + 1) * sc) + v + vo;
  2996. ttris[ti++] = (i * sc) + v + vo;
  2997. ttris[ti++] = ((i + 1) * sc) + ((v + 1) % sc) + vo;
  2998. ttris[ti++] = ((i + 1) * sc) + ((v + 1) % sc) + vo;
  2999. ttris[ti++] = (i * sc) + v + vo;
  3000. ttris[ti++] = (i * sc) + ((v + 1) % sc) + vo;
  3001. }
  3002. }
  3003. }
  3004. else
  3005. {
  3006. for ( int i = 0; i < segments; i++ )
  3007. {
  3008. for ( int v = 0; v < cross.Length - 1; v++ )
  3009. {
  3010. ttris[ti++] = ((i + 1) * sc) + v + vo;
  3011. ttris[ti++] = ((i + 1) * sc) + ((v + 1) % sc) + vo;
  3012. ttris[ti++] = (i * sc) + v + vo;
  3013. ttris[ti++] = ((i + 1) * sc) + ((v + 1) % sc) + vo;
  3014. ttris[ti++] = (i * sc) + ((v + 1) % sc) + vo;
  3015. ttris[ti++] = (i * sc) + v + vo;
  3016. }
  3017. }
  3018. }
  3019. }
  3020. }
  3021. // Conform
  3022. if ( conform )
  3023. {
  3024. CalcBounds(tverts);
  3025. DoConform(tverts);
  3026. }
  3027. //Mesh mesh = MegaUtils.GetMesh(gameObject);
  3028. shapemesh.Clear();
  3029. shapemesh.subMeshCount = 1;
  3030. shapemesh.vertices = tverts;
  3031. shapemesh.triangles = ttris;
  3032. if ( GenUV ) //builduvs )
  3033. {
  3034. shapemesh.uv = tuvs;
  3035. }
  3036. else
  3037. {
  3038. //shapemesh.vertices = tverts;
  3039. }
  3040. shapemesh.RecalculateBounds();
  3041. shapemesh.RecalculateNormals();
  3042. if ( CalcTangents )
  3043. MegaUtils.BuildTangents(shapemesh);
  3044. }
  3045. void BuildBoxMesh()
  3046. {
  3047. //float lengthuvtile = uvtiley * TubeLength;
  3048. TubeLength = Mathf.Clamp01(TubeLength);
  3049. if ( TubeLength == 0.0f || strands < 1)
  3050. {
  3051. shapemesh.Clear();
  3052. return;
  3053. }
  3054. //float sradius = (tradius * 0.5f) + strandRadius;
  3055. BuildBoxCrossSection(boxwidth, boxheight);
  3056. segments = (int)((splines[0].length * TubeLength) / (stepdist * 0.1f));
  3057. Twist = TwistPerUnit; // * TubeLength;
  3058. float sang = startAng * Mathf.Deg2Rad;
  3059. int vcount = 9 * (segments + 1) * strands;
  3060. int tcount = (8 * segments) * strands;
  3061. float off = (tradius * 0.5f) + offset;
  3062. //float off = offset;
  3063. if ( strands == 1 )
  3064. {
  3065. off = offset;
  3066. }
  3067. if ( cap )
  3068. {
  3069. vcount += 8 * strands;
  3070. tcount += 4 * strands;
  3071. }
  3072. if ( tverts == null || tverts.Length != vcount )
  3073. tverts = new Vector3[vcount];
  3074. bool builduvs = false;
  3075. if ( GenUV && (tuvs == null || tuvs.Length != vcount) )
  3076. {
  3077. tuvs = new Vector2[vcount];
  3078. builduvs = true;
  3079. }
  3080. if ( ttris == null || ttris.Length != tcount * 3 )
  3081. {
  3082. ttris = new int[tcount * 3];
  3083. }
  3084. mat = Matrix4x4.identity;
  3085. tm = Matrix4x4.identity;
  3086. switch ( axis )
  3087. {
  3088. case MegaAxis.X: MegaMatrix.RotateY(ref tm, -Mathf.PI * 0.5f); break;
  3089. case MegaAxis.Y: MegaMatrix.RotateX(ref tm, -Mathf.PI * 0.5f); break;
  3090. case MegaAxis.Z: break;
  3091. }
  3092. switch ( RopeUp )
  3093. {
  3094. case MegaAxis.X: ropeup = Vector3.right; break;
  3095. case MegaAxis.Y: ropeup = Vector3.up; break;
  3096. case MegaAxis.Z: ropeup = Vector3.forward; break;
  3097. }
  3098. MegaMatrix.SetTrans(ref tm, Pivot);
  3099. // We only need to refresh the verts, tris and uvs are done once
  3100. int vi = 0;
  3101. int ti = 0;
  3102. Vector2 uv = Vector2.zero;
  3103. Vector3 soff = Vector3.zero;
  3104. Vector3 scl = Vector3.one;
  3105. for ( int s = 0; s < strands; s++ )
  3106. {
  3107. //rollingquat = Quaternion.identity;
  3108. float ang = ((float)s / (float)strands) * Mathf.PI * 2.0f;
  3109. soff.x = Mathf.Sin(ang) * off;
  3110. soff.z = Mathf.Cos(ang) * off;
  3111. //Matrix.SetTrans(ref tm, soff);
  3112. int vo = vi;
  3113. // Cap maybe needs to be submesh, at least needs seperate verts
  3114. if ( cap )
  3115. {
  3116. // Add slice at 0
  3117. float alpha = TubeStart; //0.0f;
  3118. wtm = GetDeformMat(alpha);
  3119. //float uvt = alpha * uvtwist;
  3120. float tst = sang + (0.0f * Twist * Mathf.PI * 2.0f);
  3121. soff.x = Mathf.Sin(ang + tst) * off;
  3122. soff.z = Mathf.Cos(ang + tst) * off;
  3123. scl.x = scaleX.Evaluate(alpha);
  3124. if ( unlinkScale )
  3125. scl.z = scaleY.Evaluate(alpha);
  3126. else
  3127. scl.z = scl.x;
  3128. for ( int v = 0; v < 4; v++ )
  3129. {
  3130. Vector3 cp = cross[v * 2];
  3131. cp.x *= scl.x;
  3132. cp.z *= scl.z;
  3133. Vector3 p = tm.MultiplyPoint3x4(cp + soff);
  3134. tverts[vi] = wtm.MultiplyPoint3x4(p); //cross[v]);
  3135. if ( builduvs )
  3136. {
  3137. uv.y = 0.0f; //alpha * uvtiley;
  3138. uv.x = 0.0f; //(((float)v / (float)cross.Length) * uvtilex) + uvt;
  3139. tuvs[vi++] = uv;
  3140. }
  3141. else
  3142. vi++;
  3143. }
  3144. //if ( GenUV ) //builduvs )
  3145. {
  3146. //for ( int sd = 1; sd < 2; sd++ )
  3147. if ( flipNormals )
  3148. {
  3149. ttris[ti++] = vo;
  3150. ttris[ti++] = vo + 1;
  3151. ttris[ti++] = vo + 2;
  3152. ttris[ti++] = vo;
  3153. ttris[ti++] = vo + 2;
  3154. ttris[ti++] = vo + 3;
  3155. }
  3156. else
  3157. {
  3158. ttris[ti++] = vo;
  3159. ttris[ti++] = vo + 2;
  3160. ttris[ti++] = vo + 1;
  3161. ttris[ti++] = vo;
  3162. ttris[ti++] = vo + 3;
  3163. ttris[ti++] = vo + 2;
  3164. }
  3165. }
  3166. vo = vi;
  3167. // Other end
  3168. alpha = TubeStart + TubeLength; //.0f;
  3169. wtm = GetDeformMat(alpha);
  3170. //uvt = alpha * uvtwist;
  3171. tst = sang + (TubeLength * Twist * Mathf.PI * 2.0f);
  3172. soff.x = Mathf.Sin(ang + tst) * off;
  3173. soff.z = Mathf.Cos(ang + tst) * off;
  3174. scl.x = scaleX.Evaluate(alpha);
  3175. if ( unlinkScale )
  3176. scl.z = scaleY.Evaluate(alpha);
  3177. else
  3178. scl.z = scl.x;
  3179. for ( int v = 0; v < 4; v++ )
  3180. {
  3181. Vector3 cp = cross[v * 2];
  3182. cp.x *= scl.x;
  3183. cp.z *= scl.z;
  3184. Vector3 p = tm.MultiplyPoint3x4(cp + soff);
  3185. tverts[vi] = wtm.MultiplyPoint3x4(p); //cross[v]);
  3186. if ( GenUV ) //builduvs )
  3187. {
  3188. uv.y = 0.0f; //alpha * uvtiley;
  3189. uv.x = 0.0f; //(((float)v / (float)cross.Length) * uvtilex) + uvt;
  3190. tuvs[vi++] = uv;
  3191. }
  3192. else
  3193. vi++;
  3194. }
  3195. //if ( GenUV ) //builduvs )
  3196. {
  3197. //for ( int sd = 1; sd < 2; sd++ )
  3198. if ( flipNormals )
  3199. {
  3200. ttris[ti++] = vo;
  3201. ttris[ti++] = vo + 2;
  3202. ttris[ti++] = vo + 1;
  3203. ttris[ti++] = vo;
  3204. ttris[ti++] = vo + 3;
  3205. ttris[ti++] = vo + 2;
  3206. }
  3207. else
  3208. {
  3209. ttris[ti++] = vo;
  3210. ttris[ti++] = vo + 1;
  3211. ttris[ti++] = vo + 2;
  3212. ttris[ti++] = vo;
  3213. ttris[ti++] = vo + 2;
  3214. ttris[ti++] = vo + 3;
  3215. }
  3216. }
  3217. }
  3218. vo = vi;
  3219. for ( int i = 0; i <= segments; i++ )
  3220. {
  3221. float alpha = TubeStart + (((float)i / (float)segments) * TubeLength);
  3222. wtm = GetDeformMat(alpha);
  3223. float uvt = alpha * uvtwist;
  3224. float tst = sang + ((alpha - TubeStart) * Twist * Mathf.PI * 2.0f); // + rollang;
  3225. soff.x = Mathf.Sin(ang + tst) * off;
  3226. soff.z = Mathf.Cos(ang + tst) * off;
  3227. scl.x = scaleX.Evaluate(alpha);
  3228. if ( unlinkScale )
  3229. scl.z = scaleY.Evaluate(alpha);
  3230. else
  3231. scl.z = scl.x;
  3232. for ( int v = 0; v < cross.Length; v++ )
  3233. {
  3234. Vector3 cp = cross[v];
  3235. cp.x *= scl.x;
  3236. cp.z *= scl.z;
  3237. Vector3 p = tm.MultiplyPoint3x4(cp + soff);
  3238. tverts[vi] = wtm.MultiplyPoint3x4(p); //cross[v]);
  3239. if ( GenUV ) //builduvs )
  3240. {
  3241. //uv.y = (alpha - TubeStart) * lengthuvtile * splines[0].length; //uvtiley;
  3242. uv.y = ((alpha - TubeStart) * splines[0].length * uvtiley) + UVOffset.y;
  3243. //uv.x = (((float)v / (float)cross.Length) * uvtilex) + uvt;
  3244. uv.x = (boxuv[v] * uvtilex) + uvt + UVOffset.x;
  3245. tuvs[vi++] = uv;
  3246. }
  3247. else
  3248. vi++;
  3249. }
  3250. // Uv is - to 1 around and alpha along
  3251. }
  3252. if ( GenUV ) //builduvs )
  3253. {
  3254. int sc = 8;
  3255. if ( flipNormals )
  3256. {
  3257. for ( int i = 0; i < segments; i++ )
  3258. {
  3259. for ( int v = 0; v < 4; v++ )
  3260. {
  3261. int v2 = v * 2;
  3262. ttris[ti++] = (i * sc) + v2 + vo;
  3263. ttris[ti++] = ((i + 1) * sc) + v2 + vo;
  3264. ttris[ti++] = ((i + 1) * sc) + (v2 + 1) + vo;
  3265. ttris[ti++] = (i * sc) + v2 + vo;
  3266. ttris[ti++] = ((i + 1) * sc) + (v2 + 1) + vo;
  3267. ttris[ti++] = (i * sc) + (v2 + 1) + vo;
  3268. }
  3269. }
  3270. }
  3271. else
  3272. {
  3273. for ( int i = 0; i < segments; i++ )
  3274. {
  3275. for ( int v = 0; v < 4; v++ )
  3276. {
  3277. int v2 = v * 2;
  3278. ttris[ti++] = (i * sc) + v2 + vo;
  3279. ttris[ti++] = ((i + 1) * sc) + (v2 + 1) + vo;
  3280. ttris[ti++] = ((i + 1) * sc) + v2 + vo;
  3281. ttris[ti++] = (i * sc) + v2 + vo;
  3282. ttris[ti++] = (i * sc) + (v2 + 1) + vo;
  3283. ttris[ti++] = ((i + 1) * sc) + (v2 + 1) + vo;
  3284. }
  3285. }
  3286. }
  3287. }
  3288. }
  3289. // Conform
  3290. if ( conform )
  3291. {
  3292. CalcBounds(tverts);
  3293. DoConform(tverts);
  3294. }
  3295. //Mesh mesh = MegaUtils.GetMesh(gameObject);
  3296. shapemesh.Clear();
  3297. shapemesh.subMeshCount = 1;
  3298. shapemesh.vertices = tverts;
  3299. shapemesh.triangles = ttris;
  3300. if ( GenUV ) //builduvs )
  3301. {
  3302. shapemesh.uv = tuvs;
  3303. }
  3304. else
  3305. {
  3306. //shapemesh.vertices = tverts;
  3307. }
  3308. shapemesh.RecalculateBounds();
  3309. shapemesh.RecalculateNormals();
  3310. if ( CalcTangents )
  3311. MegaUtils.BuildTangents(shapemesh);
  3312. }
  3313. void BuildMultiStrandMesh()
  3314. {
  3315. //float lengthuvtile = uvtiley * TubeLength;
  3316. TubeLength = Mathf.Clamp01(TubeLength);
  3317. if ( TubeLength == 0.0f || strands < 1 )
  3318. {
  3319. shapemesh.Clear();
  3320. return;
  3321. }
  3322. Twist = TwistPerUnit; // * TubeLength;
  3323. //segments = (int)(RopeLength * SegsPerUnit);
  3324. segments = (int)((splines[selcurve].length * TubeLength) / (stepdist * 0.1f));
  3325. float sang = startAng * Mathf.Deg2Rad;
  3326. float off = (tradius * 0.5f) + offset;
  3327. if ( strands == 1 )
  3328. {
  3329. off = offset;
  3330. }
  3331. float sradius = (tradius * 0.5f) + strandRadius;
  3332. BuildCrossSection(sradius);
  3333. int vcount = ((segments + 1) * (tsides + 1)) * strands;
  3334. int tcount = ((tsides * 2) * segments) * strands;
  3335. //Debug.Log("segs " + segments);
  3336. //Debug.Log("verts " + vcount);
  3337. //Debug.Log("tris " + tcount);
  3338. if ( cap )
  3339. {
  3340. vcount += ((tsides + 1) * 2) * strands;
  3341. tcount += (tsides * 2) * strands;
  3342. }
  3343. if ( tverts == null || tverts.Length != vcount )
  3344. {
  3345. tverts = new Vector3[vcount];
  3346. }
  3347. bool builduvs = false;
  3348. if ( GenUV && (tuvs == null || tuvs.Length != vcount) )
  3349. {
  3350. tuvs = new Vector2[vcount];
  3351. builduvs = true;
  3352. }
  3353. if ( ttris == null || ttris.Length != tcount * 3 )
  3354. {
  3355. ttris = new int[tcount * 3];
  3356. }
  3357. mat = Matrix4x4.identity;
  3358. tm = Matrix4x4.identity;
  3359. switch ( axis )
  3360. {
  3361. case MegaAxis.X: MegaMatrix.RotateY(ref tm, -Mathf.PI * 0.5f); break;
  3362. case MegaAxis.Y: MegaMatrix.RotateX(ref tm, -Mathf.PI * 0.5f); break;
  3363. case MegaAxis.Z: break;
  3364. }
  3365. MegaMatrix.SetTrans(ref tm, Pivot);
  3366. switch ( RopeUp )
  3367. {
  3368. case MegaAxis.X: ropeup = Vector3.right; break;
  3369. case MegaAxis.Y: ropeup = Vector3.up; break;
  3370. case MegaAxis.Z: ropeup = Vector3.forward; break;
  3371. }
  3372. // We only need to refresh the verts, tris and uvs are done once
  3373. int vi = 0;
  3374. int ti = 0;
  3375. Vector2 uv = Vector2.zero;
  3376. Vector3 soff = Vector3.zero;
  3377. Vector3 scl = Vector3.one;
  3378. for ( int s = 0; s < strands; s++ )
  3379. {
  3380. //rollingquat = Quaternion.identity;
  3381. float ang = ((float)s / (float)strands) * Mathf.PI * 2.0f;
  3382. soff.x = Mathf.Sin(ang) * off;
  3383. soff.z = Mathf.Cos(ang) * off;
  3384. //Matrix.SetTrans(ref tm, soff);
  3385. int vo = vi;
  3386. // Cap maybe needs to be submesh, at least needs seperate verts
  3387. if ( cap )
  3388. {
  3389. // Add slice at 0
  3390. float alpha = TubeStart; //0.0f;
  3391. wtm = GetDeformMat(alpha);
  3392. //float uvt = alpha * uvtwist;
  3393. float tst = sang + ((alpha - TubeStart) * Twist * Mathf.PI * 2.0f);
  3394. soff.x = Mathf.Sin(ang + tst) * off;
  3395. soff.z = Mathf.Cos(ang + tst) * off;
  3396. scl.x = scaleX.Evaluate(alpha);
  3397. if ( unlinkScale )
  3398. scl.z = scaleY.Evaluate(alpha);
  3399. else
  3400. scl.z = scl.x;
  3401. for ( int v = 0; v <= cross.Length; v++ )
  3402. {
  3403. Vector3 cp = cross[v % cross.Length];
  3404. cp.x *= scl.x;
  3405. cp.z *= scl.z;
  3406. Vector3 p = tm.MultiplyPoint3x4(cp + soff);
  3407. tverts[vi] = wtm.MultiplyPoint3x4(p); //cross[v]);
  3408. if ( builduvs )
  3409. {
  3410. uv.y = 0.0f; //alpha * uvtiley;
  3411. uv.x = 0.0f; //(((float)v / (float)cross.Length) * uvtilex) + uvt;
  3412. tuvs[vi++] = uv;
  3413. }
  3414. else
  3415. vi++;
  3416. }
  3417. if ( GenUV ) //builduvs )
  3418. {
  3419. if ( flipNormals )
  3420. {
  3421. for ( int sd = 1; sd < tsides; sd++ )
  3422. {
  3423. ttris[ti++] = vo;
  3424. ttris[ti++] = vo + sd;
  3425. ttris[ti++] = vo + sd + 1;
  3426. }
  3427. }
  3428. else
  3429. {
  3430. for ( int sd = 1; sd < tsides; sd++ )
  3431. {
  3432. ttris[ti++] = vo;
  3433. ttris[ti++] = vo + sd + 1;
  3434. ttris[ti++] = vo + sd;
  3435. }
  3436. }
  3437. }
  3438. vo = vi;
  3439. // Other end
  3440. alpha = TubeStart + TubeLength; //.0f;
  3441. wtm = GetDeformMat(alpha);
  3442. //uvt = alpha * uvtwist;
  3443. tst = sang + ((alpha - TubeStart) * Twist * Mathf.PI * 2.0f);
  3444. soff.x = Mathf.Sin(ang + tst) * off;
  3445. soff.z = Mathf.Cos(ang + tst) * off;
  3446. scl.x = scaleX.Evaluate(alpha);
  3447. if ( unlinkScale )
  3448. scl.z = scaleY.Evaluate(alpha);
  3449. else
  3450. scl.z = scl.x;
  3451. for ( int v = 0; v <= cross.Length; v++ )
  3452. {
  3453. Vector3 cp = cross[v % cross.Length];
  3454. cp.x *= scl.x;
  3455. cp.z *= scl.z;
  3456. Vector3 p = tm.MultiplyPoint3x4(cp + soff);
  3457. tverts[vi] = wtm.MultiplyPoint3x4(p); //cross[v]);
  3458. if ( GenUV ) //builduvs )
  3459. {
  3460. uv.y = 0.0f; //alpha * uvtiley;
  3461. uv.x = 0.0f; //(((float)v / (float)cross.Length) * uvtilex) + uvt;
  3462. tuvs[vi++] = uv;
  3463. }
  3464. else
  3465. vi++;
  3466. }
  3467. if ( GenUV ) //builduvs )
  3468. {
  3469. if ( flipNormals )
  3470. {
  3471. for ( int sd = 1; sd < tsides; sd++ )
  3472. {
  3473. ttris[ti++] = vo;
  3474. ttris[ti++] = vo + sd + 1;
  3475. ttris[ti++] = vo + sd;
  3476. }
  3477. }
  3478. else
  3479. {
  3480. for ( int sd = 1; sd < tsides; sd++ )
  3481. {
  3482. ttris[ti++] = vo;
  3483. ttris[ti++] = vo + sd;
  3484. ttris[ti++] = vo + sd + 1;
  3485. }
  3486. }
  3487. }
  3488. }
  3489. vo = vi;
  3490. for ( int i = 0; i <= segments; i++ )
  3491. {
  3492. float alpha = TubeStart + (((float)i / (float)segments) * TubeLength);
  3493. scl.x = scaleX.Evaluate(alpha);
  3494. if ( unlinkScale )
  3495. scl.z = scaleY.Evaluate(alpha);
  3496. else
  3497. scl.z = scl.x;
  3498. wtm = GetDeformMat(alpha);
  3499. float uvt = alpha * uvtwist;
  3500. float tst = sang + ((alpha - TubeStart) * Twist * Mathf.PI * 2.0f); // + rollang;
  3501. soff.x = Mathf.Sin(ang + tst) * off;
  3502. soff.z = Mathf.Cos(ang + tst) * off;
  3503. for ( int v = 0; v <= cross.Length; v++ )
  3504. {
  3505. Vector3 cp = cross[v % cross.Length];
  3506. cp.x *= scl.x;
  3507. cp.z *= scl.z;
  3508. Vector3 p = tm.MultiplyPoint3x4(cp + soff); //cross[v % cross.Length] + soff);
  3509. tverts[vi] = wtm.MultiplyPoint3x4(p); //cross[v]);
  3510. if ( GenUV ) //builduvs )
  3511. {
  3512. //uv.y = alpha * lengthuvtile; //uvtiley;
  3513. uv.y = ((alpha - TubeStart) * splines[0].length * uvtiley) + UVOffset.y;
  3514. uv.x = (((float)v / (float)cross.Length) * uvtilex) + uvt + UVOffset.x;
  3515. tuvs[vi++] = uv;
  3516. }
  3517. else
  3518. vi++;
  3519. }
  3520. // Uv is - to 1 around and alpha along
  3521. }
  3522. if ( GenUV ) //builduvs )
  3523. {
  3524. int sc = tsides + 1;
  3525. if ( flipNormals )
  3526. {
  3527. for ( int i = 0; i < segments; i++ )
  3528. {
  3529. for ( int v = 0; v < cross.Length; v++ )
  3530. {
  3531. ttris[ti++] = (i * sc) + v + vo;
  3532. ttris[ti++] = ((i + 1) * sc) + v + vo;
  3533. ttris[ti++] = ((i + 1) * sc) + ((v + 1) % sc) + vo;
  3534. ttris[ti++] = (i * sc) + v + vo;
  3535. ttris[ti++] = ((i + 1) * sc) + ((v + 1) % sc) + vo;
  3536. ttris[ti++] = (i * sc) + ((v + 1) % sc) + vo;
  3537. }
  3538. }
  3539. }
  3540. else
  3541. {
  3542. for ( int i = 0; i < segments; i++ )
  3543. {
  3544. for ( int v = 0; v < cross.Length; v++ )
  3545. {
  3546. ttris[ti++] = (i * sc) + v + vo;
  3547. ttris[ti++] = ((i + 1) * sc) + ((v + 1) % sc) + vo;
  3548. ttris[ti++] = ((i + 1) * sc) + v + vo;
  3549. ttris[ti++] = (i * sc) + v + vo;
  3550. ttris[ti++] = (i * sc) + ((v + 1) % sc) + vo;
  3551. ttris[ti++] = ((i + 1) * sc) + ((v + 1) % sc) + vo;
  3552. }
  3553. }
  3554. }
  3555. }
  3556. }
  3557. // Conform
  3558. if ( conform )
  3559. {
  3560. CalcBounds(tverts);
  3561. DoConform(tverts);
  3562. }
  3563. //Mesh mesh = MegaUtils.GetMesh(gameObject);
  3564. shapemesh.Clear();
  3565. shapemesh.subMeshCount = 1;
  3566. shapemesh.vertices = tverts;
  3567. shapemesh.triangles = ttris;
  3568. if ( GenUV ) //builduvs )
  3569. {
  3570. shapemesh.uv = tuvs;
  3571. }
  3572. else
  3573. {
  3574. //shapemesh.vertices = tverts;
  3575. }
  3576. shapemesh.RecalculateBounds();
  3577. shapemesh.RecalculateNormals();
  3578. //MeshConstructor.BuildTangents(mesh);
  3579. if ( CalcTangents )
  3580. MegaUtils.BuildTangents(shapemesh);
  3581. }
  3582. #endif // tube mesh
  3583. public void ClearMesh()
  3584. {
  3585. MeshFilter mf = gameObject.GetComponent<MeshFilter>();
  3586. if ( mf != null )
  3587. {
  3588. mf.sharedMesh = null;
  3589. shapemesh = null;
  3590. }
  3591. }
  3592. public void SetMats()
  3593. {
  3594. MeshRenderer mr = gameObject.GetComponent<MeshRenderer>();
  3595. if ( mr == null )
  3596. {
  3597. mr = gameObject.AddComponent<MeshRenderer>();
  3598. }
  3599. if ( meshType == MeshShapeType.Fill )
  3600. {
  3601. Material[] mats = new Material[3];
  3602. mats[0] = mat1;
  3603. mats[1] = mat2;
  3604. mats[2] = mat3;
  3605. mr.sharedMaterials = mats;
  3606. }
  3607. else
  3608. {
  3609. Material[] mats = new Material[1];
  3610. mats[0] = mat1;
  3611. mr.sharedMaterials = mats;
  3612. }
  3613. }
  3614. int[] empty = new int[3] {0, 0, 0};
  3615. // Best if we calc the normals to avoid issues at join
  3616. public void BuildMesh()
  3617. {
  3618. if ( makeMesh )
  3619. {
  3620. if ( splines == null || splines.Count == 0 )
  3621. return;
  3622. if ( shapemesh == null )
  3623. {
  3624. MeshFilter mf = gameObject.GetComponent<MeshFilter>();
  3625. if ( mf == null )
  3626. mf = gameObject.AddComponent<MeshFilter>();
  3627. mf.sharedMesh = new Mesh();
  3628. MeshRenderer mr = gameObject.GetComponent<MeshRenderer>();
  3629. if ( mr == null )
  3630. {
  3631. mr = gameObject.AddComponent<MeshRenderer>();
  3632. }
  3633. SetMats();
  3634. shapemesh = mf.sharedMesh; //Utils.GetMesh(gameObject);
  3635. }
  3636. if ( meshType == MeshShapeType.Tube )
  3637. {
  3638. BuildTubeMesh();
  3639. return;
  3640. }
  3641. if ( meshType == MeshShapeType.Box )
  3642. {
  3643. BuildBoxMesh();
  3644. return;
  3645. }
  3646. if ( meshType == MeshShapeType.Ribbon )
  3647. {
  3648. BuildRibbonMesh();
  3649. return;
  3650. }
  3651. //makeMesh = false;
  3652. float sdist = stepdist * 0.1f;
  3653. if ( splines[selcurve].length / sdist > 1500.0f )
  3654. sdist = splines[selcurve].length / 1500.0f;
  3655. Vector3 size = Vector3.zero;
  3656. verts.Clear();
  3657. uvs.Clear();
  3658. tris.Clear();
  3659. tris1.Clear();
  3660. tris2.Clear();
  3661. tris = MegaTriangulator.Triangulate(this, splines[selcurve], sdist, ref verts, ref uvs, ref tris, Pivot, ref size);
  3662. if ( axis != MegaAxis.Y )
  3663. {
  3664. for ( int i = 0; i < tris.Count; i += 3 )
  3665. {
  3666. int t = tris[i];
  3667. tris[i] = tris[i + 2];
  3668. tris[i + 2] = t;
  3669. }
  3670. }
  3671. int vcount = verts.Count;
  3672. int tcount = tris.Count;
  3673. if ( Height < 0.0f )
  3674. Height = 0.0f;
  3675. float h = Height; //Mathf.Abs(Height);
  3676. Matrix4x4 tm1 = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(UVRotate.x, UVRotate.y, 0.0f), new Vector3(UVScale.x, 1.0f, UVScale.y));
  3677. //Vector3 size = shapemesh.bounds.size;
  3678. if ( GenUV )
  3679. {
  3680. uvs.Clear(); // need to stop triangulator doing uvs
  3681. Vector2 uv = Vector2.zero;
  3682. Vector3 uv1 = Vector3.zero;
  3683. int uvx = 0;
  3684. int uvy = 2;
  3685. switch ( axis )
  3686. {
  3687. case MegaAxis.X:
  3688. uvx = 1;
  3689. break;
  3690. case MegaAxis.Z:
  3691. uvy = 1;
  3692. break;
  3693. }
  3694. for ( int i = 0; i < verts.Count; i++ )
  3695. {
  3696. //uv1.x = (verts[i].x); // * UVScale.x) + UVOffset.x; // * UVScale.x;
  3697. //uv1.z = (verts[i].z); // * UVScale.y) + UVOffset.y; // * UVScale.y;
  3698. uv1.x = verts[i][uvx]; // * UVScale.x) + UVOffset.x; // * UVScale.x;
  3699. uv1.z = verts[i][uvy]; // * UVScale.y) + UVOffset.y; // * UVScale.y;
  3700. if ( !PhysUV )
  3701. {
  3702. uv1.x /= size[uvx]; //.x;
  3703. uv1.z /= size[uvy]; //.z;
  3704. }
  3705. uv1 = tm1.MultiplyPoint3x4(uv1);
  3706. uv.x = uv1.x + UVOffset.x;
  3707. uv.y = uv1.z + UVOffset.y;
  3708. uvs.Add(uv);
  3709. }
  3710. }
  3711. if ( DoubleSided && h != 0.0f )
  3712. {
  3713. //vcount = verts.Count;
  3714. for ( int i = 0; i < vcount; i++ )
  3715. {
  3716. Vector3 p = verts[i];
  3717. if ( UseHeightCurve )
  3718. {
  3719. float alpha = MegaTriangulator.m_points[i].z / splines[selcurve].length;
  3720. //p.y -= h * heightCrv.Evaluate(alpha + heightOff);
  3721. p[(int)axis] -= h * heightCrv.Evaluate(alpha + heightOff);
  3722. }
  3723. else
  3724. {
  3725. //p.y -= h;
  3726. p[(int)axis] -= h;
  3727. }
  3728. verts.Add(p); //verts[i]);
  3729. uvs.Add(uvs[i]);
  3730. }
  3731. //tcount = tris.Count;
  3732. #if false
  3733. switch ( axis )
  3734. {
  3735. case MegaAxis.X:
  3736. for ( int i = tcount - 1; i >= 0; i-- )
  3737. {
  3738. tris1.Add(tris[i] + vcount);
  3739. }
  3740. break;
  3741. case MegaAxis.Y:
  3742. for ( int i = tcount - 1; i >= 0; i-- )
  3743. {
  3744. tris1.Add(tris[i] + vcount);
  3745. }
  3746. break;
  3747. case MegaAxis.Z:
  3748. for ( int i = 0; i < tcount; i++ )
  3749. {
  3750. tris1.Add(tris[i] + vcount);
  3751. }
  3752. break;
  3753. }
  3754. #endif
  3755. for ( int i = tcount - 1; i >= 0; i-- )
  3756. {
  3757. tris1.Add(tris[i] + vcount);
  3758. }
  3759. }
  3760. #if true
  3761. // Do edge
  3762. if ( h != 0.0f )
  3763. {
  3764. int vc = verts.Count;
  3765. Vector3 ep = Vector3.zero;
  3766. Vector2 euv = Vector2.zero;
  3767. tm1 = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(UVRotate1.x, UVRotate1.y, 0.0f), new Vector3(UVScale1.x, 1.0f, UVScale1.y));
  3768. // Top loop
  3769. for ( int i = 0; i < MegaTriangulator.m_points.Count; i++ )
  3770. {
  3771. ep = verts[i];
  3772. //ep.x = MegaTriangulator.m_points[i].x;
  3773. //ep.y = 0.0f;
  3774. //ep.z = MegaTriangulator.m_points[i].y;
  3775. verts.Add(ep);
  3776. //euv.x = (MegaTriangulator.m_points[i].z / splines[0].length) * 4.0f;
  3777. //euv.x = (MegaTriangulator.m_points[i].z * UVScale1.x) + UVOffset1.x; // / splines[0].length) * 4.0f;
  3778. //euv.y = UVOffset1.y; //0.0f;
  3779. ep.x = (MegaTriangulator.m_points[i].z); // * UVScale1.x) + UVOffset1.x; // / splines[0].length) * 4.0f;
  3780. if ( !PhysUV )
  3781. {
  3782. ep.x /= size.x;
  3783. }
  3784. ep.y = 0.0f;
  3785. ep.z = 0.0f; //UVOffset1.y; //0.0f;
  3786. ep = tm1.MultiplyPoint3x4(ep);
  3787. euv.x = ep.x + UVOffset1.x;
  3788. euv.y = ep.z + UVOffset1.y;
  3789. uvs.Add(euv);
  3790. }
  3791. // Add first point again
  3792. ep = verts[0];
  3793. //ep.y -= h * heightCrv.Evaluate(0.0f);
  3794. verts.Add(ep);
  3795. //euv.x = 1.0f * 4.0f; //MegaTriangulator.m_points[0].z / splines[0].length;
  3796. euv.x = (splines[selcurve].length * UVScale1.x) + UVOffset1.x; //1.0f * 4.0f; //MegaTriangulator.m_points[0].z / splines[0].length;
  3797. if ( !PhysUV )
  3798. {
  3799. euv.x /= size.x;
  3800. }
  3801. euv.y = 0.0f + UVOffset1.y;
  3802. uvs.Add(euv);
  3803. // Bot loop
  3804. float hd = 1.0f;
  3805. for ( int i = 0; i < MegaTriangulator.m_points.Count; i++ )
  3806. {
  3807. float alpha = MegaTriangulator.m_points[i].z / splines[selcurve].length;
  3808. ep = verts[i];
  3809. if ( UseHeightCurve )
  3810. hd = heightCrv.Evaluate(alpha + heightOff);
  3811. //ep.y -= h * hd; //heightCrv.Evaluate(alpha);
  3812. ep[(int)axis] -= h * hd;
  3813. verts.Add(ep);
  3814. ep.x = (MegaTriangulator.m_points[i].z); // * UVScale1.x) + UVOffset1.x; // / splines[0].length) * 4.0f;
  3815. ep.z = ep.y; //0.0f; //UVOffset1.y; //0.0f;
  3816. ep.y = 0.0f;
  3817. if ( !PhysUV )
  3818. {
  3819. ep.x /= size.x;
  3820. ep.z /= (h * hd);
  3821. }
  3822. ep = tm1.MultiplyPoint3x4(ep);
  3823. euv.x = ep.x + UVOffset1.x;
  3824. euv.y = ep.z + UVOffset1.y;
  3825. //euv.x = (MegaTriangulator.m_points[i].z / splines[0].length) * 4.0f;
  3826. //euv.x = (MegaTriangulator.m_points[i].z * UVScale1.x) + UVOffset1.x;
  3827. //euv.y = ((h * hd) * UVScale1.y) + UVOffset1.y; //1.0f;
  3828. uvs.Add(euv);
  3829. }
  3830. // Add first point again
  3831. ep = verts[0];
  3832. if ( UseHeightCurve )
  3833. {
  3834. hd = heightCrv.Evaluate(0.0f + heightOff);
  3835. }
  3836. //ep.y -= h * hd; //heightCrv.Evaluate(0.0f);
  3837. ep[(int)axis] -= h * hd;
  3838. verts.Add(ep);
  3839. ep.x = (MegaTriangulator.m_points[0].z); // * UVScale1.x) + UVOffset1.x; // / splines[0].length) * 4.0f;
  3840. ep.z = ep.y; //0.0f; //UVOffset1.y; //0.0f;
  3841. ep.y = 0.0f;
  3842. if ( !PhysUV )
  3843. {
  3844. ep.x /= size.x;
  3845. ep.z /= (h * hd);
  3846. }
  3847. ep = tm1.MultiplyPoint3x4(ep);
  3848. euv.x = ep.x + UVOffset1.x;
  3849. euv.y = ep.z + UVOffset1.y;
  3850. //euv.x = (MegaTriangulator.m_points[i].z / splines[0].length) * 4.0f;
  3851. //euv.x = (MegaTriangulator.m_points[i].z * UVScale1.x) + UVOffset1.x;
  3852. //euv.y = ((h * hd) * UVScale1.y) + UVOffset1.y; //1.0f;
  3853. uvs.Add(euv);
  3854. //euv.x = 1.0f; //MegaTriangulator.m_points[0].z / splines[0].length;
  3855. //euv.x = (splines[0].length * UVScale1.x) + UVOffset1.x; //MegaTriangulator.m_points[0].z / splines[0].length;
  3856. //euv.y = (h * hd * UVScale1.y) + UVOffset1.y; //1.0f;
  3857. //if ( !PhysUV )
  3858. //{
  3859. // euv.x /= size.x;
  3860. // euv.y /=
  3861. //}
  3862. //uvs.Add(euv);
  3863. // Faces
  3864. int ecount = MegaTriangulator.m_points.Count + 1;
  3865. int ip = 0;
  3866. if ( splines[selcurve].reverse )
  3867. {
  3868. for ( ip = 0; ip < MegaTriangulator.m_points.Count; ip++ )
  3869. {
  3870. tris2.Add(ip + vc + 1);
  3871. tris2.Add(ip + vc + ecount);
  3872. tris2.Add(ip + vc);
  3873. tris2.Add(ip + vc + ecount + 1);
  3874. tris2.Add(ip + vc + ecount);
  3875. tris2.Add(ip + vc + 1);
  3876. }
  3877. }
  3878. else
  3879. {
  3880. for ( ip = 0; ip < MegaTriangulator.m_points.Count; ip++ )
  3881. {
  3882. tris2.Add(ip + vc);
  3883. tris2.Add(ip + vc + ecount);
  3884. tris2.Add(ip + vc + 1);
  3885. tris2.Add(ip + vc + 1);
  3886. tris2.Add(ip + vc + ecount);
  3887. tris2.Add(ip + vc + ecount + 1);
  3888. }
  3889. }
  3890. #if false
  3891. #else
  3892. #endif
  3893. #if false
  3894. tris.Add(ip + vc);
  3895. tris.Add(ip + vc + ecount);
  3896. tris.Add(vc);
  3897. tris.Add(vc);
  3898. tris.Add(ip + vc + ecount);
  3899. tris.Add(vc + ecount);
  3900. #endif
  3901. }
  3902. #endif
  3903. Vector3[] tverts = verts.ToArray();
  3904. // Conform
  3905. if ( conform )
  3906. {
  3907. CalcBounds(tverts);
  3908. DoConform(tverts);
  3909. }
  3910. shapemesh.Clear();
  3911. shapemesh.vertices = tverts; //verts.ToArray();
  3912. shapemesh.uv = uvs.ToArray();
  3913. shapemesh.subMeshCount = 3;
  3914. shapemesh.SetTriangles(tris.ToArray(), 0);
  3915. if ( tris1.Count == 0 )
  3916. shapemesh.SetTriangles(empty, 1);
  3917. else
  3918. shapemesh.SetTriangles(tris1.ToArray(), 1);
  3919. if ( tris2.Count == 0 )
  3920. shapemesh.SetTriangles(empty, 2);
  3921. else
  3922. shapemesh.SetTriangles(tris2.ToArray(), 2);
  3923. //shapemesh.triangles = tris.ToArray();
  3924. shapemesh.RecalculateNormals();
  3925. shapemesh.RecalculateBounds();
  3926. if ( CalcTangents )
  3927. MegaUtils.BuildTangents(shapemesh);
  3928. //if ( mesh != null )
  3929. //{
  3930. //BuildMesh(mesh);
  3931. //MegaModifyObject mo = GetComponent<MegaModifyObject>();
  3932. //if ( mo != null )
  3933. //{
  3934. // mo.MeshUpdated();
  3935. //}
  3936. //}
  3937. }
  3938. }
  3939. #if true
  3940. static int CURVELENGTHSTEPS = 5;
  3941. static public float CurveLength(MegaSpline spline, int knot, float v1, float v2, float size)
  3942. {
  3943. float len = 0.0f;
  3944. if ( size == 0.0f )
  3945. { // Simple curve length
  3946. Vector3 p1,p2;
  3947. p1 = spline.InterpBezier3D(knot, v1);
  3948. //Debug.Log("p1 " + p1);
  3949. float step = (v2 - v1) / (float)CURVELENGTHSTEPS;
  3950. //Debug.Log("Step " + step);
  3951. float pos;
  3952. int i;
  3953. for ( i = 1, pos = step; i < CURVELENGTHSTEPS; ++i, pos += step )
  3954. {
  3955. p2 = spline.InterpBezier3D(knot, v1 + pos);
  3956. len += Vector3.Magnitude(p2 - p1);
  3957. p1 = p2;
  3958. }
  3959. //Debug.Log("len " + len);
  3960. len += Vector3.Magnitude(spline.InterpBezier3D(knot, v2) - p1);
  3961. //Debug.Log("len " + len);
  3962. }
  3963. else
  3964. { // Need to figure based on displaced location
  3965. int knots = spline.knots.Count;
  3966. int prev = (knot + knots - 1) % knots;
  3967. int next = (knot + 1) % knots;
  3968. float pv = v1 - 0.01f;
  3969. int pk = knot;
  3970. if ( pv < 0.0f )
  3971. {
  3972. if ( spline.closed )
  3973. {
  3974. pv += 1.0f;
  3975. pk = prev;
  3976. }
  3977. else
  3978. pv = 0.0f;
  3979. }
  3980. float nv = v1 + 0.01f;
  3981. Vector3 direction = Vector3.Normalize(spline.InterpBezier3D(knot, nv) - spline.InterpBezier3D(pk, pv));
  3982. //direction.z = 0.0f; // Keep it in the XY plane
  3983. //Vector3 perp = new Vector3(direction.y * size, -direction.x * size, 0.0f);
  3984. direction.y = 0.0f; // Keep it in the XY plane
  3985. Vector3 perp = new Vector3(direction.z * size, 0.0f, -direction.x * size);
  3986. Vector3 p1,p2;
  3987. p1 = spline.InterpBezier3D(knot, v1) + perp; // Got 1st displaced point
  3988. float step = (v2 - v1) / CURVELENGTHSTEPS;
  3989. float pos;
  3990. int i;
  3991. for ( i = 1, pos = step; i < CURVELENGTHSTEPS; ++i, pos += step )
  3992. {
  3993. pv = v1 + pos - 0.01f;
  3994. nv = v1 + pos + 0.01f;
  3995. direction = Vector3.Normalize(spline.InterpBezier3D(knot, nv) - spline.InterpBezier3D(knot, pv));
  3996. //direction.z = 0.0f; // Keep it in the XY plane
  3997. //perp = new Vector3(direction.y * size, -direction.x * size, 0.0f);
  3998. direction.y = 0.0f; // Keep it in the XY plane
  3999. perp = new Vector3(direction.z * size, 0.0f, -direction.x * size);
  4000. p2 = spline.InterpBezier3D(knot, v1 + pos) + perp;
  4001. len += Vector3.Magnitude(p2 - p1);
  4002. p1 = p2;
  4003. }
  4004. pv = v2 - 0.01f;
  4005. int nk = knot;
  4006. nv = v2 + 0.01f;
  4007. if ( nv > 1.0f )
  4008. {
  4009. if ( spline.closed )
  4010. {
  4011. nv -= 1.0f;
  4012. nk = next;
  4013. }
  4014. else
  4015. nv = 1.0f;
  4016. }
  4017. direction = Vector3.Normalize(spline.InterpBezier3D(nk, nv) - spline.InterpBezier3D(knot, pv));
  4018. //direction.z = 0.0f; // Keep it in the XY plane
  4019. //perp = new Vector3(direction.y * size, -direction.x * size, 0.0f);
  4020. direction.y = 0.0f; // Keep it in the XY plane
  4021. perp = new Vector3(direction.z * size, 0.0f, -direction.x * size);
  4022. len += Vector3.Magnitude((spline.InterpBezier3D(knot, v2) + perp) - p1);
  4023. }
  4024. return len;
  4025. }
  4026. // Outline test
  4027. public void OutlineSpline(MegaShape shape, int poly, float size, bool centered)
  4028. {
  4029. MegaSpline inSpline = shape.splines[poly];
  4030. MegaSpline outSpline = new MegaSpline();
  4031. OutlineSpline(inSpline, outSpline, size, centered);
  4032. shape.splines.Add(outSpline);
  4033. outSpline.CalcLength(); //10);
  4034. }
  4035. public void OutlineSpline(MegaSpline inSpline, MegaSpline outSpline, float size, bool centered)
  4036. {
  4037. // Do some basic calculations that we'll need regardless
  4038. float size1 = (centered) ? size / 2.0f : 0.0f; // First phase offset
  4039. //float size2 = (centered) ? -size / 2.0f : -size; // Second phase offset
  4040. int knots = inSpline.knots.Count;
  4041. //Vector3 knot, invec, outvec;
  4042. int i;
  4043. //Matrix4x4 theMatrix;
  4044. outSpline.knots.Clear();
  4045. // If the input spline is closed, we wind up with two polygons
  4046. if ( inSpline.closed )
  4047. {
  4048. ///MegaSpline outSpline2 = new MegaSpline(); //shape->NewSpline();
  4049. // Generate the outline polygons...
  4050. for ( i = 0; i < knots; ++i )
  4051. {
  4052. int prevKnot = (i + knots - 1) % knots;
  4053. float oldInLength = CurveLength(inSpline, prevKnot, 0.5f, 1.0f, 0.0f);
  4054. float oldOutLength = CurveLength(inSpline, i, 0.0f, 0.5f, 0.0f);
  4055. //Debug.Log("oldlens " + oldInLength + " " + oldOutLength);
  4056. //int knotType = 0; //inSpline->GetKnotType(i);
  4057. // Determine the angle of the curve at this knot
  4058. // Get vector from interp before knot to interp after knot
  4059. Vector3 ko = inSpline.knots[i].p; //->GetKnotPoint(i);
  4060. //Debug.Log("ko " + ko);
  4061. Vector3 bVec = Vector3.Normalize(inSpline.InterpBezier3D(prevKnot, 0.99f) - ko);
  4062. Vector3 fVec = Vector3.Normalize(inSpline.InterpBezier3D(i, 0.01f) - ko);
  4063. Vector3 direction = Vector3.Normalize(fVec - bVec);
  4064. //direction.z = 0.0f; // Keep it in the XY plane
  4065. direction.y = 0.0f; // Keep it in the XY plane
  4066. // Figure the size multiplier for the crotch angle
  4067. float dot = Vector3.Dot(bVec, fVec);
  4068. float angle, wsize1; //, wsize2;
  4069. if ( dot >= -0.9999939f )
  4070. angle = -Mathf.Acos(dot) / 2.0f;
  4071. else
  4072. angle = Mathf.PI * 0.5f;
  4073. float base1 = size1 / Mathf.Tan(angle);
  4074. float sign1 = (size1 < 0.0f) ? -1.0f : 1.0f;
  4075. wsize1 = Mathf.Sqrt(base1 * base1 + size1 * size1) * sign1;
  4076. //float base2 = size2 / Mathf.Tan(angle);
  4077. //float sign2 = (size2 < 0.0f) ? -1.0f : 1.0f;
  4078. //wsize2 = Mathf.Sqrt(base2 * base2 + size2 * size2) * sign2;
  4079. //Vector3 perp = new Vector3(direction.y * wsize1, -direction.x * wsize1, 0.0f);
  4080. Vector3 perp = new Vector3(direction.z * wsize1, 0.0f, -direction.x * wsize1);
  4081. float newInLength = CurveLength(inSpline, prevKnot, 0.5f, 1.0f, size1);
  4082. float newOutLength = CurveLength(inSpline, i, 0.0f, 0.5f, size1);
  4083. //Debug.Log("newlens " + newInLength + " " + newOutLength);
  4084. //Debug.Log("i " + i + " prev " + prevKnot);
  4085. Vector3 kn = ko + perp;
  4086. //Debug.Log("kn " + kn);
  4087. float inMult = newInLength / oldInLength;
  4088. float outMult = newOutLength / oldOutLength;
  4089. //MegaKnot k(knotType, LTYPE_CURVE, kn, kn + (inSpline.knots[i].invec - ko) * inMult, kn + (inSpline.knots[i].outvec - ko) * outMult);
  4090. outSpline.AddKnot(kn, kn + (inSpline.knots[i].invec - ko) * inMult, kn + (inSpline.knots[i].outvec - ko) * outMult);
  4091. //perp = new Vector3(direction.y * wsize2, -direction.x * wsize2, 0.0f);
  4092. ///perp = new Vector3(direction.z * wsize2, 0.0f, -direction.x * wsize2);
  4093. ///newInLength = CurveLength(inSpline, prevKnot, 0.5f, 1.0f, size2);
  4094. ///newOutLength = CurveLength(inSpline, i, 0.0f, 0.5f, size2);
  4095. ///kn = ko + perp;
  4096. ///inMult = newInLength / oldInLength;
  4097. ///outMult = newOutLength / oldOutLength;
  4098. //k = MegaKnot(knotType, LTYPE_CURVE, kn, kn + (inSpline.knots[i].invec - ko) * inMult, kn + (inSpline.knots[i].outvec - ko) * outMult);
  4099. ///outSpline2.AddKnot(kn, kn + (inSpline.knots[i].invec - ko) * inMult, kn + (inSpline.knots[i].outvec - ko) * outMult);
  4100. }
  4101. outSpline.closed = true;
  4102. //outSpline.ComputeBezPoints();
  4103. //*inSpline = outSpline;
  4104. ///outSpline2.closed = true;
  4105. //outSpline2->ComputeBezPoints();
  4106. ///shape.splines.Add(outSpline);
  4107. //shape.splines.Add(outSpline2);
  4108. ///shape.CalcLength(10);
  4109. }
  4110. else
  4111. { // Otherwise, we get one closed polygon
  4112. // Generate the outline polygon...
  4113. for ( i = 0; i < knots; ++i )
  4114. {
  4115. // Determine the angle of the curve at this knot
  4116. // Get vector from interp before knot to interp after knot
  4117. Vector3 direction;
  4118. Vector3 ko = inSpline.knots[i].p;
  4119. float oldInLength = (i == 0) ? 1.0f : CurveLength(inSpline, i - 1, 0.5f, 1.0f, 0.0f);
  4120. float oldOutLength = (i == (knots - 1)) ? 1.0f : CurveLength(inSpline, i, 0.0f, 0.5f, 0.0f);
  4121. float wsize1 = 0.0f;
  4122. if ( i == 0 )
  4123. {
  4124. direction = Vector3.Normalize(inSpline.InterpBezier3D(i, 0.01f) - ko);
  4125. wsize1 = size1;
  4126. }
  4127. else
  4128. {
  4129. if ( i == (knots - 1) )
  4130. {
  4131. direction = Vector3.Normalize(ko - inSpline.InterpBezier3D(i - 1, 0.99f));
  4132. wsize1 = size1;
  4133. }
  4134. else
  4135. {
  4136. Vector3 bVec = Vector3.Normalize(inSpline.InterpBezier3D(i - 1, 0.99f) - ko);
  4137. Vector3 fVec = Vector3.Normalize(inSpline.InterpBezier3D(i, 0.01f) - ko);
  4138. direction = Vector3.Normalize(fVec - bVec);
  4139. // Figure the size multiplier for the crotch angle
  4140. float dot = Vector3.Dot(bVec, fVec);
  4141. if ( dot >= -0.9999939f )
  4142. {
  4143. float angle = -Mathf.Acos(dot) / 2.0f;
  4144. float base1 = size1 / Mathf.Tan(angle);
  4145. float sign1 = (size1 < 0.0f) ? -1.0f : 1.0f;
  4146. wsize1 = Mathf.Sqrt(base1 * base1 + size1 * size1) * sign1;
  4147. }
  4148. else
  4149. {
  4150. wsize1 = size1;
  4151. }
  4152. }
  4153. }
  4154. //direction.z = 0.0f; // Keep it in the XY plane
  4155. //Vector3 perp = new Vector3(direction.y * wsize1, -direction.x * wsize1, 0.0f);
  4156. direction.y = 0.0f; // Keep it in the XY plane
  4157. Vector3 perp = new Vector3(direction.z * wsize1, 0.0f, -direction.x * wsize1);
  4158. float newInLength = (i == 0) ? 1.0f : CurveLength(inSpline, i - 1, 0.5f, 1.0f, size1);
  4159. float newOutLength = (i == (knots - 1)) ? 1.0f : CurveLength(inSpline, i, 0.0f, 0.5f, size1);
  4160. float inMult = newInLength / oldInLength;
  4161. float outMult = newOutLength / oldOutLength;
  4162. //int knotType = 0; //inSpline->GetKnotType(i);
  4163. Vector3 kn = ko + perp;
  4164. //MegaKnot k((i==0 || i==(knots-1)) ? KTYPE_BEZIER_CORNER : knotType, LTYPE_CURVE, kn, kn + (inSpline.knots[i].invec - ko) * inMult, kn + (inSpline.knots[i].outvec - ko) * outMult);
  4165. outSpline.AddKnot(kn, kn + (inSpline.knots[i].invec - ko) * inMult, kn + (inSpline.knots[i].outvec - ko) * outMult);
  4166. }
  4167. #if false
  4168. for ( i = knots - 1; i >= 0; --i )
  4169. {
  4170. // Determine the angle of the curve at this knot
  4171. // Get vector from interp before knot to interp after knot
  4172. Vector3 direction;
  4173. Vector3 ko = inSpline.knots[i].p; //->GetKnotPoint(i);
  4174. float oldInLength = (i == 0) ? 1.0f : CurveLength(inSpline, i - 1, 0.5f, 1.0f, 0.0f);
  4175. float oldOutLength = (i == (knots - 1)) ? 1.0f : CurveLength(inSpline, i, 0.0f, 0.5f, 0.0f);
  4176. float wsize2 = 0.0f;
  4177. if ( i == 0 )
  4178. {
  4179. direction = Vector3.Normalize(inSpline.InterpBezier3D(i, 0.01f) - ko);
  4180. wsize2 = size2;
  4181. }
  4182. else
  4183. {
  4184. if ( i == (knots - 1) )
  4185. {
  4186. direction = Vector3.Normalize(ko - inSpline.InterpBezier3D(i-1, 0.99f));
  4187. wsize2 = size2;
  4188. }
  4189. else
  4190. {
  4191. Vector3 bVec = Vector3.Normalize(inSpline.InterpBezier3D(i-1, 0.99f) - ko);
  4192. Vector3 fVec = Vector3.Normalize(inSpline.InterpBezier3D(i, 0.01f) - ko);
  4193. direction = Vector3.Normalize(fVec - bVec);
  4194. // Figure the size multiplier for the crotch angle
  4195. float dot = Vector3.Dot(bVec, fVec);
  4196. if ( dot >= -0.9999939f )
  4197. {
  4198. float angle = -Mathf.Acos(dot) / 2.0f;
  4199. float base2 = size2 / Mathf.Tan(angle);
  4200. float sign2 = (size2 < 0.0f) ? -1.0f : 1.0f;
  4201. wsize2 = Mathf.Sqrt(base2 * base2 + size2 * size2) * sign2;
  4202. }
  4203. else
  4204. {
  4205. wsize2 = size2;
  4206. }
  4207. }
  4208. }
  4209. //direction.z = 0.0f; // Keep it in the XY plane
  4210. //Vector3 perp = new Vector3(direction.y * wsize2, -direction.x * wsize2, 0.0f);
  4211. direction.y = 0.0f; // Keep it in the XY plane
  4212. Vector3 perp = new Vector3(direction.z * wsize2, 0.0f, -direction.x * wsize2);
  4213. float newInLength = (i == 0) ? 1.0f : CurveLength(inSpline, i - 1, 0.5f, 1.0f, size2);
  4214. float newOutLength = (i == (knots - 1)) ? 1.0f : CurveLength(inSpline, i, 0.0f, 0.5f, size2);
  4215. float inMult = newInLength / oldInLength;
  4216. float outMult = newOutLength / oldOutLength;
  4217. //int knotType = 0; //inSpline->GetKnotType(i);
  4218. Vector3 kn = ko + perp;
  4219. //MegaKnot k((i==0 || i==(knots-1)) ? KTYPE_BEZIER_CORNER : knotType, LTYPE_CURVE, kn, kn + (inSpline.knots[i].outvec - ko) * outMult, kn + (inSpline.knots[i].invec - ko) * inMult);
  4220. outSpline.AddKnot(kn, kn + (inSpline.knots[i].outvec - ko) * outMult, kn + (inSpline.knots[i].invec - ko) * inMult);
  4221. }
  4222. int lastPt = outSpline.knots.Count - 1;
  4223. outSpline.knots[0].invec = outSpline.knots[0].p; //(0, outSpline.GetKnotPoint(0));
  4224. outSpline.knots[lastPt].outvec = outSpline.knots[lastPt].p; //GetKnotPoint(lastPt));
  4225. outSpline.knots[knots].invec = outSpline.knots[knots].p; //GetKnotPoint(knots));
  4226. outSpline.knots[knots - 1].outvec = outSpline.knots[knots - 1].p; //GetKnotPoint(knots - 1));
  4227. outSpline.closed = true;
  4228. #endif
  4229. outSpline.closed = false;
  4230. }
  4231. }
  4232. #endif
  4233. // Conform
  4234. public bool conform = false;
  4235. public GameObject target;
  4236. public Collider conformCollider;
  4237. public float[] offsets;
  4238. public float[] last;
  4239. public float conformAmount = 1.0f;
  4240. public float raystartoff = 0.0f;
  4241. public float raydist = 10.0f;
  4242. public float conformOffset = 0.0f;
  4243. float minz = 0.0f;
  4244. public void SetTarget(GameObject targ)
  4245. {
  4246. target = targ;
  4247. if ( target )
  4248. {
  4249. conformCollider = target.GetComponent<Collider>();
  4250. }
  4251. }
  4252. void CalcBounds(Vector3[] verts)
  4253. {
  4254. minz = verts[0].y;
  4255. for ( int i = 1; i < verts.Length; i++ )
  4256. {
  4257. if ( verts[i].y < minz )
  4258. minz = verts[i].y;
  4259. }
  4260. }
  4261. public void InitConform(Vector3[] verts)
  4262. {
  4263. if ( offsets == null || offsets.Length != verts.Length )
  4264. {
  4265. offsets = new float[verts.Length];
  4266. last = new float[verts.Length];
  4267. for ( int i = 0; i < verts.Length; i++ )
  4268. offsets[i] = verts[i].y - minz;
  4269. }
  4270. // Only need to do this if target changes, move to SetTarget
  4271. if ( target )
  4272. {
  4273. //MeshFilter mf = target.GetComponent<MeshFilter>();
  4274. //targetMesh = mf.sharedMesh;
  4275. conformCollider = target.GetComponent<Collider>();
  4276. }
  4277. }
  4278. // We could do a bary centric thing if we grid up the bounds
  4279. void DoConform(Vector3[] verts)
  4280. {
  4281. InitConform(verts);
  4282. if ( target && conformCollider )
  4283. {
  4284. Matrix4x4 loctoworld = transform.localToWorldMatrix;
  4285. Matrix4x4 tm = loctoworld; // * worldtoloc;
  4286. Matrix4x4 invtm = tm.inverse;
  4287. Ray ray = new Ray();
  4288. RaycastHit hit;
  4289. float ca = conformAmount;
  4290. // When calculating alpha need to do caps sep
  4291. for ( int i = 0; i < verts.Length; i++ )
  4292. {
  4293. Vector3 origin = tm.MultiplyPoint(verts[i]);
  4294. origin.y += raystartoff;
  4295. ray.origin = origin;
  4296. ray.direction = Vector3.down;
  4297. //loftverts[i] = loftverts1[i];
  4298. if ( conformCollider.Raycast(ray, out hit, raydist) )
  4299. {
  4300. Vector3 lochit = invtm.MultiplyPoint(hit.point);
  4301. verts[i].y = Mathf.Lerp(verts[i].y, lochit.y + offsets[i] + conformOffset, ca); //conformAmount);
  4302. last[i] = verts[i].y;
  4303. }
  4304. else
  4305. {
  4306. Vector3 ht = ray.origin;
  4307. ht.y -= raydist;
  4308. verts[i].y = last[i]; //lochit.z + offsets[i] + offset;
  4309. }
  4310. }
  4311. }
  4312. else
  4313. {
  4314. }
  4315. }
  4316. public float conformWeight = 1.0f; // 1 is conform only this mesh, 0 only the target
  4317. // Option to conform terrain or mesh to mesh, slider to say how much of each happens
  4318. // so 0.5 would meet in the middle
  4319. void ConformTarget()
  4320. {
  4321. // We will need the vertex paint system as will need to find nearest point and have a falloff
  4322. }
  4323. }
  4324. // Need to find major axis and flatten to 2d, then revert back to 3d
  4325. #if true //!UNITY_FLASH
  4326. public class MegaTriangulator
  4327. {
  4328. static public List<Vector3> m_points = new List<Vector3>();
  4329. //public MegaTriangulator(MegaKnot[] points)
  4330. //{
  4331. // m_points = new List<Vector2>(); //points);
  4332. //
  4333. //}
  4334. static public List<int> Triangulate(MegaShape shape, MegaSpline spline, float dist, ref List<Vector3> verts, ref List<Vector2> uvs, ref List<int> indices, Vector3 pivot, ref Vector3 size)
  4335. {
  4336. // Find
  4337. m_points.Clear();
  4338. List<MegaKnot> knots = spline.knots;
  4339. Vector3 min = knots[0].p;
  4340. Vector3 max = knots[0].p;
  4341. for ( int i = 1; i < knots.Count; i++ )
  4342. {
  4343. Vector3 p1 = knots[i].p;
  4344. if ( p1.x < min.x ) min.x = p1.x;
  4345. if ( p1.y < min.y ) min.y = p1.y;
  4346. if ( p1.z < min.z ) min.z = p1.z;
  4347. if ( p1.x > max.x ) max.x = p1.x;
  4348. if ( p1.y > max.y ) max.y = p1.y;
  4349. if ( p1.z > max.z ) max.z = p1.z;
  4350. }
  4351. size = max - min;
  4352. int removeaxis = 0;
  4353. if ( Mathf.Abs(size.x) < Mathf.Abs(size.y) )
  4354. {
  4355. if ( Mathf.Abs(size.x) < Mathf.Abs(size.z) )
  4356. removeaxis = 0;
  4357. else
  4358. removeaxis = 2;
  4359. }
  4360. else
  4361. {
  4362. if ( Mathf.Abs(size.y) < Mathf.Abs(size.z) )
  4363. removeaxis = 1;
  4364. else
  4365. removeaxis = 2;
  4366. }
  4367. Vector3 tp = Vector3.zero;
  4368. #if false
  4369. for ( int i = 0; i < knots.Count; i++ )
  4370. {
  4371. for ( int a = 0; a < steps; a ++ )
  4372. {
  4373. float alpha = (float)a / (float)steps;
  4374. Vector3 p = spline.knots[i].Interpolate(alpha, spline.knots[i]);
  4375. switch ( removeaxis )
  4376. {
  4377. case 0: tp.x = p.y; tp.y = p.z; break;
  4378. case 1: tp.x = p.x; tp.y = p.z; break;
  4379. case 2: tp.x = p.x; tp.y = p.y; break;
  4380. }
  4381. verts.Add(p);
  4382. m_points.Add(tp);
  4383. }
  4384. }
  4385. #endif
  4386. float ds = spline.length / (spline.length / dist);
  4387. if ( ds > spline.length )
  4388. ds = spline.length;
  4389. //int c = 0;
  4390. int k = -1;
  4391. //int lk = -1;
  4392. //Vector3 first = spline.Interpolate(0.0f, shape.normalizedInterp, ref lk);
  4393. Vector3 p = Vector3.zero;
  4394. for ( float dst = 0.0f; dst < spline.length; dst += ds )
  4395. {
  4396. float alpha = dst / spline.length;
  4397. p = spline.Interpolate(alpha, shape.normalizedInterp, ref k) + pivot;
  4398. switch ( removeaxis )
  4399. {
  4400. case 0: tp.x = p.y; tp.y = p.z; break;
  4401. case 1: tp.x = p.x; tp.y = p.z; break;
  4402. case 2: tp.x = p.x; tp.y = p.y; break;
  4403. }
  4404. tp.z = dst;
  4405. verts.Add(p);
  4406. m_points.Add(tp);
  4407. // Dont need this here as can do in post step
  4408. //tp.x = (tp.x - min.x) / size.x;
  4409. //tp.y = (tp.y - min.z) / size.z;
  4410. tp.x = (tp.x - min.x); // / size.x;
  4411. tp.y = (tp.y - min.z); // / size.z;
  4412. uvs.Add(tp);
  4413. }
  4414. //if ( spline.closed )
  4415. // p = spline.Interpolate(0.0f, shape.normalizedInterp, ref k);
  4416. //else
  4417. // p = spline.Interpolate(1.0f, shape.normalizedInterp, ref k);
  4418. //switch ( removeaxis )
  4419. //{
  4420. // case 0: tp.x = p.y; tp.y = p.z; break;
  4421. // case 1: tp.x = p.x; tp.y = p.z; break;
  4422. // case 2: tp.x = p.x; tp.y = p.y; break;
  4423. //}
  4424. //verts.Add(p);
  4425. //m_points.Add(tp);
  4426. return Triangulate(indices);
  4427. }
  4428. static public List<int> Triangulate(List<int> indices)
  4429. {
  4430. //List<int> indices = new List<int>();
  4431. int n = m_points.Count;
  4432. if ( n < 3 )
  4433. return indices; //.ToArray();
  4434. int[] V = new int[n];
  4435. if ( Area() > 0.0f )
  4436. {
  4437. for ( int v = 0; v < n; v++ )
  4438. V[v] = v;
  4439. }
  4440. else
  4441. {
  4442. for ( int v = 0; v < n; v++ )
  4443. V[v] = (n - 1) - v;
  4444. }
  4445. int nv = n;
  4446. int count = 2 * nv;
  4447. for ( int m = 0, v = nv - 1; nv > 2; )
  4448. {
  4449. if ( (count--) <= 0 )
  4450. return indices; //.ToArray();
  4451. int u = v;
  4452. if ( nv <= u )
  4453. u = 0;
  4454. v = u + 1;
  4455. if ( nv <= v )
  4456. v = 0;
  4457. int w = v + 1;
  4458. if ( nv <= w )
  4459. w = 0;
  4460. if ( Snip(u, v, w, nv, V) )
  4461. {
  4462. int a, b, c, s, t;
  4463. a = V[u];
  4464. b = V[v];
  4465. c = V[w];
  4466. indices.Add(c);
  4467. indices.Add(b);
  4468. indices.Add(a);
  4469. m++;
  4470. for ( s = v, t = v + 1; t < nv; s++, t++ )
  4471. V[s] = V[t];
  4472. nv--;
  4473. count = 2 * nv;
  4474. }
  4475. }
  4476. //indices.Reverse();
  4477. return indices; //.ToArray();
  4478. }
  4479. static private float Area()
  4480. {
  4481. int n = m_points.Count;
  4482. float A = 0.0f;
  4483. for ( int p = n - 1, q = 0; q < n; p = q++ )
  4484. {
  4485. Vector2 pval = m_points[p];
  4486. Vector2 qval = m_points[q];
  4487. A += pval.x * qval.y - qval.x * pval.y;
  4488. }
  4489. return A * 0.5f;
  4490. }
  4491. static private bool Snip(int u, int v, int w, int n, int[] V)
  4492. {
  4493. Vector2 A = m_points[V[u]];
  4494. Vector2 B = m_points[V[v]];
  4495. Vector2 C = m_points[V[w]];
  4496. if ( Mathf.Epsilon > (((B.x - A.x) * (C.y - A.y)) - ((B.y - A.y) * (C.x - A.x))) )
  4497. return false;
  4498. for ( int p = 0; p < n; p++ )
  4499. {
  4500. if ( (p == u) || (p == v) || (p == w) )
  4501. continue;
  4502. Vector2 P = m_points[V[p]];
  4503. if ( InsideTriangle(A, B, C, P) )
  4504. return false;
  4505. }
  4506. return true;
  4507. }
  4508. static private bool InsideTriangle(Vector2 A, Vector2 B, Vector2 C, Vector2 P)
  4509. {
  4510. float ax = C.x - B.x;
  4511. float ay = C.y - B.y;
  4512. float bx = A.x - C.x;
  4513. float by = A.y - C.y;
  4514. float cx = B.x - A.x;
  4515. float cy = B.y - A.y;
  4516. float apx = P.x - A.x;
  4517. float apy = P.y - A.y;
  4518. float bpx = P.x - B.x;
  4519. float bpy = P.y - B.y;
  4520. float cpx = P.x - C.x;
  4521. float cpy = P.y - C.y;
  4522. float aCROSSbp = ax * bpy - ay * bpx;
  4523. float cCROSSap = cx * apy - cy * apx;
  4524. float bCROSScp = bx * cpy - by * cpx;
  4525. return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f));
  4526. }
  4527. }
  4528. #endif