MegaShape.cs 126 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400
  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. }
  1305. public enum MeshShapeType
  1306. {
  1307. Fill, // options, height, doublesided
  1308. Tube, // sides, cap ends, start, end, step
  1309. Box,
  1310. Ribbon,
  1311. //Line, // height, rotate, offset, segments for height
  1312. //Lathe, // segs
  1313. }
  1314. [ExecuteInEditMode]
  1315. public class MegaShape : MonoBehaviour
  1316. {
  1317. public MegaAxis axis = MegaAxis.Y;
  1318. public Color col1 = new Color(1.0f, 1.0f, 1.0f, 1.0f);
  1319. public Color col2 = new Color(0.1f, 0.1f, 0.1f, 1.0f);
  1320. public Color KnotCol = new Color(0.0f, 1.0f, 0.0f, 1.0f);
  1321. public Color HandleCol = new Color(1.0f, 0.0f, 0.0f, 1.0f);
  1322. public Color VecCol = new Color(0.1f, 0.1f, 0.2f, 0.5f);
  1323. public float KnotSize = 10.0f;
  1324. public float stepdist = 1.0f; // Distance along whole shape
  1325. public bool normalizedInterp = true;
  1326. public bool drawHandles = false;
  1327. public bool drawKnots = true;
  1328. public bool drawspline = true;
  1329. public bool drawTwist = false;
  1330. public bool lockhandles = true;
  1331. public bool showorigin = true;
  1332. public bool usesnap = false;
  1333. public bool usesnaphandles = false;
  1334. public Vector3 snap = Vector3.one;
  1335. public MegaHandleType handleType = MegaHandleType.Position;
  1336. public float CursorPos = 0.0f;
  1337. public List<MegaSpline> splines = new List<MegaSpline>();
  1338. public bool showanimations = false;
  1339. public float keytime = 0.0f;
  1340. public bool updateondrag = true;
  1341. // Lightmap
  1342. public float angleError = 0.08f;
  1343. public float areaError = 0.15f;
  1344. public float hardAngle = 88.0f;
  1345. public float packMargin = 0.0039f;
  1346. //public virtual void MakeShape() { }
  1347. public float defRadius = 1.0f;
  1348. public bool smoothonaddknot = true;
  1349. const float CIRCLE_VECTOR_LENGTH = 0.5517861843f;
  1350. public virtual void MakeShape()
  1351. {
  1352. Matrix4x4 tm = GetMatrix();
  1353. float vector = CIRCLE_VECTOR_LENGTH * defRadius;
  1354. MegaSpline spline = NewSpline();
  1355. for ( int ix = 0; ix < 4; ++ix )
  1356. {
  1357. float angle = (Mathf.PI * 2.0f) * (float)ix / (float)4;
  1358. float sinfac = Mathf.Sin(angle);
  1359. float cosfac = Mathf.Cos(angle);
  1360. Vector3 p = new Vector3(cosfac * defRadius, sinfac * defRadius, 0.0f);
  1361. Vector3 rotvec = new Vector3(sinfac * vector, -cosfac * vector, 0.0f);
  1362. spline.AddKnot(p, p + rotvec, p - rotvec, tm);
  1363. }
  1364. spline.closed = true;
  1365. CalcLength(); //10);
  1366. }
  1367. //public List<MegaKnotAnim> animations;
  1368. public float testtime = 0.0f;
  1369. public float time = 0.0f;
  1370. public bool animate;
  1371. public float speed = 1.0f;
  1372. public int selcurve = 0;
  1373. public bool imported = false;
  1374. //public int CurrentCurve = 0;
  1375. //public int CursorKnot = 0;
  1376. public float CursorPercent = 0.0f;
  1377. public virtual string GetHelpURL() { return "?page_id=390"; }
  1378. [ContextMenu("Help")]
  1379. public void Help()
  1380. {
  1381. Application.OpenURL("http://www.west-racing.com/mf/" + GetHelpURL());
  1382. }
  1383. [ContextMenu("Reset Mesh Info")]
  1384. public void ResetMesh()
  1385. {
  1386. shapemesh = null;
  1387. BuildMesh();
  1388. }
  1389. public Matrix4x4 GetMatrix()
  1390. {
  1391. Matrix4x4 tm = Matrix4x4.identity;
  1392. switch ( axis )
  1393. {
  1394. case MegaAxis.X: MegaMatrix.RotateY(ref tm, -Mathf.PI * 0.5f);
  1395. MegaMatrix.Scale(ref tm, -Vector3.one, false);
  1396. break;
  1397. //case MegaAxis.X: MegaMatrix.RotateY(ref tm, Mathf.PI * 0.5f); break;
  1398. case MegaAxis.Y: MegaMatrix.RotateX(ref tm, Mathf.PI * 0.5f); break;
  1399. case MegaAxis.Z: break; //Matrix.RotateY(ref tm, Mathf.PI * 0.5f); break;
  1400. }
  1401. return tm;
  1402. }
  1403. public void CopyIDS(int curve)
  1404. {
  1405. if ( curve > 0 && curve < splines.Count )
  1406. {
  1407. MegaSpline tospl = splines[curve];
  1408. MegaSpline fromspl = splines[curve - 1];
  1409. for ( int i = 0; i < fromspl.knots.Count && i < tospl.knots.Count; i++ )
  1410. {
  1411. tospl.knots[i].id = fromspl.knots[i].id;
  1412. }
  1413. }
  1414. }
  1415. public void Reverse(int c)
  1416. {
  1417. if ( c >= 0 && c < splines.Count )
  1418. {
  1419. splines[c].Reverse();
  1420. }
  1421. }
  1422. public void SetHeight(int c, float y)
  1423. {
  1424. if ( c >= 0 && c < splines.Count )
  1425. {
  1426. splines[c].SetHeight(y);
  1427. }
  1428. }
  1429. public void SetTwist(int c, float twist)
  1430. {
  1431. if ( c >= 0 && c < splines.Count )
  1432. {
  1433. splines[c].SetTwist(twist);
  1434. }
  1435. }
  1436. // Should be in MegaShape
  1437. public MegaSpline NewSpline()
  1438. {
  1439. if ( splines.Count == 0 )
  1440. {
  1441. MegaSpline newspline = new MegaSpline();
  1442. splines.Add(newspline);
  1443. }
  1444. MegaSpline spline = splines[0];
  1445. spline.knots.Clear();
  1446. spline.closed = false;
  1447. return spline;
  1448. }
  1449. void Reset()
  1450. {
  1451. MakeShape();
  1452. }
  1453. void Awake()
  1454. {
  1455. if ( splines.Count == 0 )
  1456. {
  1457. MakeShape();
  1458. }
  1459. }
  1460. float t = 0.0f;
  1461. public float MaxTime = 1.0f;
  1462. public MegaRepeatMode LoopMode;
  1463. public bool dolateupdate = false;
  1464. void Update()
  1465. {
  1466. if ( !dolateupdate )
  1467. {
  1468. DoUpdate();
  1469. }
  1470. }
  1471. void LateUpdate()
  1472. {
  1473. if ( dolateupdate )
  1474. {
  1475. DoUpdate();
  1476. }
  1477. }
  1478. void DoUpdate()
  1479. {
  1480. if ( animate )
  1481. {
  1482. BuildMesh();
  1483. if ( Application.isPlaying )
  1484. time += Time.deltaTime * speed;
  1485. switch ( LoopMode )
  1486. {
  1487. case MegaRepeatMode.Loop: t = Mathf.Repeat(time, MaxTime); break;
  1488. case MegaRepeatMode.PingPong: t = Mathf.PingPong(time, MaxTime); break;
  1489. case MegaRepeatMode.Clamp: t = Mathf.Clamp(time, 0.0f, MaxTime); break;
  1490. }
  1491. for ( int s = 0; s < splines.Count; s++ )
  1492. {
  1493. if ( splines[s].splineanim != null && splines[s].splineanim.Enabled && splines[s].splineanim.NumKeys() > 1 )
  1494. {
  1495. //Debug.Log("getstate");
  1496. splines[s].splineanim.GetState1(splines[s], t);
  1497. splines[s].CalcLength(); //(10); // could use less here
  1498. }
  1499. else
  1500. {
  1501. if ( splines[s].animations != null && splines[s].animations.Count > 0 )
  1502. {
  1503. for ( int i = 0; i < splines[s].animations.Count; i++ )
  1504. {
  1505. Vector3 pos = splines[s].animations[i].con.GetVector3(t);
  1506. switch ( splines[s].animations[i].t )
  1507. {
  1508. case 0: splines[splines[s].animations[i].s].knots[splines[s].animations[i].p].invec = pos; break;
  1509. case 1: splines[splines[s].animations[i].s].knots[splines[s].animations[i].p].p = pos; break;
  1510. case 2: splines[splines[s].animations[i].s].knots[splines[s].animations[i].p].outvec = pos; break;
  1511. }
  1512. }
  1513. splines[s].CalcLength(); //(10); // could use less here
  1514. }
  1515. }
  1516. }
  1517. }
  1518. // Options here:
  1519. // Uv scale, offset, rotate, physuv, genuv
  1520. // Optimize
  1521. // recalcnorms
  1522. // tangents
  1523. // fill in shape
  1524. // pipe along shape
  1525. // wall along shape
  1526. // double sided
  1527. // extrude on fill
  1528. //BuildMesh();
  1529. #if false
  1530. if ( makeMesh )
  1531. {
  1532. //makeMesh = false;
  1533. List<Vector3> verts = new List<Vector3>();
  1534. List<Vector2> uvs = new List<Vector2>();
  1535. float sdist = stepdist * 0.1f;
  1536. if ( splines[0].length / sdist > 1500.0f )
  1537. sdist = splines[0].length / 1500.0f;
  1538. int[] tris = MegaTriangulator.Triangulate(this, splines[0], sdist, ref verts, ref uvs);
  1539. if ( shapemesh == null )
  1540. {
  1541. MeshFilter mf = gameObject.GetComponent<MeshFilter>();
  1542. if ( mf == null )
  1543. mf = gameObject.AddComponent<MeshFilter>();
  1544. mf.sharedMesh = new Mesh();
  1545. MeshRenderer mr = gameObject.GetComponent<MeshRenderer>();
  1546. if ( mr == null )
  1547. {
  1548. mr = gameObject.AddComponent<MeshRenderer>();
  1549. }
  1550. Material[] mats = new Material[1];
  1551. mr.sharedMaterials = mats;
  1552. shapemesh = mf.sharedMesh; //Utils.GetMesh(gameObject);
  1553. }
  1554. //Vector3[] verts = new Vector3[splines[0].knots.Count];
  1555. //for ( int i = 0; i < splines[0].knots.Count; i++ )
  1556. //{
  1557. // verts[i] = splines[0].knots[i].p;
  1558. //}
  1559. shapemesh.Clear();
  1560. shapemesh.vertices = verts.ToArray();
  1561. shapemesh.uv = uvs.ToArray();
  1562. shapemesh.triangles = tris;
  1563. shapemesh.RecalculateNormals();
  1564. shapemesh.RecalculateBounds();
  1565. }
  1566. #endif
  1567. }
  1568. // Meshing options
  1569. public bool makeMesh = false;
  1570. public MeshShapeType meshType = MeshShapeType.Fill;
  1571. public bool DoubleSided = true;
  1572. public bool CalcTangents = false;
  1573. public bool GenUV = true;
  1574. public bool PhysUV = false;
  1575. public float Height = 0.0f;
  1576. public int HeightSegs = 1;
  1577. public int Sides = 4;
  1578. public float TubeStep = 0.1f;
  1579. public float Start = 0.0f;
  1580. public float End = 100.0f;
  1581. public float Rotate = 0.0f;
  1582. public Vector3 Pivot = Vector3.zero;
  1583. // Material 1
  1584. public Vector2 UVOffset = Vector2.zero;
  1585. public Vector2 UVRotate = Vector2.zero;
  1586. public Vector2 UVScale = Vector2.one;
  1587. public Vector2 UVOffset1 = Vector2.zero;
  1588. public Vector2 UVRotate1 = Vector2.zero;
  1589. public Vector2 UVScale1 = Vector2.one;
  1590. public Vector2 UVOffset2 = Vector2.zero;
  1591. public Vector2 UVRotate3 = Vector2.zero;
  1592. public Vector2 UVScale3 = Vector2.one;
  1593. public bool autosmooth = false;
  1594. public float smoothness = 0.75f;
  1595. public bool flipNormals = false;
  1596. public MegaShapeBezComputeMode smoothMode = MegaShapeBezComputeMode.Old;
  1597. public bool smoothOnDrag = false;
  1598. public bool freezeX = false;
  1599. public bool freezeY = false;
  1600. public bool freezeZ = false;
  1601. // TODO:
  1602. // Pivot
  1603. // UV info per submesh
  1604. // work on multiple splines
  1605. // new poly to tri to handle holes
  1606. // merge to one mesh
  1607. // height segs
  1608. public Material mat1;
  1609. public Material mat2;
  1610. public Material mat3;
  1611. public bool UseHeightCurve = false;
  1612. public AnimationCurve heightCrv = new AnimationCurve(new Keyframe(0, 1), new Keyframe(1, 1));
  1613. public float heightOff = 0.0f;
  1614. // May need wall UV info as well
  1615. public Mesh shapemesh;
  1616. // New equal step system for faster interps etc
  1617. #if false
  1618. //Create table to convert u to distance
  1619. std::pair<float, float> u_distance_map[LENGTH_DIVISIONS + 1];
  1620. //Calculate u value and distance map
  1621. public void CreateDistMap(int divs)
  1622. {
  1623. for ( int i = 0; i <= divs; i++ )
  1624. {
  1625. float u = (float)i / (float)divs;
  1626. u_distance_map[i].first = u;
  1627. u_distance_map[i].second = track_path->Get_Path_Length(u);
  1628. }
  1629. //Determine the u values of the ties
  1630. std::vector<float> tie_u_values;
  1631. for ( int i = 0; i < num_ties; i++ )
  1632. {
  1633. bool found = false;
  1634. for ( int j = 1; j <= divs && !found; j++ )
  1635. {
  1636. /*The correct u value is less than this distance and greater than the last
  1637. so just interpolate from here.*/
  1638. if ( u_distance_map[j].second >= (i + 1) * tie_distance )
  1639. {
  1640. //Calculate percentage between u values
  1641. float distance_between_nodes = u_distance_map[j].second - u_distance_map[j - 1].second;
  1642. float distance_past_previous = ((i + 1) * tie_distance) - u_distance_map[j - 1].second;
  1643. float percent = distance_past_previous / distance_between_nodes;
  1644. //Calculate u value
  1645. float u = ((u_distance_map[j].first - u_distance_map[j - 1].first) * percent) + u_distance_map[j - 1].first;
  1646. found = true;
  1647. tie_u_values.push_back(u);
  1648. }
  1649. }
  1650. }
  1651. }
  1652. #endif
  1653. public void Centre(float scale, Vector3 axis)
  1654. {
  1655. Vector3 p = Vector3.zero;
  1656. int count = 0;
  1657. for ( int s = 0; s < splines.Count; s++ )
  1658. {
  1659. count += splines[s].knots.Count;
  1660. for ( int i = 0; i < splines[s].knots.Count; i++ )
  1661. p += splines[s].knots[i].p;
  1662. }
  1663. p /= (float)count; //knots.Count;
  1664. for ( int s = 0; s < splines.Count; s++ )
  1665. {
  1666. for ( int i = 0; i < splines[s].knots.Count; i++ )
  1667. {
  1668. splines[s].knots[i].p -= p;
  1669. splines[s].knots[i].invec -= p;
  1670. splines[s].knots[i].outvec -= p;
  1671. splines[s].knots[i].p *= scale;
  1672. splines[s].knots[i].invec *= scale;
  1673. splines[s].knots[i].outvec *= scale;
  1674. splines[s].knots[i].p = Vector3.Scale(splines[s].knots[i].p, axis);
  1675. splines[s].knots[i].invec = Vector3.Scale(splines[s].knots[i].invec, axis);
  1676. splines[s].knots[i].outvec = Vector3.Scale(splines[s].knots[i].outvec, axis);
  1677. }
  1678. }
  1679. }
  1680. public void Centre(float scale, Vector3 axis, int start)
  1681. {
  1682. Vector3 p = Vector3.zero;
  1683. int count = 0;
  1684. for ( int s = start; s < splines.Count; s++ )
  1685. {
  1686. count += splines[s].knots.Count;
  1687. for ( int i = 0; i < splines[s].knots.Count; i++ )
  1688. p += splines[s].knots[i].p;
  1689. }
  1690. p /= (float)count; //knots.Count;
  1691. for ( int s = start; s < splines.Count; s++ )
  1692. {
  1693. for ( int i = 0; i < splines[s].knots.Count; i++ )
  1694. {
  1695. splines[s].knots[i].p -= p;
  1696. splines[s].knots[i].invec -= p;
  1697. splines[s].knots[i].outvec -= p;
  1698. splines[s].knots[i].p *= scale;
  1699. splines[s].knots[i].invec *= scale;
  1700. splines[s].knots[i].outvec *= scale;
  1701. splines[s].knots[i].p = Vector3.Scale(splines[s].knots[i].p, axis);
  1702. splines[s].knots[i].invec = Vector3.Scale(splines[s].knots[i].invec, axis);
  1703. splines[s].knots[i].outvec = Vector3.Scale(splines[s].knots[i].outvec, axis);
  1704. }
  1705. }
  1706. }
  1707. public void CoordAdjust(float scale, Vector3 axis, int start)
  1708. {
  1709. for ( int s = start; s < splines.Count; s++ )
  1710. {
  1711. for ( int i = 0; i < splines[s].knots.Count; i++ )
  1712. {
  1713. splines[s].knots[i].p *= scale;
  1714. splines[s].knots[i].invec *= scale;
  1715. splines[s].knots[i].outvec *= scale;
  1716. splines[s].knots[i].p = Vector3.Scale(splines[s].knots[i].p, axis);
  1717. splines[s].knots[i].invec = Vector3.Scale(splines[s].knots[i].invec, axis);
  1718. splines[s].knots[i].outvec = Vector3.Scale(splines[s].knots[i].outvec, axis);
  1719. }
  1720. }
  1721. }
  1722. // Need a scale method?
  1723. public void Scale(float scale)
  1724. {
  1725. for ( int i = 0; i < splines.Count; i++ )
  1726. {
  1727. for ( int k = 0; k < splines[i].knots.Count; k++ )
  1728. {
  1729. splines[i].knots[k].invec *= scale;
  1730. splines[i].knots[k].p *= scale;
  1731. splines[i].knots[k].outvec *= scale;
  1732. }
  1733. if ( splines[i].animations != null )
  1734. {
  1735. for ( int a = 0; a < splines[i].animations.Count; a++ )
  1736. {
  1737. if ( splines[i].animations[a].con != null )
  1738. splines[i].animations[a].con.Scale(scale);
  1739. }
  1740. }
  1741. }
  1742. CalcLength(); //(10);
  1743. }
  1744. public void Scale(float scale, int start)
  1745. {
  1746. for ( int i = start; i < splines.Count; i++ )
  1747. {
  1748. for ( int k = 0; k < splines[i].knots.Count; k++ )
  1749. {
  1750. splines[i].knots[k].invec *= scale;
  1751. splines[i].knots[k].p *= scale;
  1752. splines[i].knots[k].outvec *= scale;
  1753. }
  1754. if ( splines[i].animations != null )
  1755. {
  1756. for ( int a = 0; a < splines[i].animations.Count; a++ )
  1757. {
  1758. if ( splines[i].animations[a].con != null )
  1759. splines[i].animations[a].con.Scale(scale);
  1760. }
  1761. }
  1762. }
  1763. CalcLength(); //(10);
  1764. }
  1765. public void Scale(Vector3 scale)
  1766. {
  1767. for ( int i = 0; i < splines.Count; i++ )
  1768. {
  1769. for ( int k = 0; k < splines[i].knots.Count; k++ )
  1770. {
  1771. splines[i].knots[k].invec.x *= scale.x;
  1772. splines[i].knots[k].invec.y *= scale.y;
  1773. splines[i].knots[k].invec.z *= scale.z;
  1774. splines[i].knots[k].p.x *= scale.x;
  1775. splines[i].knots[k].p.y *= scale.y;
  1776. splines[i].knots[k].p.z *= scale.z;
  1777. splines[i].knots[k].outvec.x *= scale.x;
  1778. splines[i].knots[k].outvec.y *= scale.y;
  1779. splines[i].knots[k].outvec.z *= scale.z;
  1780. }
  1781. if ( splines[i].animations != null )
  1782. {
  1783. for ( int a = 0; a < splines[i].animations.Count; a++ )
  1784. {
  1785. if ( splines[i].animations[a].con != null )
  1786. splines[i].animations[a].con.Scale(scale);
  1787. }
  1788. }
  1789. }
  1790. CalcLength(); //(10);
  1791. }
  1792. public void MoveSpline(Vector3 delta)
  1793. {
  1794. for ( int i = 0; i < splines.Count; i++ )
  1795. {
  1796. MoveSpline(delta, i, false);
  1797. }
  1798. CalcLength(); //(10);
  1799. }
  1800. public void MoveSpline(Vector3 delta, int c, bool calc)
  1801. {
  1802. for ( int k = 0; k < splines[c].knots.Count; k++ )
  1803. {
  1804. splines[c].knots[k].invec += delta;
  1805. splines[c].knots[k].p += delta;
  1806. splines[c].knots[k].outvec += delta;
  1807. }
  1808. if ( splines[c].animations != null )
  1809. {
  1810. for ( int a = 0; a < splines[c].animations.Count; a++ )
  1811. {
  1812. if ( splines[c].animations[a].con != null )
  1813. splines[c].animations[a].con.Move(delta);
  1814. }
  1815. }
  1816. if ( calc )
  1817. CalcLength(c); //(10);
  1818. }
  1819. public void RotateSpline(Vector3 rot, int c, bool calc)
  1820. {
  1821. Matrix4x4 tm = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(rot), Vector3.one);
  1822. for ( int k = 0; k < splines[c].knots.Count; k++ )
  1823. {
  1824. splines[c].knots[k].invec = tm.MultiplyPoint3x4(splines[c].knots[k].invec);
  1825. splines[c].knots[k].outvec = tm.MultiplyPoint3x4(splines[c].knots[k].outvec);
  1826. splines[c].knots[k].p = tm.MultiplyPoint3x4(splines[c].knots[k].p);
  1827. }
  1828. if ( splines[c].animations != null )
  1829. {
  1830. for ( int a = 0; a < splines[c].animations.Count; a++ )
  1831. {
  1832. if ( splines[c].animations[a].con != null )
  1833. splines[c].animations[a].con.Rotate(tm);
  1834. }
  1835. }
  1836. if ( calc )
  1837. CalcLength(c); //(10);
  1838. }
  1839. public int GetSpline(int p, ref MegaKnotAnim ma) //int spl, ref int sp, ref int pt)
  1840. {
  1841. int index = 0;
  1842. int pn = p / 3;
  1843. for ( int i = 0; i < splines.Count; i++ )
  1844. {
  1845. int nx = index + splines[i].knots.Count;
  1846. if ( pn < nx )
  1847. {
  1848. ma.s = i;
  1849. ma.p = pn - index;
  1850. ma.t = p % 3;
  1851. return i;
  1852. }
  1853. index = nx;
  1854. }
  1855. Debug.Log("Cant find point in spline");
  1856. return 0;
  1857. }
  1858. public float GetCurveLength(int curve)
  1859. {
  1860. if ( curve < splines.Count )
  1861. return splines[curve].length;
  1862. return splines[0].length;
  1863. }
  1864. public float CalcLength(int curve, int step)
  1865. {
  1866. if ( curve < splines.Count )
  1867. return splines[curve].CalcLength(step);
  1868. return 0.0f;
  1869. }
  1870. //public float CalcLength(int curve)
  1871. //{
  1872. // if ( curve < splines.Count )
  1873. // return splines[curve].CalcLength();
  1874. // return 0.0f;
  1875. //}
  1876. [ContextMenu("Recalc Length")]
  1877. public void ReCalcLength()
  1878. {
  1879. CalcLength(); //10);
  1880. }
  1881. //public float CalcLength(int step)
  1882. //{
  1883. // float length = 0.0f;
  1884. // for ( int i = 0; i < splines.Count; i++ )
  1885. // length += CalcLength(i, step);
  1886. // return length;
  1887. //}
  1888. public float CalcLength()
  1889. {
  1890. float length = 0.0f;
  1891. for ( int i = 0; i < splines.Count; i++ )
  1892. length += splines[i].CalcLength();
  1893. return length;
  1894. }
  1895. public float CalcLength(int curve)
  1896. {
  1897. return splines[curve].CalcLength();
  1898. }
  1899. public Vector3 GetKnotPos(int curve, int knot)
  1900. {
  1901. return splines[curve].knots[knot].p;
  1902. }
  1903. public Vector3 GetKnotInVec(int curve, int knot)
  1904. {
  1905. return splines[curve].knots[knot].invec;
  1906. }
  1907. public Vector3 GetKnotOutVec(int curve, int knot)
  1908. {
  1909. return splines[curve].knots[knot].outvec;
  1910. }
  1911. public void SetKnotPos(int curve, int knot, Vector3 p)
  1912. {
  1913. splines[curve].knots[knot].p = p;
  1914. CalcLength(); //10);
  1915. }
  1916. public void SetKnot(int curve, int knot, Vector3 p, Vector3 intan, Vector3 outtan)
  1917. {
  1918. splines[curve].knots[knot].p = p;
  1919. splines[curve].knots[knot].invec = intan;
  1920. splines[curve].knots[knot].outvec = outtan;
  1921. CalcLength(); //10);
  1922. }
  1923. public void SetHandles(int curve, int knot, Vector3 intan, Vector3 outtan)
  1924. {
  1925. splines[curve].knots[knot].invec = splines[curve].knots[knot].p + intan;
  1926. splines[curve].knots[knot].outvec = splines[curve].knots[knot].p + outtan;
  1927. CalcLength(); //10);
  1928. }
  1929. public void MoveKnot(int curve, int knot, Vector3 p)
  1930. {
  1931. Vector3 delta = p - splines[curve].knots[knot].p;
  1932. splines[curve].knots[knot].p = p;
  1933. splines[curve].knots[knot].invec += delta;
  1934. splines[curve].knots[knot].outvec += delta;
  1935. CalcLength();
  1936. }
  1937. public Quaternion GetRotate(int curve, float alpha)
  1938. {
  1939. Vector3 p = InterpCurve3D(curve, alpha, normalizedInterp);
  1940. Vector3 p1 = InterpCurve3D(curve, alpha + 0.001f, normalizedInterp);
  1941. return Quaternion.LookRotation(p - p1);
  1942. }
  1943. public Vector3 InterpCurve3D(int curve, float alpha, bool type)
  1944. {
  1945. Vector3 ret;
  1946. int k = 0;
  1947. if ( curve < splines.Count )
  1948. {
  1949. if ( alpha < 0.0f )
  1950. {
  1951. if ( splines[curve].closed )
  1952. alpha = Mathf.Repeat(alpha, 1.0f);
  1953. else
  1954. {
  1955. Vector3 ps = splines[curve].Interpolate(0.0f, type, ref k);
  1956. // Need a proper tangent function
  1957. Vector3 ps1 = splines[curve].Interpolate(0.01f, type, ref k);
  1958. // Calc the spline in out vecs
  1959. Vector3 delta = ps1 - ps;
  1960. delta.Normalize();
  1961. return ps + ((splines[curve].length * alpha) * delta);
  1962. }
  1963. }
  1964. else
  1965. {
  1966. if ( alpha > 1.0f )
  1967. {
  1968. if ( splines[curve].closed )
  1969. alpha = alpha % 1.0f;
  1970. else
  1971. {
  1972. Vector3 ps = splines[curve].Interpolate(1.0f, type, ref k);
  1973. // Need a proper tangent function
  1974. Vector3 ps1 = splines[curve].Interpolate(0.99f, type, ref k);
  1975. // Calc the spline in out vecs
  1976. Vector3 delta = ps1 - ps;
  1977. delta.Normalize();
  1978. return ps + ((splines[curve].length * (1.0f - alpha)) * delta);
  1979. }
  1980. }
  1981. }
  1982. ret = splines[curve].Interpolate(alpha, type, ref k);
  1983. }
  1984. else
  1985. {
  1986. if ( splines == null || splines.Count == 0 )
  1987. return Vector3.zero;
  1988. ret = splines[0].Interpolate(1.0f, type, ref k);
  1989. }
  1990. return ret;
  1991. }
  1992. public Vector3 InterpCurve3D(int curve, float alpha, bool type, ref float twist)
  1993. {
  1994. Vector3 ret;
  1995. int k = 0;
  1996. if ( curve < splines.Count )
  1997. {
  1998. if ( alpha < 0.0f )
  1999. {
  2000. if ( splines[curve].closed )
  2001. alpha = Mathf.Repeat(alpha, 1.0f);
  2002. else
  2003. {
  2004. Vector3 ps = splines[curve].Interpolate(0.0f, type, ref k, ref twist);
  2005. // Need a proper tangent function
  2006. Vector3 ps1 = splines[curve].Interpolate(0.01f, type, ref k, ref twist);
  2007. // Calc the spline in out vecs
  2008. Vector3 delta = ps1 - ps;
  2009. delta.Normalize();
  2010. return ps + ((splines[curve].length * alpha) * delta);
  2011. }
  2012. }
  2013. else
  2014. {
  2015. if ( alpha > 1.0f )
  2016. {
  2017. if ( splines[curve].closed )
  2018. alpha = alpha % 1.0f;
  2019. else
  2020. {
  2021. Vector3 ps = splines[curve].Interpolate(1.0f, type, ref k, ref twist);
  2022. // Need a proper tangent function
  2023. Vector3 ps1 = splines[curve].Interpolate(0.99f, type, ref k, ref twist);
  2024. // Calc the spline in out vecs
  2025. Vector3 delta = ps1 - ps;
  2026. delta.Normalize();
  2027. return ps + ((splines[curve].length * (1.0f - alpha)) * delta);
  2028. }
  2029. }
  2030. }
  2031. ret = splines[curve].Interpolate(alpha, type, ref k, ref twist);
  2032. }
  2033. else
  2034. {
  2035. if ( splines == null || splines.Count == 0 )
  2036. return Vector3.zero;
  2037. ret = splines[0].Interpolate(1.0f, type, ref k, ref twist);
  2038. }
  2039. return ret;
  2040. }
  2041. public Vector3 InterpCurve3D(int curve, float alpha, float tanalpha, bool type, ref float twist, ref Quaternion rot)
  2042. {
  2043. Vector3 ret;
  2044. int k = 0;
  2045. if ( curve < splines.Count )
  2046. {
  2047. if ( alpha < 0.0f )
  2048. {
  2049. if ( splines[curve].closed )
  2050. alpha = Mathf.Repeat(alpha, 1.0f);
  2051. else
  2052. {
  2053. Vector3 ps = splines[curve].Interpolate(0.0f, type, ref k, ref twist);
  2054. // Need a proper tangent function
  2055. Vector3 ps1 = splines[curve].Interpolate(0.01f, type, ref k, ref twist);
  2056. // Calc the spline in out vecs
  2057. Vector3 delta = ps1 - ps;
  2058. delta.Normalize();
  2059. ret = ps + ((splines[curve].length * alpha) * delta);
  2060. rot = Quaternion.LookRotation(delta) * Quaternion.Euler(0.0f, 0.0f, twist);
  2061. return ret;
  2062. }
  2063. }
  2064. else
  2065. {
  2066. if ( alpha > 1.0f )
  2067. {
  2068. if ( splines[curve].closed )
  2069. alpha = alpha % 1.0f;
  2070. else
  2071. {
  2072. Vector3 ps = splines[curve].Interpolate(1.0f, type, ref k, ref twist);
  2073. // Need a proper tangent function
  2074. Vector3 ps1 = splines[curve].Interpolate(0.99f, type, ref k, ref twist);
  2075. // Calc the spline in out vecs
  2076. Vector3 delta = ps1 - ps;
  2077. delta.Normalize();
  2078. ret = ps + ((splines[curve].length * (1.0f - alpha)) * delta);
  2079. rot = Quaternion.LookRotation(delta) * Quaternion.Euler(0.0f, 0.0f, twist);
  2080. return ret;
  2081. }
  2082. }
  2083. }
  2084. ret = splines[curve].Interpolate(alpha, type, ref k, ref twist);
  2085. Vector3 tpos = splines[curve].Interpolate(tanalpha, type, ref k, ref twist);
  2086. Vector3 dir = tpos - ret;
  2087. rot = Quaternion.LookRotation(dir) * Quaternion.Euler(0.0f, 0.0f, twist);
  2088. }
  2089. else
  2090. {
  2091. rot = Quaternion.identity;
  2092. if ( splines == null || splines.Count == 0 )
  2093. return Vector3.zero;
  2094. ret = splines[0].Interpolate(1.0f, type, ref k, ref twist);
  2095. }
  2096. return ret;
  2097. }
  2098. static float lastout = 0.0f;
  2099. static float lastin = -9999.0f;
  2100. static public float veccalc(float angstep)
  2101. {
  2102. if ( lastin == angstep )
  2103. return lastout;
  2104. float totdist;
  2105. float sinfac = Mathf.Sin(angstep);
  2106. float cosfac = Mathf.Cos(angstep);
  2107. float test;
  2108. int ix;
  2109. MegaSpline work = new MegaSpline();
  2110. Vector3 k1 = new Vector3(Mathf.Cos(0.0f), Mathf.Sin(0.0f), 0.0f);
  2111. Vector3 k2 = new Vector3(cosfac, sinfac, 0.0f);
  2112. float hi = 1.5f;
  2113. float lo = 0.0f;
  2114. int count = 200;
  2115. // Loop thru test vectors
  2116. loop:
  2117. work.knots.Clear();
  2118. test = (hi + lo) / 2.0f;
  2119. Vector3 outv = k1 + new Vector3(0.0f, test, 0.0f);
  2120. Vector3 inv = k2 + new Vector3(sinfac * test, -cosfac * test, 0.0f);
  2121. work.AddKnot(k1, k1, outv);
  2122. work.AddKnot(k2, inv, k2);
  2123. totdist = 0.0f;
  2124. int k = 0;
  2125. //totdist = work.CalcLength(10);
  2126. for ( ix = 0; ix < 10; ++ix )
  2127. {
  2128. Vector3 terp = work.Interpolate((float)ix / 10.0f, false, ref k);
  2129. totdist += Mathf.Sqrt(terp.x * terp.x + terp.y * terp.y);
  2130. }
  2131. totdist /= 10.0f;
  2132. count--;
  2133. if ( totdist == 1.0f || count <= 0 )
  2134. goto done;
  2135. if ( totdist > 1.0f )
  2136. {
  2137. hi = test;
  2138. goto loop;
  2139. }
  2140. lo = test;
  2141. goto loop;
  2142. done:
  2143. lastin = angstep;
  2144. lastout = test;
  2145. return test;
  2146. }
  2147. public Vector3 FindNearestPointWorld(Vector3 p, int iterations, ref int kn, ref Vector3 tangent, ref float alpha)
  2148. {
  2149. Vector3 pos = transform.TransformPoint(FindNearestPoint(transform.worldToLocalMatrix.MultiplyPoint(p), iterations, ref kn, ref tangent, ref alpha));
  2150. tangent = transform.TransformPoint(tangent);
  2151. return pos;
  2152. }
  2153. public Vector3 FindNearestPointWorldXZ(Vector3 p, int iterations, ref int kn, ref Vector3 tangent, ref float alpha)
  2154. {
  2155. Vector3 pos = transform.TransformPoint(FindNearestPointXZ(transform.worldToLocalMatrix.MultiplyPoint(p), iterations, ref kn, ref tangent, ref alpha));
  2156. tangent = transform.TransformPoint(tangent);
  2157. return pos;
  2158. }
  2159. // Find nearest point
  2160. public Vector3 FindNearestPoint(Vector3 p, int iterations, ref int kn, ref Vector3 tangent, ref float alpha)
  2161. {
  2162. //Vector3 np = Vector3.zero;
  2163. float positiveInfinity = float.PositiveInfinity;
  2164. float num2 = 0.0f;
  2165. iterations = Mathf.Clamp(iterations, 0, 5);
  2166. int kt = 0;
  2167. int crv = selcurve;
  2168. if ( crv >= splines.Count )
  2169. crv = splines.Count - 1;
  2170. for ( float i = 0.0f; i <= 1.0f; i += 0.01f )
  2171. {
  2172. //Vector3 vector = this.GetPositionOnSpline(i) - p;
  2173. //Vector3 vector = InterpCurve3D(0, i, true) - p; //this.GetPositionOnSpline(i) - p;
  2174. Vector3 vector = splines[crv].Interpolate(i, true, ref kt) - p; //this.GetPositionOnSpline(i) - p;
  2175. float sqrMagnitude = vector.sqrMagnitude;
  2176. if ( positiveInfinity > sqrMagnitude )
  2177. {
  2178. positiveInfinity = sqrMagnitude;
  2179. num2 = i;
  2180. }
  2181. }
  2182. for ( int j = 0; j < iterations; j++ )
  2183. {
  2184. float num6 = 0.01f * Mathf.Pow(10.0f, -((float)j));
  2185. float num7 = num6 * 0.1f;
  2186. for ( float k = Mathf.Clamp01(num2 - num6); k <= Mathf.Clamp01(num2 + num6); k += num7 )
  2187. {
  2188. //Vector3 vector2 = InterpCurve3D(0, k, true) - p; //this.GetPositionOnSpline(k) - p;
  2189. Vector3 vector2 = splines[crv].Interpolate(k, true, ref kt) - p; //this.GetPositionOnSpline(k) - p;
  2190. float num9 = vector2.sqrMagnitude;
  2191. if ( positiveInfinity > num9 )
  2192. {
  2193. positiveInfinity = num9;
  2194. num2 = k;
  2195. }
  2196. }
  2197. }
  2198. kn = kt;
  2199. tangent = InterpCurve3D(crv, num2 + 0.01f, true);
  2200. alpha = num2;
  2201. return InterpCurve3D(crv, num2, true); //num2;
  2202. //return np;
  2203. }
  2204. public Vector3 FindNearestPointXZ(Vector3 p, int iterations, ref int kn, ref Vector3 tangent, ref float alpha)
  2205. {
  2206. //Vector3 np = Vector3.zero;
  2207. float positiveInfinity = float.PositiveInfinity;
  2208. float num2 = 0.0f;
  2209. iterations = Mathf.Clamp(iterations, 0, 5);
  2210. int kt = 0;
  2211. int crv = selcurve;
  2212. if ( crv >= splines.Count )
  2213. crv = splines.Count - 1;
  2214. for ( float i = 0.0f; i <= 1.0f; i += 0.01f )
  2215. {
  2216. //Vector3 vector = this.GetPositionOnSpline(i) - p;
  2217. //Vector3 vector = InterpCurve3D(0, i, true) - p; //this.GetPositionOnSpline(i) - p;
  2218. Vector3 vector = splines[crv].Interpolate(i, true, ref kt) - p; //this.GetPositionOnSpline(i) - p;
  2219. vector.y = 0.0f;
  2220. float sqrMagnitude = vector.sqrMagnitude;
  2221. if ( positiveInfinity > sqrMagnitude )
  2222. {
  2223. positiveInfinity = sqrMagnitude;
  2224. num2 = i;
  2225. }
  2226. }
  2227. for ( int j = 0; j < iterations; j++ )
  2228. {
  2229. float num6 = 0.01f * Mathf.Pow(10.0f, -((float)j));
  2230. float num7 = num6 * 0.1f;
  2231. for ( float k = Mathf.Clamp01(num2 - num6); k <= Mathf.Clamp01(num2 + num6); k += num7 )
  2232. {
  2233. //Vector3 vector2 = InterpCurve3D(0, k, true) - p; //this.GetPositionOnSpline(k) - p;
  2234. Vector3 vector2 = splines[crv].Interpolate(k, true, ref kt) - p; //this.GetPositionOnSpline(k) - p;
  2235. vector2.y = 0.0f;
  2236. float num9 = vector2.sqrMagnitude;
  2237. if ( positiveInfinity > num9 )
  2238. {
  2239. positiveInfinity = num9;
  2240. num2 = k;
  2241. }
  2242. }
  2243. }
  2244. kn = kt;
  2245. tangent = InterpCurve3D(crv, num2 + 0.01f, true);
  2246. alpha = num2;
  2247. Vector3 rval = InterpCurve3D(crv, num2, true);
  2248. rval.y = 0.0f;
  2249. return rval;
  2250. //return np;
  2251. }
  2252. public Vector3 FindNearestPoint(int crv, Vector3 p, int iterations, ref int kn, ref Vector3 tangent, ref float alpha)
  2253. {
  2254. //Vector3 np = Vector3.zero;
  2255. float positiveInfinity = float.PositiveInfinity;
  2256. float num2 = 0.0f;
  2257. iterations = Mathf.Clamp(iterations, 0, 5);
  2258. int kt = 0;
  2259. if ( crv >= splines.Count )
  2260. crv = splines.Count - 1;
  2261. for ( float i = 0.0f; i <= 1.0f; i += 0.01f )
  2262. {
  2263. //Vector3 vector = this.GetPositionOnSpline(i) - p;
  2264. //Vector3 vector = InterpCurve3D(0, i, true) - p; //this.GetPositionOnSpline(i) - p;
  2265. Vector3 vector = splines[crv].Interpolate(i, true, ref kt) - p; //this.GetPositionOnSpline(i) - p;
  2266. float sqrMagnitude = vector.sqrMagnitude;
  2267. if ( positiveInfinity > sqrMagnitude )
  2268. {
  2269. positiveInfinity = sqrMagnitude;
  2270. num2 = i;
  2271. }
  2272. }
  2273. for ( int j = 0; j < iterations; j++ )
  2274. {
  2275. float num6 = 0.01f * Mathf.Pow(10.0f, -((float)j));
  2276. float num7 = num6 * 0.1f;
  2277. for ( float k = Mathf.Clamp01(num2 - num6); k <= Mathf.Clamp01(num2 + num6); k += num7 )
  2278. {
  2279. //Vector3 vector2 = InterpCurve3D(0, k, true) - p; //this.GetPositionOnSpline(k) - p;
  2280. Vector3 vector2 = splines[crv].Interpolate(k, true, ref kt) - p; //this.GetPositionOnSpline(k) - p;
  2281. float num9 = vector2.sqrMagnitude;
  2282. if ( positiveInfinity > num9 )
  2283. {
  2284. positiveInfinity = num9;
  2285. num2 = k;
  2286. }
  2287. }
  2288. }
  2289. kn = kt;
  2290. tangent = InterpCurve3D(crv, num2 + 0.01f, true);
  2291. alpha = num2;
  2292. return InterpCurve3D(crv, num2, true); //num2;
  2293. //return np;
  2294. }
  2295. public void BuildSplineWorld(int curve, Vector3[] points, bool closed)
  2296. {
  2297. if ( curve >= 0 && curve < splines.Count )
  2298. {
  2299. MegaSpline spline = splines[curve];
  2300. spline.knots = new List<MegaKnot>(points.Length);
  2301. for ( int i = 0; i < points.Length; i++ )
  2302. {
  2303. MegaKnot knot = new MegaKnot();
  2304. knot.p = transform.worldToLocalMatrix.MultiplyPoint(points[i]);
  2305. spline.knots.Add(knot);
  2306. }
  2307. spline.closed = closed;
  2308. AutoCurve(spline);
  2309. }
  2310. }
  2311. public void BuildSpline(int curve, Vector3[] points, bool closed)
  2312. {
  2313. if ( curve >= 0 && curve < splines.Count )
  2314. {
  2315. MegaSpline spline = splines[curve];
  2316. spline.knots = new List<MegaKnot>(points.Length);
  2317. for ( int i = 0; i < points.Length; i++ )
  2318. {
  2319. MegaKnot knot = new MegaKnot();
  2320. knot.p = points[i];
  2321. spline.knots.Add(knot);
  2322. }
  2323. spline.closed = closed;
  2324. AutoCurve(spline);
  2325. }
  2326. }
  2327. public void BuildSpline(Vector3[] points, bool closed)
  2328. {
  2329. MegaSpline spline = new MegaSpline();
  2330. spline.knots = new List<MegaKnot>(points.Length);
  2331. for ( int i = 0; i < points.Length; i++ )
  2332. {
  2333. MegaKnot knot = new MegaKnot();
  2334. knot.p = points[i];
  2335. spline.knots.Add(knot);
  2336. }
  2337. spline.closed = closed;
  2338. splines.Add(spline);
  2339. AutoCurve(spline);
  2340. }
  2341. public void AddToSpline(int curve, Vector3[] points)
  2342. {
  2343. if ( curve >= 0 && curve < splines.Count )
  2344. {
  2345. MegaSpline spline = splines[curve];
  2346. int fk = spline.knots.Count;
  2347. for ( int i = 0; i < points.Length; i++ )
  2348. {
  2349. MegaKnot knot = new MegaKnot();
  2350. knot.p = points[i];
  2351. spline.knots.Add(knot);
  2352. }
  2353. AutoCurve(spline, fk, fk + points.Length);
  2354. }
  2355. }
  2356. public void AddToSpline(int curve, Vector3 point)
  2357. {
  2358. if ( curve >= 0 && curve < splines.Count )
  2359. {
  2360. MegaSpline spline = splines[curve];
  2361. MegaKnot knot = new MegaKnot();
  2362. knot.p = point;
  2363. spline.knots.Add(knot);
  2364. AutoCurve(spline, spline.knots.Count - 2, spline.knots.Count - 1);
  2365. }
  2366. }
  2367. public void AutoCurve(int s)
  2368. {
  2369. AutoCurve(splines[s]);
  2370. }
  2371. // Calc tangents for knots
  2372. public void AutoCurve(MegaSpline spline)
  2373. {
  2374. if ( smoothMode == MegaShapeBezComputeMode.Old )
  2375. ComputeControlPointsOld(spline);
  2376. else
  2377. ComputeControlPointsNew(spline);
  2378. }
  2379. public void ComputeControlPointsOld(MegaSpline spline)
  2380. {
  2381. if ( spline.closed )
  2382. {
  2383. Vector3 premid = (spline.knots[spline.knots.Count - 1].p + spline.knots[0].p) * 0.5f;
  2384. for ( int k = 0; k < spline.knots.Count; k++ )
  2385. {
  2386. int nk = (k + 1) % spline.knots.Count;
  2387. Vector3 mid = (spline.knots[nk].p + spline.knots[k].p) * 0.5f;
  2388. Vector3 mp = (mid + premid) * 0.5f;
  2389. spline.knots[k].invec = spline.knots[k].p + ((premid - mp) * smoothness);
  2390. spline.knots[k].outvec = spline.knots[k].p + ((mid - mp) * smoothness);
  2391. //SmoothHandles(spline, k, 0.5f);
  2392. premid = mid;
  2393. }
  2394. for ( int k = 0; k < spline.knots.Count; k++ )
  2395. {
  2396. //SmoothHandles(spline, k, 0.25f);
  2397. }
  2398. }
  2399. else
  2400. {
  2401. int kc = spline.knots.Count - 1;
  2402. Vector3 premid = spline.knots[0].p - ((spline.knots[1].p - spline.knots[0].p) * 0.5f);
  2403. Vector3 endmid = spline.knots[kc - 1].p + ((spline.knots[kc].p - spline.knots[kc - 1].p) * 0.5f);
  2404. //Vector3 delta = (spline.knots[1].p - spline.knots[0].p); * 0.5f;
  2405. for ( int k = 0; k < spline.knots.Count - 1; k++ )
  2406. {
  2407. Vector3 mid = (spline.knots[k + 1].p + spline.knots[k].p) * 0.5f;
  2408. Vector3 mp = (mid + premid) * 0.5f;
  2409. spline.knots[k].invec = spline.knots[k].p + ((premid - mp) * smoothness);
  2410. spline.knots[k].outvec = spline.knots[k].p + ((mid - mp) * smoothness);
  2411. //SmoothHandles(spline, k, 0.5f);
  2412. premid = mid;
  2413. }
  2414. //Vector3 mid = (spline.knots[k + 1].p + spline.knots[k].p) * 0.5f;
  2415. //Vector3 mp1 = (premid + endmid) * 0.5f;
  2416. spline.knots[kc].invec = spline.knots[kc].p - ((spline.knots[kc].p - endmid) * smoothness);
  2417. spline.knots[kc].outvec = spline.knots[kc].p + ((spline.knots[kc].p - endmid) * smoothness); //invec; //((mid - mp) * smoothness);
  2418. for ( int k = 1; k < spline.knots.Count; k++ )
  2419. {
  2420. //SmoothHandles(spline, k, 0.25f);
  2421. }
  2422. }
  2423. spline.CalcLength(); //10);
  2424. }
  2425. public void ComputeControlPointsNew(MegaSpline spline)
  2426. {
  2427. if ( spline.closed )
  2428. {
  2429. ComputeControlPointsNewClosed(spline);
  2430. return;
  2431. }
  2432. int n = spline.knots.Count - 1; //K.length - 1;
  2433. Vector3[] p1 = new Vector3[n + 1]; // Tans
  2434. Vector3[] p2 = new Vector3[n + 1];
  2435. // rhs vector
  2436. float[] a = new float[n + 1];
  2437. float[] b = new float[n + 1];
  2438. float[] c = new float[n + 1];
  2439. Vector3[] r = new Vector3[n + 1];
  2440. // left most segment
  2441. a[0] = 0.0f;
  2442. b[0] = 2.0f;
  2443. c[0] = 1.0f;
  2444. r[0] = spline.knots[0].p + 2.0f * spline.knots[1].p;
  2445. // internal segments
  2446. for ( int i = 1; i < n - 1; i++ )
  2447. {
  2448. a[i] = 1.0f;
  2449. b[i] = 4.0f;
  2450. c[i] = 1.0f;
  2451. r[i] = 4.0f * spline.knots[i].p + 2.0f * spline.knots[i + 1].p;
  2452. }
  2453. // right segment
  2454. a[n - 1] = 2.0f;
  2455. b[n - 1] = 7.0f;
  2456. c[n - 1] = 0.0f;
  2457. r[n - 1] = 8.0f * spline.knots[n - 1].p + spline.knots[n].p;
  2458. // solves Ax = b with the Thomas algorithm (from Wikipedia)
  2459. for ( int i = 1; i < n; i++ )
  2460. {
  2461. float m = a[i] / b[i - 1];
  2462. b[i] = b[i] - m * c[i - 1];
  2463. r[i] = r[i] - m * r[i - 1];
  2464. }
  2465. p1[n - 1] = r[n - 1] / b[n - 1];
  2466. for ( int i = n - 2; i >= 0; --i )
  2467. p1[i] = (r[i] - c[i] * p1[i + 1]) / b[i];
  2468. // we have p1, now compute p2
  2469. for ( int i = 0; i < n - 1; i++ )
  2470. p2[i] = 2.0f * spline.knots[i + 1].p - p1[i + 1];
  2471. p2[n - 1] = 0.5f * (spline.knots[n].p + p1[n - 1]);
  2472. // handles are p1 and p2
  2473. for ( int i = 0; i < n; i++ )
  2474. {
  2475. spline.knots[i].outvec = p1[i];
  2476. spline.knots[i + 1].invec = p2[i];
  2477. }
  2478. spline.CalcLength();
  2479. }
  2480. public void ComputeControlPointsNewClosed(MegaSpline spline)
  2481. {
  2482. int kn = spline.knots.Count;
  2483. Vector3[] k = new Vector3[kn + 3];
  2484. k[0] = spline.knots[kn - 1].p;
  2485. for ( int i = 0; i < kn; i++ )
  2486. k[i + 1] = spline.knots[i].p;
  2487. k[kn + 1] = spline.knots[0].p;
  2488. k[kn + 2] = spline.knots[1].p;
  2489. //k[kn + 3] = spline.knots[2].p;
  2490. int n = k.Length - 1; // - 1; //K.length - 1;
  2491. Vector3[] p1 = new Vector3[n + 1]; // Tans
  2492. Vector3[] p2 = new Vector3[n + 1];
  2493. // rhs vector
  2494. float[] a = new float[n + 1];
  2495. float[] b = new float[n + 1];
  2496. float[] c = new float[n + 1];
  2497. Vector3[] r = new Vector3[n + 1];
  2498. // left most segment
  2499. a[0] = 0.0f;
  2500. b[0] = 2.0f;
  2501. c[0] = 1.0f;
  2502. r[0] = k[0] + 2.0f * k[1];
  2503. // internal segments
  2504. for ( int i = 1; i < n - 1; i++ )
  2505. {
  2506. a[i] = 1.0f;
  2507. b[i] = 4.0f;
  2508. c[i] = 1.0f;
  2509. r[i] = 4.0f * k[i] + 2.0f * k[i + 1];
  2510. }
  2511. // right segment
  2512. a[n - 1] = 2.0f;
  2513. b[n - 1] = 7.0f;
  2514. c[n - 1] = 0.0f;
  2515. r[n - 1] = 8.0f * k[n - 1] + k[n];
  2516. // solves Ax = b with the Thomas algorithm (from Wikipedia)
  2517. for ( int i = 1; i < n; i++ )
  2518. {
  2519. float m = a[i] / b[i - 1];
  2520. b[i] = b[i] - m * c[i - 1];
  2521. r[i] = r[i] - m * r[i - 1];
  2522. }
  2523. p1[n - 1] = r[n - 1] / b[n - 1];
  2524. for ( int i = n - 2; i >= 0; --i )
  2525. {
  2526. p1[i] = (r[i] - c[i] * p1[i + 1]) / b[i];
  2527. }
  2528. // we have p1, now compute p2
  2529. for ( int i = 0; i < n - 1; i++ )
  2530. {
  2531. p2[i] = 2.0f * k[i + 1] - p1[i + 1];
  2532. }
  2533. p2[n - 1] = 0.5f * (k[n] + p1[n - 1]);
  2534. // handles are p1 and p2
  2535. for ( int i = 0; i < k.Length; i++ )
  2536. {
  2537. //Debug.Log("Knot " + k[i]);
  2538. }
  2539. for ( int i = 0; i < p1.Length; i++ )
  2540. {
  2541. //Debug.Log("p1 " + p1[i] + " p2 " + p2[i]);
  2542. }
  2543. spline.knots[0].invec = p2[0];
  2544. for ( int i = 0; i < kn - 1; i++ )
  2545. {
  2546. spline.knots[i].outvec = p1[i + 1];
  2547. spline.knots[i + 1].invec = p2[i + 1];
  2548. }
  2549. spline.knots[kn - 1].outvec = p1[kn];
  2550. spline.CalcLength();
  2551. }
  2552. public void AutoCurve(MegaSpline spline, int start, int end)
  2553. {
  2554. if ( spline.closed )
  2555. {
  2556. int pk = (start - 1) % spline.knots.Count;
  2557. Vector3 premid = (spline.knots[pk].p + spline.knots[start].p) * 0.5f;
  2558. for ( int k = start; k < end; k++ )
  2559. {
  2560. int nk = (k + 1) % spline.knots.Count;
  2561. Vector3 mid = (spline.knots[nk].p + spline.knots[k].p) * 0.5f;
  2562. Vector3 mp = (mid + premid) * 0.5f;
  2563. spline.knots[k].invec = spline.knots[k].p + ((premid - mp) * smoothness);
  2564. spline.knots[k].outvec = spline.knots[k].p + ((mid - mp) * smoothness);
  2565. premid = mid;
  2566. }
  2567. for ( int k = start; k < end; k++ )
  2568. {
  2569. //SmoothHandles(spline, k, 0.25f);
  2570. }
  2571. }
  2572. else
  2573. {
  2574. int pk = (start - 1) % spline.knots.Count;
  2575. Vector3 premid = (spline.knots[pk].p + spline.knots[start].p) * 0.5f;
  2576. for ( int k = start; k < end - 1; k++ )
  2577. {
  2578. Vector3 mid = (spline.knots[k + 1].p + spline.knots[k].p) * 0.5f;
  2579. Vector3 mp = (mid + premid) * 0.5f;
  2580. spline.knots[k].invec = spline.knots[k].p + ((premid - mp) * smoothness);
  2581. spline.knots[k].outvec = spline.knots[k].p + ((mid - mp) * smoothness);
  2582. premid = mid;
  2583. }
  2584. for ( int k = start; k < end; k++ )
  2585. {
  2586. //SmoothHandles(spline, k, 0.25f);
  2587. }
  2588. }
  2589. spline.CalcLength(); //10);
  2590. }
  2591. public void AutoCurve()
  2592. {
  2593. for ( int s = 0; s < splines.Count; s++ )
  2594. {
  2595. MegaSpline spline = splines[s];
  2596. AutoCurve(spline);
  2597. #if false
  2598. if ( spline.closed )
  2599. {
  2600. Vector3 premid = (spline.knots[spline.knots.Count - 1].p + spline.knots[0].p) * 0.5f;
  2601. for ( int k = 0; k < spline.knots.Count; k++ )
  2602. {
  2603. int nk = (k + 1) % spline.knots.Count;
  2604. Vector3 mid = (spline.knots[nk].p + spline.knots[k].p) * 0.5f;
  2605. Vector3 mp = (mid + premid) * 0.5f;
  2606. Vector3 delta = spline.knots[k].p - mp;
  2607. spline.knots[k].invec = spline.knots[k].p + (premid - mp); //premid + delta;
  2608. spline.knots[k].outvec = spline.knots[k].p + (mid - mp); //mid + delta;
  2609. premid = mid;
  2610. }
  2611. }
  2612. else
  2613. {
  2614. Vector3 premid = (spline.knots[1].p + spline.knots[0].p) * 0.5f;
  2615. for ( int k = 1; k < spline.knots.Count - 1; k++ )
  2616. {
  2617. Vector3 mid = (spline.knots[k + 1].p + spline.knots[k].p) * 0.5f;
  2618. Vector3 mp = (mid + premid) * 0.5f;
  2619. Vector3 delta = spline.knots[k].p - mp;
  2620. spline.knots[k].invec = spline.knots[k].p + (premid - mp); //premid + delta;
  2621. spline.knots[k].outvec = spline.knots[k].p + (mid - mp); //mid + delta;
  2622. premid = mid;
  2623. }
  2624. }
  2625. #endif
  2626. }
  2627. //CalcLength(10);
  2628. }
  2629. Vector3 SetVectorLength(Vector3 dir, float mag)
  2630. {
  2631. return dir * mag;
  2632. }
  2633. public void SmoothHandles(MegaSpline spline, int i, float lengthFactor) //start, end)
  2634. {
  2635. if ( i < spline.knots.Count - 1 )
  2636. {
  2637. int i1 = i + 1;
  2638. if ( i1 >= spline.knots.Count )
  2639. {
  2640. if ( spline.closed )
  2641. i1 = 0;
  2642. else
  2643. return;
  2644. }
  2645. //for( int i = 0; i < spline.knots.Count - 1; i++ )
  2646. {
  2647. //get the handle length
  2648. Vector3 currentOutDir = spline.knots[i].outvec - spline.knots[i].p;
  2649. Vector3 nextInDir = spline.knots[i1].invec - spline.knots[i1].p;
  2650. //get the distance between the knots
  2651. float knotDistance = Vector3.Magnitude(spline.knots[i1].p - spline.knots[i].p);
  2652. //are the handles overlapping?
  2653. if ( (currentOutDir.magnitude + nextInDir.magnitude) > knotDistance )
  2654. {
  2655. if ( currentOutDir.magnitude > nextInDir.magnitude )
  2656. {
  2657. //make the outvec handle smaller
  2658. Vector3 dir = spline.knots[i1].invec - spline.knots[i].p;
  2659. dir = SetVectorLength(dir, nextInDir.magnitude * lengthFactor);
  2660. spline.knots[i].outvec = spline.knots[i].p + dir;
  2661. //set the invec handle
  2662. dir = SetVectorLength(dir, currentOutDir.magnitude);
  2663. spline.knots[i].invec = spline.knots[i].p - dir;
  2664. //set the next invec handle
  2665. dir = spline.knots[i1].invec - spline.knots[i1].p;
  2666. dir = SetVectorLength(dir, dir.magnitude * lengthFactor);
  2667. spline.knots[i1].invec = spline.knots[i1].p + dir;
  2668. }
  2669. if ( currentOutDir.magnitude < nextInDir.magnitude )
  2670. {
  2671. //make the invec handle smaller
  2672. Vector3 dir = spline.knots[i].outvec - spline.knots[i1].p;
  2673. dir = SetVectorLength(dir, currentOutDir.magnitude * lengthFactor);
  2674. spline.knots[i1].invec = spline.knots[i1].p + dir;
  2675. //set the outvec handle
  2676. dir = SetVectorLength(dir, nextInDir.magnitude);
  2677. spline.knots[i1].outvec = spline.knots[i].p - dir;
  2678. //set the previous outvec handle
  2679. dir = spline.knots[i].outvec - spline.knots[i].p;
  2680. dir = SetVectorLength(dir, dir.magnitude * lengthFactor);
  2681. spline.knots[i].outvec = spline.knots[i].p + dir;
  2682. }
  2683. }
  2684. }
  2685. }
  2686. }
  2687. List<Vector3> verts = new List<Vector3>();
  2688. List<Vector2> uvs = new List<Vector2>();
  2689. List<int> tris = new List<int>();
  2690. List<int> tris1 = new List<int>();
  2691. List<int> tris2 = new List<int>();
  2692. #if true // tube mesh
  2693. //Vector3[] verts;
  2694. //Vector2[] uvs;
  2695. //int[] tris;
  2696. Vector3[] cross;
  2697. public int tsides = 8;
  2698. void BuildCrossSection(float rad)
  2699. {
  2700. if ( cross == null || cross.Length != tsides )
  2701. cross = new Vector3[tsides];
  2702. float sang = rotate * Mathf.Deg2Rad;
  2703. for ( int i = 0; i < tsides; i++ )
  2704. {
  2705. float ang = sang + (((float)i / (float)tsides) * Mathf.PI * 2.0f);
  2706. cross[i] = new Vector3(Mathf.Sin(ang) * rad, 0.0f, Mathf.Cos(ang) * rad);
  2707. }
  2708. }
  2709. public void BuildTubeMesh()
  2710. {
  2711. // Start, length
  2712. BuildMultiStrandMesh();
  2713. }
  2714. public enum CrossSectionType
  2715. {
  2716. Circle,
  2717. Box,
  2718. }
  2719. public CrossSectionType crossType = CrossSectionType.Circle;
  2720. public float Twist = 0.0f;
  2721. public int strands = 1;
  2722. public float tradius = 0.1f;
  2723. public float offset = 0.0f;
  2724. public float uvtilex = 1.0f;
  2725. public float uvtiley = 1.0f;
  2726. public float uvtwist = 0.0f;
  2727. public float TubeLength = 1.0f;
  2728. public float TubeStart = 0.0f;
  2729. public float SegsPerUnit = 20.0f;
  2730. public float TwistPerUnit = 0.0f;
  2731. public float strandRadius = 0.0f;
  2732. public float startAng = 0.0f;
  2733. public float rotate = 0.0f;
  2734. int segments = 0;
  2735. public bool cap = false;
  2736. Vector3[] tverts;
  2737. Vector2[] tuvs;
  2738. int[] ttris;
  2739. Matrix4x4 tm;
  2740. Matrix4x4 mat;
  2741. Matrix4x4 wtm;
  2742. public MegaAxis RopeUp = MegaAxis.Y;
  2743. Vector3 ropeup = Vector3.up;
  2744. public AnimationCurve scaleX = new AnimationCurve(new Keyframe(0, 1), new Keyframe(1, 1));
  2745. public AnimationCurve scaleY = new AnimationCurve(new Keyframe(0, 1), new Keyframe(1, 1));
  2746. public bool unlinkScale = false;
  2747. // Add in twist etc in here to get proper matrix
  2748. Matrix4x4 GetDeformMat(float percent)
  2749. {
  2750. float alpha = percent;
  2751. float twist = 0.0f;
  2752. Vector3 ps = InterpCurve3D(selcurve, alpha, normalizedInterp, ref twist);
  2753. Vector3 ps1 = InterpCurve3D(selcurve, alpha + 0.001f, normalizedInterp, ref twist);
  2754. Vector3 relativePos = ps1 - ps; // This is Vel?
  2755. //Vector3 scl = ps * 0.99f;
  2756. Quaternion rotation = Quaternion.identity;
  2757. if ( relativePos != Vector3.zero )
  2758. rotation = Quaternion.LookRotation(relativePos, ropeup); //vertices[p + 1].point - vertices[p].point);
  2759. //Quaternion rotation = Quaternion.LookRotation(relativePos, ropeup); //vertices[p + 1].point - vertices[p].point);
  2760. Quaternion twistrot = Quaternion.Euler(0.0f, 0.0f, twist);
  2761. //wtm.SetTRS(ps, rotation, Vector3.one);
  2762. MegaMatrix.SetTR(ref wtm, ps, rotation * twistrot);
  2763. wtm = mat * wtm; // * roll;
  2764. return wtm;
  2765. }
  2766. public float boxwidth = 0.2f;
  2767. public float boxheight = 0.2f;
  2768. float[] boxuv = new float[8];
  2769. public void BuildBoxCrossSection(float width, float height)
  2770. {
  2771. if ( cross == null || cross.Length != 8 )
  2772. cross = new Vector3[8];
  2773. float sang = rotate * Mathf.Deg2Rad;
  2774. Matrix4x4 mat = Matrix4x4.identity;
  2775. MegaMatrix.RotateY(ref mat, sang); //rotate);
  2776. cross[0] = new Vector3(width * 0.5f, 0.0f, height * 0.5f);
  2777. cross[1] = new Vector3(width * 0.5f, 0.0f, -height * 0.5f);
  2778. cross[2] = new Vector3(width * 0.5f, 0.0f, -height * 0.5f);
  2779. cross[3] = new Vector3(-width * 0.5f, 0.0f, -height * 0.5f);
  2780. cross[4] = new Vector3(-width * 0.5f, 0.0f, -height * 0.5f);
  2781. cross[5] = new Vector3(-width * 0.5f, 0.0f, height * 0.5f);
  2782. cross[6] = new Vector3(-width * 0.5f, 0.0f, height * 0.5f);
  2783. cross[7] = new Vector3(width * 0.5f, 0.0f, height * 0.5f);
  2784. for ( int i = 0; i < 8; i++ )
  2785. {
  2786. cross[i] = mat.MultiplyPoint(cross[i]);
  2787. }
  2788. float uvlen = (2.0f * boxwidth) + (2.0f * boxheight);
  2789. float ux = 0.0f;
  2790. boxuv[0] = 0.0f;
  2791. ux += boxheight;
  2792. boxuv[1] = ux / uvlen;
  2793. boxuv[2] = boxuv[1];
  2794. ux += boxwidth;
  2795. boxuv[3] = ux / uvlen;
  2796. boxuv[4] = boxuv[3];
  2797. ux += boxheight;
  2798. boxuv[5] = ux / uvlen;
  2799. boxuv[6] = boxuv[5];
  2800. ux += boxwidth;
  2801. boxuv[7] = ux / uvlen;
  2802. }
  2803. public MegaAxis raxis = MegaAxis.X;
  2804. public int ribsegs = 1;
  2805. public void BuildRibbonCrossSection(float width)
  2806. {
  2807. if ( cross == null || cross.Length != ribsegs + 1 )
  2808. cross = new Vector3[ribsegs + 1];
  2809. float sang = rotate * Mathf.Deg2Rad;
  2810. for ( int i = 0; i <= ribsegs; i++ )
  2811. {
  2812. float x = (((float)i / (float)ribsegs) * width) - (width * 0.5f);
  2813. switch ( raxis )
  2814. {
  2815. case MegaAxis.X: cross[i] = new Vector3(x, 0.0f, 0.0f); break;
  2816. case MegaAxis.Y: cross[i] = new Vector3(0.0f, x, 0.0f); break;
  2817. case MegaAxis.Z: cross[i] = new Vector3(0.0f, 0.0f, x); break;
  2818. }
  2819. }
  2820. Matrix4x4 mat = Matrix4x4.identity;
  2821. MegaMatrix.RotateY(ref mat, sang); //rotate);
  2822. for ( int i = 0; i < cross.Length; i++ )
  2823. {
  2824. cross[i] = mat.MultiplyPoint(cross[i]);
  2825. }
  2826. }
  2827. // Width, segs
  2828. void BuildRibbonMesh()
  2829. {
  2830. //float lengthuvtile = uvtiley * TubeLength;
  2831. TubeLength = Mathf.Clamp01(TubeLength);
  2832. if ( TubeLength == 0.0f || strands < 1 )
  2833. {
  2834. shapemesh.Clear();
  2835. return;
  2836. }
  2837. //float sradius = (tradius * 0.5f) + strandRadius;
  2838. BuildRibbonCrossSection(boxwidth);
  2839. segments = (int)((splines[0].length * TubeLength) / (stepdist * 0.1f));
  2840. Twist = TwistPerUnit; // * TubeLength;
  2841. float sang = startAng * Mathf.Deg2Rad;
  2842. int vcount = ((segments + 1) * (ribsegs + 1)) * strands;
  2843. int tcount = (ribsegs * 2 * segments) * strands;
  2844. //Debug.Log("segs " + segments);
  2845. //Debug.Log("verts " + vcount);
  2846. //Debug.Log("tris " + tcount);
  2847. float off = (tradius * 0.5f) + offset;
  2848. //float off = offset;
  2849. if ( strands == 1 )
  2850. {
  2851. off = offset;
  2852. }
  2853. if ( tverts == null || tverts.Length != vcount )
  2854. tverts = new Vector3[vcount];
  2855. //bool builduvs = false;
  2856. if ( GenUV && (tuvs == null || tuvs.Length != vcount) )
  2857. {
  2858. tuvs = new Vector2[vcount];
  2859. //builduvs = true;
  2860. }
  2861. if ( ttris == null || ttris.Length != tcount * 3 )
  2862. {
  2863. ttris = new int[tcount * 3];
  2864. }
  2865. mat = Matrix4x4.identity;
  2866. tm = Matrix4x4.identity;
  2867. switch ( axis )
  2868. {
  2869. case MegaAxis.X: MegaMatrix.RotateY(ref tm, -Mathf.PI * 0.5f); break;
  2870. case MegaAxis.Y: MegaMatrix.RotateX(ref tm, -Mathf.PI * 0.5f); break;
  2871. case MegaAxis.Z: break;
  2872. }
  2873. MegaMatrix.SetTrans(ref tm, Pivot);
  2874. switch ( RopeUp )
  2875. {
  2876. case MegaAxis.X: ropeup = Vector3.right; break;
  2877. case MegaAxis.Y: ropeup = Vector3.up; break;
  2878. case MegaAxis.Z: ropeup = Vector3.forward; break;
  2879. }
  2880. // We only need to refresh the verts, tris and uvs are done once
  2881. int vi = 0;
  2882. int ti = 0;
  2883. Vector2 uv = Vector2.zero;
  2884. Vector3 soff = Vector3.zero;
  2885. Vector3 scl = Vector3.one;
  2886. for ( int s = 0; s < strands; s++ )
  2887. {
  2888. //rollingquat = Quaternion.identity;
  2889. float ang = ((float)s / (float)strands) * Mathf.PI * 2.0f;
  2890. soff.x = Mathf.Sin(ang) * off;
  2891. soff.z = Mathf.Cos(ang) * off;
  2892. //Matrix.SetTrans(ref tm, soff);
  2893. int vo = vi;
  2894. vo = vi;
  2895. for ( int i = 0; i <= segments; i++ )
  2896. {
  2897. float alpha = TubeStart + (((float)i / (float)segments) * TubeLength);
  2898. wtm = GetDeformMat(alpha);
  2899. float uvt = alpha * uvtwist;
  2900. float tst = sang + ((alpha - TubeStart) * Twist * Mathf.PI * 2.0f); // + rollang;
  2901. soff.x = Mathf.Sin(ang + tst) * off;
  2902. soff.z = Mathf.Cos(ang + tst) * off;
  2903. scl.x = scaleX.Evaluate(alpha);
  2904. float cuv = (float)(cross.Length - 1);
  2905. for ( int v = 0; v < cross.Length; v++ )
  2906. {
  2907. Vector3 cp = cross[v];
  2908. cp.x *= scl.x;
  2909. Vector3 p = tm.MultiplyPoint3x4(cp + soff);
  2910. tverts[vi] = wtm.MultiplyPoint3x4(p); //cross[v]);
  2911. if ( GenUV ) //builduvs )
  2912. {
  2913. uv.y = ((alpha - TubeStart) * splines[0].length * uvtiley) + UVOffset.y;
  2914. uv.x = (((float)v / cuv) * uvtilex) + uvt + UVOffset.x;
  2915. tuvs[vi++] = uv;
  2916. }
  2917. else
  2918. vi++;
  2919. }
  2920. // Uv is - to 1 around and alpha along
  2921. }
  2922. if ( GenUV ) //builduvs )
  2923. {
  2924. int sc = ribsegs + 1;
  2925. if ( flipNormals )
  2926. {
  2927. for ( int i = 0; i < segments; i++ )
  2928. {
  2929. for ( int v = 0; v < cross.Length - 1; v++ )
  2930. {
  2931. ttris[ti++] = ((i + 1) * sc) + v + vo;
  2932. ttris[ti++] = (i * sc) + v + vo;
  2933. ttris[ti++] = ((i + 1) * sc) + ((v + 1) % sc) + vo;
  2934. ttris[ti++] = ((i + 1) * sc) + ((v + 1) % sc) + vo;
  2935. ttris[ti++] = (i * sc) + v + vo;
  2936. ttris[ti++] = (i * sc) + ((v + 1) % sc) + vo;
  2937. }
  2938. }
  2939. }
  2940. else
  2941. {
  2942. for ( int i = 0; i < segments; i++ )
  2943. {
  2944. for ( int v = 0; v < cross.Length - 1; v++ )
  2945. {
  2946. ttris[ti++] = ((i + 1) * sc) + v + vo;
  2947. ttris[ti++] = ((i + 1) * sc) + ((v + 1) % sc) + vo;
  2948. ttris[ti++] = (i * sc) + v + vo;
  2949. ttris[ti++] = ((i + 1) * sc) + ((v + 1) % sc) + vo;
  2950. ttris[ti++] = (i * sc) + ((v + 1) % sc) + vo;
  2951. ttris[ti++] = (i * sc) + v + vo;
  2952. }
  2953. }
  2954. }
  2955. }
  2956. }
  2957. // Conform
  2958. if ( conform )
  2959. {
  2960. CalcBounds(tverts);
  2961. DoConform(tverts);
  2962. }
  2963. //Mesh mesh = MegaUtils.GetMesh(gameObject);
  2964. shapemesh.Clear();
  2965. shapemesh.subMeshCount = 1;
  2966. shapemesh.vertices = tverts;
  2967. shapemesh.triangles = ttris;
  2968. if ( GenUV ) //builduvs )
  2969. {
  2970. shapemesh.uv = tuvs;
  2971. }
  2972. else
  2973. {
  2974. //shapemesh.vertices = tverts;
  2975. }
  2976. shapemesh.RecalculateBounds();
  2977. shapemesh.RecalculateNormals();
  2978. if ( CalcTangents )
  2979. MegaUtils.BuildTangents(shapemesh);
  2980. }
  2981. void BuildBoxMesh()
  2982. {
  2983. //float lengthuvtile = uvtiley * TubeLength;
  2984. TubeLength = Mathf.Clamp01(TubeLength);
  2985. if ( TubeLength == 0.0f || strands < 1)
  2986. {
  2987. shapemesh.Clear();
  2988. return;
  2989. }
  2990. //float sradius = (tradius * 0.5f) + strandRadius;
  2991. BuildBoxCrossSection(boxwidth, boxheight);
  2992. segments = (int)((splines[0].length * TubeLength) / (stepdist * 0.1f));
  2993. Twist = TwistPerUnit; // * TubeLength;
  2994. float sang = startAng * Mathf.Deg2Rad;
  2995. int vcount = 9 * (segments + 1) * strands;
  2996. int tcount = (8 * segments) * strands;
  2997. float off = (tradius * 0.5f) + offset;
  2998. //float off = offset;
  2999. if ( strands == 1 )
  3000. {
  3001. off = offset;
  3002. }
  3003. if ( cap )
  3004. {
  3005. vcount += 8 * strands;
  3006. tcount += 4 * strands;
  3007. }
  3008. if ( tverts == null || tverts.Length != vcount )
  3009. tverts = new Vector3[vcount];
  3010. bool builduvs = false;
  3011. if ( GenUV && (tuvs == null || tuvs.Length != vcount) )
  3012. {
  3013. tuvs = new Vector2[vcount];
  3014. builduvs = true;
  3015. }
  3016. if ( ttris == null || ttris.Length != tcount * 3 )
  3017. {
  3018. ttris = new int[tcount * 3];
  3019. }
  3020. mat = Matrix4x4.identity;
  3021. tm = Matrix4x4.identity;
  3022. switch ( axis )
  3023. {
  3024. case MegaAxis.X: MegaMatrix.RotateY(ref tm, -Mathf.PI * 0.5f); break;
  3025. case MegaAxis.Y: MegaMatrix.RotateX(ref tm, -Mathf.PI * 0.5f); break;
  3026. case MegaAxis.Z: break;
  3027. }
  3028. switch ( RopeUp )
  3029. {
  3030. case MegaAxis.X: ropeup = Vector3.right; break;
  3031. case MegaAxis.Y: ropeup = Vector3.up; break;
  3032. case MegaAxis.Z: ropeup = Vector3.forward; break;
  3033. }
  3034. MegaMatrix.SetTrans(ref tm, Pivot);
  3035. // We only need to refresh the verts, tris and uvs are done once
  3036. int vi = 0;
  3037. int ti = 0;
  3038. Vector2 uv = Vector2.zero;
  3039. Vector3 soff = Vector3.zero;
  3040. Vector3 scl = Vector3.one;
  3041. for ( int s = 0; s < strands; s++ )
  3042. {
  3043. //rollingquat = Quaternion.identity;
  3044. float ang = ((float)s / (float)strands) * Mathf.PI * 2.0f;
  3045. soff.x = Mathf.Sin(ang) * off;
  3046. soff.z = Mathf.Cos(ang) * off;
  3047. //Matrix.SetTrans(ref tm, soff);
  3048. int vo = vi;
  3049. // Cap maybe needs to be submesh, at least needs seperate verts
  3050. if ( cap )
  3051. {
  3052. // Add slice at 0
  3053. float alpha = TubeStart; //0.0f;
  3054. wtm = GetDeformMat(alpha);
  3055. //float uvt = alpha * uvtwist;
  3056. float tst = sang + (0.0f * Twist * Mathf.PI * 2.0f);
  3057. soff.x = Mathf.Sin(ang + tst) * off;
  3058. soff.z = Mathf.Cos(ang + tst) * off;
  3059. scl.x = scaleX.Evaluate(alpha);
  3060. if ( unlinkScale )
  3061. scl.z = scaleY.Evaluate(alpha);
  3062. else
  3063. scl.z = scl.x;
  3064. for ( int v = 0; v < 4; v++ )
  3065. {
  3066. Vector3 cp = cross[v * 2];
  3067. cp.x *= scl.x;
  3068. cp.z *= scl.z;
  3069. Vector3 p = tm.MultiplyPoint3x4(cp + soff);
  3070. tverts[vi] = wtm.MultiplyPoint3x4(p); //cross[v]);
  3071. if ( builduvs )
  3072. {
  3073. uv.y = 0.0f; //alpha * uvtiley;
  3074. uv.x = 0.0f; //(((float)v / (float)cross.Length) * uvtilex) + uvt;
  3075. tuvs[vi++] = uv;
  3076. }
  3077. else
  3078. vi++;
  3079. }
  3080. //if ( GenUV ) //builduvs )
  3081. {
  3082. //for ( int sd = 1; sd < 2; sd++ )
  3083. if ( flipNormals )
  3084. {
  3085. ttris[ti++] = vo;
  3086. ttris[ti++] = vo + 1;
  3087. ttris[ti++] = vo + 2;
  3088. ttris[ti++] = vo;
  3089. ttris[ti++] = vo + 2;
  3090. ttris[ti++] = vo + 3;
  3091. }
  3092. else
  3093. {
  3094. ttris[ti++] = vo;
  3095. ttris[ti++] = vo + 2;
  3096. ttris[ti++] = vo + 1;
  3097. ttris[ti++] = vo;
  3098. ttris[ti++] = vo + 3;
  3099. ttris[ti++] = vo + 2;
  3100. }
  3101. }
  3102. vo = vi;
  3103. // Other end
  3104. alpha = TubeStart + TubeLength; //.0f;
  3105. wtm = GetDeformMat(alpha);
  3106. //uvt = alpha * uvtwist;
  3107. tst = sang + (TubeLength * Twist * Mathf.PI * 2.0f);
  3108. soff.x = Mathf.Sin(ang + tst) * off;
  3109. soff.z = Mathf.Cos(ang + tst) * off;
  3110. scl.x = scaleX.Evaluate(alpha);
  3111. if ( unlinkScale )
  3112. scl.z = scaleY.Evaluate(alpha);
  3113. else
  3114. scl.z = scl.x;
  3115. for ( int v = 0; v < 4; v++ )
  3116. {
  3117. Vector3 cp = cross[v * 2];
  3118. cp.x *= scl.x;
  3119. cp.z *= scl.z;
  3120. Vector3 p = tm.MultiplyPoint3x4(cp + soff);
  3121. tverts[vi] = wtm.MultiplyPoint3x4(p); //cross[v]);
  3122. if ( GenUV ) //builduvs )
  3123. {
  3124. uv.y = 0.0f; //alpha * uvtiley;
  3125. uv.x = 0.0f; //(((float)v / (float)cross.Length) * uvtilex) + uvt;
  3126. tuvs[vi++] = uv;
  3127. }
  3128. else
  3129. vi++;
  3130. }
  3131. //if ( GenUV ) //builduvs )
  3132. {
  3133. //for ( int sd = 1; sd < 2; sd++ )
  3134. if ( flipNormals )
  3135. {
  3136. ttris[ti++] = vo;
  3137. ttris[ti++] = vo + 2;
  3138. ttris[ti++] = vo + 1;
  3139. ttris[ti++] = vo;
  3140. ttris[ti++] = vo + 3;
  3141. ttris[ti++] = vo + 2;
  3142. }
  3143. else
  3144. {
  3145. ttris[ti++] = vo;
  3146. ttris[ti++] = vo + 1;
  3147. ttris[ti++] = vo + 2;
  3148. ttris[ti++] = vo;
  3149. ttris[ti++] = vo + 2;
  3150. ttris[ti++] = vo + 3;
  3151. }
  3152. }
  3153. }
  3154. vo = vi;
  3155. for ( int i = 0; i <= segments; i++ )
  3156. {
  3157. float alpha = TubeStart + (((float)i / (float)segments) * TubeLength);
  3158. wtm = GetDeformMat(alpha);
  3159. float uvt = alpha * uvtwist;
  3160. float tst = sang + ((alpha - TubeStart) * Twist * Mathf.PI * 2.0f); // + rollang;
  3161. soff.x = Mathf.Sin(ang + tst) * off;
  3162. soff.z = Mathf.Cos(ang + tst) * off;
  3163. scl.x = scaleX.Evaluate(alpha);
  3164. if ( unlinkScale )
  3165. scl.z = scaleY.Evaluate(alpha);
  3166. else
  3167. scl.z = scl.x;
  3168. for ( int v = 0; v < cross.Length; v++ )
  3169. {
  3170. Vector3 cp = cross[v];
  3171. cp.x *= scl.x;
  3172. cp.z *= scl.z;
  3173. Vector3 p = tm.MultiplyPoint3x4(cp + soff);
  3174. tverts[vi] = wtm.MultiplyPoint3x4(p); //cross[v]);
  3175. if ( GenUV ) //builduvs )
  3176. {
  3177. //uv.y = (alpha - TubeStart) * lengthuvtile * splines[0].length; //uvtiley;
  3178. uv.y = ((alpha - TubeStart) * splines[0].length * uvtiley) + UVOffset.y;
  3179. //uv.x = (((float)v / (float)cross.Length) * uvtilex) + uvt;
  3180. uv.x = (boxuv[v] * uvtilex) + uvt + UVOffset.x;
  3181. tuvs[vi++] = uv;
  3182. }
  3183. else
  3184. vi++;
  3185. }
  3186. // Uv is - to 1 around and alpha along
  3187. }
  3188. if ( GenUV ) //builduvs )
  3189. {
  3190. int sc = 8;
  3191. if ( flipNormals )
  3192. {
  3193. for ( int i = 0; i < segments; i++ )
  3194. {
  3195. for ( int v = 0; v < 4; v++ )
  3196. {
  3197. int v2 = v * 2;
  3198. ttris[ti++] = (i * sc) + v2 + vo;
  3199. ttris[ti++] = ((i + 1) * sc) + v2 + vo;
  3200. ttris[ti++] = ((i + 1) * sc) + (v2 + 1) + vo;
  3201. ttris[ti++] = (i * sc) + v2 + vo;
  3202. ttris[ti++] = ((i + 1) * sc) + (v2 + 1) + vo;
  3203. ttris[ti++] = (i * sc) + (v2 + 1) + vo;
  3204. }
  3205. }
  3206. }
  3207. else
  3208. {
  3209. for ( int i = 0; i < segments; i++ )
  3210. {
  3211. for ( int v = 0; v < 4; v++ )
  3212. {
  3213. int v2 = v * 2;
  3214. ttris[ti++] = (i * sc) + v2 + vo;
  3215. ttris[ti++] = ((i + 1) * sc) + (v2 + 1) + vo;
  3216. ttris[ti++] = ((i + 1) * sc) + v2 + vo;
  3217. ttris[ti++] = (i * sc) + v2 + vo;
  3218. ttris[ti++] = (i * sc) + (v2 + 1) + vo;
  3219. ttris[ti++] = ((i + 1) * sc) + (v2 + 1) + vo;
  3220. }
  3221. }
  3222. }
  3223. }
  3224. }
  3225. // Conform
  3226. if ( conform )
  3227. {
  3228. CalcBounds(tverts);
  3229. DoConform(tverts);
  3230. }
  3231. //Mesh mesh = MegaUtils.GetMesh(gameObject);
  3232. shapemesh.Clear();
  3233. shapemesh.subMeshCount = 1;
  3234. shapemesh.vertices = tverts;
  3235. shapemesh.triangles = ttris;
  3236. if ( GenUV ) //builduvs )
  3237. {
  3238. shapemesh.uv = tuvs;
  3239. }
  3240. else
  3241. {
  3242. //shapemesh.vertices = tverts;
  3243. }
  3244. shapemesh.RecalculateBounds();
  3245. shapemesh.RecalculateNormals();
  3246. if ( CalcTangents )
  3247. MegaUtils.BuildTangents(shapemesh);
  3248. }
  3249. void BuildMultiStrandMesh()
  3250. {
  3251. //float lengthuvtile = uvtiley * TubeLength;
  3252. TubeLength = Mathf.Clamp01(TubeLength);
  3253. if ( TubeLength == 0.0f || strands < 1 )
  3254. {
  3255. shapemesh.Clear();
  3256. return;
  3257. }
  3258. Twist = TwistPerUnit; // * TubeLength;
  3259. //segments = (int)(RopeLength * SegsPerUnit);
  3260. segments = (int)((splines[selcurve].length * TubeLength) / (stepdist * 0.1f));
  3261. float sang = startAng * Mathf.Deg2Rad;
  3262. float off = (tradius * 0.5f) + offset;
  3263. if ( strands == 1 )
  3264. {
  3265. off = offset;
  3266. }
  3267. float sradius = (tradius * 0.5f) + strandRadius;
  3268. BuildCrossSection(sradius);
  3269. int vcount = ((segments + 1) * (tsides + 1)) * strands;
  3270. int tcount = ((tsides * 2) * segments) * strands;
  3271. //Debug.Log("segs " + segments);
  3272. //Debug.Log("verts " + vcount);
  3273. //Debug.Log("tris " + tcount);
  3274. if ( cap )
  3275. {
  3276. vcount += ((tsides + 1) * 2) * strands;
  3277. tcount += (tsides * 2) * strands;
  3278. }
  3279. if ( tverts == null || tverts.Length != vcount )
  3280. {
  3281. tverts = new Vector3[vcount];
  3282. }
  3283. bool builduvs = false;
  3284. if ( GenUV && (tuvs == null || tuvs.Length != vcount) )
  3285. {
  3286. tuvs = new Vector2[vcount];
  3287. builduvs = true;
  3288. }
  3289. if ( ttris == null || ttris.Length != tcount * 3 )
  3290. {
  3291. ttris = new int[tcount * 3];
  3292. }
  3293. mat = Matrix4x4.identity;
  3294. tm = Matrix4x4.identity;
  3295. switch ( axis )
  3296. {
  3297. case MegaAxis.X: MegaMatrix.RotateY(ref tm, -Mathf.PI * 0.5f); break;
  3298. case MegaAxis.Y: MegaMatrix.RotateX(ref tm, -Mathf.PI * 0.5f); break;
  3299. case MegaAxis.Z: break;
  3300. }
  3301. MegaMatrix.SetTrans(ref tm, Pivot);
  3302. switch ( RopeUp )
  3303. {
  3304. case MegaAxis.X: ropeup = Vector3.right; break;
  3305. case MegaAxis.Y: ropeup = Vector3.up; break;
  3306. case MegaAxis.Z: ropeup = Vector3.forward; break;
  3307. }
  3308. // We only need to refresh the verts, tris and uvs are done once
  3309. int vi = 0;
  3310. int ti = 0;
  3311. Vector2 uv = Vector2.zero;
  3312. Vector3 soff = Vector3.zero;
  3313. Vector3 scl = Vector3.one;
  3314. for ( int s = 0; s < strands; s++ )
  3315. {
  3316. //rollingquat = Quaternion.identity;
  3317. float ang = ((float)s / (float)strands) * Mathf.PI * 2.0f;
  3318. soff.x = Mathf.Sin(ang) * off;
  3319. soff.z = Mathf.Cos(ang) * off;
  3320. //Matrix.SetTrans(ref tm, soff);
  3321. int vo = vi;
  3322. // Cap maybe needs to be submesh, at least needs seperate verts
  3323. if ( cap )
  3324. {
  3325. // Add slice at 0
  3326. float alpha = TubeStart; //0.0f;
  3327. wtm = GetDeformMat(alpha);
  3328. //float uvt = alpha * uvtwist;
  3329. float tst = sang + ((alpha - TubeStart) * Twist * Mathf.PI * 2.0f);
  3330. soff.x = Mathf.Sin(ang + tst) * off;
  3331. soff.z = Mathf.Cos(ang + tst) * off;
  3332. scl.x = scaleX.Evaluate(alpha);
  3333. if ( unlinkScale )
  3334. scl.z = scaleY.Evaluate(alpha);
  3335. else
  3336. scl.z = scl.x;
  3337. for ( int v = 0; v <= cross.Length; v++ )
  3338. {
  3339. Vector3 cp = cross[v % cross.Length];
  3340. cp.x *= scl.x;
  3341. cp.z *= scl.z;
  3342. Vector3 p = tm.MultiplyPoint3x4(cp + soff);
  3343. tverts[vi] = wtm.MultiplyPoint3x4(p); //cross[v]);
  3344. if ( builduvs )
  3345. {
  3346. uv.y = 0.0f; //alpha * uvtiley;
  3347. uv.x = 0.0f; //(((float)v / (float)cross.Length) * uvtilex) + uvt;
  3348. tuvs[vi++] = uv;
  3349. }
  3350. else
  3351. vi++;
  3352. }
  3353. if ( GenUV ) //builduvs )
  3354. {
  3355. if ( flipNormals )
  3356. {
  3357. for ( int sd = 1; sd < tsides; sd++ )
  3358. {
  3359. ttris[ti++] = vo;
  3360. ttris[ti++] = vo + sd;
  3361. ttris[ti++] = vo + sd + 1;
  3362. }
  3363. }
  3364. else
  3365. {
  3366. for ( int sd = 1; sd < tsides; sd++ )
  3367. {
  3368. ttris[ti++] = vo;
  3369. ttris[ti++] = vo + sd + 1;
  3370. ttris[ti++] = vo + sd;
  3371. }
  3372. }
  3373. }
  3374. vo = vi;
  3375. // Other end
  3376. alpha = TubeStart + TubeLength; //.0f;
  3377. wtm = GetDeformMat(alpha);
  3378. //uvt = alpha * uvtwist;
  3379. tst = sang + ((alpha - TubeStart) * Twist * Mathf.PI * 2.0f);
  3380. soff.x = Mathf.Sin(ang + tst) * off;
  3381. soff.z = Mathf.Cos(ang + tst) * off;
  3382. scl.x = scaleX.Evaluate(alpha);
  3383. if ( unlinkScale )
  3384. scl.z = scaleY.Evaluate(alpha);
  3385. else
  3386. scl.z = scl.x;
  3387. for ( int v = 0; v <= cross.Length; v++ )
  3388. {
  3389. Vector3 cp = cross[v % cross.Length];
  3390. cp.x *= scl.x;
  3391. cp.z *= scl.z;
  3392. Vector3 p = tm.MultiplyPoint3x4(cp + soff);
  3393. tverts[vi] = wtm.MultiplyPoint3x4(p); //cross[v]);
  3394. if ( GenUV ) //builduvs )
  3395. {
  3396. uv.y = 0.0f; //alpha * uvtiley;
  3397. uv.x = 0.0f; //(((float)v / (float)cross.Length) * uvtilex) + uvt;
  3398. tuvs[vi++] = uv;
  3399. }
  3400. else
  3401. vi++;
  3402. }
  3403. if ( GenUV ) //builduvs )
  3404. {
  3405. if ( flipNormals )
  3406. {
  3407. for ( int sd = 1; sd < tsides; sd++ )
  3408. {
  3409. ttris[ti++] = vo;
  3410. ttris[ti++] = vo + sd + 1;
  3411. ttris[ti++] = vo + sd;
  3412. }
  3413. }
  3414. else
  3415. {
  3416. for ( int sd = 1; sd < tsides; sd++ )
  3417. {
  3418. ttris[ti++] = vo;
  3419. ttris[ti++] = vo + sd;
  3420. ttris[ti++] = vo + sd + 1;
  3421. }
  3422. }
  3423. }
  3424. }
  3425. vo = vi;
  3426. for ( int i = 0; i <= segments; i++ )
  3427. {
  3428. float alpha = TubeStart + (((float)i / (float)segments) * TubeLength);
  3429. scl.x = scaleX.Evaluate(alpha);
  3430. if ( unlinkScale )
  3431. scl.z = scaleY.Evaluate(alpha);
  3432. else
  3433. scl.z = scl.x;
  3434. wtm = GetDeformMat(alpha);
  3435. float uvt = alpha * uvtwist;
  3436. float tst = sang + ((alpha - TubeStart) * Twist * Mathf.PI * 2.0f); // + rollang;
  3437. soff.x = Mathf.Sin(ang + tst) * off;
  3438. soff.z = Mathf.Cos(ang + tst) * off;
  3439. for ( int v = 0; v <= cross.Length; v++ )
  3440. {
  3441. Vector3 cp = cross[v % cross.Length];
  3442. cp.x *= scl.x;
  3443. cp.z *= scl.z;
  3444. Vector3 p = tm.MultiplyPoint3x4(cp + soff); //cross[v % cross.Length] + soff);
  3445. tverts[vi] = wtm.MultiplyPoint3x4(p); //cross[v]);
  3446. if ( GenUV ) //builduvs )
  3447. {
  3448. //uv.y = alpha * lengthuvtile; //uvtiley;
  3449. uv.y = ((alpha - TubeStart) * splines[0].length * uvtiley) + UVOffset.y;
  3450. uv.x = (((float)v / (float)cross.Length) * uvtilex) + uvt + UVOffset.x;
  3451. tuvs[vi++] = uv;
  3452. }
  3453. else
  3454. vi++;
  3455. }
  3456. // Uv is - to 1 around and alpha along
  3457. }
  3458. if ( GenUV ) //builduvs )
  3459. {
  3460. int sc = tsides + 1;
  3461. if ( flipNormals )
  3462. {
  3463. for ( int i = 0; i < segments; i++ )
  3464. {
  3465. for ( int v = 0; v < cross.Length; v++ )
  3466. {
  3467. ttris[ti++] = (i * sc) + v + vo;
  3468. ttris[ti++] = ((i + 1) * sc) + v + vo;
  3469. ttris[ti++] = ((i + 1) * sc) + ((v + 1) % sc) + vo;
  3470. ttris[ti++] = (i * sc) + v + vo;
  3471. ttris[ti++] = ((i + 1) * sc) + ((v + 1) % sc) + vo;
  3472. ttris[ti++] = (i * sc) + ((v + 1) % sc) + vo;
  3473. }
  3474. }
  3475. }
  3476. else
  3477. {
  3478. for ( int i = 0; i < segments; i++ )
  3479. {
  3480. for ( int v = 0; v < cross.Length; v++ )
  3481. {
  3482. ttris[ti++] = (i * sc) + v + vo;
  3483. ttris[ti++] = ((i + 1) * sc) + ((v + 1) % sc) + vo;
  3484. ttris[ti++] = ((i + 1) * sc) + v + vo;
  3485. ttris[ti++] = (i * sc) + v + vo;
  3486. ttris[ti++] = (i * sc) + ((v + 1) % sc) + vo;
  3487. ttris[ti++] = ((i + 1) * sc) + ((v + 1) % sc) + vo;
  3488. }
  3489. }
  3490. }
  3491. }
  3492. }
  3493. // Conform
  3494. if ( conform )
  3495. {
  3496. CalcBounds(tverts);
  3497. DoConform(tverts);
  3498. }
  3499. //Mesh mesh = MegaUtils.GetMesh(gameObject);
  3500. shapemesh.Clear();
  3501. shapemesh.subMeshCount = 1;
  3502. shapemesh.vertices = tverts;
  3503. shapemesh.triangles = ttris;
  3504. if ( GenUV ) //builduvs )
  3505. {
  3506. shapemesh.uv = tuvs;
  3507. }
  3508. else
  3509. {
  3510. //shapemesh.vertices = tverts;
  3511. }
  3512. shapemesh.RecalculateBounds();
  3513. shapemesh.RecalculateNormals();
  3514. //MeshConstructor.BuildTangents(mesh);
  3515. if ( CalcTangents )
  3516. MegaUtils.BuildTangents(shapemesh);
  3517. }
  3518. #endif // tube mesh
  3519. public void ClearMesh()
  3520. {
  3521. MeshFilter mf = gameObject.GetComponent<MeshFilter>();
  3522. if ( mf != null )
  3523. {
  3524. mf.sharedMesh = null;
  3525. shapemesh = null;
  3526. }
  3527. }
  3528. public void SetMats()
  3529. {
  3530. MeshRenderer mr = gameObject.GetComponent<MeshRenderer>();
  3531. if ( mr == null )
  3532. {
  3533. mr = gameObject.AddComponent<MeshRenderer>();
  3534. }
  3535. if ( meshType == MeshShapeType.Fill )
  3536. {
  3537. Material[] mats = new Material[3];
  3538. mats[0] = mat1;
  3539. mats[1] = mat2;
  3540. mats[2] = mat3;
  3541. mr.sharedMaterials = mats;
  3542. }
  3543. else
  3544. {
  3545. Material[] mats = new Material[1];
  3546. mats[0] = mat1;
  3547. mr.sharedMaterials = mats;
  3548. }
  3549. }
  3550. int[] empty = new int[3] {0, 0, 0};
  3551. // Best if we calc the normals to avoid issues at join
  3552. public void BuildMesh()
  3553. {
  3554. if ( makeMesh )
  3555. {
  3556. if ( splines == null || splines.Count == 0 )
  3557. return;
  3558. if ( shapemesh == null )
  3559. {
  3560. MeshFilter mf = gameObject.GetComponent<MeshFilter>();
  3561. if ( mf == null )
  3562. mf = gameObject.AddComponent<MeshFilter>();
  3563. mf.sharedMesh = new Mesh();
  3564. MeshRenderer mr = gameObject.GetComponent<MeshRenderer>();
  3565. if ( mr == null )
  3566. {
  3567. mr = gameObject.AddComponent<MeshRenderer>();
  3568. }
  3569. SetMats();
  3570. shapemesh = mf.sharedMesh; //Utils.GetMesh(gameObject);
  3571. }
  3572. if ( meshType == MeshShapeType.Tube )
  3573. {
  3574. BuildTubeMesh();
  3575. return;
  3576. }
  3577. if ( meshType == MeshShapeType.Box )
  3578. {
  3579. BuildBoxMesh();
  3580. return;
  3581. }
  3582. if ( meshType == MeshShapeType.Ribbon )
  3583. {
  3584. BuildRibbonMesh();
  3585. return;
  3586. }
  3587. //makeMesh = false;
  3588. float sdist = stepdist * 0.1f;
  3589. if ( splines[selcurve].length / sdist > 1500.0f )
  3590. sdist = splines[selcurve].length / 1500.0f;
  3591. Vector3 size = Vector3.zero;
  3592. verts.Clear();
  3593. uvs.Clear();
  3594. tris.Clear();
  3595. tris1.Clear();
  3596. tris2.Clear();
  3597. tris = MegaTriangulator.Triangulate(this, splines[selcurve], sdist, ref verts, ref uvs, ref tris, Pivot, ref size);
  3598. if ( axis != MegaAxis.Y )
  3599. {
  3600. for ( int i = 0; i < tris.Count; i += 3 )
  3601. {
  3602. int t = tris[i];
  3603. tris[i] = tris[i + 2];
  3604. tris[i + 2] = t;
  3605. }
  3606. }
  3607. int vcount = verts.Count;
  3608. int tcount = tris.Count;
  3609. if ( Height < 0.0f )
  3610. Height = 0.0f;
  3611. float h = Height; //Mathf.Abs(Height);
  3612. Matrix4x4 tm1 = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(UVRotate.x, UVRotate.y, 0.0f), new Vector3(UVScale.x, 1.0f, UVScale.y));
  3613. //Vector3 size = shapemesh.bounds.size;
  3614. if ( GenUV )
  3615. {
  3616. uvs.Clear(); // need to stop triangulator doing uvs
  3617. Vector2 uv = Vector2.zero;
  3618. Vector3 uv1 = Vector3.zero;
  3619. int uvx = 0;
  3620. int uvy = 2;
  3621. switch ( axis )
  3622. {
  3623. case MegaAxis.X:
  3624. uvx = 1;
  3625. break;
  3626. case MegaAxis.Z:
  3627. uvy = 1;
  3628. break;
  3629. }
  3630. for ( int i = 0; i < verts.Count; i++ )
  3631. {
  3632. //uv1.x = (verts[i].x); // * UVScale.x) + UVOffset.x; // * UVScale.x;
  3633. //uv1.z = (verts[i].z); // * UVScale.y) + UVOffset.y; // * UVScale.y;
  3634. uv1.x = verts[i][uvx]; // * UVScale.x) + UVOffset.x; // * UVScale.x;
  3635. uv1.z = verts[i][uvy]; // * UVScale.y) + UVOffset.y; // * UVScale.y;
  3636. if ( !PhysUV )
  3637. {
  3638. uv1.x /= size[uvx]; //.x;
  3639. uv1.z /= size[uvy]; //.z;
  3640. }
  3641. uv1 = tm1.MultiplyPoint3x4(uv1);
  3642. uv.x = uv1.x + UVOffset.x;
  3643. uv.y = uv1.z + UVOffset.y;
  3644. uvs.Add(uv);
  3645. }
  3646. }
  3647. if ( DoubleSided && h != 0.0f )
  3648. {
  3649. //vcount = verts.Count;
  3650. for ( int i = 0; i < vcount; i++ )
  3651. {
  3652. Vector3 p = verts[i];
  3653. if ( UseHeightCurve )
  3654. {
  3655. float alpha = MegaTriangulator.m_points[i].z / splines[selcurve].length;
  3656. //p.y -= h * heightCrv.Evaluate(alpha + heightOff);
  3657. p[(int)axis] -= h * heightCrv.Evaluate(alpha + heightOff);
  3658. }
  3659. else
  3660. {
  3661. //p.y -= h;
  3662. p[(int)axis] -= h;
  3663. }
  3664. verts.Add(p); //verts[i]);
  3665. uvs.Add(uvs[i]);
  3666. }
  3667. //tcount = tris.Count;
  3668. #if false
  3669. switch ( axis )
  3670. {
  3671. case MegaAxis.X:
  3672. for ( int i = tcount - 1; i >= 0; i-- )
  3673. {
  3674. tris1.Add(tris[i] + vcount);
  3675. }
  3676. break;
  3677. case MegaAxis.Y:
  3678. for ( int i = tcount - 1; i >= 0; i-- )
  3679. {
  3680. tris1.Add(tris[i] + vcount);
  3681. }
  3682. break;
  3683. case MegaAxis.Z:
  3684. for ( int i = 0; i < tcount; i++ )
  3685. {
  3686. tris1.Add(tris[i] + vcount);
  3687. }
  3688. break;
  3689. }
  3690. #endif
  3691. for ( int i = tcount - 1; i >= 0; i-- )
  3692. {
  3693. tris1.Add(tris[i] + vcount);
  3694. }
  3695. }
  3696. #if true
  3697. // Do edge
  3698. if ( h != 0.0f )
  3699. {
  3700. int vc = verts.Count;
  3701. Vector3 ep = Vector3.zero;
  3702. Vector2 euv = Vector2.zero;
  3703. tm1 = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(UVRotate1.x, UVRotate1.y, 0.0f), new Vector3(UVScale1.x, 1.0f, UVScale1.y));
  3704. // Top loop
  3705. for ( int i = 0; i < MegaTriangulator.m_points.Count; i++ )
  3706. {
  3707. ep = verts[i];
  3708. //ep.x = MegaTriangulator.m_points[i].x;
  3709. //ep.y = 0.0f;
  3710. //ep.z = MegaTriangulator.m_points[i].y;
  3711. verts.Add(ep);
  3712. //euv.x = (MegaTriangulator.m_points[i].z / splines[0].length) * 4.0f;
  3713. //euv.x = (MegaTriangulator.m_points[i].z * UVScale1.x) + UVOffset1.x; // / splines[0].length) * 4.0f;
  3714. //euv.y = UVOffset1.y; //0.0f;
  3715. ep.x = (MegaTriangulator.m_points[i].z); // * UVScale1.x) + UVOffset1.x; // / splines[0].length) * 4.0f;
  3716. if ( !PhysUV )
  3717. {
  3718. ep.x /= size.x;
  3719. }
  3720. ep.y = 0.0f;
  3721. ep.z = 0.0f; //UVOffset1.y; //0.0f;
  3722. ep = tm1.MultiplyPoint3x4(ep);
  3723. euv.x = ep.x + UVOffset1.x;
  3724. euv.y = ep.z + UVOffset1.y;
  3725. uvs.Add(euv);
  3726. }
  3727. // Add first point again
  3728. ep = verts[0];
  3729. //ep.y -= h * heightCrv.Evaluate(0.0f);
  3730. verts.Add(ep);
  3731. //euv.x = 1.0f * 4.0f; //MegaTriangulator.m_points[0].z / splines[0].length;
  3732. euv.x = (splines[selcurve].length * UVScale1.x) + UVOffset1.x; //1.0f * 4.0f; //MegaTriangulator.m_points[0].z / splines[0].length;
  3733. if ( !PhysUV )
  3734. {
  3735. euv.x /= size.x;
  3736. }
  3737. euv.y = 0.0f + UVOffset1.y;
  3738. uvs.Add(euv);
  3739. // Bot loop
  3740. float hd = 1.0f;
  3741. for ( int i = 0; i < MegaTriangulator.m_points.Count; i++ )
  3742. {
  3743. float alpha = MegaTriangulator.m_points[i].z / splines[selcurve].length;
  3744. ep = verts[i];
  3745. if ( UseHeightCurve )
  3746. hd = heightCrv.Evaluate(alpha + heightOff);
  3747. //ep.y -= h * hd; //heightCrv.Evaluate(alpha);
  3748. ep[(int)axis] -= h * hd;
  3749. verts.Add(ep);
  3750. ep.x = (MegaTriangulator.m_points[i].z); // * UVScale1.x) + UVOffset1.x; // / splines[0].length) * 4.0f;
  3751. ep.z = ep.y; //0.0f; //UVOffset1.y; //0.0f;
  3752. ep.y = 0.0f;
  3753. if ( !PhysUV )
  3754. {
  3755. ep.x /= size.x;
  3756. ep.z /= (h * hd);
  3757. }
  3758. ep = tm1.MultiplyPoint3x4(ep);
  3759. euv.x = ep.x + UVOffset1.x;
  3760. euv.y = ep.z + UVOffset1.y;
  3761. //euv.x = (MegaTriangulator.m_points[i].z / splines[0].length) * 4.0f;
  3762. //euv.x = (MegaTriangulator.m_points[i].z * UVScale1.x) + UVOffset1.x;
  3763. //euv.y = ((h * hd) * UVScale1.y) + UVOffset1.y; //1.0f;
  3764. uvs.Add(euv);
  3765. }
  3766. // Add first point again
  3767. ep = verts[0];
  3768. if ( UseHeightCurve )
  3769. {
  3770. hd = heightCrv.Evaluate(0.0f + heightOff);
  3771. }
  3772. //ep.y -= h * hd; //heightCrv.Evaluate(0.0f);
  3773. ep[(int)axis] -= h * hd;
  3774. verts.Add(ep);
  3775. ep.x = (MegaTriangulator.m_points[0].z); // * UVScale1.x) + UVOffset1.x; // / splines[0].length) * 4.0f;
  3776. ep.z = ep.y; //0.0f; //UVOffset1.y; //0.0f;
  3777. ep.y = 0.0f;
  3778. if ( !PhysUV )
  3779. {
  3780. ep.x /= size.x;
  3781. ep.z /= (h * hd);
  3782. }
  3783. ep = tm1.MultiplyPoint3x4(ep);
  3784. euv.x = ep.x + UVOffset1.x;
  3785. euv.y = ep.z + UVOffset1.y;
  3786. //euv.x = (MegaTriangulator.m_points[i].z / splines[0].length) * 4.0f;
  3787. //euv.x = (MegaTriangulator.m_points[i].z * UVScale1.x) + UVOffset1.x;
  3788. //euv.y = ((h * hd) * UVScale1.y) + UVOffset1.y; //1.0f;
  3789. uvs.Add(euv);
  3790. //euv.x = 1.0f; //MegaTriangulator.m_points[0].z / splines[0].length;
  3791. //euv.x = (splines[0].length * UVScale1.x) + UVOffset1.x; //MegaTriangulator.m_points[0].z / splines[0].length;
  3792. //euv.y = (h * hd * UVScale1.y) + UVOffset1.y; //1.0f;
  3793. //if ( !PhysUV )
  3794. //{
  3795. // euv.x /= size.x;
  3796. // euv.y /=
  3797. //}
  3798. //uvs.Add(euv);
  3799. // Faces
  3800. int ecount = MegaTriangulator.m_points.Count + 1;
  3801. int ip = 0;
  3802. if ( splines[selcurve].reverse )
  3803. {
  3804. for ( ip = 0; ip < MegaTriangulator.m_points.Count; ip++ )
  3805. {
  3806. tris2.Add(ip + vc + 1);
  3807. tris2.Add(ip + vc + ecount);
  3808. tris2.Add(ip + vc);
  3809. tris2.Add(ip + vc + ecount + 1);
  3810. tris2.Add(ip + vc + ecount);
  3811. tris2.Add(ip + vc + 1);
  3812. }
  3813. }
  3814. else
  3815. {
  3816. for ( ip = 0; ip < MegaTriangulator.m_points.Count; ip++ )
  3817. {
  3818. tris2.Add(ip + vc);
  3819. tris2.Add(ip + vc + ecount);
  3820. tris2.Add(ip + vc + 1);
  3821. tris2.Add(ip + vc + 1);
  3822. tris2.Add(ip + vc + ecount);
  3823. tris2.Add(ip + vc + ecount + 1);
  3824. }
  3825. }
  3826. #if false
  3827. #else
  3828. #endif
  3829. #if false
  3830. tris.Add(ip + vc);
  3831. tris.Add(ip + vc + ecount);
  3832. tris.Add(vc);
  3833. tris.Add(vc);
  3834. tris.Add(ip + vc + ecount);
  3835. tris.Add(vc + ecount);
  3836. #endif
  3837. }
  3838. #endif
  3839. Vector3[] tverts = verts.ToArray();
  3840. // Conform
  3841. if ( conform )
  3842. {
  3843. CalcBounds(tverts);
  3844. DoConform(tverts);
  3845. }
  3846. shapemesh.Clear();
  3847. shapemesh.vertices = tverts; //verts.ToArray();
  3848. shapemesh.uv = uvs.ToArray();
  3849. shapemesh.subMeshCount = 3;
  3850. shapemesh.SetTriangles(tris.ToArray(), 0);
  3851. if ( tris1.Count == 0 )
  3852. shapemesh.SetTriangles(empty, 1);
  3853. else
  3854. shapemesh.SetTriangles(tris1.ToArray(), 1);
  3855. if ( tris2.Count == 0 )
  3856. shapemesh.SetTriangles(empty, 2);
  3857. else
  3858. shapemesh.SetTriangles(tris2.ToArray(), 2);
  3859. //shapemesh.triangles = tris.ToArray();
  3860. shapemesh.RecalculateNormals();
  3861. shapemesh.RecalculateBounds();
  3862. if ( CalcTangents )
  3863. MegaUtils.BuildTangents(shapemesh);
  3864. //if ( mesh != null )
  3865. //{
  3866. //BuildMesh(mesh);
  3867. //MegaModifyObject mo = GetComponent<MegaModifyObject>();
  3868. //if ( mo != null )
  3869. //{
  3870. // mo.MeshUpdated();
  3871. //}
  3872. //}
  3873. }
  3874. }
  3875. #if true
  3876. static int CURVELENGTHSTEPS = 5;
  3877. static public float CurveLength(MegaSpline spline, int knot, float v1, float v2, float size)
  3878. {
  3879. float len = 0.0f;
  3880. if ( size == 0.0f )
  3881. { // Simple curve length
  3882. Vector3 p1,p2;
  3883. p1 = spline.InterpBezier3D(knot, v1);
  3884. //Debug.Log("p1 " + p1);
  3885. float step = (v2 - v1) / (float)CURVELENGTHSTEPS;
  3886. //Debug.Log("Step " + step);
  3887. float pos;
  3888. int i;
  3889. for ( i = 1, pos = step; i < CURVELENGTHSTEPS; ++i, pos += step )
  3890. {
  3891. p2 = spline.InterpBezier3D(knot, v1 + pos);
  3892. len += Vector3.Magnitude(p2 - p1);
  3893. p1 = p2;
  3894. }
  3895. //Debug.Log("len " + len);
  3896. len += Vector3.Magnitude(spline.InterpBezier3D(knot, v2) - p1);
  3897. //Debug.Log("len " + len);
  3898. }
  3899. else
  3900. { // Need to figure based on displaced location
  3901. int knots = spline.knots.Count;
  3902. int prev = (knot + knots - 1) % knots;
  3903. int next = (knot + 1) % knots;
  3904. float pv = v1 - 0.01f;
  3905. int pk = knot;
  3906. if ( pv < 0.0f )
  3907. {
  3908. if ( spline.closed )
  3909. {
  3910. pv += 1.0f;
  3911. pk = prev;
  3912. }
  3913. else
  3914. pv = 0.0f;
  3915. }
  3916. float nv = v1 + 0.01f;
  3917. Vector3 direction = Vector3.Normalize(spline.InterpBezier3D(knot, nv) - spline.InterpBezier3D(pk, pv));
  3918. //direction.z = 0.0f; // Keep it in the XY plane
  3919. //Vector3 perp = new Vector3(direction.y * size, -direction.x * size, 0.0f);
  3920. direction.y = 0.0f; // Keep it in the XY plane
  3921. Vector3 perp = new Vector3(direction.z * size, 0.0f, -direction.x * size);
  3922. Vector3 p1,p2;
  3923. p1 = spline.InterpBezier3D(knot, v1) + perp; // Got 1st displaced point
  3924. float step = (v2 - v1) / CURVELENGTHSTEPS;
  3925. float pos;
  3926. int i;
  3927. for ( i = 1, pos = step; i < CURVELENGTHSTEPS; ++i, pos += step )
  3928. {
  3929. pv = v1 + pos - 0.01f;
  3930. nv = v1 + pos + 0.01f;
  3931. direction = Vector3.Normalize(spline.InterpBezier3D(knot, nv) - spline.InterpBezier3D(knot, pv));
  3932. //direction.z = 0.0f; // Keep it in the XY plane
  3933. //perp = new Vector3(direction.y * size, -direction.x * size, 0.0f);
  3934. direction.y = 0.0f; // Keep it in the XY plane
  3935. perp = new Vector3(direction.z * size, 0.0f, -direction.x * size);
  3936. p2 = spline.InterpBezier3D(knot, v1 + pos) + perp;
  3937. len += Vector3.Magnitude(p2 - p1);
  3938. p1 = p2;
  3939. }
  3940. pv = v2 - 0.01f;
  3941. int nk = knot;
  3942. nv = v2 + 0.01f;
  3943. if ( nv > 1.0f )
  3944. {
  3945. if ( spline.closed )
  3946. {
  3947. nv -= 1.0f;
  3948. nk = next;
  3949. }
  3950. else
  3951. nv = 1.0f;
  3952. }
  3953. direction = Vector3.Normalize(spline.InterpBezier3D(nk, nv) - spline.InterpBezier3D(knot, pv));
  3954. //direction.z = 0.0f; // Keep it in the XY plane
  3955. //perp = new Vector3(direction.y * size, -direction.x * size, 0.0f);
  3956. direction.y = 0.0f; // Keep it in the XY plane
  3957. perp = new Vector3(direction.z * size, 0.0f, -direction.x * size);
  3958. len += Vector3.Magnitude((spline.InterpBezier3D(knot, v2) + perp) - p1);
  3959. }
  3960. return len;
  3961. }
  3962. // Outline test
  3963. public void OutlineSpline(MegaShape shape, int poly, float size, bool centered)
  3964. {
  3965. MegaSpline inSpline = shape.splines[poly];
  3966. MegaSpline outSpline = new MegaSpline();
  3967. OutlineSpline(inSpline, outSpline, size, centered);
  3968. shape.splines.Add(outSpline);
  3969. outSpline.CalcLength(); //10);
  3970. }
  3971. public void OutlineSpline(MegaSpline inSpline, MegaSpline outSpline, float size, bool centered)
  3972. {
  3973. // Do some basic calculations that we'll need regardless
  3974. float size1 = (centered) ? size / 2.0f : 0.0f; // First phase offset
  3975. //float size2 = (centered) ? -size / 2.0f : -size; // Second phase offset
  3976. int knots = inSpline.knots.Count;
  3977. //Vector3 knot, invec, outvec;
  3978. int i;
  3979. //Matrix4x4 theMatrix;
  3980. outSpline.knots.Clear();
  3981. // If the input spline is closed, we wind up with two polygons
  3982. if ( inSpline.closed )
  3983. {
  3984. ///MegaSpline outSpline2 = new MegaSpline(); //shape->NewSpline();
  3985. // Generate the outline polygons...
  3986. for ( i = 0; i < knots; ++i )
  3987. {
  3988. int prevKnot = (i + knots - 1) % knots;
  3989. float oldInLength = CurveLength(inSpline, prevKnot, 0.5f, 1.0f, 0.0f);
  3990. float oldOutLength = CurveLength(inSpline, i, 0.0f, 0.5f, 0.0f);
  3991. //Debug.Log("oldlens " + oldInLength + " " + oldOutLength);
  3992. //int knotType = 0; //inSpline->GetKnotType(i);
  3993. // Determine the angle of the curve at this knot
  3994. // Get vector from interp before knot to interp after knot
  3995. Vector3 ko = inSpline.knots[i].p; //->GetKnotPoint(i);
  3996. //Debug.Log("ko " + ko);
  3997. Vector3 bVec = Vector3.Normalize(inSpline.InterpBezier3D(prevKnot, 0.99f) - ko);
  3998. Vector3 fVec = Vector3.Normalize(inSpline.InterpBezier3D(i, 0.01f) - ko);
  3999. Vector3 direction = Vector3.Normalize(fVec - bVec);
  4000. //direction.z = 0.0f; // Keep it in the XY plane
  4001. direction.y = 0.0f; // Keep it in the XY plane
  4002. // Figure the size multiplier for the crotch angle
  4003. float dot = Vector3.Dot(bVec, fVec);
  4004. float angle, wsize1; //, wsize2;
  4005. if ( dot >= -0.9999939f )
  4006. angle = -Mathf.Acos(dot) / 2.0f;
  4007. else
  4008. angle = Mathf.PI * 0.5f;
  4009. float base1 = size1 / Mathf.Tan(angle);
  4010. float sign1 = (size1 < 0.0f) ? -1.0f : 1.0f;
  4011. wsize1 = Mathf.Sqrt(base1 * base1 + size1 * size1) * sign1;
  4012. //float base2 = size2 / Mathf.Tan(angle);
  4013. //float sign2 = (size2 < 0.0f) ? -1.0f : 1.0f;
  4014. //wsize2 = Mathf.Sqrt(base2 * base2 + size2 * size2) * sign2;
  4015. //Vector3 perp = new Vector3(direction.y * wsize1, -direction.x * wsize1, 0.0f);
  4016. Vector3 perp = new Vector3(direction.z * wsize1, 0.0f, -direction.x * wsize1);
  4017. float newInLength = CurveLength(inSpline, prevKnot, 0.5f, 1.0f, size1);
  4018. float newOutLength = CurveLength(inSpline, i, 0.0f, 0.5f, size1);
  4019. //Debug.Log("newlens " + newInLength + " " + newOutLength);
  4020. //Debug.Log("i " + i + " prev " + prevKnot);
  4021. Vector3 kn = ko + perp;
  4022. //Debug.Log("kn " + kn);
  4023. float inMult = newInLength / oldInLength;
  4024. float outMult = newOutLength / oldOutLength;
  4025. //MegaKnot k(knotType, LTYPE_CURVE, kn, kn + (inSpline.knots[i].invec - ko) * inMult, kn + (inSpline.knots[i].outvec - ko) * outMult);
  4026. outSpline.AddKnot(kn, kn + (inSpline.knots[i].invec - ko) * inMult, kn + (inSpline.knots[i].outvec - ko) * outMult);
  4027. //perp = new Vector3(direction.y * wsize2, -direction.x * wsize2, 0.0f);
  4028. ///perp = new Vector3(direction.z * wsize2, 0.0f, -direction.x * wsize2);
  4029. ///newInLength = CurveLength(inSpline, prevKnot, 0.5f, 1.0f, size2);
  4030. ///newOutLength = CurveLength(inSpline, i, 0.0f, 0.5f, size2);
  4031. ///kn = ko + perp;
  4032. ///inMult = newInLength / oldInLength;
  4033. ///outMult = newOutLength / oldOutLength;
  4034. //k = MegaKnot(knotType, LTYPE_CURVE, kn, kn + (inSpline.knots[i].invec - ko) * inMult, kn + (inSpline.knots[i].outvec - ko) * outMult);
  4035. ///outSpline2.AddKnot(kn, kn + (inSpline.knots[i].invec - ko) * inMult, kn + (inSpline.knots[i].outvec - ko) * outMult);
  4036. }
  4037. outSpline.closed = true;
  4038. //outSpline.ComputeBezPoints();
  4039. //*inSpline = outSpline;
  4040. ///outSpline2.closed = true;
  4041. //outSpline2->ComputeBezPoints();
  4042. ///shape.splines.Add(outSpline);
  4043. //shape.splines.Add(outSpline2);
  4044. ///shape.CalcLength(10);
  4045. }
  4046. else
  4047. { // Otherwise, we get one closed polygon
  4048. // Generate the outline polygon...
  4049. for ( i = 0; i < knots; ++i )
  4050. {
  4051. // Determine the angle of the curve at this knot
  4052. // Get vector from interp before knot to interp after knot
  4053. Vector3 direction;
  4054. Vector3 ko = inSpline.knots[i].p;
  4055. float oldInLength = (i == 0) ? 1.0f : CurveLength(inSpline, i - 1, 0.5f, 1.0f, 0.0f);
  4056. float oldOutLength = (i == (knots - 1)) ? 1.0f : CurveLength(inSpline, i, 0.0f, 0.5f, 0.0f);
  4057. float wsize1 = 0.0f;
  4058. if ( i == 0 )
  4059. {
  4060. direction = Vector3.Normalize(inSpline.InterpBezier3D(i, 0.01f) - ko);
  4061. wsize1 = size1;
  4062. }
  4063. else
  4064. {
  4065. if ( i == (knots - 1) )
  4066. {
  4067. direction = Vector3.Normalize(ko - inSpline.InterpBezier3D(i - 1, 0.99f));
  4068. wsize1 = size1;
  4069. }
  4070. else
  4071. {
  4072. Vector3 bVec = Vector3.Normalize(inSpline.InterpBezier3D(i - 1, 0.99f) - ko);
  4073. Vector3 fVec = Vector3.Normalize(inSpline.InterpBezier3D(i, 0.01f) - ko);
  4074. direction = Vector3.Normalize(fVec - bVec);
  4075. // Figure the size multiplier for the crotch angle
  4076. float dot = Vector3.Dot(bVec, fVec);
  4077. if ( dot >= -0.9999939f )
  4078. {
  4079. float angle = -Mathf.Acos(dot) / 2.0f;
  4080. float base1 = size1 / Mathf.Tan(angle);
  4081. float sign1 = (size1 < 0.0f) ? -1.0f : 1.0f;
  4082. wsize1 = Mathf.Sqrt(base1 * base1 + size1 * size1) * sign1;
  4083. }
  4084. else
  4085. {
  4086. wsize1 = size1;
  4087. }
  4088. }
  4089. }
  4090. //direction.z = 0.0f; // Keep it in the XY plane
  4091. //Vector3 perp = new Vector3(direction.y * wsize1, -direction.x * wsize1, 0.0f);
  4092. direction.y = 0.0f; // Keep it in the XY plane
  4093. Vector3 perp = new Vector3(direction.z * wsize1, 0.0f, -direction.x * wsize1);
  4094. float newInLength = (i == 0) ? 1.0f : CurveLength(inSpline, i - 1, 0.5f, 1.0f, size1);
  4095. float newOutLength = (i == (knots - 1)) ? 1.0f : CurveLength(inSpline, i, 0.0f, 0.5f, size1);
  4096. float inMult = newInLength / oldInLength;
  4097. float outMult = newOutLength / oldOutLength;
  4098. //int knotType = 0; //inSpline->GetKnotType(i);
  4099. Vector3 kn = ko + perp;
  4100. //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);
  4101. outSpline.AddKnot(kn, kn + (inSpline.knots[i].invec - ko) * inMult, kn + (inSpline.knots[i].outvec - ko) * outMult);
  4102. }
  4103. #if false
  4104. for ( i = knots - 1; i >= 0; --i )
  4105. {
  4106. // Determine the angle of the curve at this knot
  4107. // Get vector from interp before knot to interp after knot
  4108. Vector3 direction;
  4109. Vector3 ko = inSpline.knots[i].p; //->GetKnotPoint(i);
  4110. float oldInLength = (i == 0) ? 1.0f : CurveLength(inSpline, i - 1, 0.5f, 1.0f, 0.0f);
  4111. float oldOutLength = (i == (knots - 1)) ? 1.0f : CurveLength(inSpline, i, 0.0f, 0.5f, 0.0f);
  4112. float wsize2 = 0.0f;
  4113. if ( i == 0 )
  4114. {
  4115. direction = Vector3.Normalize(inSpline.InterpBezier3D(i, 0.01f) - ko);
  4116. wsize2 = size2;
  4117. }
  4118. else
  4119. {
  4120. if ( i == (knots - 1) )
  4121. {
  4122. direction = Vector3.Normalize(ko - inSpline.InterpBezier3D(i-1, 0.99f));
  4123. wsize2 = size2;
  4124. }
  4125. else
  4126. {
  4127. Vector3 bVec = Vector3.Normalize(inSpline.InterpBezier3D(i-1, 0.99f) - ko);
  4128. Vector3 fVec = Vector3.Normalize(inSpline.InterpBezier3D(i, 0.01f) - ko);
  4129. direction = Vector3.Normalize(fVec - bVec);
  4130. // Figure the size multiplier for the crotch angle
  4131. float dot = Vector3.Dot(bVec, fVec);
  4132. if ( dot >= -0.9999939f )
  4133. {
  4134. float angle = -Mathf.Acos(dot) / 2.0f;
  4135. float base2 = size2 / Mathf.Tan(angle);
  4136. float sign2 = (size2 < 0.0f) ? -1.0f : 1.0f;
  4137. wsize2 = Mathf.Sqrt(base2 * base2 + size2 * size2) * sign2;
  4138. }
  4139. else
  4140. {
  4141. wsize2 = size2;
  4142. }
  4143. }
  4144. }
  4145. //direction.z = 0.0f; // Keep it in the XY plane
  4146. //Vector3 perp = new Vector3(direction.y * wsize2, -direction.x * wsize2, 0.0f);
  4147. direction.y = 0.0f; // Keep it in the XY plane
  4148. Vector3 perp = new Vector3(direction.z * wsize2, 0.0f, -direction.x * wsize2);
  4149. float newInLength = (i == 0) ? 1.0f : CurveLength(inSpline, i - 1, 0.5f, 1.0f, size2);
  4150. float newOutLength = (i == (knots - 1)) ? 1.0f : CurveLength(inSpline, i, 0.0f, 0.5f, size2);
  4151. float inMult = newInLength / oldInLength;
  4152. float outMult = newOutLength / oldOutLength;
  4153. //int knotType = 0; //inSpline->GetKnotType(i);
  4154. Vector3 kn = ko + perp;
  4155. //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);
  4156. outSpline.AddKnot(kn, kn + (inSpline.knots[i].outvec - ko) * outMult, kn + (inSpline.knots[i].invec - ko) * inMult);
  4157. }
  4158. int lastPt = outSpline.knots.Count - 1;
  4159. outSpline.knots[0].invec = outSpline.knots[0].p; //(0, outSpline.GetKnotPoint(0));
  4160. outSpline.knots[lastPt].outvec = outSpline.knots[lastPt].p; //GetKnotPoint(lastPt));
  4161. outSpline.knots[knots].invec = outSpline.knots[knots].p; //GetKnotPoint(knots));
  4162. outSpline.knots[knots - 1].outvec = outSpline.knots[knots - 1].p; //GetKnotPoint(knots - 1));
  4163. outSpline.closed = true;
  4164. #endif
  4165. outSpline.closed = false;
  4166. }
  4167. }
  4168. #endif
  4169. // Conform
  4170. public bool conform = false;
  4171. public GameObject target;
  4172. public Collider conformCollider;
  4173. public float[] offsets;
  4174. public float[] last;
  4175. public float conformAmount = 1.0f;
  4176. public float raystartoff = 0.0f;
  4177. public float raydist = 10.0f;
  4178. public float conformOffset = 0.0f;
  4179. float minz = 0.0f;
  4180. public void SetTarget(GameObject targ)
  4181. {
  4182. target = targ;
  4183. if ( target )
  4184. {
  4185. conformCollider = target.GetComponent<Collider>();
  4186. }
  4187. }
  4188. void CalcBounds(Vector3[] verts)
  4189. {
  4190. minz = verts[0].y;
  4191. for ( int i = 1; i < verts.Length; i++ )
  4192. {
  4193. if ( verts[i].y < minz )
  4194. minz = verts[i].y;
  4195. }
  4196. }
  4197. public void InitConform(Vector3[] verts)
  4198. {
  4199. if ( offsets == null || offsets.Length != verts.Length )
  4200. {
  4201. offsets = new float[verts.Length];
  4202. last = new float[verts.Length];
  4203. for ( int i = 0; i < verts.Length; i++ )
  4204. offsets[i] = verts[i].y - minz;
  4205. }
  4206. // Only need to do this if target changes, move to SetTarget
  4207. if ( target )
  4208. {
  4209. //MeshFilter mf = target.GetComponent<MeshFilter>();
  4210. //targetMesh = mf.sharedMesh;
  4211. conformCollider = target.GetComponent<Collider>();
  4212. }
  4213. }
  4214. // We could do a bary centric thing if we grid up the bounds
  4215. void DoConform(Vector3[] verts)
  4216. {
  4217. InitConform(verts);
  4218. if ( target && conformCollider )
  4219. {
  4220. Matrix4x4 loctoworld = transform.localToWorldMatrix;
  4221. Matrix4x4 tm = loctoworld; // * worldtoloc;
  4222. Matrix4x4 invtm = tm.inverse;
  4223. Ray ray = new Ray();
  4224. RaycastHit hit;
  4225. float ca = conformAmount;
  4226. // When calculating alpha need to do caps sep
  4227. for ( int i = 0; i < verts.Length; i++ )
  4228. {
  4229. Vector3 origin = tm.MultiplyPoint(verts[i]);
  4230. origin.y += raystartoff;
  4231. ray.origin = origin;
  4232. ray.direction = Vector3.down;
  4233. //loftverts[i] = loftverts1[i];
  4234. if ( conformCollider.Raycast(ray, out hit, raydist) )
  4235. {
  4236. Vector3 lochit = invtm.MultiplyPoint(hit.point);
  4237. verts[i].y = Mathf.Lerp(verts[i].y, lochit.y + offsets[i] + conformOffset, ca); //conformAmount);
  4238. last[i] = verts[i].y;
  4239. }
  4240. else
  4241. {
  4242. Vector3 ht = ray.origin;
  4243. ht.y -= raydist;
  4244. verts[i].y = last[i]; //lochit.z + offsets[i] + offset;
  4245. }
  4246. }
  4247. }
  4248. else
  4249. {
  4250. }
  4251. }
  4252. public float conformWeight = 1.0f; // 1 is conform only this mesh, 0 only the target
  4253. // Option to conform terrain or mesh to mesh, slider to say how much of each happens
  4254. // so 0.5 would meet in the middle
  4255. void ConformTarget()
  4256. {
  4257. // We will need the vertex paint system as will need to find nearest point and have a falloff
  4258. }
  4259. }
  4260. // Need to find major axis and flatten to 2d, then revert back to 3d
  4261. #if true //!UNITY_FLASH
  4262. public class MegaTriangulator
  4263. {
  4264. static public List<Vector3> m_points = new List<Vector3>();
  4265. //public MegaTriangulator(MegaKnot[] points)
  4266. //{
  4267. // m_points = new List<Vector2>(); //points);
  4268. //
  4269. //}
  4270. 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)
  4271. {
  4272. // Find
  4273. m_points.Clear();
  4274. List<MegaKnot> knots = spline.knots;
  4275. Vector3 min = knots[0].p;
  4276. Vector3 max = knots[0].p;
  4277. for ( int i = 1; i < knots.Count; i++ )
  4278. {
  4279. Vector3 p1 = knots[i].p;
  4280. if ( p1.x < min.x ) min.x = p1.x;
  4281. if ( p1.y < min.y ) min.y = p1.y;
  4282. if ( p1.z < min.z ) min.z = p1.z;
  4283. if ( p1.x > max.x ) max.x = p1.x;
  4284. if ( p1.y > max.y ) max.y = p1.y;
  4285. if ( p1.z > max.z ) max.z = p1.z;
  4286. }
  4287. size = max - min;
  4288. int removeaxis = 0;
  4289. if ( Mathf.Abs(size.x) < Mathf.Abs(size.y) )
  4290. {
  4291. if ( Mathf.Abs(size.x) < Mathf.Abs(size.z) )
  4292. removeaxis = 0;
  4293. else
  4294. removeaxis = 2;
  4295. }
  4296. else
  4297. {
  4298. if ( Mathf.Abs(size.y) < Mathf.Abs(size.z) )
  4299. removeaxis = 1;
  4300. else
  4301. removeaxis = 2;
  4302. }
  4303. Vector3 tp = Vector3.zero;
  4304. #if false
  4305. for ( int i = 0; i < knots.Count; i++ )
  4306. {
  4307. for ( int a = 0; a < steps; a ++ )
  4308. {
  4309. float alpha = (float)a / (float)steps;
  4310. Vector3 p = spline.knots[i].Interpolate(alpha, spline.knots[i]);
  4311. switch ( removeaxis )
  4312. {
  4313. case 0: tp.x = p.y; tp.y = p.z; break;
  4314. case 1: tp.x = p.x; tp.y = p.z; break;
  4315. case 2: tp.x = p.x; tp.y = p.y; break;
  4316. }
  4317. verts.Add(p);
  4318. m_points.Add(tp);
  4319. }
  4320. }
  4321. #endif
  4322. float ds = spline.length / (spline.length / dist);
  4323. if ( ds > spline.length )
  4324. ds = spline.length;
  4325. //int c = 0;
  4326. int k = -1;
  4327. //int lk = -1;
  4328. //Vector3 first = spline.Interpolate(0.0f, shape.normalizedInterp, ref lk);
  4329. Vector3 p = Vector3.zero;
  4330. for ( float dst = 0.0f; dst < spline.length; dst += ds )
  4331. {
  4332. float alpha = dst / spline.length;
  4333. p = spline.Interpolate(alpha, shape.normalizedInterp, ref k) + pivot;
  4334. switch ( removeaxis )
  4335. {
  4336. case 0: tp.x = p.y; tp.y = p.z; break;
  4337. case 1: tp.x = p.x; tp.y = p.z; break;
  4338. case 2: tp.x = p.x; tp.y = p.y; break;
  4339. }
  4340. tp.z = dst;
  4341. verts.Add(p);
  4342. m_points.Add(tp);
  4343. // Dont need this here as can do in post step
  4344. //tp.x = (tp.x - min.x) / size.x;
  4345. //tp.y = (tp.y - min.z) / size.z;
  4346. tp.x = (tp.x - min.x); // / size.x;
  4347. tp.y = (tp.y - min.z); // / size.z;
  4348. uvs.Add(tp);
  4349. }
  4350. //if ( spline.closed )
  4351. // p = spline.Interpolate(0.0f, shape.normalizedInterp, ref k);
  4352. //else
  4353. // p = spline.Interpolate(1.0f, shape.normalizedInterp, ref k);
  4354. //switch ( removeaxis )
  4355. //{
  4356. // case 0: tp.x = p.y; tp.y = p.z; break;
  4357. // case 1: tp.x = p.x; tp.y = p.z; break;
  4358. // case 2: tp.x = p.x; tp.y = p.y; break;
  4359. //}
  4360. //verts.Add(p);
  4361. //m_points.Add(tp);
  4362. return Triangulate(indices);
  4363. }
  4364. static public List<int> Triangulate(List<int> indices)
  4365. {
  4366. //List<int> indices = new List<int>();
  4367. int n = m_points.Count;
  4368. if ( n < 3 )
  4369. return indices; //.ToArray();
  4370. int[] V = new int[n];
  4371. if ( Area() > 0.0f )
  4372. {
  4373. for ( int v = 0; v < n; v++ )
  4374. V[v] = v;
  4375. }
  4376. else
  4377. {
  4378. for ( int v = 0; v < n; v++ )
  4379. V[v] = (n - 1) - v;
  4380. }
  4381. int nv = n;
  4382. int count = 2 * nv;
  4383. for ( int m = 0, v = nv - 1; nv > 2; )
  4384. {
  4385. if ( (count--) <= 0 )
  4386. return indices; //.ToArray();
  4387. int u = v;
  4388. if ( nv <= u )
  4389. u = 0;
  4390. v = u + 1;
  4391. if ( nv <= v )
  4392. v = 0;
  4393. int w = v + 1;
  4394. if ( nv <= w )
  4395. w = 0;
  4396. if ( Snip(u, v, w, nv, V) )
  4397. {
  4398. int a, b, c, s, t;
  4399. a = V[u];
  4400. b = V[v];
  4401. c = V[w];
  4402. indices.Add(c);
  4403. indices.Add(b);
  4404. indices.Add(a);
  4405. m++;
  4406. for ( s = v, t = v + 1; t < nv; s++, t++ )
  4407. V[s] = V[t];
  4408. nv--;
  4409. count = 2 * nv;
  4410. }
  4411. }
  4412. //indices.Reverse();
  4413. return indices; //.ToArray();
  4414. }
  4415. static private float Area()
  4416. {
  4417. int n = m_points.Count;
  4418. float A = 0.0f;
  4419. for ( int p = n - 1, q = 0; q < n; p = q++ )
  4420. {
  4421. Vector2 pval = m_points[p];
  4422. Vector2 qval = m_points[q];
  4423. A += pval.x * qval.y - qval.x * pval.y;
  4424. }
  4425. return A * 0.5f;
  4426. }
  4427. static private bool Snip(int u, int v, int w, int n, int[] V)
  4428. {
  4429. Vector2 A = m_points[V[u]];
  4430. Vector2 B = m_points[V[v]];
  4431. Vector2 C = m_points[V[w]];
  4432. if ( Mathf.Epsilon > (((B.x - A.x) * (C.y - A.y)) - ((B.y - A.y) * (C.x - A.x))) )
  4433. return false;
  4434. for ( int p = 0; p < n; p++ )
  4435. {
  4436. if ( (p == u) || (p == v) || (p == w) )
  4437. continue;
  4438. Vector2 P = m_points[V[p]];
  4439. if ( InsideTriangle(A, B, C, P) )
  4440. return false;
  4441. }
  4442. return true;
  4443. }
  4444. static private bool InsideTriangle(Vector2 A, Vector2 B, Vector2 C, Vector2 P)
  4445. {
  4446. float ax = C.x - B.x;
  4447. float ay = C.y - B.y;
  4448. float bx = A.x - C.x;
  4449. float by = A.y - C.y;
  4450. float cx = B.x - A.x;
  4451. float cy = B.y - A.y;
  4452. float apx = P.x - A.x;
  4453. float apy = P.y - A.y;
  4454. float bpx = P.x - B.x;
  4455. float bpy = P.y - B.y;
  4456. float cpx = P.x - C.x;
  4457. float cpy = P.y - C.y;
  4458. float aCROSSbp = ax * bpy - ay * bpx;
  4459. float cCROSSap = cx * apy - cy * apx;
  4460. float bCROSScp = bx * cpy - by * cpx;
  4461. return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f));
  4462. }
  4463. }
  4464. #endif