Random.cpp 134 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159
  1. /******************************************************************************
  2. Xor Shift
  3. http://prng.di.unimi.it/
  4. http://xoroshiro.di.unimi.it/xoroshiro128plus.c
  5. http://xorshift.di.unimi.it/xorshift128plus.c
  6. https://en.wikipedia.org/wiki/Xorshift#Xorshift.2B
  7. Interesting links:
  8. https://gist.github.com/KdotJPG
  9. https://github.com/smcameron/open-simplex-noise-in-c
  10. https://github.com/Auburns/FastNoise
  11. http://staffwww.itn.liu.se/~stegu/aqsis/aqsis-newnoise/
  12. http://accidentalnoise.sourceforge.net/
  13. Performance comparison (64/32 means 64/32-bit platform targets, NOT size of integer), time in seconds needed for 1000000x4 Random calls
  14. UInt-64 ULong-64 UInt-32 ULong-32
  15. xoroshiro 0.012922 0.012616 0.019902 0.020393
  16. xorshift 0.012998 0.012683 0.016544 0.016328
  17. Measured using code below:
  18. Dbl tc;
  19. tc=Time.curTime(); REP(1000000){Random (); Random (); Random (); Random ();} tc=Time.curTime()-tc; MIN(t[0], tc);
  20. tc=Time.curTime(); REP(1000000){Random.l(); Random.l(); Random.l(); Random.l();} tc=Time.curTime()-tc; MIN(t[1], tc);
  21. Performance in 64-bit is the same, in 32-bit xorshift is better, however xoroshiro is chosen, because supposedly it has better statistical quality - http://xoroshiro.di.unimi.it/
  22. /******************************************************************************/
  23. #include "stdafx.h"
  24. #define USE_UID 0 // this is high quality however it's very slow and ignores seed
  25. #define USE_XOROSHIRO 1
  26. #define USE_XORSHIFT 0
  27. #define E 2.71828182845904523536028747135266249775724709369995f
  28. #define E_D 2.71828182845904523536028747135266249775724709369995
  29. // average max values
  30. #define PERLIN_2D_AVG_MAX 0.805
  31. #define PERLIN_3D_AVG_MAX 0.805
  32. #define SIMPLEX_2D_AVG_MAX 0.716
  33. #define SIMPLEX_3D_AVG_MAX 0.755
  34. #define SIMPLEX_4D_AVG_MAX 0.827
  35. // !! if changing this then recalc SIMPLEX_2D_AVG_MAX !! constants were set so average value of Abs(noise) = average value of Abs(Random.normal()/PI)
  36. #define SIMPLEX_NORM_CONSTANT_2D 57.8897114 // Kurt Spencer=47
  37. #define SIMPLEX_NORM_CONSTANT_3D 106.285923 // Kurt Spencer=103
  38. #define SIMPLEX_NORM_CONSTANT_4D 23.9058128 // Kurt Spencer=30
  39. //static Flt OrganicAlt(Flt x) {return 1-Sqr(1-Abs(x));} this is brighter
  40. #define SIMPLEX_WRAP_CIRCLE 0 // don't use circle, because 2D tiled circle version doesn't look much like 2D non-tiled version, and 3D/4D introduce artifacts (the shape is not uniform but bent)
  41. namespace EE{
  42. /******************************************************************************/
  43. Randomizer Random;
  44. /******************************************************************************/
  45. Flt SkewNormalAvg(Flt shape) // calculate average value for Skew Normal distribution
  46. {
  47. return shape/SqrtFast(1+Sqr(shape))*SqrtFast(2/PI);
  48. }
  49. Flt SkewNormalShape(Flt avg) // calculate shape value for Skew Normal distribution which has an average value of 'avg'
  50. {
  51. // avg=shape/SqrtFast(1+Sqr(shape))*SqrtFast(2/PI);
  52. // avg/SqrtFast(2/PI)=shape/SqrtFast(1+Sqr(shape));
  53. // Sqr(avg/SqrtFast(2/PI))=Sqr(shape)/(1+Sqr(shape));
  54. Flt y=avg/SqrtFast(2/PI); // x=shape
  55. // Sqr(y)=Sqr(x)/(1+Sqr(x))
  56. // x*x/(1+x*x)=y*y
  57. // x*x=y*y*(1+x*x)
  58. // x*x=y*y+y*y*x*x
  59. // -y*y=(y*y-1)*x*x
  60. // -y*y/(y*y-1)=x*x
  61. // y*y/(1-y*y)=x*x
  62. // x*x=y*y/(1-y*y)
  63. // x=Sqrt(y*y/(1-y*y))
  64. // x=y*Sqrt(1/(1-y*y))
  65. // x=y/Sqrt(1-y*y)
  66. if(y>= 1)return 2048; // 2048 was calculated by using "y=1-FLT_EPSILON"
  67. if(y<=-1)return -2048;
  68. return y/Sqrt(1-y*y);
  69. }
  70. /******************************************************************************/
  71. void Randomizer::fix()
  72. {
  73. if(!seed.valid())seed.b[0]=1; // can't be zero
  74. }
  75. void Randomizer::randomize()
  76. {
  77. seed.randomize(); fix();
  78. }
  79. Randomizer::Randomizer(UInt s0, UInt s1, UInt s2, UInt s3) : seed(s0, s1, s2, s3) {fix();}
  80. Randomizer::Randomizer(ULong s0, ULong s1 ) : seed(s0, s1 ) {fix();}
  81. Randomizer::Randomizer(C UID &seed ) : seed(seed ) {fix();}
  82. /******************************************************************************/
  83. INLINE static ULong rotl(ULong x, UInt k) {return (x<<k) | (x>>(64-k));}
  84. INLINE static ULong rotr(ULong x, UInt k) {return (x>>k) | (x<<(64-k));}
  85. static ULong SolveXorShr(ULong y, UInt s) // solve the formula "y=x^(x>>s)" and return x, assumes s!=0
  86. {
  87. ULong x=0; // start with zero
  88. for(UInt t=s; ; t+=s)
  89. {
  90. x=y^(x>>s); // guess what we should have based on what we know
  91. if(t>=64)break; // if we've reached all bits then stop
  92. x&=(~0ULL)<<(64-t); // AND with a growing mask (at start we know only 's' bits, but with every step we know 's' bits more)
  93. }
  94. return x;
  95. }
  96. static ULong SolveXorShl(ULong y, UInt s) // solve the formula "y=x^(x<<s)" and return x, assumes s!=0
  97. {
  98. ULong x=0; // start with zero
  99. for(UInt t=s; ; t+=s)
  100. {
  101. x=y^(x<<s); // guess what we should have based on what we know
  102. if(t>=64)break; // if we've reached all bits then stop
  103. x&=(~0ULL)>>(64-t); // AND with a growing mask (at start we know only 's' bits, but with every step we know 's' bits more)
  104. }
  105. return x;
  106. }
  107. #pragma runtime_checks("", off)
  108. UInt Randomizer::operator()()
  109. {
  110. #if USE_UID
  111. UID id; id.randomize(); return id.i[0]^id.i[1]^id.i[2]^id.i[3];
  112. #elif USE_XOROSHIRO
  113. const ULong s0=seed.l[0];
  114. ULong s1=seed.l[1];
  115. s1^=s0;
  116. seed.l[0]=rotl(s0, 55)^s1^(s1<<14); // a, b
  117. seed.l[1]=rotl(s1, 36); // c
  118. return seed.i[0]+seed.i[2];
  119. #elif USE_XORSHIFT
  120. ULong s1=seed.l[0];
  121. const ULong s0=seed.l[1];
  122. seed.l[0]=s0;
  123. s1^=s1<<23;
  124. seed.l[1]=s1^s0^(s1>>17)^(s0>>26);
  125. return seed.l[1]+s0;
  126. #else
  127. return 0;
  128. #endif
  129. }
  130. #pragma runtime_checks("", restore)
  131. ULong Randomizer::l()
  132. {
  133. #if USE_UID
  134. UID id; id.randomize(); return id.l[0]^id.l[1];
  135. #elif USE_XOROSHIRO
  136. const ULong s0=seed.l[0];
  137. ULong s1=seed.l[1];
  138. s1^=s0;
  139. seed.l[0]=rotl(s0, 55)^s1^(s1<<14); // a, b
  140. seed.l[1]=rotl(s1, 36); // c
  141. return seed.l[0]+seed.l[1];
  142. #elif USE_XORSHIFT
  143. ULong s1=seed.l[0];
  144. const ULong s0=seed.l[1];
  145. seed.l[0]=s0;
  146. s1^=s1<<23;
  147. seed.l[1]=s1^s0^(s1>>17)^(s0>>26);
  148. return seed.l[1]+s0;
  149. #else
  150. return 0;
  151. #endif
  152. }
  153. Randomizer& Randomizer::back()
  154. {
  155. #if USE_XOROSHIRO
  156. ULong s1=rotr(seed.l[1], 36), // at this time it's actually "s1^s0" and not "s1"
  157. s0=rotr(seed.l[0]^s1^(s1<<14), 55); // rotl(s0, 55)=seed.l[0]^s1^(s1<<14);
  158. s1^=s0; // get actual s1
  159. seed.l[0]=s0;
  160. seed.l[1]=s1;
  161. #elif USE_XORSHIFT
  162. ULong s0=seed.l[0],
  163. s1=SolveXorShr(seed.l[1]^s0^(s0>>26), 17); // s1^(s1>>17)=seed.l[1]^s0^(s0>>26);
  164. s1=SolveXorShl(s1, 23); // s1=s1^(s1<<23);
  165. seed.l[0]=s1;
  166. seed.l[1]=s0;
  167. #else
  168. #error not supported
  169. #endif
  170. return T;
  171. }
  172. UInt Randomizer::operator()(UInt n ) {return n ? T()%n : 0;}
  173. Int Randomizer::operator()(Int min, Int max) {return min+T(max-min+1);}
  174. Bool Randomizer::b ( ) {return T()&1;}
  175. Flt Randomizer::f ( ) {return T()*(1.0/UINT_MAX);}
  176. Flt Randomizer::f (Flt x ) {return f()*x;}
  177. Flt Randomizer::f (Flt min, Flt max) {return min+f()*(max-min);}
  178. Vec2 Randomizer::vec2 ( ) {return Vec2(f( ), f( ) );}
  179. Vec2 Randomizer::vec2 (Flt x ) {return Vec2(f(x ), f(x ) );}
  180. Vec2 Randomizer::vec2 (Flt min, Flt max) {return Vec2(f(min, max), f(min, max) );}
  181. Vec Randomizer::vec ( ) {return Vec (f( ), f( ), f( ));}
  182. Vec Randomizer::vec (Flt x ) {return Vec (f(x ), f(x ), f(x ));}
  183. Vec Randomizer::vec (Flt min, Flt max) {return Vec (f(min, max), f(min, max), f(min, max));}
  184. /******************************************************************************/
  185. UInt Randomizer::align (UInt n , Flt (&func)(Flt x)) {if(!n)return 0; UInt u=TruncU(alignF(func)*n); if(u==n)u--; return u;}
  186. Int Randomizer::align (Int min, Int max, Flt (&func)(Flt x)) {return min+align(max-min+1, func);}
  187. Flt Randomizer::alignF( Flt (&func)(Flt x)) {return func(f());}
  188. Flt Randomizer::alignF(Flt x , Flt (&func)(Flt x)) {return alignF(func)* x ;}
  189. Flt Randomizer::alignF(Flt min, Flt max, Flt (&func)(Flt x)) {return alignF(func)*(max-min)+min;}
  190. UInt Randomizer::align (UInt n , Flt (&func)(Flt x, Flt y), Flt y) {if(!n)return 0; UInt u=TruncU(alignF(func, y)*n); if(u==n)u--; return u;}
  191. Int Randomizer::align (Int min, Int max, Flt (&func)(Flt x, Flt y), Flt y) {return min+align(max-min+1, func, y);}
  192. Flt Randomizer::alignF( Flt (&func)(Flt x, Flt y), Flt y) {return func(f(), y);}
  193. Flt Randomizer::alignF(Flt x , Flt (&func)(Flt x, Flt y), Flt y) {return alignF(func, y)* x ;}
  194. Flt Randomizer::alignF(Flt min, Flt max, Flt (&func)(Flt x, Flt y), Flt y) {return alignF(func, y)*(max-min)+min;}
  195. static Flt ProbabilityPow(Flt x, Flt y) {return (y>=1) ? Pow(x, y) : 1-Pow(1-x, 1.0f/y);}
  196. UInt Randomizer::alignPow (UInt n , Flt pow) {return align (n, ProbabilityPow, pow);}
  197. Int Randomizer::alignPow (Int min, Int max, Flt pow) {return align (min, max, ProbabilityPow, pow);}
  198. Flt Randomizer::alignPowF( Flt pow) {return alignF( ProbabilityPow, pow);}
  199. Flt Randomizer::alignPowF(Flt x , Flt pow) {return alignF(x, ProbabilityPow, pow);}
  200. Flt Randomizer::alignPowF(Flt min, Flt max, Flt pow) {return alignF(min, max, ProbabilityPow, pow);}
  201. /******************************************************************************/
  202. Flt Randomizer::alignTargetNormalF(Flt min, Flt max, Flt target, Flt sharpness)
  203. {
  204. Flt bias=LerpR(min, max, target)*2-1; // -1..1
  205. // tweak bias
  206. if(bias> 0.5f)bias+=Cube(bias-0.5f)*9;else
  207. if(bias<-0.5f)bias+=Cube(bias+0.5f)*9;
  208. // for sharpness=2 -> E, sharpness=1 -> 2
  209. //bias=powf(E, bias*2); for sharpness=2 which is bias=expf(bias*2);
  210. //bias=powf(2, bias*2); for sharpness=1
  211. const Flt scale=E-2, add=2-scale, base=Min(E, sharpness*scale+add);
  212. bias=Pow(base, bias*2);
  213. return min+(max-min)*bias/(bias+expf(normal()/sharpness));
  214. }
  215. /******************************************************************************/
  216. Flt Randomizer::normal()
  217. {
  218. return SqrtFast(-2*Ln(f()+FLT_MIN))*Cos(PI2*f());
  219. }
  220. Flt Randomizer::normalSkew(Flt shape)
  221. {
  222. Flt sigma=shape/SqrtFast(1+Sqr(shape)),
  223. u0 =normal(),
  224. u1 =sigma*u0 + SqrtFast(1-Sqr(sigma))*normal();
  225. return (u0>=0) ? u1 : -u1;
  226. }
  227. /******************************************************************************/
  228. Vec Randomizer::dir(C Vec &dir, Flt a)
  229. {
  230. Flt c0, s0; CosSin(c0, s0, f(a ));
  231. Flt c1, s1; CosSin(c1, s1, f(PI2));
  232. Vec z=PerpN(dir),
  233. x=Cross(dir, z);
  234. return (x*c1 + z*s1)*s0 + dir*c0;
  235. }
  236. Vec Randomizer::dir(C Vec &dir, Flt min, Flt max)
  237. {
  238. Flt c0, s0; CosSin(c0, s0, f(min, max));
  239. Flt c1, s1; CosSin(c1, s1, f(PI2));
  240. Vec z=PerpN(dir),
  241. x=Cross(dir, z);
  242. return (x*c1 + z*s1)*s0 + dir*c0;
  243. }
  244. /******************************************************************************/
  245. Vec Randomizer::sphere(C Ball &ball, Flt min, Flt max)
  246. {
  247. Flt ac, as; CosSin(ac, as, f(PI2));
  248. Flt bs=f(min, max),
  249. bc=CosSin(bs);
  250. return Vec(bc*ac*ball.r, bs*ball.r,
  251. bc*as*ball.r) +ball.pos;
  252. }
  253. /******************************************************************************/
  254. Vec Randomizer::operator()(C Edge &edge)
  255. {
  256. return Lerp(edge.p[0], edge.p[1], f());
  257. }
  258. /******************************************************************************/
  259. Vec2 Randomizer::operator()(C Tri2 &tri, Bool inside)
  260. {
  261. if(inside)
  262. {
  263. Flt u=f(),
  264. v=f();
  265. if(u+v>1)
  266. {
  267. u=1-u;
  268. v=1-v;
  269. }
  270. return tri.p[0]
  271. +(tri.p[1]-tri.p[0])*u
  272. +(tri.p[2]-tri.p[0])*v;
  273. }else
  274. {
  275. Flt l01=Dist(tri.p[0], tri.p[1]),
  276. l12=Dist(tri.p[1], tri.p[2]),
  277. l20=Dist(tri.p[2], tri.p[0]),
  278. l =f (l01+l12+l20);
  279. // when changing codes watch for division by zero
  280. if(l<l01)return Lerp(tri.p[0], tri.p[1], l/l01); l-=l01;
  281. if(l<l12)return Lerp(tri.p[1], tri.p[2], l/l12); l-=l12;
  282. if(l<l20)return Lerp(tri.p[2], tri.p[0], l/l20);
  283. return tri.p[0];
  284. }
  285. }
  286. Vec Randomizer::operator()(C Tri &tri, Bool inside)
  287. {
  288. if(inside)
  289. {
  290. Flt u=f(),
  291. v=f();
  292. if(u+v>1)
  293. {
  294. u=1-u;
  295. v=1-v;
  296. }
  297. return tri.p[0]
  298. +(tri.p[1]-tri.p[0])*u
  299. +(tri.p[2]-tri.p[0])*v;
  300. }else
  301. {
  302. Flt l01=Dist(tri.p[0], tri.p[1]),
  303. l12=Dist(tri.p[1], tri.p[2]),
  304. l20=Dist(tri.p[2], tri.p[0]),
  305. l =f (l01+l12+l20);
  306. // when changing codes watch for division by zero
  307. if(l<l01)return Lerp(tri.p[0], tri.p[1], l/l01); l-=l01;
  308. if(l<l12)return Lerp(tri.p[1], tri.p[2], l/l12); l-=l12;
  309. if(l<l20)return Lerp(tri.p[2], tri.p[0], l/l20);
  310. return tri.p[0];
  311. }
  312. }
  313. /******************************************************************************/
  314. Vec2 Randomizer::operator()(C Quad2 &quad, Bool inside)
  315. {
  316. if(inside)
  317. {
  318. Tri2 t0=quad.tri013(),
  319. t1=quad.tri123();
  320. Flt a0=t0 .area (),
  321. a1=t1 .area ();
  322. Flt a =f(a0+a1);
  323. if( a<=a0)return T(t0);
  324. return T(t1);
  325. }else
  326. {
  327. Flt l01=Dist(quad.p[0], quad.p[1]),
  328. l12=Dist(quad.p[1], quad.p[2]),
  329. l23=Dist(quad.p[2], quad.p[3]),
  330. l30=Dist(quad.p[3], quad.p[0]),
  331. l =f (l01+l12+l23+l30);
  332. // when changing codes watch for division by zero
  333. if(l<l01)return Lerp(quad.p[0], quad.p[1], l/l01); l-=l01;
  334. if(l<l12)return Lerp(quad.p[1], quad.p[2], l/l12); l-=l12;
  335. if(l<l23)return Lerp(quad.p[2], quad.p[3], l/l23); l-=l23;
  336. if(l<l30)return Lerp(quad.p[3], quad.p[0], l/l30);
  337. return quad.p[0];
  338. }
  339. }
  340. Vec Randomizer::operator()(C Quad &quad, Bool inside)
  341. {
  342. if(inside)
  343. {
  344. Tri t0=quad.tri013(),
  345. t1=quad.tri123();
  346. Flt a0=t0 .area (),
  347. a1=t1 .area ();
  348. Flt a =f(a0+a1);
  349. if( a<=a0)return T(t0);
  350. return T(t1);
  351. }else
  352. {
  353. Flt l01=Dist(quad.p[0], quad.p[1]),
  354. l12=Dist(quad.p[1], quad.p[2]),
  355. l23=Dist(quad.p[2], quad.p[3]),
  356. l30=Dist(quad.p[3], quad.p[0]),
  357. l =f (l01+l12+l23+l30);
  358. // when changing codes watch for division by zero
  359. if(l<l01)return Lerp(quad.p[0], quad.p[1], l/l01); l-=l01;
  360. if(l<l12)return Lerp(quad.p[1], quad.p[2], l/l12); l-=l12;
  361. if(l<l23)return Lerp(quad.p[2], quad.p[3], l/l23); l-=l23;
  362. if(l<l30)return Lerp(quad.p[3], quad.p[0], l/l30);
  363. return quad.p[0];
  364. }
  365. }
  366. /******************************************************************************/
  367. Vec2 Randomizer::operator()(C Rect &rect, Bool inside)
  368. {
  369. if(inside)return rect.min+vec2()*rect.size();
  370. Flt w=rect.w(),
  371. h=rect.h(),
  372. r=f(w*2 + h*2);
  373. if(r<=w)return Vec2(rect.min.x+r, rect.min.y ); r-=w;
  374. if(r<=w)return Vec2(rect.min.x+r, rect.max.y ); r-=w;
  375. if(r<=h)return Vec2(rect.min.x , rect.min.y+r); r-=h;
  376. return Vec2(rect.max.x , rect.min.y+r);
  377. }
  378. /******************************************************************************/
  379. Vec Randomizer::operator()(C Box &box, Bool inside)
  380. {
  381. if(inside)return box.min+vec()*box.size();
  382. Flt w=box.w(),
  383. h=box.h(),
  384. d=box.d(),
  385. x=d*h,
  386. y=w*d,
  387. z=w*h,
  388. r=f(x*2 + y*2 + z*2);
  389. if(r<=x)return Vec(box.min.x , box.min.y+f(h), box.min.z+f(d)); r-=x;
  390. if(r<=x)return Vec(box.max.x , box.min.y+f(h), box.min.z+f(d)); r-=x;
  391. if(r<=y)return Vec(box.min.x+f(w), box.min.y , box.min.z+f(d)); r-=y;
  392. if(r<=y)return Vec(box.min.x+f(w), box.max.y , box.min.z+f(d)); r-=y;
  393. if(r<=z)return Vec(box.min.x+f(w), box.min.y+f(h), box.min.z ); r-=z;
  394. return Vec(box.min.x+f(w), box.min.y+f(h), box.max.z );
  395. }
  396. Vec Randomizer::operator()(C OBox &obox, Bool inside) {return T(obox.box, inside)*obox.matrix;}
  397. Vec Randomizer::operator()(C Extent &ext , Bool inside) {return T(Box(ext), inside);}
  398. /******************************************************************************/
  399. Vec2 Randomizer::circle1(Bool inside)
  400. {
  401. Vec2 O; CosSin(O.x, O.y, f(PI2));
  402. if(inside)O*=Sqrt(f());
  403. return O;
  404. }
  405. Vec2 Randomizer::circle(Flt radius, Bool inside)
  406. {
  407. Vec2 O; CosSin(O.x, O.y, f(PI2));
  408. return O*(inside ? Sqrt(f())*radius : radius);
  409. }
  410. Vec2 Randomizer::operator()(C Circle &circle, Bool inside)
  411. {
  412. Vec2 O; CosSin(O.x, O.y, f(PI2));
  413. return O*(inside ? Sqrt(f())*circle.r : circle.r)+circle.pos;
  414. }
  415. /******************************************************************************/
  416. Vec Randomizer::operator()(C Ball &ball, Bool inside)
  417. {
  418. Flt ac, as; CosSin(ac, as, f(PI2));
  419. Flt bs=f(-1, 1),
  420. bc=CosSin(bs);
  421. Vec O(bc*ac, bs,
  422. bc*as);
  423. return O*(inside ? Cbrt(f())*ball.r : ball.r)+ball.pos;
  424. }
  425. /******************************************************************************/
  426. Vec Randomizer::operator()(C Capsule &capsule, Bool inside)
  427. {
  428. Flt c, s;
  429. if(inside){c=capsule.volume(); s=Ball(capsule.r).volume();}
  430. else {c=capsule.area (); s=Ball(capsule.r).area ();}
  431. if(f(c)>=s)
  432. {
  433. return T(Tube(capsule.r, capsule.h-capsule.r*2, capsule.pos, capsule.up), inside);
  434. }else
  435. {
  436. Vec O=T(Ball(capsule.r), inside);
  437. return O+capsule.pos
  438. +capsule.up*((capsule.h*0.5f-capsule.r)*Sign(Dot(O, capsule.up)));
  439. }
  440. }
  441. /******************************************************************************/
  442. Vec Randomizer::operator()(C Tube &tube, Bool inside)
  443. {
  444. Vec z=PerpN (tube.up),
  445. x=Cross (tube.up, z);
  446. Vec2 c=circle(tube.r, inside);
  447. return tube.pos
  448. +tube.up*(f(-0.5f, 0.5f)*tube.h)
  449. +x*c.x
  450. +z*c.y;
  451. }
  452. /******************************************************************************/
  453. Vec Randomizer::operator()(C Torus &torus, Bool inside)
  454. {
  455. Vec2 circle=T.circle(torus.r, inside);
  456. Matrix matrix; matrix.setPosUp(torus.pos, torus.up).rotateYL(f(PI2));
  457. return Vec(circle.x+torus.R, circle.y, 0)*matrix;
  458. }
  459. /******************************************************************************/
  460. Vec Randomizer::operator()(C Cone &cone, Bool inside)
  461. {
  462. if(inside)
  463. {
  464. Flt y_step;
  465. if(cone.h<=0)y_step=0;else
  466. if(Equal(cone.r_low, cone.r_high))y_step=f(1);else
  467. {
  468. // normally 'step' should be calculated from formula : "step=Cbrt(f(1))"
  469. // however since top and bottom of the cone can have different radius values, that's why we need to add the "missing piece" (in it calculate the limit values of radiuses, and randomize a point in this step range)
  470. Flt r0=0,
  471. r1=Min(cone.r_low, cone.r_high),
  472. r2=Max(cone.r_low, cone.r_high);
  473. if( r1<=EPS)
  474. {
  475. y_step=Cbrt(f(1));
  476. }else
  477. {
  478. Flt dr=(r2-r1)/cone.h, // radius increase on unit of height
  479. h0=0,
  480. h1=r1/dr,
  481. h2=h1+cone.h;
  482. y_step=Cbrt(f(Cube(h1/h2), 1))*h2; // gives uniform distribution in range h1..h2
  483. y_step=LerpRS(h1, h2, y_step);
  484. }
  485. if(cone.r_low>cone.r_high)y_step=1-y_step;
  486. }
  487. Vec2 p=T.circle(Lerp(cone.r_low, cone.r_high, y_step));
  488. Matrix3 m; m.setUp(cone.up);
  489. return cone.pos
  490. +m.y*(y_step*cone.h)
  491. +m.x*p.x
  492. +m.z*p.y;
  493. }else
  494. {
  495. Flt area=cone.area(),
  496. f =T.f(area);
  497. Matrix3 m; m.setUp(cone.up);
  498. // check lower surface
  499. Circle circle_lo(cone.r_low);
  500. Flt circle_lo_area=circle_lo.area();
  501. if( f<=circle_lo_area)
  502. {
  503. Vec2 p=T.circle(circle_lo.r);
  504. return cone.pos
  505. +m.x*p.x
  506. +m.z*p.y;
  507. }
  508. f-=circle_lo_area;
  509. // check upper surface
  510. Circle circle_hi(cone.r_high);
  511. Flt circle_hi_area=circle_hi.area();
  512. if( f<=circle_hi_area)
  513. {
  514. Vec2 p=T.circle(circle_hi.r);
  515. return cone.pos
  516. +m.y*cone.h
  517. +m.x*p.x
  518. +m.z*p.y;
  519. }
  520. // create on side surface
  521. Flt y_step;
  522. if(cone.h<=0)y_step=0;else
  523. if(Equal(cone.r_low, cone.r_high))y_step=T.f(1);else
  524. {
  525. // normally 'step' should be calculated from formula : "step=Sqrt(f(1))"
  526. // however since top and bottom of the cone can have different radius values, that's why we need to add the "missing piece" (in it calculate the limit values of radiuses, and randomize a point in this step range)
  527. Flt r0=0,
  528. r1=Min(cone.r_low, cone.r_high),
  529. r2=Max(cone.r_low, cone.r_high);
  530. if( r1<=EPS)
  531. {
  532. y_step=Sqrt(T.f(1));
  533. }else
  534. {
  535. Flt dr=(r2-r1)/cone.h, // radius increase on unit of height
  536. h0=0,
  537. h1=r1/dr,
  538. h2=h1+cone.h;
  539. y_step=Sqrt(T.f(Sqr(h1/h2), 1))*h2; // gives uniform distribution in range h1..h2
  540. y_step=LerpRS(h1, h2, y_step);
  541. }
  542. if(cone.r_low>cone.r_high)y_step=1-y_step;
  543. }
  544. Flt angle=T.f(PI2);
  545. Vec2 p; CosSin(p.x, p.y, angle); p*=Lerp(cone.r_low, cone.r_high, y_step);
  546. return cone.pos
  547. +m.y*(cone.h*y_step)
  548. +m.x*p.x
  549. +m.z*p.y;
  550. }
  551. }
  552. /******************************************************************************/
  553. Vec Randomizer::operator()(C Pyramid &pyramid, Bool inside)
  554. {
  555. if(inside)
  556. {
  557. Flt z=Cbrt(f( 1 ))*pyramid.h,
  558. y= f(-1, 1) *pyramid.scale*z,
  559. x= f(-1, 1) *pyramid.scale*z;
  560. return pyramid.pos
  561. +pyramid.dir *z
  562. +pyramid.perp *y
  563. +pyramid.cross()*x;
  564. }else
  565. {
  566. Flt area =pyramid.area(),
  567. f =T.f(area), // randomize 'f' on surface
  568. square=Sqr(pyramid.side()); // base surface area
  569. if(f<square) // if placed on base surface (use '<' instead of '<=' to take division by zero into account)
  570. {
  571. Flt x=(f/square)*2-1,
  572. y=T.f(-1, 1);
  573. return pyramid.pos
  574. +pyramid.dir * pyramid.h
  575. +pyramid.perp *(y*pyramid.scale*pyramid.h)
  576. +pyramid.cross()*(x*pyramid.scale*pyramid.h);
  577. }
  578. Vec x =pyramid.cross()*(pyramid.scale*pyramid.h),
  579. y =pyramid.perp *(pyramid.scale*pyramid.h),
  580. z =pyramid.dir * pyramid.h,
  581. center=pyramid.pos + z,
  582. lu =center-x+y,
  583. ru =center+x+y,
  584. rd =center+x-y,
  585. ld =center-x-y;
  586. switch(T(4))
  587. {
  588. case 0: return T(Tri(pyramid.pos, lu, ru));
  589. case 1: return T(Tri(pyramid.pos, ru, rd));
  590. case 2: return T(Tri(pyramid.pos, rd, ld));
  591. default: return T(Tri(pyramid.pos, ld, lu));
  592. }
  593. }
  594. }
  595. /******************************************************************************/
  596. Vec Randomizer::operator()(C Shape &shape, Bool inside)
  597. {
  598. switch(shape.type)
  599. {
  600. case SHAPE_POINT : return shape.point ;
  601. case SHAPE_EDGE : return T(shape.edge );
  602. case SHAPE_RECT : return Vec(T(shape.rect , inside), 0);
  603. case SHAPE_BOX : return T(shape.box , inside);
  604. case SHAPE_OBOX : return T(shape.obox , inside);
  605. case SHAPE_CIRCLE : return Vec(T(shape.circle , inside), 0);
  606. case SHAPE_BALL : return T(shape.ball , inside);
  607. case SHAPE_CAPSULE: return T(shape.capsule, inside);
  608. case SHAPE_TUBE : return T(shape.tube , inside);
  609. case SHAPE_TORUS : return T(shape.torus , inside);
  610. case SHAPE_CONE : return T(shape.cone , inside);
  611. case SHAPE_PYRAMID: return T(shape.pyramid, inside);
  612. default : return 0;
  613. }
  614. }
  615. /******************************************************************************/
  616. Vec Randomizer::operator()(C MeshBase &mshb, C AnimatedSkeleton *anim_skel)
  617. {
  618. if( Int faces=mshb.faces ())
  619. if(C Vec *pos =mshb.vtx.pos())
  620. {
  621. C VecB4 *bone;
  622. C VecB4 *weight;
  623. Int face=T(faces);
  624. if( face<mshb.tris()) // triangle
  625. {
  626. C VecI &ind=mshb.tri.ind(face);
  627. C Vec &a =pos[ind.x],
  628. &b =pos[ind.y],
  629. &c =pos[ind.z];
  630. if(anim_skel && (bone=mshb.vtx.matrix()) && (weight=mshb.vtx.blend())) // animated
  631. {
  632. Byte msb_a=bone[ind.x].c[weight[ind.x].maxI()], // for performance reasons only one bone with biggest weight is used
  633. msb_b=bone[ind.y].c[weight[ind.y].maxI()],
  634. msb_c=bone[ind.z].c[weight[ind.z].maxI()];
  635. return T(Tri(a*anim_skel->boneRoot(msb_a-1).matrix(),
  636. b*anim_skel->boneRoot(msb_b-1).matrix(),
  637. c*anim_skel->boneRoot(msb_c-1).matrix()));
  638. }else // static
  639. {
  640. return T(Tri(a, b, c));
  641. }
  642. }else // quad
  643. {
  644. face-=mshb.tris();
  645. C VecI4 &ind=mshb.quad.ind(face);
  646. C Vec &a =pos[ind.x],
  647. &b =pos[ind.y],
  648. &c =pos[ind.z],
  649. &d =pos[ind.w];
  650. if(anim_skel && (bone=mshb.vtx.matrix()) && (weight=mshb.vtx.blend())) // animated
  651. {
  652. Byte msb_a=bone[ind.x].c[weight[ind.x].maxI()], // for performance reasons only one bone with biggest weight is used
  653. msb_b=bone[ind.y].c[weight[ind.y].maxI()],
  654. msb_c=bone[ind.z].c[weight[ind.z].maxI()],
  655. msb_d=bone[ind.w].c[weight[ind.w].maxI()];
  656. return T(Quad(a*anim_skel->boneRoot(msb_a-1).matrix(),
  657. b*anim_skel->boneRoot(msb_b-1).matrix(),
  658. c*anim_skel->boneRoot(msb_c-1).matrix(),
  659. d*anim_skel->boneRoot(msb_d-1).matrix()));
  660. }else // static
  661. {
  662. return T(Quad(a, b, c, d));
  663. }
  664. }
  665. }
  666. return 0;
  667. }
  668. Vec Randomizer::operator()(C MeshRender &mshr, C AnimatedSkeleton *anim_skel)
  669. {
  670. Vec out(0);
  671. if(mshr.tris())
  672. {
  673. Int pos_ofs =mshr.vtxOfs(VTX_POS);
  674. if( pos_ofs>=0)
  675. if(C Byte *vtx_data=mshr.vtxLockRead())
  676. {
  677. if(CPtr ind=mshr.indLockRead())
  678. {
  679. // calculate random face and its vertexes
  680. VecI vtx_ofs;
  681. Int face=T(mshr.tris())*3; // 3 vtx indexes in each triangle
  682. if(mshr._ib.bit16()){U16 *d=(U16*)ind; vtx_ofs.set(d[face], d[face+1], d[face+2]);}
  683. else {U32 *d=(U32*)ind; vtx_ofs.set(d[face], d[face+1], d[face+2]);}
  684. vtx_ofs*=mshr.vtxSize();
  685. // get vertex positions
  686. C Vec &a=*(Vec*)(vtx_data+vtx_ofs.x+pos_ofs),
  687. &b=*(Vec*)(vtx_data+vtx_ofs.y+pos_ofs),
  688. &c=*(Vec*)(vtx_data+vtx_ofs.z+pos_ofs);
  689. Int bone_ofs,
  690. weight_ofs;
  691. if(anim_skel && ((bone_ofs=mshr.vtxOfs(VTX_MATRIX))>=0) && ((weight_ofs=mshr.vtxOfs(VTX_BLEND))>=0)) // animated
  692. {
  693. C VecB4 & bone_a=*(VecB4*)(vtx_data+vtx_ofs.x+ bone_ofs),
  694. & bone_b=*(VecB4*)(vtx_data+vtx_ofs.y+ bone_ofs),
  695. & bone_c=*(VecB4*)(vtx_data+vtx_ofs.z+ bone_ofs),
  696. &weight_a=*(VecB4*)(vtx_data+vtx_ofs.x+weight_ofs),
  697. &weight_b=*(VecB4*)(vtx_data+vtx_ofs.y+weight_ofs),
  698. &weight_c=*(VecB4*)(vtx_data+vtx_ofs.z+weight_ofs);
  699. // get most significant bone
  700. Byte msb_a=bone_a.c[weight_a.maxI()],
  701. msb_b=bone_b.c[weight_b.maxI()],
  702. msb_c=bone_c.c[weight_c.maxI()];
  703. if(mshr._bone_split)
  704. {
  705. Int tris=0; FREP(mshr._bone_splits)
  706. {
  707. MeshRender::BoneSplit &bs=mshr._bone_split[i];
  708. if(face>=tris && face<tris+bs.tris)
  709. {
  710. msb_a=bs.split_to_real[msb_a];
  711. msb_b=bs.split_to_real[msb_b];
  712. msb_c=bs.split_to_real[msb_c];
  713. break;
  714. }
  715. tris+=bs.tris;
  716. }
  717. }
  718. out=T(Tri(a*anim_skel->boneRoot(msb_a-1).matrix(),
  719. b*anim_skel->boneRoot(msb_b-1).matrix(),
  720. c*anim_skel->boneRoot(msb_c-1).matrix()));
  721. }else // static
  722. {
  723. out=T(Tri(a, b, c));
  724. }
  725. mshr.indUnlock();
  726. }
  727. mshr.vtxUnlock();
  728. }
  729. }
  730. return out;
  731. }
  732. Vec Randomizer::operator()(C MeshPart &part, C AnimatedSkeleton *anim_skel)
  733. {
  734. return part.base.faces() ? T(part.base, anim_skel) : T(part.render, anim_skel);
  735. }
  736. Vec Randomizer::operator()(C Mesh &mesh, C AnimatedSkeleton *anim_skel)
  737. {
  738. return mesh.parts.elms() ? T(mesh.parts[T(mesh.parts.elms())], anim_skel) : 0;
  739. }
  740. /******************************************************************************/
  741. StrO Randomizer::password(Int length, Bool chars, Bool digs, Bool symbols)
  742. {
  743. if(length>0)
  744. {
  745. Str8 elms; if(chars)elms+="abcdefghijklmnopqrstuvwxyz"; if(digs)elms+="0123456789"; if(symbols)elms+="~!@#$%^&*()_-+=[]{};:,.<>?'\"/|\\";
  746. if( elms.length())
  747. {
  748. StrO pass; REP(length)pass+=elms[T(elms.length())];
  749. return pass;
  750. }
  751. }
  752. return S;
  753. }
  754. static Char8 LicenseKeyChars[]={'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
  755. StrO Randomizer::licenseKey()
  756. {
  757. StrO key; key.reserve(5*5+4);
  758. FREP(5)
  759. {
  760. if(i)key+='-';
  761. REP(5)key+=LicenseKeyChars[T(Elms(LicenseKeyChars))];
  762. }
  763. return key;
  764. }
  765. /******************************************************************************/
  766. // PERLIN NOISE
  767. /******************************************************************************/
  768. #if 0 // Esenthel version (not finished) produces less blocky results, however requires a lot more memory
  769. static Flt R[256][256][2];
  770. struct TEMP
  771. {
  772. TEMP()
  773. {
  774. Random.seed.set(1,1,1,1);
  775. REPD(x, 256)
  776. REPD(y, 256)
  777. {
  778. //R[y][x][0]=Random.f()*2-1;
  779. //R[y][x][1]=Random.f()*2-1;
  780. Vec2 p=Random.circle(1, false);
  781. R[y][x][0]=p.x;
  782. R[y][x][1]=p.y;
  783. //R[y][x][0]=SignBool(Random.b());
  784. //R[y][x][1]=SignBool(Random.b());
  785. //R[y][x][0]=Round(p.x);
  786. //R[y][x][1]=Round(p.y);
  787. }
  788. }
  789. }TT;
  790. static Flt Grad(Int x, Int y, Flt fx, Flt fy, UInt seed)
  791. {
  792. //Randomizer rnd(x, y, 0, seed);
  793. //return (rnd.f()*2-1)*fx + (rnd.f()*2-1)*fy;
  794. return R[x&255][y&255][0]*fx + R[x&255][y&255][1]*fy;
  795. }
  796. PerlinNoise::PerlinNoise(UInt seed)
  797. {
  798. T.seed=seed;
  799. }
  800. Flt PerlinNoise::noise(Dbl x, Dbl y)C
  801. {
  802. Int X=Floor(x); Flt fx=x-X, fx1=fx-1; Flt u=_SmoothQuintic(fx);
  803. Int Y=Floor(y); Flt fy=y-Y, fy1=fy-1; Flt v=_SmoothQuintic(fy);
  804. return Lerp(Lerp(Grad(X , Y , fx , fy , seed),
  805. Grad(X+1, Y , fx1, fy , seed), u),
  806. Lerp(Grad(X , Y+1, fx , fy1, seed),
  807. Grad(X+1, Y+1, fx1, fy1, seed), u), v);
  808. }
  809. #else // Ken Perlin "Optimized" version, with "Byte p[512];" member
  810. static Flt Grad(Int hash, Flt x)
  811. {
  812. Int h=(hash&15);
  813. Flt u=(h<8) ? x : 0,
  814. v=(h<4) ? 0 : (h==12 || h==14) ? x : 0;
  815. return ((h&1) ? -u : u) + ((h&2) ? -v : v);
  816. }
  817. static Flt Grad(Int hash, Flt x, Flt y)
  818. {
  819. Int h=(hash&15);
  820. Flt u=(h<8) ? x : y,
  821. v=(h<4) ? y : (h==12 || h==14) ? x : 0;
  822. return ((h&1) ? -u : u) + ((h&2) ? -v : v);
  823. }
  824. static Flt Grad(Int hash, Flt x, Flt y, Flt z)
  825. {
  826. Int h=(hash&15);
  827. Flt u=(h<8) ? x : y,
  828. v=(h<4) ? y : (h==12 || h==14) ? x : z;
  829. return ((h&1) ? -u : u) + ((h&2) ? -v : v);
  830. }
  831. static Flt Grad(Int hash, Flt x, Flt y, Flt z, Flt t)
  832. {
  833. Int h=(hash&31);
  834. Flt u=(h<24) ? x : y,
  835. v=(h<16) ? y : z,
  836. w=(h< 8) ? z : t;
  837. return ((h&1) ? -u : u) + ((h&2) ? -v : v) + ((h&4) ? -w : w);
  838. }
  839. PerlinNoise::PerlinNoise(UInt seed)
  840. {
  841. Randomizer rnd(seed, 0, 0, 0);
  842. REP(256)p[i]=i;
  843. FREP(255)Swap(p[i], p[rnd(i, 255)]); // 'RandomizeOrder'
  844. CopyN(p+256, p, 256);
  845. }
  846. Flt PerlinNoise::noise(Dbl x)C
  847. {
  848. Int X=Floor(x); Flt fx=x-X, fx1=fx-1; X&=0xFF; Flt u=_SmoothQuintic(fx);
  849. Int A=p[X ], AA=p[A],
  850. B=p[X+1], BA=p[B];
  851. return Lerp(Grad(p[AA], fx ),
  852. Grad(p[BA], fx1), u)/0.5f;
  853. }
  854. Flt PerlinNoise::noise(Dbl x, Dbl y)C
  855. {
  856. Int X=Floor(x); Flt fx=x-X, fx1=fx-1; X&=0xFF; Flt u=_SmoothQuintic(fx);
  857. Int Y=Floor(y); Flt fy=y-Y, fy1=fy-1; Y&=0xFF; Flt v=_SmoothQuintic(fy);
  858. Int A=p[X ]+Y, AA=p[A], AB=p[A+1],
  859. B=p[X+1]+Y, BA=p[B], BB=p[B+1];
  860. return Lerp(Lerp(Grad(p[AA], fx , fy ),
  861. Grad(p[BA], fx1, fy ), u),
  862. Lerp(Grad(p[AB], fx , fy1),
  863. Grad(p[BB], fx1, fy1), u), v);
  864. }
  865. Flt PerlinNoise::noise(Dbl x, Dbl y, Dbl z)C
  866. {
  867. Int X=Floor(x); Flt fx=x-X, fx1=fx-1; X&=0xFF; Flt u=_SmoothQuintic(fx);
  868. Int Y=Floor(y); Flt fy=y-Y, fy1=fy-1; Y&=0xFF; Flt v=_SmoothQuintic(fy);
  869. Int Z=Floor(z); Flt fz=z-Z, fz1=fz-1; Z&=0xFF; Flt w=_SmoothQuintic(fz);
  870. Int A=p[X ]+Y, AA=p[A]+Z, AB=p[A+1]+Z,
  871. B=p[X+1]+Y, BA=p[B]+Z, BB=p[B+1]+Z;
  872. return Lerp(Lerp(Lerp(Grad(p[AA ], fx , fy , fz ),
  873. Grad(p[BA ], fx1, fy , fz ), u),
  874. Lerp(Grad(p[AB ], fx , fy1, fz ),
  875. Grad(p[BB ], fx1, fy1, fz ), u), v),
  876. Lerp(Lerp(Grad(p[AA+1], fx , fy , fz1),
  877. Grad(p[BA+1], fx1, fy , fz1), u),
  878. Lerp(Grad(p[AB+1], fx , fy1, fz1),
  879. Grad(p[BB+1], fx1, fy1, fz1), u), v), w);
  880. }
  881. /******************************************************************************/
  882. Flt PerlinNoise::tiledNoise(Dbl x, Int tile)C
  883. {
  884. MAX(tile, 1); // can't be smaller than 1, because of division by zero resulting in exception, and <0 giving negative values
  885. Int X=Floor(x); Flt fx=x-X, fx1=fx-1; X=Mod(X, tile); Int X1=((X+1)%tile)&255; X&=255; Flt u=_SmoothQuintic(fx);
  886. Int A=p[X ], AA=p[A],
  887. B=p[X1], BA=p[B];
  888. return Lerp(Grad(p[AA], fx ),
  889. Grad(p[BA], fx1), u);
  890. }
  891. Flt PerlinNoise::tiledNoise(Dbl x, Dbl y, C VecI2 &tile)C
  892. {
  893. VecI2 t(Max(tile.x, 1), Max(tile.y, 1)); // can't be smaller than 1, because of division by zero resulting in exception, and <0 giving negative values
  894. Int X=Floor(x); Flt fx=x-X, fx1=fx-1; X=Mod(X, t.x); Int X1=((X+1)%t.x)&255; X&=255; Flt u=_SmoothQuintic(fx);
  895. Int Y=Floor(y); Flt fy=y-Y, fy1=fy-1; Y=Mod(Y, t.y); Int Y1=((Y+1)%t.y)&255; Y&=255; Flt v=_SmoothQuintic(fy);
  896. Int A=p[X ], AA=p[A+Y], AB=p[A+Y1],
  897. B=p[X1], BA=p[B+Y], BB=p[B+Y1];
  898. return Lerp(Lerp(Grad(p[AA], fx , fy ),
  899. Grad(p[BA], fx1, fy ), u),
  900. Lerp(Grad(p[AB], fx , fy1),
  901. Grad(p[BB], fx1, fy1), u), v);
  902. }
  903. Flt PerlinNoise::tiledNoise(Dbl x, Dbl y, Dbl z, C VecI &tile)C
  904. {
  905. VecI t(Max(tile.x, 1), Max(tile.y, 1), Max(tile.z, 1)); // can't be smaller than 1, because of division by zero resulting in exception, and <0 giving negative values
  906. Int X=Floor(x); Flt fx=x-X, fx1=fx-1; X=Mod(X, t.x); Int X1=((X+1)%t.x)&255; X&=255; Flt u=_SmoothQuintic(fx);
  907. Int Y=Floor(y); Flt fy=y-Y, fy1=fy-1; Y=Mod(Y, t.y); Int Y1=((Y+1)%t.y)&255; Y&=255; Flt v=_SmoothQuintic(fy);
  908. Int Z=Floor(z); Flt fz=z-Z, fz1=fz-1; Z=Mod(Z, t.z); Int Z1=((Z+1)%t.z)&255; Z&=255; Flt w=_SmoothQuintic(fz);
  909. Int A=p[X ], AA=p[A+Y], AB=p[A+Y1],
  910. B=p[X1], BA=p[B+Y], BB=p[B+Y1];
  911. return Lerp(Lerp(Lerp(Grad(p[AA+Z ], fx , fy , fz ),
  912. Grad(p[BA+Z ], fx1, fy , fz ), u),
  913. Lerp(Grad(p[AB+Z ], fx , fy1, fz ),
  914. Grad(p[BB+Z ], fx1, fy1, fz ), u), v),
  915. Lerp(Lerp(Grad(p[AA+Z1], fx , fy , fz1),
  916. Grad(p[BA+Z1], fx1, fy , fz1), u),
  917. Lerp(Grad(p[AB+Z1], fx , fy1, fz1),
  918. Grad(p[BB+Z1], fx1, fy1, fz1), u), v), w);
  919. }
  920. #endif
  921. /******************************************************************************/
  922. // MULTI
  923. /******************************************************************************/
  924. Flt PerlinNoise::noise1(Dbl x, Int octaves, Flt gain, Flt Transform(Flt noise))C
  925. {
  926. Flt result=0, amp=1; REP(octaves)
  927. {
  928. Flt n=noise(x); if(Transform)n=Transform(n);
  929. result+=n*amp;
  930. x *=2;
  931. amp *=gain;
  932. }
  933. return result;
  934. }
  935. Flt PerlinNoise::noise2(Dbl x, Dbl y, Int octaves, Flt gain, Flt Transform(Flt noise))C
  936. {
  937. Flt result=0, amp=1; REP(octaves)
  938. {
  939. Flt n=noise(x, y); if(Transform)n=Transform(n);
  940. result+=n*amp;
  941. x *=2;
  942. y *=2;
  943. amp *=gain;
  944. }
  945. return result;
  946. }
  947. Flt PerlinNoise::noise3(Dbl x, Dbl y, Dbl z, Int octaves, Flt gain, Flt Transform(Flt noise))C
  948. {
  949. Flt result=0, amp=1; REP(octaves)
  950. {
  951. Flt n=noise(x, y, z); if(Transform)n=Transform(n);
  952. result+=n*amp;
  953. x *=2;
  954. y *=2;
  955. z *=2;
  956. amp *=gain;
  957. }
  958. return result;
  959. }
  960. /******************************************************************************/
  961. Flt PerlinNoise::tiledNoise1(Dbl x, Int tile, Int octaves, Flt gain, Flt Transform(Flt noise))C
  962. {
  963. Flt result=0, amp=1; REP(octaves)
  964. {
  965. Flt n=tiledNoise(x, tile); if(Transform)n=Transform(n);
  966. result+=n*amp;
  967. x *=2;
  968. tile *=2;
  969. amp *=gain;
  970. }
  971. return result;
  972. }
  973. Flt PerlinNoise::tiledNoise2(Dbl x, Dbl y, VecI2 tile, Int octaves, Flt gain, Flt Transform(Flt noise))C
  974. {
  975. Flt result=0, amp=1; REP(octaves)
  976. {
  977. Flt n=tiledNoise(x, y, tile); if(Transform)n=Transform(n);
  978. result+=n*amp;
  979. x *=2;
  980. y *=2;
  981. tile *=2;
  982. amp *=gain;
  983. }
  984. return result;
  985. }
  986. Flt PerlinNoise::tiledNoise3(Dbl x, Dbl y, Dbl z, VecI tile, Int octaves, Flt gain, Flt Transform(Flt noise))C
  987. {
  988. Flt result=0, amp=1; REP(octaves)
  989. {
  990. Flt n=tiledNoise(x, y, z, tile); if(Transform)n=Transform(n);
  991. result+=n*amp;
  992. x *=2;
  993. y *=2;
  994. z *=2;
  995. tile *=2;
  996. amp *=gain;
  997. }
  998. return result;
  999. }
  1000. /******************************************************************************/
  1001. // BLOOM
  1002. /******************************************************************************/
  1003. static const Flt BloomGain=0.85f;
  1004. Flt PerlinNoise::noise1Bloom(Dbl x, Int octaves, Flt bloom, Flt sharpness)C
  1005. {
  1006. Flt result=noise(x), weight=result*bloom+sharpness, amp=1;
  1007. for(Int i=1; i<octaves; i++)
  1008. {
  1009. Flt n=noise(x*=2);
  1010. amp *=BloomGain;
  1011. weight*=amp;
  1012. MAX(weight, 0);
  1013. result+=weight*n;
  1014. weight*=n*bloom+sharpness;
  1015. }
  1016. return result;
  1017. }
  1018. Flt PerlinNoise::noise2Bloom(Dbl x, Dbl y, Int octaves, Flt bloom, Flt sharpness)C
  1019. {
  1020. Flt result=noise(x, y), weight=result*bloom+sharpness, amp=1;
  1021. for(Int i=1; i<octaves; i++)
  1022. {
  1023. Flt n=noise(x*=2, y*=2);
  1024. amp *=BloomGain;
  1025. weight*=amp;
  1026. MAX(weight, 0);
  1027. result+=weight*n;
  1028. weight*=n*bloom+sharpness;
  1029. }
  1030. return result;
  1031. }
  1032. Flt PerlinNoise::noise3Bloom(Dbl x, Dbl y, Dbl z, Int octaves, Flt bloom, Flt sharpness)C
  1033. {
  1034. Flt result=noise(x, y, z), weight=result*bloom+sharpness, amp=1;
  1035. for(Int i=1; i<octaves; i++)
  1036. {
  1037. Flt n=noise(x*=2, y*=2, z*=2);
  1038. amp *=BloomGain;
  1039. weight*=amp;
  1040. MAX(weight, 0);
  1041. result+=weight*n;
  1042. weight*=n*bloom+sharpness;
  1043. }
  1044. return result;
  1045. }
  1046. /******************************************************************************/
  1047. Flt PerlinNoise::tiledNoise1Bloom(Dbl x, Int tile, Int octaves, Flt bloom, Flt sharpness)C
  1048. {
  1049. Flt result=tiledNoise(x, tile), weight=result*bloom+sharpness, amp=1;
  1050. for(Int i=1; i<octaves; i++)
  1051. {
  1052. Flt n=tiledNoise(x*=2, tile*=2);
  1053. amp *=BloomGain;
  1054. weight*=amp;
  1055. MAX(weight, 0);
  1056. result+=weight*n;
  1057. weight*=n*bloom+sharpness;
  1058. }
  1059. return result;
  1060. }
  1061. Flt PerlinNoise::tiledNoise2Bloom(Dbl x, Dbl y, VecI2 tile, Int octaves, Flt bloom, Flt sharpness)C
  1062. {
  1063. Flt result=tiledNoise(x, y, tile), weight=result*bloom+sharpness, amp=1;
  1064. for(Int i=1; i<octaves; i++)
  1065. {
  1066. Flt n=tiledNoise(x*=2, y*=2, tile*=2);
  1067. amp *=BloomGain;
  1068. weight*=amp;
  1069. MAX(weight, 0);
  1070. result+=weight*n;
  1071. weight*=n*bloom+sharpness;
  1072. }
  1073. return result;
  1074. }
  1075. Flt PerlinNoise::tiledNoise3Bloom(Dbl x, Dbl y, Dbl z, VecI tile, Int octaves, Flt bloom, Flt sharpness)C
  1076. {
  1077. Flt result=tiledNoise(x, y, z, tile), weight=result*bloom+sharpness, amp=1;
  1078. for(Int i=1; i<octaves; i++)
  1079. {
  1080. Flt n=tiledNoise(x*=2, y*=2, z*=2, tile*=2);
  1081. amp *=BloomGain;
  1082. weight*=amp;
  1083. MAX(weight, 0);
  1084. result+=weight*n;
  1085. weight*=n*bloom+sharpness;
  1086. }
  1087. return result;
  1088. }
  1089. /******************************************************************************/
  1090. #if 0 // so so, Open Simplex is much better
  1091. /******************************************************************************/
  1092. // SIMPLEX NOISE
  1093. /******************************************************************************
  1094. SimplexNoise1234
  1095. Copyright 2003-2011, Stefan Gustavson
  1096. Contact: [email protected]
  1097. This library is public domain software, released by the author into the public domain in February 2011. You may do anything you like with it. You may even remove all attributions, but of course I'd appreciate it if you kept my name somewhere.
  1098. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  1099. /******************************************************************************/
  1100. static Byte Simplex[64][4]=
  1101. {
  1102. {0,1,2,3}, {0,1,3,2}, {0,0,0,0}, {0,2,3,1}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {1,2,3,0},
  1103. {0,2,1,3}, {0,0,0,0}, {0,3,1,2}, {0,3,2,1}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {1,3,2,0},
  1104. {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0},
  1105. {1,2,0,3}, {0,0,0,0}, {1,3,0,2}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {2,3,0,1}, {2,3,1,0},
  1106. {1,0,2,3}, {1,0,3,2}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {2,0,3,1}, {0,0,0,0}, {2,1,3,0},
  1107. {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0},
  1108. {2,0,1,3}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {3,0,1,2}, {3,0,2,1}, {0,0,0,0}, {3,1,2,0},
  1109. {2,1,0,3}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {3,1,0,2}, {0,0,0,0}, {3,2,0,1}, {3,2,1,0},
  1110. };
  1111. /******************************************************************************/
  1112. struct PerlinSimplexNoise
  1113. {
  1114. Flt noise(Dbl x )C;
  1115. Flt noise(Dbl x, Dbl y)C;
  1116. PerlinSimplexNoise(UInt seed=0);
  1117. private:
  1118. Byte p[512];
  1119. };
  1120. PerlinSimplexNoise::PerlinSimplexNoise(UInt seed)
  1121. {
  1122. Randomizer rnd(seed, 0, 0, 0);
  1123. REP(256)p[i]=i;
  1124. FREP(255)Swap(p[i], p[rnd(i, 255)]); // 'RandomizeOrder'
  1125. CopyN(p+256, p, 256);
  1126. }
  1127. /******************************************************************************/
  1128. Flt PerlinSimplexNoise::noise(Dbl x)C
  1129. {
  1130. Int i0=Floor(x);
  1131. Int i1=i0+1;
  1132. Flt x0=x-i0;
  1133. Flt x1=x0-1.0f;
  1134. Flt n0, n1;
  1135. Flt t0=1.0f-x0*x0;
  1136. //if(t0<0.0f)t0=0.0f;
  1137. t0*=t0;
  1138. n0=t0*t0*Grad(p[i0&0xff], x0);
  1139. Flt t1=1.0f-x1*x1;
  1140. //if(t1<0.0f)t1=0.0f;
  1141. t1*=t1;
  1142. n1=t1*t1*Grad(p[i1&0xff], x1);
  1143. return (n0+n1)/0.316406310f;
  1144. }
  1145. Flt PerlinSimplexNoise::noise(Dbl x, Dbl y)C
  1146. {
  1147. #define F2 0.366025403f // F2=0.5*(Sqrt(3.0)-1.0)
  1148. #define G2 0.211324865f // G2=(3.0-Sqrt(3.0))/6.0
  1149. Flt n0, n1, n2; // Noise contributions from the three corners
  1150. // Skew the input space to determine which simplex cell we're in
  1151. Flt s=(x+y)*F2; // Hairy factor for 2D
  1152. Flt xs=x+s;
  1153. Flt ys=y+s;
  1154. Int i=Floor(xs);
  1155. Int j=Floor(ys);
  1156. Flt t=(Flt)(i+j)*G2;
  1157. Flt X0=i-t; // Unskew the cell origin back to (x,y)space
  1158. Flt Y0=j-t;
  1159. Flt x0=x-X0; // The x,y distances from the cell origin
  1160. Flt y0=y-Y0;
  1161. // For the 2D case, the simplex shape is an equilateral triangle.
  1162. // Determine which simplex we are in.
  1163. Int i1, j1; // Offsets for second (middle)corner of simplex in (i,j)coords
  1164. if(x0>y0){i1=1; j1=0;} // lower triangle, XY order: (0,0)->(1,0)->(1,1)
  1165. else {i1=0; j1=1;} // upper triangle, YX order: (0,0)->(0,1)->(1,1)
  1166. // A step of (1,0)in (i,j)means a step of (1-c,-c)in (x,y), and
  1167. // a step of (0,1)in (i,j)means a step of (-c,1-c)in (x,y), where
  1168. // c=(3-Sqrt(3))/6
  1169. Flt x1=x0-i1+G2; // Offsets for middle corner in (x,y)unskewed coords
  1170. Flt y1=y0-j1+G2;
  1171. Flt x2=x0-1.0f+2.0f*G2; // Offsets for last corner in (x,y)unskewed coords
  1172. Flt y2=y0-1.0f+2.0f*G2;
  1173. // Wrap the integer indices at 256, to avoid indexing p[] out of bounds
  1174. Int ii=i&0xff;
  1175. Int jj=j&0xff;
  1176. // Calculate the contribution from the three corners
  1177. Flt t0=0.5f-x0*x0-y0*y0;
  1178. if(t0<0.0f)n0=0.0f;else
  1179. {
  1180. t0*=t0;
  1181. n0=t0*t0*Grad(p[ii+p[jj]], x0, y0);
  1182. }
  1183. Flt t1=0.5f-x1*x1-y1*y1;
  1184. if(t1<0.0f)n1=0.0f;else
  1185. {
  1186. t1*=t1;
  1187. n1=t1*t1*Grad(p[ii+i1+p[jj+j1]], x1, y1);
  1188. }
  1189. Flt t2=0.5f-x2*x2-y2*y2;
  1190. if(t2<0.0f)n2=0.0f;else
  1191. {
  1192. t2*=t2;
  1193. n2=t2*t2*Grad(p[ii+1+p[jj+1]], x2, y2);
  1194. }
  1195. return (n0+n1+n2)/0.014255565f;
  1196. }
  1197. Flt PerlinSimplexNoise::noise(Dbl x, Dbl y, Dbl z)C
  1198. {
  1199. // Simple skewing factors for the 3D case
  1200. #define F3 0.333333333f
  1201. #define G3 0.166666667f
  1202. Flt n0, n1, n2, n3; // Noise contributions from the four corners
  1203. // Skew the input space to determine which simplex cell we're in
  1204. Flt s=(x+y+z)*F3; // Very nice and simple skew factor for 3D
  1205. Flt xs=x+s;
  1206. Flt ys=y+s;
  1207. Flt zs=z+s;
  1208. Int i=Floor(xs);
  1209. Int j=Floor(ys);
  1210. Int k=Floor(zs);
  1211. Flt t=(Flt)(i+j+k)*G3;
  1212. Flt X0=i-t; // Unskew the cell origin back to (x,y,z)space
  1213. Flt Y0=j-t;
  1214. Flt Z0=k-t;
  1215. Flt x0=x-X0; // The x,y,z distances from the cell origin
  1216. Flt y0=y-Y0;
  1217. Flt z0=z-Z0;
  1218. // For the 3D case, the simplex shape is a slightly irregular tetrahedron.
  1219. // Determine which simplex we are in.
  1220. Int i1, j1, k1; // Offsets for second corner of simplex in (i,j,k)coords
  1221. Int i2, j2, k2; // Offsets for third corner of simplex in (i,j,k)coords
  1222. /* This code would benefit from a backport from the GLSL version! */
  1223. if(x0>=y0)
  1224. {
  1225. if(y0>=z0){i1=1; j1=0; k1=0; i2=1; j2=1; k2=0;}else // X Y Z order
  1226. if(x0>=z0){i1=1; j1=0; k1=0; i2=1; j2=0; k2=1;}else // X Z Y order
  1227. {i1=0; j1=0; k1=1; i2=1; j2=0; k2=1;} // Z X Y order
  1228. }else // x0<y0
  1229. {
  1230. if(y0<z0){i1=0; j1=0; k1=1; i2=0; j2=1; k2=1;}else // Z Y X order
  1231. if(x0<z0){i1=0; j1=1; k1=0; i2=0; j2=1; k2=1;}else // Y Z X order
  1232. {i1=0; j1=1; k1=0; i2=1; j2=1; k2=0;} // Y X Z order
  1233. }
  1234. // A step of (1,0,0)in (i,j,k)means a step of (1-c,-c,-c)in (x,y,z),
  1235. // a step of (0,1,0)in (i,j,k)means a step of (-c,1-c,-c)in (x,y,z), and
  1236. // a step of (0,0,1)in (i,j,k)means a step of (-c,-c,1-c)in (x,y,z), where
  1237. // c=1/6.
  1238. Flt x1=x0-i1+G3; // Offsets for second corner in (x,y,z)coords
  1239. Flt y1=y0-j1+G3;
  1240. Flt z1=z0-k1+G3;
  1241. Flt x2=x0-i2+2.0f*G3; // Offsets for third corner in (x,y,z)coords
  1242. Flt y2=y0-j2+2.0f*G3;
  1243. Flt z2=z0-k2+2.0f*G3;
  1244. Flt x3=x0-1.0f+3.0f*G3; // Offsets for last corner in (x,y,z)coords
  1245. Flt y3=y0-1.0f+3.0f*G3;
  1246. Flt z3=z0-1.0f+3.0f*G3;
  1247. // Wrap the integer indices at 256, to avoid indexing p[] out of bounds
  1248. Int ii=i&0xff;
  1249. Int jj=j&0xff;
  1250. Int kk=k&0xff;
  1251. // Calculate the contribution from the four corners
  1252. Flt t0=0.6f-x0*x0-y0*y0-z0*z0;
  1253. if(t0<0.0f)n0=0.0f;else
  1254. {
  1255. t0*=t0;
  1256. n0=t0*t0*Grad(p[ii+p[jj+p[kk]]], x0, y0, z0);
  1257. }
  1258. Flt t1=0.6f-x1*x1-y1*y1-z1*z1;
  1259. if(t1<0.0f)n1=0.0f;else
  1260. {
  1261. t1*=t1;
  1262. n1=t1*t1*Grad(p[ii+i1+p[jj+j1+p[kk+k1]]], x1, y1, z1);
  1263. }
  1264. Flt t2=0.6f-x2*x2-y2*y2-z2*z2;
  1265. if(t2<0.0f)n2=0.0f;else
  1266. {
  1267. t2*=t2;
  1268. n2=t2*t2*Grad(p[ii+i2+p[jj+j2+p[kk+k2]]], x2, y2, z2);
  1269. }
  1270. Flt t3=0.6f-x3*x3-y3*y3-z3*z3;
  1271. if(t3<0.0f)n3=0.0f;else
  1272. {
  1273. t3*=t3;
  1274. n3=t3*t3*Grad(p[ii+1+p[jj+1+p[kk+1]]], x3, y3, z3);
  1275. }
  1276. return 32.0f*(n0+n1+n2+n3);
  1277. }
  1278. Flt PerlinSimplexNoise::noise(Dbl x, Dbl y, Dbl z, Dbl w)C
  1279. {
  1280. // The skewing and unskewing factors are hairy again for the 4D case
  1281. #define F4 0.309016994f // F4=(Sqrt(5.0)-1.0)/4.0
  1282. #define G4 0.138196601f // G4=(5.0-Sqrt(5.0))/20.0
  1283. Flt n0, n1, n2, n3, n4; // Noise contributions from the five corners
  1284. // Skew the (x,y,z,w)space to determine which cell of 24 simplices we're in
  1285. Flt s=(x+y+z+w)*F4; // Factor for 4D skewing
  1286. Flt xs=x+s;
  1287. Flt ys=y+s;
  1288. Flt zs=z+s;
  1289. Flt ws=w+s;
  1290. Int i=Floor(xs);
  1291. Int j=Floor(ys);
  1292. Int k=Floor(zs);
  1293. Int l=Floor(ws);
  1294. Flt t=(i+j+k+l)*G4; // Factor for 4D unskewing
  1295. Flt X0=i-t; // Unskew the cell origin back to (x,y,z,w)space
  1296. Flt Y0=j-t;
  1297. Flt Z0=k-t;
  1298. Flt W0=l-t;
  1299. Flt x0=x-X0; // The x,y,z,w distances from the cell origin
  1300. Flt y0=y-Y0;
  1301. Flt z0=z-Z0;
  1302. Flt w0=w-W0;
  1303. // For the 4D case, the simplex is a 4D shape I won't even try to describe.
  1304. // To find out which of the 24 possible simplices we're in, we need to
  1305. // determine the magnitude ordering of x0, y0, z0 and w0.
  1306. // The method below is a good way of finding the ordering of x,y,z,w and
  1307. // then find the correct traversal order for the simplex we're in.
  1308. // First, six pair-wise comparisons are performed between each possible pair
  1309. // of the four coordinates, and the results are used to add up binary bits
  1310. // for an integer index.
  1311. Int c1=(x0>y0)? 32 : 0;
  1312. Int c2=(x0>z0)? 16 : 0;
  1313. Int c3=(y0>z0)? 8 : 0;
  1314. Int c4=(x0>w0)? 4 : 0;
  1315. Int c5=(y0>w0)? 2 : 0;
  1316. Int c6=(z0>w0)? 1 : 0;
  1317. Int c=c1+c2+c3+c4+c5+c6;
  1318. Int i1, j1, k1, l1; // The integer offsets for the second simplex corner
  1319. Int i2, j2, k2, l2; // The integer offsets for the third simplex corner
  1320. Int i3, j3, k3, l3; // The integer offsets for the fourth simplex corner
  1321. // simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order.
  1322. // Many values of c will never occur, since e.g. x>y>z>w makes x<z, y<w and x<w
  1323. // impossible. Only the 24 indices which have non-zero entries make any sense.
  1324. // We use a thresholding to set the coordinates in turn from the largest magnitude.
  1325. // The number 3 in the "Simplex" array is at the position of the largest coordinate.
  1326. i1=Simplex[c][0]>=3 ? 1 : 0;
  1327. j1=Simplex[c][1]>=3 ? 1 : 0;
  1328. k1=Simplex[c][2]>=3 ? 1 : 0;
  1329. l1=Simplex[c][3]>=3 ? 1 : 0;
  1330. // The number 2 in the "Simplex" array is at the second largest coordinate.
  1331. i2=Simplex[c][0]>=2 ? 1 : 0;
  1332. j2=Simplex[c][1]>=2 ? 1 : 0;
  1333. k2=Simplex[c][2]>=2 ? 1 : 0;
  1334. l2=Simplex[c][3]>=2 ? 1 : 0;
  1335. // The number 1 in the "Simplex" array is at the second smallest coordinate.
  1336. i3=Simplex[c][0]>=1 ? 1 : 0;
  1337. j3=Simplex[c][1]>=1 ? 1 : 0;
  1338. k3=Simplex[c][2]>=1 ? 1 : 0;
  1339. l3=Simplex[c][3]>=1 ? 1 : 0;
  1340. // The fifth corner has all coordinate offsets=1, so no need to look that up.
  1341. Flt x1=x0-i1+G4; // Offsets for second corner in (x,y,z,w)coords
  1342. Flt y1=y0-j1+G4;
  1343. Flt z1=z0-k1+G4;
  1344. Flt w1=w0-l1+G4;
  1345. Flt x2=x0-i2+2.0f*G4; // Offsets for third corner in (x,y,z,w)coords
  1346. Flt y2=y0-j2+2.0f*G4;
  1347. Flt z2=z0-k2+2.0f*G4;
  1348. Flt w2=w0-l2+2.0f*G4;
  1349. Flt x3=x0-i3+3.0f*G4; // Offsets for fourth corner in (x,y,z,w)coords
  1350. Flt y3=y0-j3+3.0f*G4;
  1351. Flt z3=z0-k3+3.0f*G4;
  1352. Flt w3=w0-l3+3.0f*G4;
  1353. Flt x4=x0-1.0f+4.0f*G4; // Offsets for last corner in (x,y,z,w)coords
  1354. Flt y4=y0-1.0f+4.0f*G4;
  1355. Flt z4=z0-1.0f+4.0f*G4;
  1356. Flt w4=w0-1.0f+4.0f*G4;
  1357. // Wrap the integer indices at 256, to avoid indexing p[] out of bounds
  1358. Int ii=i&0xff;
  1359. Int jj=j&0xff;
  1360. Int kk=k&0xff;
  1361. Int ll=l&0xff;
  1362. // Calculate the contribution from the five corners
  1363. Flt t0=0.6f-x0*x0-y0*y0-z0*z0-w0*w0;
  1364. if(t0<0.0f)n0=0.0f;else
  1365. {
  1366. t0*=t0;
  1367. n0=t0*t0*Grad(p[ii+p[jj+p[kk+p[ll]]]], x0, y0, z0, w0);
  1368. }
  1369. Flt t1=0.6f-x1*x1-y1*y1-z1*z1-w1*w1;
  1370. if(t1<0.0f)n1=0.0f;else
  1371. {
  1372. t1*=t1;
  1373. n1=t1*t1*Grad(p[ii+i1+p[jj+j1+p[kk+k1+p[ll+l1]]]], x1, y1, z1, w1);
  1374. }
  1375. Flt t2=0.6f-x2*x2-y2*y2-z2*z2-w2*w2;
  1376. if(t2<0.0f)n2=0.0f;else
  1377. {
  1378. t2*=t2;
  1379. n2=t2*t2*Grad(p[ii+i2+p[jj+j2+p[kk+k2+p[ll+l2]]]], x2, y2, z2, w2);
  1380. }
  1381. Flt t3=0.6f-x3*x3-y3*y3-z3*z3-w3*w3;
  1382. if(t3<0.0f)n3=0.0f;else
  1383. {
  1384. t3*=t3;
  1385. n3=t3*t3*Grad(p[ii+i3+p[jj+j3+p[kk+k3+p[ll+l3]]]], x3, y3, z3, w3);
  1386. }
  1387. Flt t4=0.6f-x4*x4-y4*y4-z4*z4-w4*w4;
  1388. if(t4<0.0f)n4=0.0f;else
  1389. {
  1390. t4*=t4;
  1391. n4=t4*t4*Grad(p[ii+1+p[jj+1+p[kk+1+p[ll+1]]]], x4, y4, z4, w4);
  1392. }
  1393. // Sum up and scale the result to cover the range [-1,1]
  1394. return 27.0f*(n0+n1+n2+n3+n4); // TODO: The scale factor is preliminary!
  1395. }
  1396. /******************************************************************************/
  1397. #endif
  1398. /******************************************************************************/
  1399. // OPEN SIMPLEX NOISE
  1400. // Ported by Stephen M. Cameron from Kurt Spencer's Java implementation
  1401. /******************************************************************************/
  1402. #define STRETCH_CONSTANT_2D (-0.211324865405187) // (1 / Sqrt(2 + 1) - 1 ) / 2
  1403. #define SQUISH_CONSTANT_2D (0.366025403784439) // (Sqrt(2 + 1) -1) / 2
  1404. #define STRETCH_CONSTANT_3D (-1.0 / 6.0) // (1 / Sqrt(3 + 1) - 1) / 3
  1405. #define SQUISH_CONSTANT_3D (1.0 / 3.0) // (Sqrt(3+1)-1)/3
  1406. #define STRETCH_CONSTANT_4D (-0.138196601125011) // (1 / Sqrt(4 + 1) - 1) / 4
  1407. #define SQUISH_CONSTANT_4D (0.309016994374947) // (Sqrt(4 + 1) - 1) / 4
  1408. // Gradients for 2D. They approximate the directions to the vertices of an octagon from the center
  1409. static const I8 gradients2D[]=
  1410. {
  1411. 5, 2, 2, 5,
  1412. -5, 2, -2, 5,
  1413. 5, -2, 2, -5,
  1414. -5, -2, -2, -5,
  1415. };
  1416. // Gradients for 3D. They approximate the directions to the vertices of a rhombicuboctahedron from the center, skewed so that the triangular and square facets can be inscribed inside circles of the same radius
  1417. static const I8 gradients3D[]=
  1418. {
  1419. -11, 4, 4, -4, 11, 4, -4, 4, 11,
  1420. 11, 4, 4, 4, 11, 4, 4, 4, 11,
  1421. -11, -4, 4, -4, -11, 4, -4, -4, 11,
  1422. 11, -4, 4, 4, -11, 4, 4, -4, 11,
  1423. -11, 4, -4, -4, 11, -4, -4, 4, -11,
  1424. 11, 4, -4, 4, 11, -4, 4, 4, -11,
  1425. -11, -4, -4, -4, -11, -4, -4, -4, -11,
  1426. 11, -4, -4, 4, -11, -4, 4, -4, -11,
  1427. };
  1428. // Gradients for 4D. They approximate the directions to the vertices of a disprismatotesseractihexadecachoron from the center, skewed so that the tetrahedral and cubic facets can be inscribed inside spheres of the same radius.
  1429. static const I8 gradients4D[]=
  1430. {
  1431. 3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3,
  1432. -3, 1, 1, 1, -1, 3, 1, 1, -1, 1, 3, 1, -1, 1, 1, 3,
  1433. 3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3, 1, 1, -1, 1, 3,
  1434. -3, -1, 1, 1, -1, -3, 1, 1, -1, -1, 3, 1, -1, -1, 1, 3,
  1435. 3, 1, -1, 1, 1, 3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3,
  1436. -3, 1, -1, 1, -1, 3, -1, 1, -1, 1, -3, 1, -1, 1, -1, 3,
  1437. 3, -1, -1, 1, 1, -3, -1, 1, 1, -1, -3, 1, 1, -1, -1, 3,
  1438. -3, -1, -1, 1, -1, -3, -1, 1, -1, -1, -3, 1, -1, -1, -1, 3,
  1439. 3, 1, 1, -1, 1, 3, 1, -1, 1, 1, 3, -1, 1, 1, 1, -3,
  1440. -3, 1, 1, -1, -1, 3, 1, -1, -1, 1, 3, -1, -1, 1, 1, -3,
  1441. 3, -1, 1, -1, 1, -3, 1, -1, 1, -1, 3, -1, 1, -1, 1, -3,
  1442. -3, -1, 1, -1, -1, -3, 1, -1, -1, -1, 3, -1, -1, -1, 1, -3,
  1443. 3, 1, -1, -1, 1, 3, -1, -1, 1, 1, -3, -1, 1, 1, -1, -3,
  1444. -3, 1, -1, -1, -1, 3, -1, -1, -1, 1, -3, -1, -1, 1, -1, -3,
  1445. 3, -1, -1, -1, 1, -3, -1, -1, 1, -1, -3, -1, 1, -1, -1, -3,
  1446. -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3,
  1447. };
  1448. /******************************************************************************/
  1449. SimplexNoise::SimplexNoise(UInt seed)
  1450. {
  1451. Randomizer rnd(seed, 0, 0, 0);
  1452. REP(256)p[i]=i;
  1453. FREP(255)Swap(p[i], p[rnd(i, 255)]); // 'RandomizeOrder'
  1454. REPAO(permGradIndex3D)=(p[i]%(Elms(gradients3D)/3))*3;
  1455. }
  1456. /******************************************************************************/
  1457. Dbl SimplexNoise::extrapolate2(Int xsb, Int ysb, Dbl dx, Dbl dy)C
  1458. {
  1459. Int index=p[(p[xsb&0xFF]+ysb)&0xFF]&0x0E; // 0x0E mask limits to 0..15 (0xF) elements and disables bit 1 so index+1 is in range
  1460. return gradients2D[index ]*dx
  1461. +gradients2D[index+1]*dy;
  1462. }
  1463. Dbl SimplexNoise::extrapolate3(Int xsb, Int ysb, Int zsb, Dbl dx, Dbl dy, Dbl dz)C
  1464. {
  1465. Int index=permGradIndex3D[(p[(p[xsb&0xFF]+ysb)&0xFF]+zsb)&0xFF];
  1466. return gradients3D[index ]*dx
  1467. +gradients3D[index+1]*dy
  1468. +gradients3D[index+2]*dz;
  1469. }
  1470. Dbl SimplexNoise::extrapolate4(Int xsb, Int ysb, Int zsb, Int wsb, Dbl dx, Dbl dy, Dbl dz, Dbl dw)C
  1471. {
  1472. Int index=p[(p[(p[(p[xsb&0xFF]+ysb)&0xFF]+zsb)&0xFF]+wsb)&0xFF]&0xFC; // 0xFC mask limits to 0..255 (0xFF) elements and disables bit 1+2 so index+1..3 are in range
  1473. return gradients4D[index ]*dx
  1474. +gradients4D[index+1]*dy
  1475. +gradients4D[index+2]*dz
  1476. +gradients4D[index+3]*dw;
  1477. }
  1478. /******************************************************************************/
  1479. Flt SimplexNoise::noise(Dbl x)C {return noise(x, 0);}
  1480. /******************************************************************************/
  1481. Flt SimplexNoise::noise(Dbl x, Dbl y)C
  1482. {
  1483. // Place input coordinates onto grid.
  1484. Dbl stretchOffset=(x+y)*STRETCH_CONSTANT_2D;
  1485. Dbl xs=x+stretchOffset;
  1486. Dbl ys=y+stretchOffset;
  1487. // Floor to get grid coordinates of rhombus (stretched square) super-cell origin.
  1488. Int xsb=Floor(xs);
  1489. Int ysb=Floor(ys);
  1490. // Skew out to get actual coordinates of rhombus origin. We'll need these later.
  1491. Dbl squishOffset=(xsb+ysb)*SQUISH_CONSTANT_2D;
  1492. Dbl xb=xsb+squishOffset;
  1493. Dbl yb=ysb+squishOffset;
  1494. // Compute grid coordinates relative to rhombus origin.
  1495. Dbl xins=xs-xsb;
  1496. Dbl yins=ys-ysb;
  1497. // Sum those together to get a value that determines which region we're in.
  1498. Dbl inSum=xins+yins;
  1499. // Positions relative to origin point.
  1500. Dbl dx0=x-xb;
  1501. Dbl dy0=y-yb;
  1502. // We'll be defining these inside the next block and using them afterwards.
  1503. Dbl dx_ext, dy_ext;
  1504. Int xsv_ext, ysv_ext;
  1505. Dbl dx1;
  1506. Dbl dy1;
  1507. Dbl attn1;
  1508. Dbl dx2;
  1509. Dbl dy2;
  1510. Dbl attn2;
  1511. Dbl zins;
  1512. Dbl attn0;
  1513. Dbl attn_ext;
  1514. Dbl value=0;
  1515. // Contribution (1,0)
  1516. dx1=dx0-1-SQUISH_CONSTANT_2D;
  1517. dy1=dy0-0-SQUISH_CONSTANT_2D;
  1518. attn1=2-dx1*dx1-dy1*dy1;
  1519. if(attn1>0)
  1520. {
  1521. attn1*=attn1;
  1522. value+=attn1*attn1*extrapolate2(xsb+1, ysb+0, dx1, dy1);
  1523. }
  1524. // Contribution (0,1)
  1525. dx2=dx0-0-SQUISH_CONSTANT_2D;
  1526. dy2=dy0-1-SQUISH_CONSTANT_2D;
  1527. attn2=2-dx2*dx2-dy2*dy2;
  1528. if(attn2>0)
  1529. {
  1530. attn2*=attn2;
  1531. value+=attn2*attn2*extrapolate2(xsb+0, ysb+1, dx2, dy2);
  1532. }
  1533. if(inSum<=1) // We're inside the triangle (2-Simplex) at (0,0)
  1534. {
  1535. zins=1-inSum;
  1536. if(zins>xins || zins>yins) // (0,0) is one of the closest two triangular vertices
  1537. {
  1538. if(xins>yins)
  1539. {
  1540. xsv_ext=xsb+1;
  1541. ysv_ext=ysb-1;
  1542. dx_ext=dx0-1;
  1543. dy_ext=dy0+1;
  1544. }else
  1545. {
  1546. xsv_ext=xsb-1;
  1547. ysv_ext=ysb+1;
  1548. dx_ext=dx0+1;
  1549. dy_ext=dy0-1;
  1550. }
  1551. }else // (1,0) and (0,1) are the closest two vertices.
  1552. {
  1553. xsv_ext=xsb+1;
  1554. ysv_ext=ysb+1;
  1555. dx_ext=dx0-1-2*SQUISH_CONSTANT_2D;
  1556. dy_ext=dy0-1-2*SQUISH_CONSTANT_2D;
  1557. }
  1558. }else // We're inside the triangle (2-Simplex) at (1,1)
  1559. {
  1560. zins=2-inSum;
  1561. if(zins<xins || zins<yins) // (0,0) is one of the closest two triangular vertices
  1562. {
  1563. if(xins>yins)
  1564. {
  1565. xsv_ext=xsb+2;
  1566. ysv_ext=ysb+0;
  1567. dx_ext=dx0-2-2*SQUISH_CONSTANT_2D;
  1568. dy_ext=dy0+0-2*SQUISH_CONSTANT_2D;
  1569. }else
  1570. {
  1571. xsv_ext=xsb+0;
  1572. ysv_ext=ysb+2;
  1573. dx_ext=dx0+0-2*SQUISH_CONSTANT_2D;
  1574. dy_ext=dy0-2-2*SQUISH_CONSTANT_2D;
  1575. }
  1576. }else // (1,0) and (0,1) are the closest two vertices.
  1577. {
  1578. dx_ext=dx0;
  1579. dy_ext=dy0;
  1580. xsv_ext=xsb;
  1581. ysv_ext=ysb;
  1582. }
  1583. xsb+=1;
  1584. ysb+=1;
  1585. dx0=dx0-1-2*SQUISH_CONSTANT_2D;
  1586. dy0=dy0-1-2*SQUISH_CONSTANT_2D;
  1587. }
  1588. // Contribution (0,0) or (1,1)
  1589. attn0=2-dx0*dx0-dy0*dy0;
  1590. if(attn0>0)
  1591. {
  1592. attn0*=attn0;
  1593. value+=attn0*attn0*extrapolate2(xsb, ysb, dx0, dy0);
  1594. }
  1595. // Extra Vertex
  1596. attn_ext=2-dx_ext*dx_ext-dy_ext*dy_ext;
  1597. if(attn_ext>0)
  1598. {
  1599. attn_ext*=attn_ext;
  1600. value+=attn_ext*attn_ext*extrapolate2(xsv_ext, ysv_ext, dx_ext, dy_ext);
  1601. }
  1602. return value/(SIMPLEX_NORM_CONSTANT_2D);
  1603. }
  1604. /******************************************************************************/
  1605. Flt SimplexNoise::noise(Dbl x, Dbl y, Dbl z)C
  1606. {
  1607. // Place input coordinates on simplectic honeycomb.
  1608. Dbl stretchOffset=(x+y+z)*STRETCH_CONSTANT_3D;
  1609. Dbl xs=x+stretchOffset;
  1610. Dbl ys=y+stretchOffset;
  1611. Dbl zs=z+stretchOffset;
  1612. // Floor to get simplectic honeycomb coordinates of rhombohedron (stretched cube) super-cell origin.
  1613. Int xsb=Floor(xs);
  1614. Int ysb=Floor(ys);
  1615. Int zsb=Floor(zs);
  1616. // Skew out to get actual coordinates of rhombohedron origin. We'll need these later.
  1617. Dbl squishOffset=(xsb+ysb+zsb)*SQUISH_CONSTANT_3D;
  1618. Dbl xb=xsb+squishOffset;
  1619. Dbl yb=ysb+squishOffset;
  1620. Dbl zb=zsb+squishOffset;
  1621. // Compute simplectic honeycomb coordinates relative to rhombohedral origin.
  1622. Dbl xins=xs-xsb;
  1623. Dbl yins=ys-ysb;
  1624. Dbl zins=zs-zsb;
  1625. // Sum those together to get a value that determines which region we're in.
  1626. Dbl inSum=xins+yins+zins;
  1627. // Positions relative to origin point.
  1628. Dbl dx0=x-xb;
  1629. Dbl dy0=y-yb;
  1630. Dbl dz0=z-zb;
  1631. // We'll be defining these inside the next block and using them afterwards.
  1632. Dbl dx_ext0, dy_ext0, dz_ext0;
  1633. Dbl dx_ext1, dy_ext1, dz_ext1;
  1634. Int xsv_ext0, ysv_ext0, zsv_ext0;
  1635. Int xsv_ext1, ysv_ext1, zsv_ext1;
  1636. Dbl wins;
  1637. I8 c, c1, c2;
  1638. I8 aPoint, bPoint;
  1639. Dbl aScore, bScore;
  1640. Int aIsFurtherSide;
  1641. Int bIsFurtherSide;
  1642. Dbl p1, p2, p3;
  1643. Dbl score;
  1644. Dbl attn0, attn1, attn2, attn3, attn4, attn5, attn6;
  1645. Dbl dx1, dy1, dz1;
  1646. Dbl dx2, dy2, dz2;
  1647. Dbl dx3, dy3, dz3;
  1648. Dbl dx4, dy4, dz4;
  1649. Dbl dx5, dy5, dz5;
  1650. Dbl dx6, dy6, dz6;
  1651. Dbl attn_ext0, attn_ext1;
  1652. Dbl value=0;
  1653. if(inSum<=1) // We're inside the tetrahedron (3-Simplex) at (0,0,0)
  1654. {
  1655. // Determine which two of (0,0,1), (0,1,0), (1,0,0) are closest.
  1656. aPoint=0x01;
  1657. aScore=xins;
  1658. bPoint=0x02;
  1659. bScore=yins;
  1660. if(aScore>=bScore && zins>bScore)
  1661. {
  1662. bScore=zins;
  1663. bPoint=0x04;
  1664. }else
  1665. if(aScore<bScore && zins>aScore)
  1666. {
  1667. aScore=zins;
  1668. aPoint=0x04;
  1669. }
  1670. // Now we determine the two lattice points not part of the tetrahedron that may contribute. This depends on the closest two tetrahedral vertices, including (0,0,0)
  1671. wins=1-inSum;
  1672. if(wins>aScore || wins>bScore) // (0,0,0) is one of the closest two tetrahedral vertices.
  1673. {
  1674. c=(bScore>aScore ? bPoint : aPoint); // Our other closest vertex is the closest out of a and b.
  1675. if((c&0x01) == 0)
  1676. {
  1677. xsv_ext0=xsb-1;
  1678. xsv_ext1=xsb;
  1679. dx_ext0=dx0+1;
  1680. dx_ext1=dx0;
  1681. }else
  1682. {
  1683. xsv_ext0=xsv_ext1=xsb+1;
  1684. dx_ext0=dx_ext1=dx0-1;
  1685. }
  1686. if((c&0x02) == 0)
  1687. {
  1688. ysv_ext0=ysv_ext1=ysb;
  1689. dy_ext0=dy_ext1=dy0;
  1690. if((c&0x01) == 0)
  1691. {
  1692. ysv_ext1-=1;
  1693. dy_ext1+=1;
  1694. }else
  1695. {
  1696. ysv_ext0-=1;
  1697. dy_ext0+=1;
  1698. }
  1699. }else
  1700. {
  1701. ysv_ext0=ysv_ext1=ysb+1;
  1702. dy_ext0=dy_ext1=dy0-1;
  1703. }
  1704. if((c&0x04) == 0)
  1705. {
  1706. zsv_ext0=zsb;
  1707. zsv_ext1=zsb-1;
  1708. dz_ext0=dz0;
  1709. dz_ext1=dz0+1;
  1710. }else
  1711. {
  1712. zsv_ext0=zsv_ext1=zsb+1;
  1713. dz_ext0=dz_ext1=dz0-1;
  1714. }
  1715. }else // (0,0,0) is not one of the closest two tetrahedral vertices.
  1716. {
  1717. c=(I8)(aPoint | bPoint); // Our two extra vertices are determined by the closest two.
  1718. if((c&0x01) == 0)
  1719. {
  1720. xsv_ext0=xsb;
  1721. xsv_ext1=xsb-1;
  1722. dx_ext0=dx0-2*SQUISH_CONSTANT_3D;
  1723. dx_ext1=dx0+1-SQUISH_CONSTANT_3D;
  1724. }else
  1725. {
  1726. xsv_ext0=xsv_ext1=xsb+1;
  1727. dx_ext0=dx0-1-2*SQUISH_CONSTANT_3D;
  1728. dx_ext1=dx0-1-SQUISH_CONSTANT_3D;
  1729. }
  1730. if((c&0x02) == 0)
  1731. {
  1732. ysv_ext0=ysb;
  1733. ysv_ext1=ysb-1;
  1734. dy_ext0=dy0-2*SQUISH_CONSTANT_3D;
  1735. dy_ext1=dy0+1-SQUISH_CONSTANT_3D;
  1736. }else
  1737. {
  1738. ysv_ext0=ysv_ext1=ysb+1;
  1739. dy_ext0=dy0-1-2*SQUISH_CONSTANT_3D;
  1740. dy_ext1=dy0-1-SQUISH_CONSTANT_3D;
  1741. }
  1742. if((c&0x04) == 0)
  1743. {
  1744. zsv_ext0=zsb;
  1745. zsv_ext1=zsb-1;
  1746. dz_ext0=dz0-2*SQUISH_CONSTANT_3D;
  1747. dz_ext1=dz0+1-SQUISH_CONSTANT_3D;
  1748. }else
  1749. {
  1750. zsv_ext0=zsv_ext1=zsb+1;
  1751. dz_ext0=dz0-1-2*SQUISH_CONSTANT_3D;
  1752. dz_ext1=dz0-1-SQUISH_CONSTANT_3D;
  1753. }
  1754. }
  1755. // Contribution (0,0,0)
  1756. attn0=2-dx0*dx0-dy0*dy0-dz0*dz0;
  1757. if(attn0>0)
  1758. {
  1759. attn0*=attn0;
  1760. value+=attn0*attn0*extrapolate3(xsb+0, ysb+0, zsb+0, dx0, dy0, dz0);
  1761. }
  1762. // Contribution (1,0,0)
  1763. dx1=dx0-1-SQUISH_CONSTANT_3D;
  1764. dy1=dy0-0-SQUISH_CONSTANT_3D;
  1765. dz1=dz0-0-SQUISH_CONSTANT_3D;
  1766. attn1=2-dx1*dx1-dy1*dy1-dz1*dz1;
  1767. if(attn1>0)
  1768. {
  1769. attn1*=attn1;
  1770. value+=attn1*attn1*extrapolate3(xsb+1, ysb+0, zsb+0, dx1, dy1, dz1);
  1771. }
  1772. // Contribution (0,1,0)
  1773. dx2=dx0-0-SQUISH_CONSTANT_3D;
  1774. dy2=dy0-1-SQUISH_CONSTANT_3D;
  1775. dz2=dz1;
  1776. attn2=2-dx2*dx2-dy2*dy2-dz2*dz2;
  1777. if(attn2>0)
  1778. {
  1779. attn2*=attn2;
  1780. value+=attn2*attn2*extrapolate3(xsb+0, ysb+1, zsb+0, dx2, dy2, dz2);
  1781. }
  1782. // Contribution (0,0,1)
  1783. dx3=dx2;
  1784. dy3=dy1;
  1785. dz3=dz0-1-SQUISH_CONSTANT_3D;
  1786. attn3=2-dx3*dx3-dy3*dy3-dz3*dz3;
  1787. if(attn3>0)
  1788. {
  1789. attn3*=attn3;
  1790. value+=attn3*attn3*extrapolate3(xsb+0, ysb+0, zsb+1, dx3, dy3, dz3);
  1791. }
  1792. }else
  1793. if(inSum>=2) // We're inside the tetrahedron (3-Simplex) at (1,1,1)
  1794. {
  1795. // Determine which two tetrahedral vertices are the closest, out of (1,1,0), (1,0,1), (0,1,1) but not (1,1,1).
  1796. aPoint=0x06;
  1797. aScore=xins;
  1798. bPoint=0x05;
  1799. bScore=yins;
  1800. if(aScore<=bScore && zins<bScore)
  1801. {
  1802. bScore=zins;
  1803. bPoint=0x03;
  1804. }else
  1805. if(aScore>bScore && zins<aScore)
  1806. {
  1807. aScore=zins;
  1808. aPoint=0x03;
  1809. }
  1810. // Now we determine the two lattice points not part of the tetrahedron that may contribute. This depends on the closest two tetrahedral vertices, including (1,1,1)
  1811. wins=3-inSum;
  1812. if(wins<aScore || wins<bScore) // (1,1,1) is one of the closest two tetrahedral vertices.
  1813. {
  1814. c=(bScore<aScore ? bPoint : aPoint); // Our other closest vertex is the closest out of a and b.
  1815. if((c&0x01) != 0)
  1816. {
  1817. xsv_ext0=xsb+2;
  1818. xsv_ext1=xsb+1;
  1819. dx_ext0=dx0-2-3*SQUISH_CONSTANT_3D;
  1820. dx_ext1=dx0-1-3*SQUISH_CONSTANT_3D;
  1821. }else
  1822. {
  1823. xsv_ext0=xsv_ext1=xsb;
  1824. dx_ext0=dx_ext1=dx0-3*SQUISH_CONSTANT_3D;
  1825. }
  1826. if((c&0x02) != 0)
  1827. {
  1828. ysv_ext0=ysv_ext1=ysb+1;
  1829. dy_ext0=dy_ext1=dy0-1-3*SQUISH_CONSTANT_3D;
  1830. if((c&0x01) != 0)
  1831. {
  1832. ysv_ext1+=1;
  1833. dy_ext1-=1;
  1834. }else
  1835. {
  1836. ysv_ext0+=1;
  1837. dy_ext0-=1;
  1838. }
  1839. }else
  1840. {
  1841. ysv_ext0=ysv_ext1=ysb;
  1842. dy_ext0=dy_ext1=dy0-3*SQUISH_CONSTANT_3D;
  1843. }
  1844. if((c&0x04) != 0)
  1845. {
  1846. zsv_ext0=zsb+1;
  1847. zsv_ext1=zsb+2;
  1848. dz_ext0=dz0-1-3*SQUISH_CONSTANT_3D;
  1849. dz_ext1=dz0-2-3*SQUISH_CONSTANT_3D;
  1850. }else
  1851. {
  1852. zsv_ext0=zsv_ext1=zsb;
  1853. dz_ext0=dz_ext1=dz0-3*SQUISH_CONSTANT_3D;
  1854. }
  1855. }else // (1,1,1) is not one of the closest two tetrahedral vertices.
  1856. {
  1857. c=(I8)(aPoint&bPoint); // Our two extra vertices are determined by the closest two.
  1858. if((c&0x01) != 0)
  1859. {
  1860. xsv_ext0=xsb+1;
  1861. xsv_ext1=xsb+2;
  1862. dx_ext0=dx0-1-SQUISH_CONSTANT_3D;
  1863. dx_ext1=dx0-2-2*SQUISH_CONSTANT_3D;
  1864. }else
  1865. {
  1866. xsv_ext0=xsv_ext1=xsb;
  1867. dx_ext0=dx0-SQUISH_CONSTANT_3D;
  1868. dx_ext1=dx0-2*SQUISH_CONSTANT_3D;
  1869. }
  1870. if((c&0x02) != 0)
  1871. {
  1872. ysv_ext0=ysb+1;
  1873. ysv_ext1=ysb+2;
  1874. dy_ext0=dy0-1-SQUISH_CONSTANT_3D;
  1875. dy_ext1=dy0-2-2*SQUISH_CONSTANT_3D;
  1876. }else
  1877. {
  1878. ysv_ext0=ysv_ext1=ysb;
  1879. dy_ext0=dy0-SQUISH_CONSTANT_3D;
  1880. dy_ext1=dy0-2*SQUISH_CONSTANT_3D;
  1881. }
  1882. if((c&0x04) != 0)
  1883. {
  1884. zsv_ext0=zsb+1;
  1885. zsv_ext1=zsb+2;
  1886. dz_ext0=dz0-1-SQUISH_CONSTANT_3D;
  1887. dz_ext1=dz0-2-2*SQUISH_CONSTANT_3D;
  1888. }else
  1889. {
  1890. zsv_ext0=zsv_ext1=zsb;
  1891. dz_ext0=dz0-SQUISH_CONSTANT_3D;
  1892. dz_ext1=dz0-2*SQUISH_CONSTANT_3D;
  1893. }
  1894. }
  1895. // Contribution (1,1,0)
  1896. dx3=dx0-1-2*SQUISH_CONSTANT_3D;
  1897. dy3=dy0-1-2*SQUISH_CONSTANT_3D;
  1898. dz3=dz0-0-2*SQUISH_CONSTANT_3D;
  1899. attn3=2-dx3*dx3-dy3*dy3-dz3*dz3;
  1900. if(attn3>0)
  1901. {
  1902. attn3*=attn3;
  1903. value+=attn3*attn3*extrapolate3(xsb+1, ysb+1, zsb+0, dx3, dy3, dz3);
  1904. }
  1905. // Contribution (1,0,1)
  1906. dx2=dx3;
  1907. dy2=dy0-0-2*SQUISH_CONSTANT_3D;
  1908. dz2=dz0-1-2*SQUISH_CONSTANT_3D;
  1909. attn2=2-dx2*dx2-dy2*dy2-dz2*dz2;
  1910. if(attn2>0)
  1911. {
  1912. attn2*=attn2;
  1913. value+=attn2*attn2*extrapolate3(xsb+1, ysb+0, zsb+1, dx2, dy2, dz2);
  1914. }
  1915. // Contribution (0,1,1)
  1916. dx1=dx0-0-2*SQUISH_CONSTANT_3D;
  1917. dy1=dy3;
  1918. dz1=dz2;
  1919. attn1=2-dx1*dx1-dy1*dy1-dz1*dz1;
  1920. if(attn1>0)
  1921. {
  1922. attn1*=attn1;
  1923. value+=attn1*attn1*extrapolate3(xsb+0, ysb+1, zsb+1, dx1, dy1, dz1);
  1924. }
  1925. // Contribution (1,1,1)
  1926. dx0=dx0-1-3*SQUISH_CONSTANT_3D;
  1927. dy0=dy0-1-3*SQUISH_CONSTANT_3D;
  1928. dz0=dz0-1-3*SQUISH_CONSTANT_3D;
  1929. attn0=2-dx0*dx0-dy0*dy0-dz0*dz0;
  1930. if(attn0>0)
  1931. {
  1932. attn0*=attn0;
  1933. value+=attn0*attn0*extrapolate3(xsb+1, ysb+1, zsb+1, dx0, dy0, dz0);
  1934. }
  1935. }else // We're inside the octahedron (Rectified 3-Simplex) in between. Decide between point (0,0,1) and (1,1,0) as closest
  1936. {
  1937. p1=xins+yins;
  1938. if(p1>1)
  1939. {
  1940. aScore=p1-1;
  1941. aPoint=0x03;
  1942. aIsFurtherSide=1;
  1943. }else
  1944. {
  1945. aScore=1-p1;
  1946. aPoint=0x04;
  1947. aIsFurtherSide=0;
  1948. }
  1949. // Decide between point (0,1,0) and (1,0,1) as closest
  1950. p2=xins+zins;
  1951. if(p2>1)
  1952. {
  1953. bScore=p2-1;
  1954. bPoint=0x05;
  1955. bIsFurtherSide=1;
  1956. }else
  1957. {
  1958. bScore=1-p2;
  1959. bPoint=0x02;
  1960. bIsFurtherSide=0;
  1961. }
  1962. // The closest out of the two (1,0,0) and (0,1,1) will replace the furthest out of the two decided above, if closer.
  1963. p3=yins+zins;
  1964. if(p3>1)
  1965. {
  1966. score=p3-1;
  1967. if(aScore<=bScore && aScore<score)
  1968. {
  1969. aScore=score;
  1970. aPoint=0x06;
  1971. aIsFurtherSide=1;
  1972. }else
  1973. if(aScore>bScore && bScore<score)
  1974. {
  1975. bScore=score;
  1976. bPoint=0x06;
  1977. bIsFurtherSide=1;
  1978. }
  1979. }else
  1980. {
  1981. score=1-p3;
  1982. if(aScore<=bScore && aScore<score)
  1983. {
  1984. aScore=score;
  1985. aPoint=0x01;
  1986. aIsFurtherSide=0;
  1987. }else
  1988. if(aScore>bScore && bScore<score)
  1989. {
  1990. bScore=score;
  1991. bPoint=0x01;
  1992. bIsFurtherSide=0;
  1993. }
  1994. }
  1995. // Where each of the two closest points are determines how the extra two vertices are calculated.
  1996. if(aIsFurtherSide == bIsFurtherSide)
  1997. {
  1998. if(aIsFurtherSide) // Both closest points on (1,1,1) side
  1999. {
  2000. // One of the two extra points is (1,1,1)
  2001. dx_ext0=dx0-1-3*SQUISH_CONSTANT_3D;
  2002. dy_ext0=dy0-1-3*SQUISH_CONSTANT_3D;
  2003. dz_ext0=dz0-1-3*SQUISH_CONSTANT_3D;
  2004. xsv_ext0=xsb+1;
  2005. ysv_ext0=ysb+1;
  2006. zsv_ext0=zsb+1;
  2007. // Other extra point is based on the shared axis.
  2008. c=(I8)(aPoint&bPoint);
  2009. if((c&0x01) != 0)
  2010. {
  2011. dx_ext1=dx0-2-2*SQUISH_CONSTANT_3D;
  2012. dy_ext1=dy0-2*SQUISH_CONSTANT_3D;
  2013. dz_ext1=dz0-2*SQUISH_CONSTANT_3D;
  2014. xsv_ext1=xsb+2;
  2015. ysv_ext1=ysb;
  2016. zsv_ext1=zsb;
  2017. }else
  2018. if((c&0x02) != 0)
  2019. {
  2020. dx_ext1=dx0-2*SQUISH_CONSTANT_3D;
  2021. dy_ext1=dy0-2-2*SQUISH_CONSTANT_3D;
  2022. dz_ext1=dz0-2*SQUISH_CONSTANT_3D;
  2023. xsv_ext1=xsb;
  2024. ysv_ext1=ysb+2;
  2025. zsv_ext1=zsb;
  2026. }else
  2027. {
  2028. dx_ext1=dx0-2*SQUISH_CONSTANT_3D;
  2029. dy_ext1=dy0-2*SQUISH_CONSTANT_3D;
  2030. dz_ext1=dz0-2-2*SQUISH_CONSTANT_3D;
  2031. xsv_ext1=xsb;
  2032. ysv_ext1=ysb;
  2033. zsv_ext1=zsb+2;
  2034. }
  2035. }else // Both closest points on (0,0,0) side
  2036. {
  2037. // One of the two extra points is (0,0,0)
  2038. dx_ext0=dx0;
  2039. dy_ext0=dy0;
  2040. dz_ext0=dz0;
  2041. xsv_ext0=xsb;
  2042. ysv_ext0=ysb;
  2043. zsv_ext0=zsb;
  2044. // Other extra point is based on the omitted axis.
  2045. c=(I8)(aPoint | bPoint);
  2046. if((c&0x01) == 0)
  2047. {
  2048. dx_ext1=dx0+1-SQUISH_CONSTANT_3D;
  2049. dy_ext1=dy0-1-SQUISH_CONSTANT_3D;
  2050. dz_ext1=dz0-1-SQUISH_CONSTANT_3D;
  2051. xsv_ext1=xsb-1;
  2052. ysv_ext1=ysb+1;
  2053. zsv_ext1=zsb+1;
  2054. }else
  2055. if((c&0x02) == 0)
  2056. {
  2057. dx_ext1=dx0-1-SQUISH_CONSTANT_3D;
  2058. dy_ext1=dy0+1-SQUISH_CONSTANT_3D;
  2059. dz_ext1=dz0-1-SQUISH_CONSTANT_3D;
  2060. xsv_ext1=xsb+1;
  2061. ysv_ext1=ysb-1;
  2062. zsv_ext1=zsb+1;
  2063. }else
  2064. {
  2065. dx_ext1=dx0-1-SQUISH_CONSTANT_3D;
  2066. dy_ext1=dy0-1-SQUISH_CONSTANT_3D;
  2067. dz_ext1=dz0+1-SQUISH_CONSTANT_3D;
  2068. xsv_ext1=xsb+1;
  2069. ysv_ext1=ysb+1;
  2070. zsv_ext1=zsb-1;
  2071. }
  2072. }
  2073. }else // One point on (0,0,0) side, one point on (1,1,1) side
  2074. {
  2075. if(aIsFurtherSide)
  2076. {
  2077. c1=aPoint;
  2078. c2=bPoint;
  2079. }else
  2080. {
  2081. c1=bPoint;
  2082. c2=aPoint;
  2083. }
  2084. // One contribution is a permutation of (1,1,-1)
  2085. if((c1&0x01) == 0)
  2086. {
  2087. dx_ext0=dx0+1-SQUISH_CONSTANT_3D;
  2088. dy_ext0=dy0-1-SQUISH_CONSTANT_3D;
  2089. dz_ext0=dz0-1-SQUISH_CONSTANT_3D;
  2090. xsv_ext0=xsb-1;
  2091. ysv_ext0=ysb+1;
  2092. zsv_ext0=zsb+1;
  2093. }else
  2094. if((c1&0x02) == 0)
  2095. {
  2096. dx_ext0=dx0-1-SQUISH_CONSTANT_3D;
  2097. dy_ext0=dy0+1-SQUISH_CONSTANT_3D;
  2098. dz_ext0=dz0-1-SQUISH_CONSTANT_3D;
  2099. xsv_ext0=xsb+1;
  2100. ysv_ext0=ysb-1;
  2101. zsv_ext0=zsb+1;
  2102. }else
  2103. {
  2104. dx_ext0=dx0-1-SQUISH_CONSTANT_3D;
  2105. dy_ext0=dy0-1-SQUISH_CONSTANT_3D;
  2106. dz_ext0=dz0+1-SQUISH_CONSTANT_3D;
  2107. xsv_ext0=xsb+1;
  2108. ysv_ext0=ysb+1;
  2109. zsv_ext0=zsb-1;
  2110. }
  2111. // One contribution is a permutation of (0,0,2)
  2112. dx_ext1=dx0-2*SQUISH_CONSTANT_3D;
  2113. dy_ext1=dy0-2*SQUISH_CONSTANT_3D;
  2114. dz_ext1=dz0-2*SQUISH_CONSTANT_3D;
  2115. xsv_ext1=xsb;
  2116. ysv_ext1=ysb;
  2117. zsv_ext1=zsb;
  2118. if((c2&0x01) != 0)
  2119. {
  2120. dx_ext1-=2;
  2121. xsv_ext1+=2;
  2122. }else
  2123. if((c2&0x02) != 0)
  2124. {
  2125. dy_ext1-=2;
  2126. ysv_ext1+=2;
  2127. }else
  2128. {
  2129. dz_ext1-=2;
  2130. zsv_ext1+=2;
  2131. }
  2132. }
  2133. // Contribution (1,0,0)
  2134. dx1=dx0-1-SQUISH_CONSTANT_3D;
  2135. dy1=dy0-0-SQUISH_CONSTANT_3D;
  2136. dz1=dz0-0-SQUISH_CONSTANT_3D;
  2137. attn1=2-dx1*dx1-dy1*dy1-dz1*dz1;
  2138. if(attn1>0)
  2139. {
  2140. attn1*=attn1;
  2141. value+=attn1*attn1*extrapolate3(xsb+1, ysb+0, zsb+0, dx1, dy1, dz1);
  2142. }
  2143. // Contribution (0,1,0)
  2144. dx2=dx0-0-SQUISH_CONSTANT_3D;
  2145. dy2=dy0-1-SQUISH_CONSTANT_3D;
  2146. dz2=dz1;
  2147. attn2=2-dx2*dx2-dy2*dy2-dz2*dz2;
  2148. if(attn2>0)
  2149. {
  2150. attn2*=attn2;
  2151. value+=attn2*attn2*extrapolate3(xsb+0, ysb+1, zsb+0, dx2, dy2, dz2);
  2152. }
  2153. // Contribution (0,0,1)
  2154. dx3=dx2;
  2155. dy3=dy1;
  2156. dz3=dz0-1-SQUISH_CONSTANT_3D;
  2157. attn3=2-dx3*dx3-dy3*dy3-dz3*dz3;
  2158. if(attn3>0)
  2159. {
  2160. attn3*=attn3;
  2161. value+=attn3*attn3*extrapolate3(xsb+0, ysb+0, zsb+1, dx3, dy3, dz3);
  2162. }
  2163. // Contribution (1,1,0)
  2164. dx4=dx0-1-2*SQUISH_CONSTANT_3D;
  2165. dy4=dy0-1-2*SQUISH_CONSTANT_3D;
  2166. dz4=dz0-0-2*SQUISH_CONSTANT_3D;
  2167. attn4=2-dx4*dx4-dy4*dy4-dz4*dz4;
  2168. if(attn4>0)
  2169. {
  2170. attn4*=attn4;
  2171. value+=attn4*attn4*extrapolate3(xsb+1, ysb+1, zsb+0, dx4, dy4, dz4);
  2172. }
  2173. // Contribution (1,0,1)
  2174. dx5=dx4;
  2175. dy5=dy0-0-2*SQUISH_CONSTANT_3D;
  2176. dz5=dz0-1-2*SQUISH_CONSTANT_3D;
  2177. attn5=2-dx5*dx5-dy5*dy5-dz5*dz5;
  2178. if(attn5>0)
  2179. {
  2180. attn5*=attn5;
  2181. value+=attn5*attn5*extrapolate3(xsb+1, ysb+0, zsb+1, dx5, dy5, dz5);
  2182. }
  2183. // Contribution (0,1,1)
  2184. dx6=dx0-0-2*SQUISH_CONSTANT_3D;
  2185. dy6=dy4;
  2186. dz6=dz5;
  2187. attn6=2-dx6*dx6-dy6*dy6-dz6*dz6;
  2188. if(attn6>0)
  2189. {
  2190. attn6*=attn6;
  2191. value+=attn6*attn6*extrapolate3(xsb+0, ysb+1, zsb+1, dx6, dy6, dz6);
  2192. }
  2193. }
  2194. // First extra vertex
  2195. attn_ext0=2-dx_ext0*dx_ext0-dy_ext0*dy_ext0-dz_ext0*dz_ext0;
  2196. if(attn_ext0>0)
  2197. {
  2198. attn_ext0*=attn_ext0;
  2199. value+=attn_ext0*attn_ext0*extrapolate3(xsv_ext0, ysv_ext0, zsv_ext0, dx_ext0, dy_ext0, dz_ext0);
  2200. }
  2201. // Second extra vertex
  2202. attn_ext1=2-dx_ext1*dx_ext1-dy_ext1*dy_ext1-dz_ext1*dz_ext1;
  2203. if(attn_ext1>0)
  2204. {
  2205. attn_ext1*=attn_ext1;
  2206. value+=attn_ext1*attn_ext1*extrapolate3(xsv_ext1, ysv_ext1, zsv_ext1, dx_ext1, dy_ext1, dz_ext1);
  2207. }
  2208. return value/(SIMPLEX_NORM_CONSTANT_3D);
  2209. }
  2210. /******************************************************************************/
  2211. Flt SimplexNoise::noise(Dbl x, Dbl y, Dbl z, Dbl w)C
  2212. {
  2213. Dbl uins;
  2214. Dbl dx1, dy1, dz1, dw1;
  2215. Dbl dx2, dy2, dz2, dw2;
  2216. Dbl dx3, dy3, dz3, dw3;
  2217. Dbl dx4, dy4, dz4, dw4;
  2218. Dbl dx5, dy5, dz5, dw5;
  2219. Dbl dx6, dy6, dz6, dw6;
  2220. Dbl dx7, dy7, dz7, dw7;
  2221. Dbl dx8, dy8, dz8, dw8;
  2222. Dbl dx9, dy9, dz9, dw9;
  2223. Dbl dx10, dy10, dz10, dw10;
  2224. Dbl attn0, attn1, attn2, attn3, attn4;
  2225. Dbl attn5, attn6, attn7, attn8, attn9, attn10;
  2226. Dbl attn_ext0, attn_ext1, attn_ext2;
  2227. I8 c, c1, c2;
  2228. I8 aPoint, bPoint;
  2229. Dbl aScore, bScore;
  2230. Int aIsBiggerSide;
  2231. Int bIsBiggerSide;
  2232. Dbl p1, p2, p3, p4;
  2233. Dbl score;
  2234. // Place input coordinates on simplectic honeycomb.
  2235. Dbl stretchOffset=(x+y+z+w)*STRETCH_CONSTANT_4D;
  2236. Dbl xs=x+stretchOffset;
  2237. Dbl ys=y+stretchOffset;
  2238. Dbl zs=z+stretchOffset;
  2239. Dbl ws=w+stretchOffset;
  2240. // Floor to get simplectic honeycomb coordinates of rhombo-hypercube super-cell origin.
  2241. Int xsb=Floor(xs);
  2242. Int ysb=Floor(ys);
  2243. Int zsb=Floor(zs);
  2244. Int wsb=Floor(ws);
  2245. // Skew out to get actual coordinates of stretched rhombo-hypercube origin. We'll need these later.
  2246. Dbl squishOffset=(xsb+ysb+zsb+wsb)*SQUISH_CONSTANT_4D;
  2247. Dbl xb=xsb+squishOffset;
  2248. Dbl yb=ysb+squishOffset;
  2249. Dbl zb=zsb+squishOffset;
  2250. Dbl wb=wsb+squishOffset;
  2251. // Compute simplectic honeycomb coordinates relative to rhombo-hypercube origin.
  2252. Dbl xins=xs-xsb;
  2253. Dbl yins=ys-ysb;
  2254. Dbl zins=zs-zsb;
  2255. Dbl wins=ws-wsb;
  2256. // Sum those together to get a value that determines which region we're in.
  2257. Dbl inSum=xins+yins+zins+wins;
  2258. // Positions relative to origin point.
  2259. Dbl dx0=x-xb;
  2260. Dbl dy0=y-yb;
  2261. Dbl dz0=z-zb;
  2262. Dbl dw0=w-wb;
  2263. // We'll be defining these inside the next block and using them afterwards.
  2264. Dbl dx_ext0, dy_ext0, dz_ext0, dw_ext0;
  2265. Dbl dx_ext1, dy_ext1, dz_ext1, dw_ext1;
  2266. Dbl dx_ext2, dy_ext2, dz_ext2, dw_ext2;
  2267. Int xsv_ext0, ysv_ext0, zsv_ext0, wsv_ext0;
  2268. Int xsv_ext1, ysv_ext1, zsv_ext1, wsv_ext1;
  2269. Int xsv_ext2, ysv_ext2, zsv_ext2, wsv_ext2;
  2270. Dbl value=0;
  2271. if(inSum<=1) { // We're inside the pentachoron (4-Simplex) at (0,0,0,0)
  2272. // Determine which two of (0,0,0,1), (0,0,1,0), (0,1,0,0), (1,0,0,0) are closest.
  2273. aPoint=0x01;
  2274. aScore=xins;
  2275. bPoint=0x02;
  2276. bScore=yins;
  2277. if(aScore>=bScore && zins>bScore) {
  2278. bScore=zins;
  2279. bPoint=0x04;
  2280. } else if(aScore<bScore && zins>aScore) {
  2281. aScore=zins;
  2282. aPoint=0x04;
  2283. }
  2284. if(aScore>=bScore && wins>bScore) {
  2285. bScore=wins;
  2286. bPoint=0x08;
  2287. } else if(aScore<bScore && wins>aScore) {
  2288. aScore=wins;
  2289. aPoint=0x08;
  2290. }
  2291. // Now we determine the three lattice points not part of the pentachoron that may contribute. This depends on the closest two pentachoron vertices, including (0,0,0,0)
  2292. uins=1-inSum;
  2293. if(uins>aScore || uins>bScore) { // (0,0,0,0) is one of the closest two pentachoron vertices.
  2294. c=(bScore>aScore ? bPoint : aPoint); // Our other closest vertex is the closest out of a and b.
  2295. if((c&0x01) == 0) {
  2296. xsv_ext0=xsb-1;
  2297. xsv_ext1=xsv_ext2=xsb;
  2298. dx_ext0=dx0+1;
  2299. dx_ext1=dx_ext2=dx0;
  2300. } else {
  2301. xsv_ext0=xsv_ext1=xsv_ext2=xsb+1;
  2302. dx_ext0=dx_ext1=dx_ext2=dx0-1;
  2303. }
  2304. if((c&0x02) == 0) {
  2305. ysv_ext0=ysv_ext1=ysv_ext2=ysb;
  2306. dy_ext0=dy_ext1=dy_ext2=dy0;
  2307. if((c&0x01) == 0x01) {
  2308. ysv_ext0-=1;
  2309. dy_ext0+=1;
  2310. } else {
  2311. ysv_ext1-=1;
  2312. dy_ext1+=1;
  2313. }
  2314. } else {
  2315. ysv_ext0=ysv_ext1=ysv_ext2=ysb+1;
  2316. dy_ext0=dy_ext1=dy_ext2=dy0-1;
  2317. }
  2318. if((c&0x04) == 0) {
  2319. zsv_ext0=zsv_ext1=zsv_ext2=zsb;
  2320. dz_ext0=dz_ext1=dz_ext2=dz0;
  2321. if((c&0x03) != 0) {
  2322. if((c&0x03) == 0x03) {
  2323. zsv_ext0-=1;
  2324. dz_ext0+=1;
  2325. } else {
  2326. zsv_ext1-=1;
  2327. dz_ext1+=1;
  2328. }
  2329. } else {
  2330. zsv_ext2-=1;
  2331. dz_ext2+=1;
  2332. }
  2333. } else {
  2334. zsv_ext0=zsv_ext1=zsv_ext2=zsb+1;
  2335. dz_ext0=dz_ext1=dz_ext2=dz0-1;
  2336. }
  2337. if((c&0x08) == 0) {
  2338. wsv_ext0=wsv_ext1=wsb;
  2339. wsv_ext2=wsb-1;
  2340. dw_ext0=dw_ext1=dw0;
  2341. dw_ext2=dw0+1;
  2342. } else {
  2343. wsv_ext0=wsv_ext1=wsv_ext2=wsb+1;
  2344. dw_ext0=dw_ext1=dw_ext2=dw0-1;
  2345. }
  2346. } else { // (0,0,0,0) is not one of the closest two pentachoron vertices.
  2347. c=(I8)(aPoint | bPoint); // Our three extra vertices are determined by the closest two.
  2348. if((c&0x01) == 0) {
  2349. xsv_ext0=xsv_ext2=xsb;
  2350. xsv_ext1=xsb-1;
  2351. dx_ext0=dx0-2*SQUISH_CONSTANT_4D;
  2352. dx_ext1=dx0+1-SQUISH_CONSTANT_4D;
  2353. dx_ext2=dx0-SQUISH_CONSTANT_4D;
  2354. } else {
  2355. xsv_ext0=xsv_ext1=xsv_ext2=xsb+1;
  2356. dx_ext0=dx0-1-2*SQUISH_CONSTANT_4D;
  2357. dx_ext1=dx_ext2=dx0-1-SQUISH_CONSTANT_4D;
  2358. }
  2359. if((c&0x02) == 0) {
  2360. ysv_ext0=ysv_ext1=ysv_ext2=ysb;
  2361. dy_ext0=dy0-2*SQUISH_CONSTANT_4D;
  2362. dy_ext1=dy_ext2=dy0-SQUISH_CONSTANT_4D;
  2363. if((c&0x01) == 0x01) {
  2364. ysv_ext1-=1;
  2365. dy_ext1+=1;
  2366. } else {
  2367. ysv_ext2-=1;
  2368. dy_ext2+=1;
  2369. }
  2370. } else {
  2371. ysv_ext0=ysv_ext1=ysv_ext2=ysb+1;
  2372. dy_ext0=dy0-1-2*SQUISH_CONSTANT_4D;
  2373. dy_ext1=dy_ext2=dy0-1-SQUISH_CONSTANT_4D;
  2374. }
  2375. if((c&0x04) == 0) {
  2376. zsv_ext0=zsv_ext1=zsv_ext2=zsb;
  2377. dz_ext0=dz0-2*SQUISH_CONSTANT_4D;
  2378. dz_ext1=dz_ext2=dz0-SQUISH_CONSTANT_4D;
  2379. if((c&0x03) == 0x03) {
  2380. zsv_ext1-=1;
  2381. dz_ext1+=1;
  2382. } else {
  2383. zsv_ext2-=1;
  2384. dz_ext2+=1;
  2385. }
  2386. } else {
  2387. zsv_ext0=zsv_ext1=zsv_ext2=zsb+1;
  2388. dz_ext0=dz0-1-2*SQUISH_CONSTANT_4D;
  2389. dz_ext1=dz_ext2=dz0-1-SQUISH_CONSTANT_4D;
  2390. }
  2391. if((c&0x08) == 0) {
  2392. wsv_ext0=wsv_ext1=wsb;
  2393. wsv_ext2=wsb-1;
  2394. dw_ext0=dw0-2*SQUISH_CONSTANT_4D;
  2395. dw_ext1=dw0-SQUISH_CONSTANT_4D;
  2396. dw_ext2=dw0+1-SQUISH_CONSTANT_4D;
  2397. } else {
  2398. wsv_ext0=wsv_ext1=wsv_ext2=wsb+1;
  2399. dw_ext0=dw0-1-2*SQUISH_CONSTANT_4D;
  2400. dw_ext1=dw_ext2=dw0-1-SQUISH_CONSTANT_4D;
  2401. }
  2402. }
  2403. // Contribution (0,0,0,0)
  2404. attn0=2-dx0*dx0-dy0*dy0-dz0*dz0-dw0*dw0;
  2405. if(attn0>0) {
  2406. attn0*=attn0;
  2407. value+=attn0*attn0*extrapolate4(xsb+0, ysb+0, zsb+0, wsb+0, dx0, dy0, dz0, dw0);
  2408. }
  2409. // Contribution (1,0,0,0)
  2410. dx1=dx0-1-SQUISH_CONSTANT_4D;
  2411. dy1=dy0-0-SQUISH_CONSTANT_4D;
  2412. dz1=dz0-0-SQUISH_CONSTANT_4D;
  2413. dw1=dw0-0-SQUISH_CONSTANT_4D;
  2414. attn1=2-dx1*dx1-dy1*dy1-dz1*dz1-dw1*dw1;
  2415. if(attn1>0) {
  2416. attn1*=attn1;
  2417. value+=attn1*attn1*extrapolate4(xsb+1, ysb+0, zsb+0, wsb+0, dx1, dy1, dz1, dw1);
  2418. }
  2419. // Contribution (0,1,0,0)
  2420. dx2=dx0-0-SQUISH_CONSTANT_4D;
  2421. dy2=dy0-1-SQUISH_CONSTANT_4D;
  2422. dz2=dz1;
  2423. dw2=dw1;
  2424. attn2=2-dx2*dx2-dy2*dy2-dz2*dz2-dw2*dw2;
  2425. if(attn2>0) {
  2426. attn2*=attn2;
  2427. value+=attn2*attn2*extrapolate4(xsb+0, ysb+1, zsb+0, wsb+0, dx2, dy2, dz2, dw2);
  2428. }
  2429. // Contribution (0,0,1,0)
  2430. dx3=dx2;
  2431. dy3=dy1;
  2432. dz3=dz0-1-SQUISH_CONSTANT_4D;
  2433. dw3=dw1;
  2434. attn3=2-dx3*dx3-dy3*dy3-dz3*dz3-dw3*dw3;
  2435. if(attn3>0) {
  2436. attn3*=attn3;
  2437. value+=attn3*attn3*extrapolate4(xsb+0, ysb+0, zsb+1, wsb+0, dx3, dy3, dz3, dw3);
  2438. }
  2439. // Contribution (0,0,0,1)
  2440. dx4=dx2;
  2441. dy4=dy1;
  2442. dz4=dz1;
  2443. dw4=dw0-1-SQUISH_CONSTANT_4D;
  2444. attn4=2-dx4*dx4-dy4*dy4-dz4*dz4-dw4*dw4;
  2445. if(attn4>0) {
  2446. attn4*=attn4;
  2447. value+=attn4*attn4*extrapolate4(xsb+0, ysb+0, zsb+0, wsb+1, dx4, dy4, dz4, dw4);
  2448. }
  2449. } else if(inSum>=3) { // We're inside the pentachoron (4-Simplex) at (1,1,1,1) Determine which two of (1,1,1,0), (1,1,0,1), (1,0,1,1), (0,1,1,1) are closest.
  2450. aPoint=0x0E;
  2451. aScore=xins;
  2452. bPoint=0x0D;
  2453. bScore=yins;
  2454. if(aScore<=bScore && zins<bScore) {
  2455. bScore=zins;
  2456. bPoint=0x0B;
  2457. } else if(aScore>bScore && zins<aScore) {
  2458. aScore=zins;
  2459. aPoint=0x0B;
  2460. }
  2461. if(aScore<=bScore && wins<bScore) {
  2462. bScore=wins;
  2463. bPoint=0x07;
  2464. } else if(aScore>bScore && wins<aScore) {
  2465. aScore=wins;
  2466. aPoint=0x07;
  2467. }
  2468. // Now we determine the three lattice points not part of the pentachoron that may contribute. This depends on the closest two pentachoron vertices, including (0,0,0,0)
  2469. uins=4-inSum;
  2470. if(uins<aScore || uins<bScore) { // (1,1,1,1) is one of the closest two pentachoron vertices.
  2471. c=(bScore<aScore ? bPoint : aPoint); // Our other closest vertex is the closest out of a and b.
  2472. if((c&0x01) != 0) {
  2473. xsv_ext0=xsb+2;
  2474. xsv_ext1=xsv_ext2=xsb+1;
  2475. dx_ext0=dx0-2-4*SQUISH_CONSTANT_4D;
  2476. dx_ext1=dx_ext2=dx0-1-4*SQUISH_CONSTANT_4D;
  2477. } else {
  2478. xsv_ext0=xsv_ext1=xsv_ext2=xsb;
  2479. dx_ext0=dx_ext1=dx_ext2=dx0-4*SQUISH_CONSTANT_4D;
  2480. }
  2481. if((c&0x02) != 0) {
  2482. ysv_ext0=ysv_ext1=ysv_ext2=ysb+1;
  2483. dy_ext0=dy_ext1=dy_ext2=dy0-1-4*SQUISH_CONSTANT_4D;
  2484. if((c&0x01) != 0) {
  2485. ysv_ext1+=1;
  2486. dy_ext1-=1;
  2487. } else {
  2488. ysv_ext0+=1;
  2489. dy_ext0-=1;
  2490. }
  2491. } else {
  2492. ysv_ext0=ysv_ext1=ysv_ext2=ysb;
  2493. dy_ext0=dy_ext1=dy_ext2=dy0-4*SQUISH_CONSTANT_4D;
  2494. }
  2495. if((c&0x04) != 0) {
  2496. zsv_ext0=zsv_ext1=zsv_ext2=zsb+1;
  2497. dz_ext0=dz_ext1=dz_ext2=dz0-1-4*SQUISH_CONSTANT_4D;
  2498. if((c&0x03) != 0x03) {
  2499. if((c&0x03) == 0) {
  2500. zsv_ext0+=1;
  2501. dz_ext0-=1;
  2502. } else {
  2503. zsv_ext1+=1;
  2504. dz_ext1-=1;
  2505. }
  2506. } else {
  2507. zsv_ext2+=1;
  2508. dz_ext2-=1;
  2509. }
  2510. } else {
  2511. zsv_ext0=zsv_ext1=zsv_ext2=zsb;
  2512. dz_ext0=dz_ext1=dz_ext2=dz0-4*SQUISH_CONSTANT_4D;
  2513. }
  2514. if((c&0x08) != 0) {
  2515. wsv_ext0=wsv_ext1=wsb+1;
  2516. wsv_ext2=wsb+2;
  2517. dw_ext0=dw_ext1=dw0-1-4*SQUISH_CONSTANT_4D;
  2518. dw_ext2=dw0-2-4*SQUISH_CONSTANT_4D;
  2519. } else {
  2520. wsv_ext0=wsv_ext1=wsv_ext2=wsb;
  2521. dw_ext0=dw_ext1=dw_ext2=dw0-4*SQUISH_CONSTANT_4D;
  2522. }
  2523. } else { // (1,1,1,1) is not one of the closest two pentachoron vertices.
  2524. c=(I8)(aPoint&bPoint); // Our three extra vertices are determined by the closest two.
  2525. if((c&0x01) != 0) {
  2526. xsv_ext0=xsv_ext2=xsb+1;
  2527. xsv_ext1=xsb+2;
  2528. dx_ext0=dx0-1-2*SQUISH_CONSTANT_4D;
  2529. dx_ext1=dx0-2-3*SQUISH_CONSTANT_4D;
  2530. dx_ext2=dx0-1-3*SQUISH_CONSTANT_4D;
  2531. } else {
  2532. xsv_ext0=xsv_ext1=xsv_ext2=xsb;
  2533. dx_ext0=dx0-2*SQUISH_CONSTANT_4D;
  2534. dx_ext1=dx_ext2=dx0-3*SQUISH_CONSTANT_4D;
  2535. }
  2536. if((c&0x02) != 0) {
  2537. ysv_ext0=ysv_ext1=ysv_ext2=ysb+1;
  2538. dy_ext0=dy0-1-2*SQUISH_CONSTANT_4D;
  2539. dy_ext1=dy_ext2=dy0-1-3*SQUISH_CONSTANT_4D;
  2540. if((c&0x01) != 0) {
  2541. ysv_ext2+=1;
  2542. dy_ext2-=1;
  2543. } else {
  2544. ysv_ext1+=1;
  2545. dy_ext1-=1;
  2546. }
  2547. } else {
  2548. ysv_ext0=ysv_ext1=ysv_ext2=ysb;
  2549. dy_ext0=dy0-2*SQUISH_CONSTANT_4D;
  2550. dy_ext1=dy_ext2=dy0-3*SQUISH_CONSTANT_4D;
  2551. }
  2552. if((c&0x04) != 0) {
  2553. zsv_ext0=zsv_ext1=zsv_ext2=zsb+1;
  2554. dz_ext0=dz0-1-2*SQUISH_CONSTANT_4D;
  2555. dz_ext1=dz_ext2=dz0-1-3*SQUISH_CONSTANT_4D;
  2556. if((c&0x03) != 0) {
  2557. zsv_ext2+=1;
  2558. dz_ext2-=1;
  2559. } else {
  2560. zsv_ext1+=1;
  2561. dz_ext1-=1;
  2562. }
  2563. } else {
  2564. zsv_ext0=zsv_ext1=zsv_ext2=zsb;
  2565. dz_ext0=dz0-2*SQUISH_CONSTANT_4D;
  2566. dz_ext1=dz_ext2=dz0-3*SQUISH_CONSTANT_4D;
  2567. }
  2568. if((c&0x08) != 0) {
  2569. wsv_ext0=wsv_ext1=wsb+1;
  2570. wsv_ext2=wsb+2;
  2571. dw_ext0=dw0-1-2*SQUISH_CONSTANT_4D;
  2572. dw_ext1=dw0-1-3*SQUISH_CONSTANT_4D;
  2573. dw_ext2=dw0-2-3*SQUISH_CONSTANT_4D;
  2574. } else {
  2575. wsv_ext0=wsv_ext1=wsv_ext2=wsb;
  2576. dw_ext0=dw0-2*SQUISH_CONSTANT_4D;
  2577. dw_ext1=dw_ext2=dw0-3*SQUISH_CONSTANT_4D;
  2578. }
  2579. }
  2580. // Contribution (1,1,1,0)
  2581. dx4=dx0-1-3*SQUISH_CONSTANT_4D;
  2582. dy4=dy0-1-3*SQUISH_CONSTANT_4D;
  2583. dz4=dz0-1-3*SQUISH_CONSTANT_4D;
  2584. dw4=dw0-3*SQUISH_CONSTANT_4D;
  2585. attn4=2-dx4*dx4-dy4*dy4-dz4*dz4-dw4*dw4;
  2586. if(attn4>0) {
  2587. attn4*=attn4;
  2588. value+=attn4*attn4*extrapolate4(xsb+1, ysb+1, zsb+1, wsb+0, dx4, dy4, dz4, dw4);
  2589. }
  2590. // Contribution (1,1,0,1)
  2591. dx3=dx4;
  2592. dy3=dy4;
  2593. dz3=dz0-3*SQUISH_CONSTANT_4D;
  2594. dw3=dw0-1-3*SQUISH_CONSTANT_4D;
  2595. attn3=2-dx3*dx3-dy3*dy3-dz3*dz3-dw3*dw3;
  2596. if(attn3>0) {
  2597. attn3*=attn3;
  2598. value+=attn3*attn3*extrapolate4(xsb+1, ysb+1, zsb+0, wsb+1, dx3, dy3, dz3, dw3);
  2599. }
  2600. // Contribution (1,0,1,1)
  2601. dx2=dx4;
  2602. dy2=dy0-3*SQUISH_CONSTANT_4D;
  2603. dz2=dz4;
  2604. dw2=dw3;
  2605. attn2=2-dx2*dx2-dy2*dy2-dz2*dz2-dw2*dw2;
  2606. if(attn2>0) {
  2607. attn2*=attn2;
  2608. value+=attn2*attn2*extrapolate4(xsb+1, ysb+0, zsb+1, wsb+1, dx2, dy2, dz2, dw2);
  2609. }
  2610. // Contribution (0,1,1,1)
  2611. dx1=dx0-3*SQUISH_CONSTANT_4D;
  2612. dz1=dz4;
  2613. dy1=dy4;
  2614. dw1=dw3;
  2615. attn1=2-dx1*dx1-dy1*dy1-dz1*dz1-dw1*dw1;
  2616. if(attn1>0) {
  2617. attn1*=attn1;
  2618. value+=attn1*attn1*extrapolate4(xsb+0, ysb+1, zsb+1, wsb+1, dx1, dy1, dz1, dw1);
  2619. }
  2620. // Contribution (1,1,1,1)
  2621. dx0=dx0-1-4*SQUISH_CONSTANT_4D;
  2622. dy0=dy0-1-4*SQUISH_CONSTANT_4D;
  2623. dz0=dz0-1-4*SQUISH_CONSTANT_4D;
  2624. dw0=dw0-1-4*SQUISH_CONSTANT_4D;
  2625. attn0=2-dx0*dx0-dy0*dy0-dz0*dz0-dw0*dw0;
  2626. if(attn0>0) {
  2627. attn0*=attn0;
  2628. value+=attn0*attn0*extrapolate4(xsb+1, ysb+1, zsb+1, wsb+1, dx0, dy0, dz0, dw0);
  2629. }
  2630. } else if(inSum<=2) { // We're inside the first dispentachoron (Rectified 4-Simplex)
  2631. aIsBiggerSide=1;
  2632. bIsBiggerSide=1;
  2633. // Decide between (1,1,0,0) and (0,0,1,1)
  2634. if(xins+yins>zins+wins) {
  2635. aScore=xins+yins;
  2636. aPoint=0x03;
  2637. } else {
  2638. aScore=zins+wins;
  2639. aPoint=0x0C;
  2640. }
  2641. // Decide between (1,0,1,0) and (0,1,0,1)
  2642. if(xins+zins>yins+wins) {
  2643. bScore=xins+zins;
  2644. bPoint=0x05;
  2645. } else {
  2646. bScore=yins+wins;
  2647. bPoint=0x0A;
  2648. }
  2649. // Closer between (1,0,0,1) and (0,1,1,0) will replace the further of a and b, if closer.
  2650. if(xins+wins>yins+zins) {
  2651. score=xins+wins;
  2652. if(aScore>=bScore && score>bScore) {
  2653. bScore=score;
  2654. bPoint=0x09;
  2655. } else if(aScore<bScore && score>aScore) {
  2656. aScore=score;
  2657. aPoint=0x09;
  2658. }
  2659. } else {
  2660. score=yins+zins;
  2661. if(aScore>=bScore && score>bScore) {
  2662. bScore=score;
  2663. bPoint=0x06;
  2664. } else if(aScore<bScore && score>aScore) {
  2665. aScore=score;
  2666. aPoint=0x06;
  2667. }
  2668. }
  2669. // Decide if(1,0,0,0) is closer.
  2670. p1=2-inSum+xins;
  2671. if(aScore>=bScore && p1>bScore) {
  2672. bScore=p1;
  2673. bPoint=0x01;
  2674. bIsBiggerSide=0;
  2675. } else if(aScore<bScore && p1>aScore) {
  2676. aScore=p1;
  2677. aPoint=0x01;
  2678. aIsBiggerSide=0;
  2679. }
  2680. // Decide if(0,1,0,0) is closer.
  2681. p2=2-inSum+yins;
  2682. if(aScore>=bScore && p2>bScore) {
  2683. bScore=p2;
  2684. bPoint=0x02;
  2685. bIsBiggerSide=0;
  2686. } else if(aScore<bScore && p2>aScore) {
  2687. aScore=p2;
  2688. aPoint=0x02;
  2689. aIsBiggerSide=0;
  2690. }
  2691. // Decide if(0,0,1,0) is closer.
  2692. p3=2-inSum+zins;
  2693. if(aScore>=bScore && p3>bScore) {
  2694. bScore=p3;
  2695. bPoint=0x04;
  2696. bIsBiggerSide=0;
  2697. } else if(aScore<bScore && p3>aScore) {
  2698. aScore=p3;
  2699. aPoint=0x04;
  2700. aIsBiggerSide=0;
  2701. }
  2702. // Decide if(0,0,0,1) is closer.
  2703. p4=2-inSum+wins;
  2704. if(aScore>=bScore && p4>bScore) {
  2705. bScore=p4;
  2706. bPoint=0x08;
  2707. bIsBiggerSide=0;
  2708. } else if(aScore<bScore && p4>aScore) {
  2709. aScore=p4;
  2710. aPoint=0x08;
  2711. aIsBiggerSide=0;
  2712. }
  2713. // Where each of the two closest points are determines how the extra three vertices are calculated.
  2714. if(aIsBiggerSide == bIsBiggerSide) {
  2715. if(aIsBiggerSide) { // Both closest points on the bigger side
  2716. c1=(I8)(aPoint | bPoint);
  2717. c2=(I8)(aPoint&bPoint);
  2718. if((c1&0x01) == 0) {
  2719. xsv_ext0=xsb;
  2720. xsv_ext1=xsb-1;
  2721. dx_ext0=dx0-3*SQUISH_CONSTANT_4D;
  2722. dx_ext1=dx0+1-2*SQUISH_CONSTANT_4D;
  2723. } else {
  2724. xsv_ext0=xsv_ext1=xsb+1;
  2725. dx_ext0=dx0-1-3*SQUISH_CONSTANT_4D;
  2726. dx_ext1=dx0-1-2*SQUISH_CONSTANT_4D;
  2727. }
  2728. if((c1&0x02) == 0) {
  2729. ysv_ext0=ysb;
  2730. ysv_ext1=ysb-1;
  2731. dy_ext0=dy0-3*SQUISH_CONSTANT_4D;
  2732. dy_ext1=dy0+1-2*SQUISH_CONSTANT_4D;
  2733. } else {
  2734. ysv_ext0=ysv_ext1=ysb+1;
  2735. dy_ext0=dy0-1-3*SQUISH_CONSTANT_4D;
  2736. dy_ext1=dy0-1-2*SQUISH_CONSTANT_4D;
  2737. }
  2738. if((c1&0x04) == 0) {
  2739. zsv_ext0=zsb;
  2740. zsv_ext1=zsb-1;
  2741. dz_ext0=dz0-3*SQUISH_CONSTANT_4D;
  2742. dz_ext1=dz0+1-2*SQUISH_CONSTANT_4D;
  2743. } else {
  2744. zsv_ext0=zsv_ext1=zsb+1;
  2745. dz_ext0=dz0-1-3*SQUISH_CONSTANT_4D;
  2746. dz_ext1=dz0-1-2*SQUISH_CONSTANT_4D;
  2747. }
  2748. if((c1&0x08) == 0) {
  2749. wsv_ext0=wsb;
  2750. wsv_ext1=wsb-1;
  2751. dw_ext0=dw0-3*SQUISH_CONSTANT_4D;
  2752. dw_ext1=dw0+1-2*SQUISH_CONSTANT_4D;
  2753. } else {
  2754. wsv_ext0=wsv_ext1=wsb+1;
  2755. dw_ext0=dw0-1-3*SQUISH_CONSTANT_4D;
  2756. dw_ext1=dw0-1-2*SQUISH_CONSTANT_4D;
  2757. }
  2758. // One combination is a permutation of (0,0,0,2) based on c2
  2759. xsv_ext2=xsb;
  2760. ysv_ext2=ysb;
  2761. zsv_ext2=zsb;
  2762. wsv_ext2=wsb;
  2763. dx_ext2=dx0-2*SQUISH_CONSTANT_4D;
  2764. dy_ext2=dy0-2*SQUISH_CONSTANT_4D;
  2765. dz_ext2=dz0-2*SQUISH_CONSTANT_4D;
  2766. dw_ext2=dw0-2*SQUISH_CONSTANT_4D;
  2767. if((c2&0x01) != 0) {
  2768. xsv_ext2+=2;
  2769. dx_ext2-=2;
  2770. } else if((c2&0x02) != 0) {
  2771. ysv_ext2+=2;
  2772. dy_ext2-=2;
  2773. } else if((c2&0x04) != 0) {
  2774. zsv_ext2+=2;
  2775. dz_ext2-=2;
  2776. } else {
  2777. wsv_ext2+=2;
  2778. dw_ext2-=2;
  2779. }
  2780. } else { // Both closest points on the smaller side
  2781. // One of the two extra points is (0,0,0,0)
  2782. xsv_ext2=xsb;
  2783. ysv_ext2=ysb;
  2784. zsv_ext2=zsb;
  2785. wsv_ext2=wsb;
  2786. dx_ext2=dx0;
  2787. dy_ext2=dy0;
  2788. dz_ext2=dz0;
  2789. dw_ext2=dw0;
  2790. // Other two points are based on the omitted axes.
  2791. c=(I8)(aPoint | bPoint);
  2792. if((c&0x01) == 0) {
  2793. xsv_ext0=xsb-1;
  2794. xsv_ext1=xsb;
  2795. dx_ext0=dx0+1-SQUISH_CONSTANT_4D;
  2796. dx_ext1=dx0-SQUISH_CONSTANT_4D;
  2797. } else {
  2798. xsv_ext0=xsv_ext1=xsb+1;
  2799. dx_ext0=dx_ext1=dx0-1-SQUISH_CONSTANT_4D;
  2800. }
  2801. if((c&0x02) == 0) {
  2802. ysv_ext0=ysv_ext1=ysb;
  2803. dy_ext0=dy_ext1=dy0-SQUISH_CONSTANT_4D;
  2804. if((c&0x01) == 0x01)
  2805. {
  2806. ysv_ext0-=1;
  2807. dy_ext0+=1;
  2808. } else {
  2809. ysv_ext1-=1;
  2810. dy_ext1+=1;
  2811. }
  2812. } else {
  2813. ysv_ext0=ysv_ext1=ysb+1;
  2814. dy_ext0=dy_ext1=dy0-1-SQUISH_CONSTANT_4D;
  2815. }
  2816. if((c&0x04) == 0) {
  2817. zsv_ext0=zsv_ext1=zsb;
  2818. dz_ext0=dz_ext1=dz0-SQUISH_CONSTANT_4D;
  2819. if((c&0x03) == 0x03)
  2820. {
  2821. zsv_ext0-=1;
  2822. dz_ext0+=1;
  2823. } else {
  2824. zsv_ext1-=1;
  2825. dz_ext1+=1;
  2826. }
  2827. } else {
  2828. zsv_ext0=zsv_ext1=zsb+1;
  2829. dz_ext0=dz_ext1=dz0-1-SQUISH_CONSTANT_4D;
  2830. }
  2831. if((c&0x08) == 0)
  2832. {
  2833. wsv_ext0=wsb;
  2834. wsv_ext1=wsb-1;
  2835. dw_ext0=dw0-SQUISH_CONSTANT_4D;
  2836. dw_ext1=dw0+1-SQUISH_CONSTANT_4D;
  2837. } else {
  2838. wsv_ext0=wsv_ext1=wsb+1;
  2839. dw_ext0=dw_ext1=dw0-1-SQUISH_CONSTANT_4D;
  2840. }
  2841. }
  2842. } else { // One point on each "side"
  2843. if(aIsBiggerSide) {
  2844. c1=aPoint;
  2845. c2=bPoint;
  2846. } else {
  2847. c1=bPoint;
  2848. c2=aPoint;
  2849. }
  2850. // Two contributions are the bigger-sided point with each 0 replaced with -1.
  2851. if((c1&0x01) == 0) {
  2852. xsv_ext0=xsb-1;
  2853. xsv_ext1=xsb;
  2854. dx_ext0=dx0+1-SQUISH_CONSTANT_4D;
  2855. dx_ext1=dx0-SQUISH_CONSTANT_4D;
  2856. } else {
  2857. xsv_ext0=xsv_ext1=xsb+1;
  2858. dx_ext0=dx_ext1=dx0-1-SQUISH_CONSTANT_4D;
  2859. }
  2860. if((c1&0x02) == 0) {
  2861. ysv_ext0=ysv_ext1=ysb;
  2862. dy_ext0=dy_ext1=dy0-SQUISH_CONSTANT_4D;
  2863. if((c1&0x01) == 0x01) {
  2864. ysv_ext0-=1;
  2865. dy_ext0+=1;
  2866. } else {
  2867. ysv_ext1-=1;
  2868. dy_ext1+=1;
  2869. }
  2870. } else {
  2871. ysv_ext0=ysv_ext1=ysb+1;
  2872. dy_ext0=dy_ext1=dy0-1-SQUISH_CONSTANT_4D;
  2873. }
  2874. if((c1&0x04) == 0) {
  2875. zsv_ext0=zsv_ext1=zsb;
  2876. dz_ext0=dz_ext1=dz0-SQUISH_CONSTANT_4D;
  2877. if((c1&0x03) == 0x03) {
  2878. zsv_ext0-=1;
  2879. dz_ext0+=1;
  2880. } else {
  2881. zsv_ext1-=1;
  2882. dz_ext1+=1;
  2883. }
  2884. } else {
  2885. zsv_ext0=zsv_ext1=zsb+1;
  2886. dz_ext0=dz_ext1=dz0-1-SQUISH_CONSTANT_4D;
  2887. }
  2888. if((c1&0x08) == 0) {
  2889. wsv_ext0=wsb;
  2890. wsv_ext1=wsb-1;
  2891. dw_ext0=dw0-SQUISH_CONSTANT_4D;
  2892. dw_ext1=dw0+1-SQUISH_CONSTANT_4D;
  2893. } else {
  2894. wsv_ext0=wsv_ext1=wsb+1;
  2895. dw_ext0=dw_ext1=dw0-1-SQUISH_CONSTANT_4D;
  2896. }
  2897. // One contribution is a permutation of (0,0,0,2) based on the smaller-sided point
  2898. xsv_ext2=xsb;
  2899. ysv_ext2=ysb;
  2900. zsv_ext2=zsb;
  2901. wsv_ext2=wsb;
  2902. dx_ext2=dx0-2*SQUISH_CONSTANT_4D;
  2903. dy_ext2=dy0-2*SQUISH_CONSTANT_4D;
  2904. dz_ext2=dz0-2*SQUISH_CONSTANT_4D;
  2905. dw_ext2=dw0-2*SQUISH_CONSTANT_4D;
  2906. if((c2&0x01) != 0) {
  2907. xsv_ext2+=2;
  2908. dx_ext2-=2;
  2909. } else if((c2&0x02) != 0) {
  2910. ysv_ext2+=2;
  2911. dy_ext2-=2;
  2912. } else if((c2&0x04) != 0) {
  2913. zsv_ext2+=2;
  2914. dz_ext2-=2;
  2915. } else {
  2916. wsv_ext2+=2;
  2917. dw_ext2-=2;
  2918. }
  2919. }
  2920. // Contribution (1,0,0,0)
  2921. dx1=dx0-1-SQUISH_CONSTANT_4D;
  2922. dy1=dy0-0-SQUISH_CONSTANT_4D;
  2923. dz1=dz0-0-SQUISH_CONSTANT_4D;
  2924. dw1=dw0-0-SQUISH_CONSTANT_4D;
  2925. attn1=2-dx1*dx1-dy1*dy1-dz1*dz1-dw1*dw1;
  2926. if(attn1>0) {
  2927. attn1*=attn1;
  2928. value+=attn1*attn1*extrapolate4(xsb+1, ysb+0, zsb+0, wsb+0, dx1, dy1, dz1, dw1);
  2929. }
  2930. // Contribution (0,1,0,0)
  2931. dx2=dx0-0-SQUISH_CONSTANT_4D;
  2932. dy2=dy0-1-SQUISH_CONSTANT_4D;
  2933. dz2=dz1;
  2934. dw2=dw1;
  2935. attn2=2-dx2*dx2-dy2*dy2-dz2*dz2-dw2*dw2;
  2936. if(attn2>0) {
  2937. attn2*=attn2;
  2938. value+=attn2*attn2*extrapolate4(xsb+0, ysb+1, zsb+0, wsb+0, dx2, dy2, dz2, dw2);
  2939. }
  2940. // Contribution (0,0,1,0)
  2941. dx3=dx2;
  2942. dy3=dy1;
  2943. dz3=dz0-1-SQUISH_CONSTANT_4D;
  2944. dw3=dw1;
  2945. attn3=2-dx3*dx3-dy3*dy3-dz3*dz3-dw3*dw3;
  2946. if(attn3>0) {
  2947. attn3*=attn3;
  2948. value+=attn3*attn3*extrapolate4(xsb+0, ysb+0, zsb+1, wsb+0, dx3, dy3, dz3, dw3);
  2949. }
  2950. // Contribution (0,0,0,1)
  2951. dx4=dx2;
  2952. dy4=dy1;
  2953. dz4=dz1;
  2954. dw4=dw0-1-SQUISH_CONSTANT_4D;
  2955. attn4=2-dx4*dx4-dy4*dy4-dz4*dz4-dw4*dw4;
  2956. if(attn4>0) {
  2957. attn4*=attn4;
  2958. value+=attn4*attn4*extrapolate4(xsb+0, ysb+0, zsb+0, wsb+1, dx4, dy4, dz4, dw4);
  2959. }
  2960. // Contribution (1,1,0,0)
  2961. dx5=dx0-1-2*SQUISH_CONSTANT_4D;
  2962. dy5=dy0-1-2*SQUISH_CONSTANT_4D;
  2963. dz5=dz0-0-2*SQUISH_CONSTANT_4D;
  2964. dw5=dw0-0-2*SQUISH_CONSTANT_4D;
  2965. attn5=2-dx5*dx5-dy5*dy5-dz5*dz5-dw5*dw5;
  2966. if(attn5>0) {
  2967. attn5*=attn5;
  2968. value+=attn5*attn5*extrapolate4(xsb+1, ysb+1, zsb+0, wsb+0, dx5, dy5, dz5, dw5);
  2969. }
  2970. // Contribution (1,0,1,0)
  2971. dx6=dx0-1-2*SQUISH_CONSTANT_4D;
  2972. dy6=dy0-0-2*SQUISH_CONSTANT_4D;
  2973. dz6=dz0-1-2*SQUISH_CONSTANT_4D;
  2974. dw6=dw0-0-2*SQUISH_CONSTANT_4D;
  2975. attn6=2-dx6*dx6-dy6*dy6-dz6*dz6-dw6*dw6;
  2976. if(attn6>0) {
  2977. attn6*=attn6;
  2978. value+=attn6*attn6*extrapolate4(xsb+1, ysb+0, zsb+1, wsb+0, dx6, dy6, dz6, dw6);
  2979. }
  2980. // Contribution (1,0,0,1)
  2981. dx7=dx0-1-2*SQUISH_CONSTANT_4D;
  2982. dy7=dy0-0-2*SQUISH_CONSTANT_4D;
  2983. dz7=dz0-0-2*SQUISH_CONSTANT_4D;
  2984. dw7=dw0-1-2*SQUISH_CONSTANT_4D;
  2985. attn7=2-dx7*dx7-dy7*dy7-dz7*dz7-dw7*dw7;
  2986. if(attn7>0) {
  2987. attn7*=attn7;
  2988. value+=attn7*attn7*extrapolate4(xsb+1, ysb+0, zsb+0, wsb+1, dx7, dy7, dz7, dw7);
  2989. }
  2990. // Contribution (0,1,1,0)
  2991. dx8=dx0-0-2*SQUISH_CONSTANT_4D;
  2992. dy8=dy0-1-2*SQUISH_CONSTANT_4D;
  2993. dz8=dz0-1-2*SQUISH_CONSTANT_4D;
  2994. dw8=dw0-0-2*SQUISH_CONSTANT_4D;
  2995. attn8=2-dx8*dx8-dy8*dy8-dz8*dz8-dw8*dw8;
  2996. if(attn8>0) {
  2997. attn8*=attn8;
  2998. value+=attn8*attn8*extrapolate4(xsb+0, ysb+1, zsb+1, wsb+0, dx8, dy8, dz8, dw8);
  2999. }
  3000. // Contribution (0,1,0,1)
  3001. dx9=dx0-0-2*SQUISH_CONSTANT_4D;
  3002. dy9=dy0-1-2*SQUISH_CONSTANT_4D;
  3003. dz9=dz0-0-2*SQUISH_CONSTANT_4D;
  3004. dw9=dw0-1-2*SQUISH_CONSTANT_4D;
  3005. attn9=2-dx9*dx9-dy9*dy9-dz9*dz9-dw9*dw9;
  3006. if(attn9>0) {
  3007. attn9*=attn9;
  3008. value+=attn9*attn9*extrapolate4(xsb+0, ysb+1, zsb+0, wsb+1, dx9, dy9, dz9, dw9);
  3009. }
  3010. // Contribution (0,0,1,1)
  3011. dx10=dx0-0-2*SQUISH_CONSTANT_4D;
  3012. dy10=dy0-0-2*SQUISH_CONSTANT_4D;
  3013. dz10=dz0-1-2*SQUISH_CONSTANT_4D;
  3014. dw10=dw0-1-2*SQUISH_CONSTANT_4D;
  3015. attn10=2-dx10*dx10-dy10*dy10-dz10*dz10-dw10*dw10;
  3016. if(attn10>0) {
  3017. attn10*=attn10;
  3018. value+=attn10*attn10*extrapolate4(xsb+0, ysb+0, zsb+1, wsb+1, dx10, dy10, dz10, dw10);
  3019. }
  3020. } else { // We're inside the second dispentachoron (Rectified 4-Simplex)
  3021. aIsBiggerSide=1;
  3022. bIsBiggerSide=1;
  3023. // Decide between (0,0,1,1) and (1,1,0,0)
  3024. if(xins+yins<zins+wins) {
  3025. aScore=xins+yins;
  3026. aPoint=0x0C;
  3027. } else {
  3028. aScore=zins+wins;
  3029. aPoint=0x03;
  3030. }
  3031. // Decide between (0,1,0,1) and (1,0,1,0)
  3032. if(xins+zins<yins+wins) {
  3033. bScore=xins+zins;
  3034. bPoint=0x0A;
  3035. } else {
  3036. bScore=yins+wins;
  3037. bPoint=0x05;
  3038. }
  3039. // Closer between (0,1,1,0) and (1,0,0,1) will replace the further of a and b, if closer.
  3040. if(xins+wins<yins+zins) {
  3041. score=xins+wins;
  3042. if(aScore<=bScore && score<bScore) {
  3043. bScore=score;
  3044. bPoint=0x06;
  3045. } else if(aScore>bScore && score<aScore) {
  3046. aScore=score;
  3047. aPoint=0x06;
  3048. }
  3049. } else {
  3050. score=yins+zins;
  3051. if(aScore<=bScore && score<bScore) {
  3052. bScore=score;
  3053. bPoint=0x09;
  3054. } else if(aScore>bScore && score<aScore) {
  3055. aScore=score;
  3056. aPoint=0x09;
  3057. }
  3058. }
  3059. // Decide if(0,1,1,1) is closer.
  3060. p1=3-inSum+xins;
  3061. if(aScore<=bScore && p1<bScore) {
  3062. bScore=p1;
  3063. bPoint=0x0E;
  3064. bIsBiggerSide=0;
  3065. } else if(aScore>bScore && p1<aScore) {
  3066. aScore=p1;
  3067. aPoint=0x0E;
  3068. aIsBiggerSide=0;
  3069. }
  3070. // Decide if(1,0,1,1) is closer.
  3071. p2=3-inSum+yins;
  3072. if(aScore<=bScore && p2<bScore) {
  3073. bScore=p2;
  3074. bPoint=0x0D;
  3075. bIsBiggerSide=0;
  3076. } else if(aScore>bScore && p2<aScore) {
  3077. aScore=p2;
  3078. aPoint=0x0D;
  3079. aIsBiggerSide=0;
  3080. }
  3081. // Decide if(1,1,0,1) is closer.
  3082. p3=3-inSum+zins;
  3083. if(aScore<=bScore && p3<bScore) {
  3084. bScore=p3;
  3085. bPoint=0x0B;
  3086. bIsBiggerSide=0;
  3087. } else if(aScore>bScore && p3<aScore) {
  3088. aScore=p3;
  3089. aPoint=0x0B;
  3090. aIsBiggerSide=0;
  3091. }
  3092. // Decide if(1,1,1,0) is closer.
  3093. p4=3-inSum+wins;
  3094. if(aScore<=bScore && p4<bScore) {
  3095. bScore=p4;
  3096. bPoint=0x07;
  3097. bIsBiggerSide=0;
  3098. } else if(aScore>bScore && p4<aScore) {
  3099. aScore=p4;
  3100. aPoint=0x07;
  3101. aIsBiggerSide=0;
  3102. }
  3103. // Where each of the two closest points are determines how the extra three vertices are calculated.
  3104. if(aIsBiggerSide == bIsBiggerSide) {
  3105. if(aIsBiggerSide) { // Both closest points on the bigger side
  3106. c1=(I8)(aPoint&bPoint);
  3107. c2=(I8)(aPoint | bPoint);
  3108. // Two contributions are permutations of (0,0,0,1) and (0,0,0,2) based on c1
  3109. xsv_ext0=xsv_ext1=xsb;
  3110. ysv_ext0=ysv_ext1=ysb;
  3111. zsv_ext0=zsv_ext1=zsb;
  3112. wsv_ext0=wsv_ext1=wsb;
  3113. dx_ext0=dx0-SQUISH_CONSTANT_4D;
  3114. dy_ext0=dy0-SQUISH_CONSTANT_4D;
  3115. dz_ext0=dz0-SQUISH_CONSTANT_4D;
  3116. dw_ext0=dw0-SQUISH_CONSTANT_4D;
  3117. dx_ext1=dx0-2*SQUISH_CONSTANT_4D;
  3118. dy_ext1=dy0-2*SQUISH_CONSTANT_4D;
  3119. dz_ext1=dz0-2*SQUISH_CONSTANT_4D;
  3120. dw_ext1=dw0-2*SQUISH_CONSTANT_4D;
  3121. if((c1&0x01) != 0) {
  3122. xsv_ext0+=1;
  3123. dx_ext0-=1;
  3124. xsv_ext1+=2;
  3125. dx_ext1-=2;
  3126. } else if((c1&0x02) != 0) {
  3127. ysv_ext0+=1;
  3128. dy_ext0-=1;
  3129. ysv_ext1+=2;
  3130. dy_ext1-=2;
  3131. } else if((c1&0x04) != 0) {
  3132. zsv_ext0+=1;
  3133. dz_ext0-=1;
  3134. zsv_ext1+=2;
  3135. dz_ext1-=2;
  3136. } else {
  3137. wsv_ext0+=1;
  3138. dw_ext0-=1;
  3139. wsv_ext1+=2;
  3140. dw_ext1-=2;
  3141. }
  3142. // One contribution is a permutation of (1,1,1,-1) based on c2
  3143. xsv_ext2=xsb+1;
  3144. ysv_ext2=ysb+1;
  3145. zsv_ext2=zsb+1;
  3146. wsv_ext2=wsb+1;
  3147. dx_ext2=dx0-1-2*SQUISH_CONSTANT_4D;
  3148. dy_ext2=dy0-1-2*SQUISH_CONSTANT_4D;
  3149. dz_ext2=dz0-1-2*SQUISH_CONSTANT_4D;
  3150. dw_ext2=dw0-1-2*SQUISH_CONSTANT_4D;
  3151. if((c2&0x01) == 0) {
  3152. xsv_ext2-=2;
  3153. dx_ext2+=2;
  3154. } else if((c2&0x02) == 0) {
  3155. ysv_ext2-=2;
  3156. dy_ext2+=2;
  3157. } else if((c2&0x04) == 0) {
  3158. zsv_ext2-=2;
  3159. dz_ext2+=2;
  3160. } else {
  3161. wsv_ext2-=2;
  3162. dw_ext2+=2;
  3163. }
  3164. } else { // Both closest points on the smaller side
  3165. // One of the two extra points is (1,1,1,1)
  3166. xsv_ext2=xsb+1;
  3167. ysv_ext2=ysb+1;
  3168. zsv_ext2=zsb+1;
  3169. wsv_ext2=wsb+1;
  3170. dx_ext2=dx0-1-4*SQUISH_CONSTANT_4D;
  3171. dy_ext2=dy0-1-4*SQUISH_CONSTANT_4D;
  3172. dz_ext2=dz0-1-4*SQUISH_CONSTANT_4D;
  3173. dw_ext2=dw0-1-4*SQUISH_CONSTANT_4D;
  3174. // Other two points are based on the shared axes.
  3175. c=(I8)(aPoint&bPoint);
  3176. if((c&0x01) != 0) {
  3177. xsv_ext0=xsb+2;
  3178. xsv_ext1=xsb+1;
  3179. dx_ext0=dx0-2-3*SQUISH_CONSTANT_4D;
  3180. dx_ext1=dx0-1-3*SQUISH_CONSTANT_4D;
  3181. } else {
  3182. xsv_ext0=xsv_ext1=xsb;
  3183. dx_ext0=dx_ext1=dx0-3*SQUISH_CONSTANT_4D;
  3184. }
  3185. if((c&0x02) != 0) {
  3186. ysv_ext0=ysv_ext1=ysb+1;
  3187. dy_ext0=dy_ext1=dy0-1-3*SQUISH_CONSTANT_4D;
  3188. if((c&0x01) == 0)
  3189. {
  3190. ysv_ext0+=1;
  3191. dy_ext0-=1;
  3192. } else {
  3193. ysv_ext1+=1;
  3194. dy_ext1-=1;
  3195. }
  3196. } else {
  3197. ysv_ext0=ysv_ext1=ysb;
  3198. dy_ext0=dy_ext1=dy0-3*SQUISH_CONSTANT_4D;
  3199. }
  3200. if((c&0x04) != 0) {
  3201. zsv_ext0=zsv_ext1=zsb+1;
  3202. dz_ext0=dz_ext1=dz0-1-3*SQUISH_CONSTANT_4D;
  3203. if((c&0x03) == 0)
  3204. {
  3205. zsv_ext0+=1;
  3206. dz_ext0-=1;
  3207. } else {
  3208. zsv_ext1+=1;
  3209. dz_ext1-=1;
  3210. }
  3211. } else {
  3212. zsv_ext0=zsv_ext1=zsb;
  3213. dz_ext0=dz_ext1=dz0-3*SQUISH_CONSTANT_4D;
  3214. }
  3215. if((c&0x08) != 0)
  3216. {
  3217. wsv_ext0=wsb+1;
  3218. wsv_ext1=wsb+2;
  3219. dw_ext0=dw0-1-3*SQUISH_CONSTANT_4D;
  3220. dw_ext1=dw0-2-3*SQUISH_CONSTANT_4D;
  3221. } else {
  3222. wsv_ext0=wsv_ext1=wsb;
  3223. dw_ext0=dw_ext1=dw0-3*SQUISH_CONSTANT_4D;
  3224. }
  3225. }
  3226. } else { // One point on each "side"
  3227. if(aIsBiggerSide) {
  3228. c1=aPoint;
  3229. c2=bPoint;
  3230. } else {
  3231. c1=bPoint;
  3232. c2=aPoint;
  3233. }
  3234. // Two contributions are the bigger-sided point with each 1 replaced with 2.
  3235. if((c1&0x01) != 0) {
  3236. xsv_ext0=xsb+2;
  3237. xsv_ext1=xsb+1;
  3238. dx_ext0=dx0-2-3*SQUISH_CONSTANT_4D;
  3239. dx_ext1=dx0-1-3*SQUISH_CONSTANT_4D;
  3240. } else {
  3241. xsv_ext0=xsv_ext1=xsb;
  3242. dx_ext0=dx_ext1=dx0-3*SQUISH_CONSTANT_4D;
  3243. }
  3244. if((c1&0x02) != 0) {
  3245. ysv_ext0=ysv_ext1=ysb+1;
  3246. dy_ext0=dy_ext1=dy0-1-3*SQUISH_CONSTANT_4D;
  3247. if((c1&0x01) == 0) {
  3248. ysv_ext0+=1;
  3249. dy_ext0-=1;
  3250. } else {
  3251. ysv_ext1+=1;
  3252. dy_ext1-=1;
  3253. }
  3254. } else {
  3255. ysv_ext0=ysv_ext1=ysb;
  3256. dy_ext0=dy_ext1=dy0-3*SQUISH_CONSTANT_4D;
  3257. }
  3258. if((c1&0x04) != 0) {
  3259. zsv_ext0=zsv_ext1=zsb+1;
  3260. dz_ext0=dz_ext1=dz0-1-3*SQUISH_CONSTANT_4D;
  3261. if((c1&0x03) == 0) {
  3262. zsv_ext0+=1;
  3263. dz_ext0-=1;
  3264. } else {
  3265. zsv_ext1+=1;
  3266. dz_ext1-=1;
  3267. }
  3268. } else {
  3269. zsv_ext0=zsv_ext1=zsb;
  3270. dz_ext0=dz_ext1=dz0-3*SQUISH_CONSTANT_4D;
  3271. }
  3272. if((c1&0x08) != 0) {
  3273. wsv_ext0=wsb+1;
  3274. wsv_ext1=wsb+2;
  3275. dw_ext0=dw0-1-3*SQUISH_CONSTANT_4D;
  3276. dw_ext1=dw0-2-3*SQUISH_CONSTANT_4D;
  3277. } else {
  3278. wsv_ext0=wsv_ext1=wsb;
  3279. dw_ext0=dw_ext1=dw0-3*SQUISH_CONSTANT_4D;
  3280. }
  3281. // One contribution is a permutation of (1,1,1,-1) based on the smaller-sided point
  3282. xsv_ext2=xsb+1;
  3283. ysv_ext2=ysb+1;
  3284. zsv_ext2=zsb+1;
  3285. wsv_ext2=wsb+1;
  3286. dx_ext2=dx0-1-2*SQUISH_CONSTANT_4D;
  3287. dy_ext2=dy0-1-2*SQUISH_CONSTANT_4D;
  3288. dz_ext2=dz0-1-2*SQUISH_CONSTANT_4D;
  3289. dw_ext2=dw0-1-2*SQUISH_CONSTANT_4D;
  3290. if((c2&0x01) == 0) {
  3291. xsv_ext2-=2;
  3292. dx_ext2+=2;
  3293. } else if((c2&0x02) == 0) {
  3294. ysv_ext2-=2;
  3295. dy_ext2+=2;
  3296. } else if((c2&0x04) == 0) {
  3297. zsv_ext2-=2;
  3298. dz_ext2+=2;
  3299. } else {
  3300. wsv_ext2-=2;
  3301. dw_ext2+=2;
  3302. }
  3303. }
  3304. // Contribution (1,1,1,0)
  3305. dx4=dx0-1-3*SQUISH_CONSTANT_4D;
  3306. dy4=dy0-1-3*SQUISH_CONSTANT_4D;
  3307. dz4=dz0-1-3*SQUISH_CONSTANT_4D;
  3308. dw4=dw0-3*SQUISH_CONSTANT_4D;
  3309. attn4=2-dx4*dx4-dy4*dy4-dz4*dz4-dw4*dw4;
  3310. if(attn4>0) {
  3311. attn4*=attn4;
  3312. value+=attn4*attn4*extrapolate4(xsb+1, ysb+1, zsb+1, wsb+0, dx4, dy4, dz4, dw4);
  3313. }
  3314. // Contribution (1,1,0,1)
  3315. dx3=dx4;
  3316. dy3=dy4;
  3317. dz3=dz0-3*SQUISH_CONSTANT_4D;
  3318. dw3=dw0-1-3*SQUISH_CONSTANT_4D;
  3319. attn3=2-dx3*dx3-dy3*dy3-dz3*dz3-dw3*dw3;
  3320. if(attn3>0) {
  3321. attn3*=attn3;
  3322. value+=attn3*attn3*extrapolate4(xsb+1, ysb+1, zsb+0, wsb+1, dx3, dy3, dz3, dw3);
  3323. }
  3324. // Contribution (1,0,1,1)
  3325. dx2=dx4;
  3326. dy2=dy0-3*SQUISH_CONSTANT_4D;
  3327. dz2=dz4;
  3328. dw2=dw3;
  3329. attn2=2-dx2*dx2-dy2*dy2-dz2*dz2-dw2*dw2;
  3330. if(attn2>0) {
  3331. attn2*=attn2;
  3332. value+=attn2*attn2*extrapolate4(xsb+1, ysb+0, zsb+1, wsb+1, dx2, dy2, dz2, dw2);
  3333. }
  3334. // Contribution (0,1,1,1)
  3335. dx1=dx0-3*SQUISH_CONSTANT_4D;
  3336. dz1=dz4;
  3337. dy1=dy4;
  3338. dw1=dw3;
  3339. attn1=2-dx1*dx1-dy1*dy1-dz1*dz1-dw1*dw1;
  3340. if(attn1>0) {
  3341. attn1*=attn1;
  3342. value+=attn1*attn1*extrapolate4(xsb+0, ysb+1, zsb+1, wsb+1, dx1, dy1, dz1, dw1);
  3343. }
  3344. // Contribution (1,1,0,0)
  3345. dx5=dx0-1-2*SQUISH_CONSTANT_4D;
  3346. dy5=dy0-1-2*SQUISH_CONSTANT_4D;
  3347. dz5=dz0-0-2*SQUISH_CONSTANT_4D;
  3348. dw5=dw0-0-2*SQUISH_CONSTANT_4D;
  3349. attn5=2-dx5*dx5-dy5*dy5-dz5*dz5-dw5*dw5;
  3350. if(attn5>0) {
  3351. attn5*=attn5;
  3352. value+=attn5*attn5*extrapolate4(xsb+1, ysb+1, zsb+0, wsb+0, dx5, dy5, dz5, dw5);
  3353. }
  3354. // Contribution (1,0,1,0)
  3355. dx6=dx0-1-2*SQUISH_CONSTANT_4D;
  3356. dy6=dy0-0-2*SQUISH_CONSTANT_4D;
  3357. dz6=dz0-1-2*SQUISH_CONSTANT_4D;
  3358. dw6=dw0-0-2*SQUISH_CONSTANT_4D;
  3359. attn6=2-dx6*dx6-dy6*dy6-dz6*dz6-dw6*dw6;
  3360. if(attn6>0) {
  3361. attn6*=attn6;
  3362. value+=attn6*attn6*extrapolate4(xsb+1, ysb+0, zsb+1, wsb+0, dx6, dy6, dz6, dw6);
  3363. }
  3364. // Contribution (1,0,0,1)
  3365. dx7=dx0-1-2*SQUISH_CONSTANT_4D;
  3366. dy7=dy0-0-2*SQUISH_CONSTANT_4D;
  3367. dz7=dz0-0-2*SQUISH_CONSTANT_4D;
  3368. dw7=dw0-1-2*SQUISH_CONSTANT_4D;
  3369. attn7=2-dx7*dx7-dy7*dy7-dz7*dz7-dw7*dw7;
  3370. if(attn7>0) {
  3371. attn7*=attn7;
  3372. value+=attn7*attn7*extrapolate4(xsb+1, ysb+0, zsb+0, wsb+1, dx7, dy7, dz7, dw7);
  3373. }
  3374. // Contribution (0,1,1,0)
  3375. dx8=dx0-0-2*SQUISH_CONSTANT_4D;
  3376. dy8=dy0-1-2*SQUISH_CONSTANT_4D;
  3377. dz8=dz0-1-2*SQUISH_CONSTANT_4D;
  3378. dw8=dw0-0-2*SQUISH_CONSTANT_4D;
  3379. attn8=2-dx8*dx8-dy8*dy8-dz8*dz8-dw8*dw8;
  3380. if(attn8>0) {
  3381. attn8*=attn8;
  3382. value+=attn8*attn8*extrapolate4(xsb+0, ysb+1, zsb+1, wsb+0, dx8, dy8, dz8, dw8);
  3383. }
  3384. // Contribution (0,1,0,1)
  3385. dx9=dx0-0-2*SQUISH_CONSTANT_4D;
  3386. dy9=dy0-1-2*SQUISH_CONSTANT_4D;
  3387. dz9=dz0-0-2*SQUISH_CONSTANT_4D;
  3388. dw9=dw0-1-2*SQUISH_CONSTANT_4D;
  3389. attn9=2-dx9*dx9-dy9*dy9-dz9*dz9-dw9*dw9;
  3390. if(attn9>0) {
  3391. attn9*=attn9;
  3392. value+=attn9*attn9*extrapolate4(xsb+0, ysb+1, zsb+0, wsb+1, dx9, dy9, dz9, dw9);
  3393. }
  3394. // Contribution (0,0,1,1)
  3395. dx10=dx0-0-2*SQUISH_CONSTANT_4D;
  3396. dy10=dy0-0-2*SQUISH_CONSTANT_4D;
  3397. dz10=dz0-1-2*SQUISH_CONSTANT_4D;
  3398. dw10=dw0-1-2*SQUISH_CONSTANT_4D;
  3399. attn10=2-dx10*dx10-dy10*dy10-dz10*dz10-dw10*dw10;
  3400. if(attn10>0) {
  3401. attn10*=attn10;
  3402. value+=attn10*attn10*extrapolate4(xsb+0, ysb+0, zsb+1, wsb+1, dx10, dy10, dz10, dw10);
  3403. }
  3404. }
  3405. // First extra vertex
  3406. attn_ext0=2-dx_ext0*dx_ext0-dy_ext0*dy_ext0-dz_ext0*dz_ext0-dw_ext0*dw_ext0;
  3407. if(attn_ext0>0)
  3408. {
  3409. attn_ext0*=attn_ext0;
  3410. value+=attn_ext0*attn_ext0*extrapolate4(xsv_ext0, ysv_ext0, zsv_ext0, wsv_ext0, dx_ext0, dy_ext0, dz_ext0, dw_ext0);
  3411. }
  3412. // Second extra vertex
  3413. attn_ext1=2-dx_ext1*dx_ext1-dy_ext1*dy_ext1-dz_ext1*dz_ext1-dw_ext1*dw_ext1;
  3414. if(attn_ext1>0)
  3415. {
  3416. attn_ext1*=attn_ext1;
  3417. value+=attn_ext1*attn_ext1*extrapolate4(xsv_ext1, ysv_ext1, zsv_ext1, wsv_ext1, dx_ext1, dy_ext1, dz_ext1, dw_ext1);
  3418. }
  3419. // Third extra vertex
  3420. attn_ext2=2-dx_ext2*dx_ext2-dy_ext2*dy_ext2-dz_ext2*dz_ext2-dw_ext2*dw_ext2;
  3421. if(attn_ext2>0)
  3422. {
  3423. attn_ext2*=attn_ext2;
  3424. value+=attn_ext2*attn_ext2*extrapolate4(xsv_ext2, ysv_ext2, zsv_ext2, wsv_ext2, dx_ext2, dy_ext2, dz_ext2, dw_ext2);
  3425. }
  3426. return value/(SIMPLEX_NORM_CONSTANT_4D);
  3427. }
  3428. /******************************************************************************/
  3429. Flt SimplexNoise::tiledNoise(Dbl x, Int tile)C
  3430. {
  3431. #if SIMPLEX_WRAP_CIRCLE // CosSin
  3432. VecD2 X; Dbl mul=PID2/tile;
  3433. CosSin(X.x, X.y, x*mul);
  3434. mul=1/mul; // 'CosSin' generates a circle with radius=1, that Circle will have a perimeter "PI2*r" = "PI2", so the coordinates will travel 'PI2' distance, however we want them to travel 'tile' distance, so we need to multiply by "tile/PI2", since we already have 'mul' calculated as "PI2/tile", we can just inverse it
  3435. return noise(X.x*mul, X.y*mul);
  3436. #else // Lerp
  3437. x=Frac(x, tile);
  3438. Flt n=noise(x);
  3439. if(x>tile-1) // if X is at the border
  3440. {
  3441. Flt x1=x-tile;
  3442. n=Lerp(noise(x1), n, _SmoothCube(-x1)); // then lerp smoothly with the start
  3443. }
  3444. return n;
  3445. #endif
  3446. }
  3447. Flt SimplexNoise::tiledNoise(Dbl x, Dbl y, C VecI2 &tile)C
  3448. {
  3449. #if SIMPLEX_WRAP_CIRCLE // CosSin
  3450. VecD2 X, Y; VecD2 mul=PID2/tile;
  3451. CosSin(X.x, X.y, x*mul.x);
  3452. CosSin(Y.x, Y.y, y*mul.y);
  3453. mul=1/mul; // 'CosSin' generates a circle with radius=1, that Circle will have a perimeter "PI2*r" = "PI2", so the coordinates will travel 'PI2' distance, however we want them to travel 'tile' distance, so we need to multiply by "tile/PI2", since we already have 'mul' calculated as "PI2/tile", we can just inverse it
  3454. return noise(X.x*mul.x, X.y*mul.x, Y.x*mul.y, Y.y*mul.y);
  3455. #else // Lerp
  3456. x=Frac(x, tile.x);
  3457. y=Frac(y, tile.y);
  3458. Flt n=noise(x, y);
  3459. if(y>tile.y-1) // if Y is at the border
  3460. {
  3461. Flt y1=y-tile.y, sy=_SmoothCube(-y1), sy1=1-sy; // use smooth blending
  3462. n=n*sy + noise(x, y1)*sy1; // lerp with the start
  3463. if(x>tile.x-1) // if X is at the border
  3464. {
  3465. Flt x1=x-tile.x;
  3466. n=Lerp(noise(x1, y)*sy + noise(x1, y1)*sy1, n, _SmoothCube(-x1));
  3467. }
  3468. }else
  3469. if(x>tile.x-1) // if X is at the border
  3470. {
  3471. Flt x1=x-tile.x;
  3472. n=Lerp(noise(x1, y), n, _SmoothCube(-x1)); // then lerp smoothly with the start
  3473. }
  3474. return n;
  3475. #endif
  3476. }
  3477. Flt SimplexNoise::tiledNoise(Dbl x, Dbl y, Dbl z, C VecI &tile)C
  3478. {
  3479. #if SIMPLEX_WRAP_CIRCLE // CosSin
  3480. VecD2 X, Y, Z; VecD mul=PID2/tile;
  3481. CosSin(X.x, X.y, x*mul.x);
  3482. CosSin(Y.x, Y.y, y*mul.y);
  3483. CosSin(Z.x, Z.y, z*mul.z);
  3484. mul=1/mul; // 'CosSin' generates a circle with radius=1, that Circle will have a perimeter "PI2*r" = "PI2", so the coordinates will travel 'PI2' distance, however we want them to travel 'tile' distance, so we need to multiply by "tile/PI2", since we already have 'mul' calculated as "PI2/tile", we can just inverse it
  3485. return noise(X.x*mul.x + Z.x*mul.z, X.y*mul.x, // Warning: here we just offset 2 coordinates by the Z coordinate, this is not perfect
  3486. Y.x*mul.y + Z.y*mul.z, Y.y*mul.y);
  3487. #else // Lerp
  3488. x=Frac(x, tile.x);
  3489. y=Frac(y, tile.y);
  3490. z=Frac(z, tile.z);
  3491. Flt n=noise(x, y, z);
  3492. if(z>tile.z-1) // if Z is at the border
  3493. {
  3494. Flt z1=z-tile.z, sz=_SmoothCube(-z1), sz1=1-sz; // use smooth blending
  3495. n=n*sz + noise(x, y, z1)*sz1; // lerp with the start
  3496. if(y>tile.y-1) // if Y is at the border
  3497. {
  3498. Flt y1=y-tile.y, sy=_SmoothCube(-y1), sy1=1-sy; // use smooth blending
  3499. n=n*sy + (noise(x, y1, z)*sz + noise(x, y1, z1)*sz1)*sy1;
  3500. if(x>tile.x-1) // if X is at the border
  3501. {
  3502. Flt x1=x-tile.x;
  3503. n=Lerp((noise(x1, y , z)*sz + noise(x1, y , z1)*sz1)*sy
  3504. +(noise(x1, y1, z)*sz + noise(x1, y1, z1)*sz1)*sy1, n, _SmoothCube(-x1));
  3505. }
  3506. }else
  3507. if(x>tile.x-1) // if X is at the border
  3508. {
  3509. Flt x1=x-tile.x;
  3510. n=Lerp(noise(x1, y, z)*sz + noise(x1, y, z1)*sz1, n, _SmoothCube(-x1));
  3511. }
  3512. }else
  3513. if(y>tile.y-1) // if Y is at the border
  3514. {
  3515. Flt y1=y-tile.y, sy=_SmoothCube(-y1), sy1=1-sy; // use smooth blending
  3516. n=n*sy + noise(x, y1, z)*sy1; // lerp with the start
  3517. if(x>tile.x-1) // if X is at the border
  3518. {
  3519. Flt x1=x-tile.x;
  3520. n=Lerp(noise(x1, y, z)*sy + noise(x1, y1, z)*sy1, n, _SmoothCube(-x1));
  3521. }
  3522. }else
  3523. if(x>tile.x-1) // if X is at the border
  3524. {
  3525. Flt x1=x-tile.x;
  3526. n=Lerp(noise(x1, y, z), n, _SmoothCube(-x1)); // then lerp smoothly with the start
  3527. }
  3528. return n;
  3529. #endif
  3530. }
  3531. Flt SimplexNoise::tiledNoise(Dbl x, Dbl y, Dbl z, Dbl w, C VecI4 &tile)C
  3532. {
  3533. #if SIMPLEX_WRAP_CIRCLE // CosSin
  3534. VecD2 X, Y, Z, W; VecD4 mul=PID2/tile;
  3535. CosSin(X.x, X.y, x*mul.x);
  3536. CosSin(Y.x, Y.y, y*mul.y);
  3537. CosSin(Z.x, Z.y, z*mul.z);
  3538. CosSin(W.x, W.y, w*mul.w);
  3539. mul=1/mul; // 'CosSin' generates a circle with radius=1, that Circle will have a perimeter "PI2*r" = "PI2", so the coordinates will travel 'PI2' distance, however we want them to travel 'tile' distance, so we need to multiply by "tile/PI2", since we already have 'mul' calculated as "PI2/tile", we can just inverse it
  3540. return noise(X.x*mul.x + Z.x*mul.z, X.y*mul.x + W.x*mul.w, // Warning: here we just offset coordinates by the ZW coordinates, this is not perfect
  3541. Y.x*mul.y + Z.y*mul.z, Y.y*mul.y + W.y*mul.w);
  3542. #else // Lerp
  3543. x=Frac(x, tile.x);
  3544. y=Frac(y, tile.y);
  3545. z=Frac(z, tile.z);
  3546. w=Frac(w, tile.w);
  3547. Flt n=noise(x, y, z, w);
  3548. if(w>tile.w-1) // if W is at the border
  3549. {
  3550. Flt w1=w-tile.w, sw=_SmoothCube(-w1), sw1=1-sw; // use smooth blending
  3551. n=n*sw + noise(x, y, z, w1)*sw1; // lerp with the start
  3552. if(z>tile.z-1) // if Z is at the border
  3553. {
  3554. Flt z1=z-tile.z, sz=_SmoothCube(-z1), sz1=1-sz; // use smooth blending
  3555. n=n*sz + (noise(x, y, z1, w)*sw + noise(x, y, z1, w1)*sw1)*sz1; // lerp with the start
  3556. if(y>tile.y-1) // if Y is at the border
  3557. {
  3558. Flt y1=y-tile.y, sy=_SmoothCube(-y1), sy1=1-sy; // use smooth blending
  3559. n=n*sy + ((noise(x, y1, z, w )*sz + noise(x, y1, z1, w )*sz1)*sw
  3560. +(noise(x, y1, z, w1)*sz + noise(x, y1, z1, w1)*sz1)*sw1)*sy1;
  3561. if(x>tile.x-1) // if X is at the border
  3562. {
  3563. Flt x1=x-tile.x;
  3564. n=Lerp(((noise(x1, y , z, w )*sz + noise(x1, y , z1, w )*sz1)*sy
  3565. +(noise(x1, y1, z, w )*sz + noise(x1, y1, z1, w )*sz1)*sy1)*sw
  3566. +((noise(x1, y , z, w1)*sz + noise(x1, y , z1, w1)*sz1)*sy
  3567. +(noise(x1, y1, z, w1)*sz + noise(x1, y1, z1, w1)*sz1)*sy1)*sw1, n, _SmoothCube(-x1));
  3568. }
  3569. }else
  3570. if(x>tile.x-1) // if X is at the border
  3571. {
  3572. Flt x1=x-tile.x;
  3573. n=Lerp((noise(x1, y, z, w )*sz + noise(x1, y, z1, w )*sz1)*sw
  3574. +(noise(x1, y, z, w1)*sz + noise(x1, y, z1, w1)*sz1)*sw1, n, _SmoothCube(-x1));
  3575. }
  3576. }else
  3577. if(y>tile.y-1) // if Y is at the border
  3578. {
  3579. Flt y1=y-tile.y, sy=_SmoothCube(-y1), sy1=1-sy; // use smooth blending
  3580. n=n*sy + (noise(x, y1, z, w)*sw + noise(x, y1, z, w1)*sw1)*sy1; // lerp with the start
  3581. if(x>tile.x-1) // if X is at the border
  3582. {
  3583. Flt x1=x-tile.x;
  3584. n=Lerp((noise(x1, y, z, w )*sy + noise(x1, y1, z, w )*sy1)*sw
  3585. +(noise(x1, y, z, w1)*sy + noise(x1, y1, z, w1)*sy1)*sw1, n, _SmoothCube(-x1));
  3586. }
  3587. }else
  3588. if(x>tile.x-1) // if X is at the border
  3589. {
  3590. Flt x1=x-tile.x;
  3591. n=Lerp(noise(x1, y, z, w)*sw + noise(x1, y, z, w1)*sw1, n, _SmoothCube(-x1)); // then lerp smoothly with the start
  3592. }
  3593. }else
  3594. if(z>tile.z-1) // if Z is at the border
  3595. {
  3596. Flt z1=z-tile.z, sz=_SmoothCube(-z1), sz1=1-sz; // use smooth blending
  3597. n=n*sz + noise(x, y, z1, w)*sz1; // lerp with the start
  3598. if(y>tile.y-1) // if Y is at the border
  3599. {
  3600. Flt y1=y-tile.y, sy=_SmoothCube(-y1), sy1=1-sy; // use smooth blending
  3601. n=n*sy + (noise(x, y1, z, w)*sz + noise(x, y1, z1, w)*sz1)*sy1;
  3602. if(x>tile.x-1) // if X is at the border
  3603. {
  3604. Flt x1=x-tile.x;
  3605. n=Lerp((noise(x1, y , z, w)*sz + noise(x1, y , z1, w)*sz1)*sy
  3606. +(noise(x1, y1, z, w)*sz + noise(x1, y1, z1, w)*sz1)*sy1, n, _SmoothCube(-x1));
  3607. }
  3608. }else
  3609. if(x>tile.x-1) // if X is at the border
  3610. {
  3611. Flt x1=x-tile.x;
  3612. n=Lerp(noise(x1, y, z, w)*sz + noise(x1, y, z1, w)*sz1, n, _SmoothCube(-x1));
  3613. }
  3614. }else
  3615. if(y>tile.y-1) // if Y is at the border
  3616. {
  3617. Flt y1=y-tile.y, sy=_SmoothCube(-y1), sy1=1-sy; // use smooth blending
  3618. n=n*sy + noise(x, y1, z, w)*sy1; // lerp with the start
  3619. if(x>tile.x-1) // if X is at the border
  3620. {
  3621. Flt x1=x-tile.x;
  3622. n=Lerp(noise(x1, y, z, w)*sy + noise(x1, y1, z, w)*sy1, n, _SmoothCube(-x1));
  3623. }
  3624. }else
  3625. if(x>tile.x-1) // if X is at the border
  3626. {
  3627. Flt x1=x-tile.x;
  3628. n=Lerp(noise(x1, y, z, w), n, _SmoothCube(-x1)); // then lerp smoothly with the start
  3629. }
  3630. return n;
  3631. #endif
  3632. }
  3633. /******************************************************************************/
  3634. // MULTI
  3635. /******************************************************************************/
  3636. Flt SimplexNoise::noise1(Dbl x, Int octaves, Flt gain, Flt Transform(Flt noise))C
  3637. {
  3638. Flt result=0, amp=1; REP(octaves)
  3639. {
  3640. Flt n=noise(x); if(Transform)n=Transform(n);
  3641. result+=n*amp;
  3642. x *=2;
  3643. amp *=gain;
  3644. }
  3645. return result;
  3646. }
  3647. Flt SimplexNoise::noise2(Dbl x, Dbl y, Int octaves, Flt gain, Flt Transform(Flt noise))C
  3648. {
  3649. Flt result=0, amp=1; REP(octaves)
  3650. {
  3651. Flt n=noise(x, y); if(Transform)n=Transform(n);
  3652. result+=n*amp;
  3653. x *=2;
  3654. y *=2;
  3655. amp *=gain;
  3656. }
  3657. return result;
  3658. }
  3659. Flt SimplexNoise::noise3(Dbl x, Dbl y, Dbl z, Int octaves, Flt gain, Flt Transform(Flt noise))C
  3660. {
  3661. Flt result=0, amp=1; REP(octaves)
  3662. {
  3663. Flt n=noise(x, y, z); if(Transform)n=Transform(n);
  3664. result+=n*amp;
  3665. x *=2;
  3666. y *=2;
  3667. z *=2;
  3668. amp *=gain;
  3669. }
  3670. return result;
  3671. }
  3672. Flt SimplexNoise::noise4(Dbl x, Dbl y, Dbl z, Dbl w, Int octaves, Flt gain, Flt Transform(Flt noise))C
  3673. {
  3674. Flt result=0, amp=1; REP(octaves)
  3675. {
  3676. Flt n=noise(x, y, z, w); if(Transform)n=Transform(n);
  3677. result+=n*amp;
  3678. x *=2;
  3679. y *=2;
  3680. z *=2;
  3681. w *=2;
  3682. amp *=gain;
  3683. }
  3684. return result;
  3685. }
  3686. /******************************************************************************/
  3687. Flt SimplexNoise::tiledNoise1(Dbl x, Int tile, Int octaves, Flt gain, Flt Transform(Flt noise))C
  3688. {
  3689. Flt result=0, amp=1; REP(octaves)
  3690. {
  3691. Flt n=tiledNoise(x, tile); if(Transform)n=Transform(n);
  3692. result+=n*amp;
  3693. x *=2;
  3694. tile *=2;
  3695. amp *=gain;
  3696. }
  3697. return result;
  3698. }
  3699. Flt SimplexNoise::tiledNoise2(Dbl x, Dbl y, VecI2 tile, Int octaves, Flt gain, Flt Transform(Flt noise))C
  3700. {
  3701. Flt result=0, amp=1; REP(octaves)
  3702. {
  3703. Flt n=tiledNoise(x, y, tile); if(Transform)n=Transform(n);
  3704. result+=n*amp;
  3705. x *=2;
  3706. y *=2;
  3707. tile *=2;
  3708. amp *=gain;
  3709. }
  3710. return result;
  3711. }
  3712. Flt SimplexNoise::tiledNoise3(Dbl x, Dbl y, Dbl z, VecI tile, Int octaves, Flt gain, Flt Transform(Flt noise))C
  3713. {
  3714. Flt result=0, amp=1; REP(octaves)
  3715. {
  3716. Flt n=tiledNoise(x, y, z, tile); if(Transform)n=Transform(n);
  3717. result+=n*amp;
  3718. x *=2;
  3719. y *=2;
  3720. z *=2;
  3721. tile *=2;
  3722. amp *=gain;
  3723. }
  3724. return result;
  3725. }
  3726. Flt SimplexNoise::tiledNoise4(Dbl x, Dbl y, Dbl z, Dbl w, VecI4 tile, Int octaves, Flt gain, Flt Transform(Flt noise))C
  3727. {
  3728. Flt result=0, amp=1; REP(octaves)
  3729. {
  3730. Flt n=tiledNoise(x, y, z, w, tile); if(Transform)n=Transform(n);
  3731. result+=n*amp;
  3732. x *=2;
  3733. y *=2;
  3734. z *=2;
  3735. w *=2;
  3736. tile *=2;
  3737. amp *=gain;
  3738. }
  3739. return result;
  3740. }
  3741. /******************************************************************************/
  3742. // BLOOM
  3743. /******************************************************************************/
  3744. Flt SimplexNoise::noise1Bloom(Dbl x, Int octaves, Flt bloom, Flt sharpness)C
  3745. {
  3746. Flt result=noise(x), weight=result*bloom+sharpness, amp=1;
  3747. for(Int i=1; i<octaves; i++)
  3748. {
  3749. Flt n=noise(x*=2);
  3750. amp *=BloomGain;
  3751. weight*=amp;
  3752. MAX(weight, 0);
  3753. result+=weight*n;
  3754. weight*=n*bloom+sharpness;
  3755. }
  3756. return result;
  3757. }
  3758. Flt SimplexNoise::noise2Bloom(Dbl x, Dbl y, Int octaves, Flt bloom, Flt sharpness)C
  3759. {
  3760. Flt result=noise(x, y), weight=result*bloom+sharpness, amp=1;
  3761. for(Int i=1; i<octaves; i++)
  3762. {
  3763. Flt n=noise(x*=2, y*=2);
  3764. amp *=BloomGain;
  3765. weight*=amp;
  3766. MAX(weight, 0);
  3767. result+=weight*n;
  3768. weight*=n*bloom+sharpness;
  3769. }
  3770. return result;
  3771. }
  3772. Flt SimplexNoise::noise3Bloom(Dbl x, Dbl y, Dbl z, Int octaves, Flt bloom, Flt sharpness)C
  3773. {
  3774. Flt result=noise(x, y, z), weight=result*bloom+sharpness, amp=1;
  3775. for(Int i=1; i<octaves; i++)
  3776. {
  3777. Flt n=noise(x*=2, y*=2, z*=2);
  3778. amp *=BloomGain;
  3779. weight*=amp;
  3780. MAX(weight, 0);
  3781. result+=weight*n;
  3782. weight*=n*bloom+sharpness;
  3783. }
  3784. return result;
  3785. }
  3786. Flt SimplexNoise::noise4Bloom(Dbl x, Dbl y, Dbl z, Dbl w, Int octaves, Flt bloom, Flt sharpness)C
  3787. {
  3788. Flt result=noise(x, y, z, w), weight=result*bloom+sharpness, amp=1;
  3789. for(Int i=1; i<octaves; i++)
  3790. {
  3791. Flt n=noise(x*=2, y*=2, z*=2, w*=2);
  3792. amp *=BloomGain;
  3793. weight*=amp;
  3794. MAX(weight, 0);
  3795. result+=weight*n;
  3796. weight*=n*bloom+sharpness;
  3797. }
  3798. return result;
  3799. }
  3800. /******************************************************************************/
  3801. Flt SimplexNoise::tiledNoise1Bloom(Dbl x, Int tile, Int octaves, Flt bloom, Flt sharpness)C
  3802. {
  3803. Flt result=tiledNoise(x, tile), weight=result*bloom+sharpness, amp=1;
  3804. for(Int i=1; i<octaves; i++)
  3805. {
  3806. Flt n=tiledNoise(x*=2, tile*=2);
  3807. amp *=BloomGain;
  3808. weight*=amp;
  3809. MAX(weight, 0);
  3810. result+=weight*n;
  3811. weight*=n*bloom+sharpness;
  3812. }
  3813. return result;
  3814. }
  3815. Flt SimplexNoise::tiledNoise2Bloom(Dbl x, Dbl y, VecI2 tile, Int octaves, Flt bloom, Flt sharpness)C
  3816. {
  3817. Flt result=tiledNoise(x, y, tile), weight=result*bloom+sharpness, amp=1;
  3818. for(Int i=1; i<octaves; i++)
  3819. {
  3820. Flt n=tiledNoise(x*=2, y*=2, tile*=2);
  3821. amp *=BloomGain;
  3822. weight*=amp;
  3823. MAX(weight, 0);
  3824. result+=weight*n;
  3825. weight*=n*bloom+sharpness;
  3826. }
  3827. return result;
  3828. }
  3829. Flt SimplexNoise::tiledNoise3Bloom(Dbl x, Dbl y, Dbl z, VecI tile, Int octaves, Flt bloom, Flt sharpness)C
  3830. {
  3831. Flt result=tiledNoise(x, y, z, tile), weight=result*bloom+sharpness, amp=1;
  3832. for(Int i=1; i<octaves; i++)
  3833. {
  3834. Flt n=tiledNoise(x*=2, y*=2, z*=2, tile*=2);
  3835. amp *=BloomGain;
  3836. weight*=amp;
  3837. MAX(weight, 0);
  3838. result+=weight*n;
  3839. weight*=n*bloom+sharpness;
  3840. }
  3841. return result;
  3842. }
  3843. Flt SimplexNoise::tiledNoise4Bloom(Dbl x, Dbl y, Dbl z, Dbl w, VecI4 tile, Int octaves, Flt bloom, Flt sharpness)C
  3844. {
  3845. Flt result=tiledNoise(x, y, z, w, tile), weight=result*bloom+sharpness, amp=1;
  3846. for(Int i=1; i<octaves; i++)
  3847. {
  3848. Flt n=tiledNoise(x*=2, y*=2, z*=2, w*=2, tile*=2);
  3849. amp *=BloomGain;
  3850. weight*=amp;
  3851. MAX(weight, 0);
  3852. result+=weight*n;
  3853. weight*=n*bloom+sharpness;
  3854. }
  3855. return result;
  3856. }
  3857. /******************************************************************************/
  3858. // MASK
  3859. /******************************************************************************/
  3860. Flt PerlinNoise::mask2(Dbl x, Dbl y, Int octaves, Flt sharpness)C
  3861. {
  3862. Flt mask=1; REP(octaves)
  3863. {
  3864. Flt m=noise(x, y);
  3865. mask*=SmoothCube(m*sharpness+0.5f);
  3866. x*=2;
  3867. y*=2;
  3868. }
  3869. return mask;
  3870. }
  3871. /******************************************************************************/
  3872. Flt SimplexNoise::mask2(Dbl x, Dbl y, Int octaves, Flt sharpness)C
  3873. {
  3874. Flt mask=1; REP(octaves)
  3875. {
  3876. Flt m=noise(x, y);
  3877. mask*=SmoothCube(m*sharpness+0.5f);
  3878. x*=2;
  3879. y*=2;
  3880. }
  3881. return mask;
  3882. }
  3883. /******************************************************************************/
  3884. }
  3885. /******************************************************************************/