opensimplex.py 78 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934
  1. """
  2. This is a copy of the OpenSimplex library,
  3. based on commit d861cb290531ad15825f21dc4cc35c5d4f407259 from 20.07.2017.
  4. """
  5. # Based on: https://gist.github.com/KdotJPG/b1270127455a94ac5d19
  6. import sys
  7. from ctypes import c_long
  8. from math import floor as _floor
  9. if sys.version_info[0] < 3:
  10. def floor(num):
  11. return int(_floor(num))
  12. else:
  13. floor = _floor
  14. STRETCH_CONSTANT_2D = -0.211324865405187 # (1/Math.sqrt(2+1)-1)/2
  15. SQUISH_CONSTANT_2D = 0.366025403784439 # (Math.sqrt(2+1)-1)/2
  16. STRETCH_CONSTANT_3D = -1.0 / 6 # (1/Math.sqrt(3+1)-1)/3
  17. SQUISH_CONSTANT_3D = 1.0 / 3 # (Math.sqrt(3+1)-1)/3
  18. STRETCH_CONSTANT_4D = -0.138196601125011 # (1/Math.sqrt(4+1)-1)/4
  19. SQUISH_CONSTANT_4D = 0.309016994374947 # (Math.sqrt(4+1)-1)/4
  20. NORM_CONSTANT_2D = 47
  21. NORM_CONSTANT_3D = 103
  22. NORM_CONSTANT_4D = 30
  23. DEFAULT_SEED = 0
  24. # Gradients for 2D. They approximate the directions to the
  25. # vertices of an octagon from the center.
  26. GRADIENTS_2D = (
  27. 5, 2, 2, 5,
  28. -5, 2, -2, 5,
  29. 5, -2, 2, -5,
  30. -5, -2, -2, -5,
  31. )
  32. # Gradients for 3D. They approximate the directions to the
  33. # vertices of a rhombicuboctahedron from the center, skewed so
  34. # that the triangular and square facets can be inscribed inside
  35. # circles of the same radius.
  36. GRADIENTS_3D = (
  37. -11, 4, 4, -4, 11, 4, -4, 4, 11,
  38. 11, 4, 4, 4, 11, 4, 4, 4, 11,
  39. -11, -4, 4, -4, -11, 4, -4, -4, 11,
  40. 11, -4, 4, 4, -11, 4, 4, -4, 11,
  41. -11, 4, -4, -4, 11, -4, -4, 4, -11,
  42. 11, 4, -4, 4, 11, -4, 4, 4, -11,
  43. -11, -4, -4, -4, -11, -4, -4, -4, -11,
  44. 11, -4, -4, 4, -11, -4, 4, -4, -11,
  45. )
  46. # Gradients for 4D. They approximate the directions to the
  47. # vertices of a disprismatotesseractihexadecachoron from the center,
  48. # skewed so that the tetrahedral and cubic facets can be inscribed inside
  49. # spheres of the same radius.
  50. GRADIENTS_4D = (
  51. 3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3,
  52. -3, 1, 1, 1, -1, 3, 1, 1, -1, 1, 3, 1, -1, 1, 1, 3,
  53. 3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3, 1, 1, -1, 1, 3,
  54. -3, -1, 1, 1, -1, -3, 1, 1, -1, -1, 3, 1, -1, -1, 1, 3,
  55. 3, 1, -1, 1, 1, 3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3,
  56. -3, 1, -1, 1, -1, 3, -1, 1, -1, 1, -3, 1, -1, 1, -1, 3,
  57. 3, -1, -1, 1, 1, -3, -1, 1, 1, -1, -3, 1, 1, -1, -1, 3,
  58. -3, -1, -1, 1, -1, -3, -1, 1, -1, -1, -3, 1, -1, -1, -1, 3,
  59. 3, 1, 1, -1, 1, 3, 1, -1, 1, 1, 3, -1, 1, 1, 1, -3,
  60. -3, 1, 1, -1, -1, 3, 1, -1, -1, 1, 3, -1, -1, 1, 1, -3,
  61. 3, -1, 1, -1, 1, -3, 1, -1, 1, -1, 3, -1, 1, -1, 1, -3,
  62. -3, -1, 1, -1, -1, -3, 1, -1, -1, -1, 3, -1, -1, -1, 1, -3,
  63. 3, 1, -1, -1, 1, 3, -1, -1, 1, 1, -3, -1, 1, 1, -1, -3,
  64. -3, 1, -1, -1, -1, 3, -1, -1, -1, 1, -3, -1, -1, 1, -1, -3,
  65. 3, -1, -1, -1, 1, -3, -1, -1, 1, -1, -3, -1, 1, -1, -1, -3,
  66. -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3,
  67. )
  68. def overflow(x):
  69. # Since normal python ints and longs can be quite humongous we have to use
  70. # this hack to make them be able to overflow
  71. return c_long(x).value
  72. class OpenSimplex(object):
  73. """
  74. OpenSimplex n-dimensional gradient noise functions.
  75. """
  76. def __init__(self, seed=DEFAULT_SEED):
  77. """
  78. Initiate the class and generate permutation arrays from a seed number.
  79. """
  80. # Initializes the class using a permutation array generated from a 64-bit seed.
  81. # Generates a proper permutation (i.e. doesn't merely perform N
  82. # successive pair swaps on a base array)
  83. perm = self._perm = [0] * 256 # Have to zero fill so we can properly loop over it later
  84. perm_grad_index_3D = self._perm_grad_index_3D = [0] * 256
  85. source = [i for i in range(0, 256)]
  86. seed = overflow(seed * 6364136223846793005 + 1442695040888963407)
  87. seed = overflow(seed * 6364136223846793005 + 1442695040888963407)
  88. seed = overflow(seed * 6364136223846793005 + 1442695040888963407)
  89. for i in range(255, -1, -1):
  90. seed = overflow(seed * 6364136223846793005 + 1442695040888963407)
  91. r = int((seed + 31) % (i + 1))
  92. if r < 0:
  93. r += i + 1
  94. perm[i] = source[r]
  95. perm_grad_index_3D[i] = int((perm[i] % (len(GRADIENTS_3D) / 3)) * 3)
  96. source[r] = source[i]
  97. def _extrapolate2d(self, xsb, ysb, dx, dy):
  98. perm = self._perm
  99. index = perm[(perm[xsb & 0xFF] + ysb) & 0xFF] & 0x0E
  100. g1, g2 = GRADIENTS_2D[index:index + 2]
  101. return g1 * dx + g2 * dy
  102. def _extrapolate3d(self, xsb, ysb, zsb, dx, dy, dz):
  103. perm = self._perm
  104. index = self._perm_grad_index_3D[
  105. (perm[(perm[xsb & 0xFF] + ysb) & 0xFF] + zsb) & 0xFF
  106. ]
  107. g1, g2, g3 = GRADIENTS_3D[index:index + 3]
  108. return g1 * dx + g2 * dy + g3 * dz
  109. def _extrapolate4d(self, xsb, ysb, zsb, wsb, dx, dy, dz, dw):
  110. perm = self._perm
  111. index = perm[(
  112. perm[(
  113. perm[(perm[xsb & 0xFF] + ysb) & 0xFF] + zsb
  114. ) & 0xFF] + wsb
  115. ) & 0xFF] & 0xFC
  116. g1, g2, g3, g4 = GRADIENTS_4D[index:index + 4]
  117. return g1 * dx + g2 * dy + g3 * dz + g4 * dw
  118. def noise2d(self, x, y):
  119. """
  120. Generate 2D OpenSimplex noise from X,Y coordinates.
  121. """
  122. # Place input coordinates onto grid.
  123. stretch_offset = (x + y) * STRETCH_CONSTANT_2D
  124. xs = x + stretch_offset
  125. ys = y + stretch_offset
  126. # Floor to get grid coordinates of rhombus (stretched square) super-cell origin.
  127. xsb = floor(xs)
  128. ysb = floor(ys)
  129. # Skew out to get actual coordinates of rhombus origin. We'll need these later.
  130. squish_offset = (xsb + ysb) * SQUISH_CONSTANT_2D
  131. xb = xsb + squish_offset
  132. yb = ysb + squish_offset
  133. # Compute grid coordinates relative to rhombus origin.
  134. xins = xs - xsb
  135. yins = ys - ysb
  136. # Sum those together to get a value that determines which region we're in.
  137. in_sum = xins + yins
  138. # Positions relative to origin point.
  139. dx0 = x - xb
  140. dy0 = y - yb
  141. value = 0
  142. # Contribution (1,0)
  143. dx1 = dx0 - 1 - SQUISH_CONSTANT_2D
  144. dy1 = dy0 - 0 - SQUISH_CONSTANT_2D
  145. attn1 = 2 - dx1 * dx1 - dy1 * dy1
  146. extrapolate = self._extrapolate2d
  147. if attn1 > 0:
  148. attn1 *= attn1
  149. value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, dx1, dy1)
  150. # Contribution (0,1)
  151. dx2 = dx0 - 0 - SQUISH_CONSTANT_2D
  152. dy2 = dy0 - 1 - SQUISH_CONSTANT_2D
  153. attn2 = 2 - dx2 * dx2 - dy2 * dy2
  154. if attn2 > 0:
  155. attn2 *= attn2
  156. value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, dx2, dy2)
  157. if in_sum <= 1: # We're inside the triangle (2-Simplex) at (0,0)
  158. zins = 1 - in_sum
  159. if zins > xins or zins > yins: # (0,0) is one of the closest two triangular vertices
  160. if xins > yins:
  161. xsv_ext = xsb + 1
  162. ysv_ext = ysb - 1
  163. dx_ext = dx0 - 1
  164. dy_ext = dy0 + 1
  165. else:
  166. xsv_ext = xsb - 1
  167. ysv_ext = ysb + 1
  168. dx_ext = dx0 + 1
  169. dy_ext = dy0 - 1
  170. else: # (1,0) and (0,1) are the closest two vertices.
  171. xsv_ext = xsb + 1
  172. ysv_ext = ysb + 1
  173. dx_ext = dx0 - 1 - 2 * SQUISH_CONSTANT_2D
  174. dy_ext = dy0 - 1 - 2 * SQUISH_CONSTANT_2D
  175. else: # We're inside the triangle (2-Simplex) at (1,1)
  176. zins = 2 - in_sum
  177. if zins < xins or zins < yins: # (0,0) is one of the closest two triangular vertices
  178. if xins > yins:
  179. xsv_ext = xsb + 2
  180. ysv_ext = ysb + 0
  181. dx_ext = dx0 - 2 - 2 * SQUISH_CONSTANT_2D
  182. dy_ext = dy0 + 0 - 2 * SQUISH_CONSTANT_2D
  183. else:
  184. xsv_ext = xsb + 0
  185. ysv_ext = ysb + 2
  186. dx_ext = dx0 + 0 - 2 * SQUISH_CONSTANT_2D
  187. dy_ext = dy0 - 2 - 2 * SQUISH_CONSTANT_2D
  188. else: # (1,0) and (0,1) are the closest two vertices.
  189. dx_ext = dx0
  190. dy_ext = dy0
  191. xsv_ext = xsb
  192. ysv_ext = ysb
  193. xsb += 1
  194. ysb += 1
  195. dx0 = dx0 - 1 - 2 * SQUISH_CONSTANT_2D
  196. dy0 = dy0 - 1 - 2 * SQUISH_CONSTANT_2D
  197. # Contribution (0,0) or (1,1)
  198. attn0 = 2 - dx0 * dx0 - dy0 * dy0
  199. if attn0 > 0:
  200. attn0 *= attn0
  201. value += attn0 * attn0 * extrapolate(xsb, ysb, dx0, dy0)
  202. # Extra Vertex
  203. attn_ext = 2 - dx_ext * dx_ext - dy_ext * dy_ext
  204. if attn_ext > 0:
  205. attn_ext *= attn_ext
  206. value += attn_ext * attn_ext * extrapolate(xsv_ext, ysv_ext, dx_ext, dy_ext)
  207. return value / NORM_CONSTANT_2D
  208. def noise3d(self, x, y, z):
  209. """
  210. Generate 3D OpenSimplex noise from X,Y,Z coordinates.
  211. """
  212. # Place input coordinates on simplectic honeycomb.
  213. stretch_offset = (x + y + z) * STRETCH_CONSTANT_3D
  214. xs = x + stretch_offset
  215. ys = y + stretch_offset
  216. zs = z + stretch_offset
  217. # Floor to get simplectic honeycomb coordinates of rhombohedron (stretched cube) super-cell origin.
  218. xsb = floor(xs)
  219. ysb = floor(ys)
  220. zsb = floor(zs)
  221. # Skew out to get actual coordinates of rhombohedron origin. We'll need these later.
  222. squish_offset = (xsb + ysb + zsb) * SQUISH_CONSTANT_3D
  223. xb = xsb + squish_offset
  224. yb = ysb + squish_offset
  225. zb = zsb + squish_offset
  226. # Compute simplectic honeycomb coordinates relative to rhombohedral origin.
  227. xins = xs - xsb
  228. yins = ys - ysb
  229. zins = zs - zsb
  230. # Sum those together to get a value that determines which region we're in.
  231. in_sum = xins + yins + zins
  232. # Positions relative to origin point.
  233. dx0 = x - xb
  234. dy0 = y - yb
  235. dz0 = z - zb
  236. value = 0
  237. extrapolate = self._extrapolate3d
  238. if in_sum <= 1: # We're inside the tetrahedron (3-Simplex) at (0,0,0)
  239. # Determine which two of (0,0,1), (0,1,0), (1,0,0) are closest.
  240. a_point = 0x01
  241. a_score = xins
  242. b_point = 0x02
  243. b_score = yins
  244. if a_score >= b_score and zins > b_score:
  245. b_score = zins
  246. b_point = 0x04
  247. elif a_score < b_score and zins > a_score:
  248. a_score = zins
  249. a_point = 0x04
  250. # Now we determine the two lattice points not part of the tetrahedron that may contribute.
  251. # This depends on the closest two tetrahedral vertices, including (0,0,0)
  252. wins = 1 - in_sum
  253. if wins > a_score or wins > b_score: # (0,0,0) is one of the closest two tetrahedral vertices.
  254. c = b_point if (b_score > a_score) else a_point # Our other closest vertex is the closest out of a and b.
  255. if (c & 0x01) == 0:
  256. xsv_ext0 = xsb - 1
  257. xsv_ext1 = xsb
  258. dx_ext0 = dx0 + 1
  259. dx_ext1 = dx0
  260. else:
  261. xsv_ext0 = xsv_ext1 = xsb + 1
  262. dx_ext0 = dx_ext1 = dx0 - 1
  263. if (c & 0x02) == 0:
  264. ysv_ext0 = ysv_ext1 = ysb
  265. dy_ext0 = dy_ext1 = dy0
  266. if (c & 0x01) == 0:
  267. ysv_ext1 -= 1
  268. dy_ext1 += 1
  269. else:
  270. ysv_ext0 -= 1
  271. dy_ext0 += 1
  272. else:
  273. ysv_ext0 = ysv_ext1 = ysb + 1
  274. dy_ext0 = dy_ext1 = dy0 - 1
  275. if (c & 0x04) == 0:
  276. zsv_ext0 = zsb
  277. zsv_ext1 = zsb - 1
  278. dz_ext0 = dz0
  279. dz_ext1 = dz0 + 1
  280. else:
  281. zsv_ext0 = zsv_ext1 = zsb + 1
  282. dz_ext0 = dz_ext1 = dz0 - 1
  283. else: # (0,0,0) is not one of the closest two tetrahedral vertices.
  284. c = (a_point | b_point) # Our two extra vertices are determined by the closest two.
  285. if (c & 0x01) == 0:
  286. xsv_ext0 = xsb
  287. xsv_ext1 = xsb - 1
  288. dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_3D
  289. dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_3D
  290. else:
  291. xsv_ext0 = xsv_ext1 = xsb + 1
  292. dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D
  293. dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D
  294. if (c & 0x02) == 0:
  295. ysv_ext0 = ysb
  296. ysv_ext1 = ysb - 1
  297. dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_3D
  298. dy_ext1 = dy0 + 1 - SQUISH_CONSTANT_3D
  299. else:
  300. ysv_ext0 = ysv_ext1 = ysb + 1
  301. dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D
  302. dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D
  303. if (c & 0x04) == 0:
  304. zsv_ext0 = zsb
  305. zsv_ext1 = zsb - 1
  306. dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_3D
  307. dz_ext1 = dz0 + 1 - SQUISH_CONSTANT_3D
  308. else:
  309. zsv_ext0 = zsv_ext1 = zsb + 1
  310. dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D
  311. dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D
  312. # Contribution (0,0,0)
  313. attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0
  314. if attn0 > 0:
  315. attn0 *= attn0
  316. value += attn0 * attn0 * extrapolate(xsb + 0, ysb + 0, zsb + 0, dx0, dy0, dz0)
  317. # Contribution (1,0,0)
  318. dx1 = dx0 - 1 - SQUISH_CONSTANT_3D
  319. dy1 = dy0 - 0 - SQUISH_CONSTANT_3D
  320. dz1 = dz0 - 0 - SQUISH_CONSTANT_3D
  321. attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1
  322. if attn1 > 0:
  323. attn1 *= attn1
  324. value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, dx1, dy1, dz1)
  325. # Contribution (0,1,0)
  326. dx2 = dx0 - 0 - SQUISH_CONSTANT_3D
  327. dy2 = dy0 - 1 - SQUISH_CONSTANT_3D
  328. dz2 = dz1
  329. attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2
  330. if attn2 > 0:
  331. attn2 *= attn2
  332. value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, dx2, dy2, dz2)
  333. # Contribution (0,0,1)
  334. dx3 = dx2
  335. dy3 = dy1
  336. dz3 = dz0 - 1 - SQUISH_CONSTANT_3D
  337. attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3
  338. if attn3 > 0:
  339. attn3 *= attn3
  340. value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, dx3, dy3, dz3)
  341. elif in_sum >= 2: # We're inside the tetrahedron (3-Simplex) at (1,1,1)
  342. # Determine which two tetrahedral vertices are the closest, out of (1,1,0), (1,0,1), (0,1,1) but not (1,1,1).
  343. a_point = 0x06
  344. a_score = xins
  345. b_point = 0x05
  346. b_score = yins
  347. if a_score <= b_score and zins < b_score:
  348. b_score = zins
  349. b_point = 0x03
  350. elif a_score > b_score and zins < a_score:
  351. a_score = zins
  352. a_point = 0x03
  353. # Now we determine the two lattice points not part of the tetrahedron that may contribute.
  354. # This depends on the closest two tetrahedral vertices, including (1,1,1)
  355. wins = 3 - in_sum
  356. if wins < a_score or wins < b_score: # (1,1,1) is one of the closest two tetrahedral vertices.
  357. c = b_point if (b_score < a_score) else a_point # Our other closest vertex is the closest out of a and b.
  358. if (c & 0x01) != 0:
  359. xsv_ext0 = xsb + 2
  360. xsv_ext1 = xsb + 1
  361. dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_3D
  362. dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D
  363. else:
  364. xsv_ext0 = xsv_ext1 = xsb
  365. dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_3D
  366. if (c & 0x02) != 0:
  367. ysv_ext0 = ysv_ext1 = ysb + 1
  368. dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D
  369. if (c & 0x01) != 0:
  370. ysv_ext1 += 1
  371. dy_ext1 -= 1
  372. else:
  373. ysv_ext0 += 1
  374. dy_ext0 -= 1
  375. else:
  376. ysv_ext0 = ysv_ext1 = ysb
  377. dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_3D
  378. if (c & 0x04) != 0:
  379. zsv_ext0 = zsb + 1
  380. zsv_ext1 = zsb + 2
  381. dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D
  382. dz_ext1 = dz0 - 2 - 3 * SQUISH_CONSTANT_3D
  383. else:
  384. zsv_ext0 = zsv_ext1 = zsb
  385. dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_3D
  386. else: # (1,1,1) is not one of the closest two tetrahedral vertices.
  387. c = (a_point & b_point) # Our two extra vertices are determined by the closest two.
  388. if (c & 0x01) != 0:
  389. xsv_ext0 = xsb + 1
  390. xsv_ext1 = xsb + 2
  391. dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D
  392. dx_ext1 = dx0 - 2 - 2 * SQUISH_CONSTANT_3D
  393. else:
  394. xsv_ext0 = xsv_ext1 = xsb
  395. dx_ext0 = dx0 - SQUISH_CONSTANT_3D
  396. dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D
  397. if (c & 0x02) != 0:
  398. ysv_ext0 = ysb + 1
  399. ysv_ext1 = ysb + 2
  400. dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D
  401. dy_ext1 = dy0 - 2 - 2 * SQUISH_CONSTANT_3D
  402. else:
  403. ysv_ext0 = ysv_ext1 = ysb
  404. dy_ext0 = dy0 - SQUISH_CONSTANT_3D
  405. dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D
  406. if (c & 0x04) != 0:
  407. zsv_ext0 = zsb + 1
  408. zsv_ext1 = zsb + 2
  409. dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D
  410. dz_ext1 = dz0 - 2 - 2 * SQUISH_CONSTANT_3D
  411. else:
  412. zsv_ext0 = zsv_ext1 = zsb
  413. dz_ext0 = dz0 - SQUISH_CONSTANT_3D
  414. dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D
  415. # Contribution (1,1,0)
  416. dx3 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D
  417. dy3 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D
  418. dz3 = dz0 - 0 - 2 * SQUISH_CONSTANT_3D
  419. attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3
  420. if attn3 > 0:
  421. attn3 *= attn3
  422. value += attn3 * attn3 * extrapolate(xsb + 1, ysb + 1, zsb + 0, dx3, dy3, dz3)
  423. # Contribution (1,0,1)
  424. dx2 = dx3
  425. dy2 = dy0 - 0 - 2 * SQUISH_CONSTANT_3D
  426. dz2 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D
  427. attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2
  428. if attn2 > 0:
  429. attn2 *= attn2
  430. value += attn2 * attn2 * extrapolate(xsb + 1, ysb + 0, zsb + 1, dx2, dy2, dz2)
  431. # Contribution (0,1,1)
  432. dx1 = dx0 - 0 - 2 * SQUISH_CONSTANT_3D
  433. dy1 = dy3
  434. dz1 = dz2
  435. attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1
  436. if attn1 > 0:
  437. attn1 *= attn1
  438. value += attn1 * attn1 * extrapolate(xsb + 0, ysb + 1, zsb + 1, dx1, dy1, dz1)
  439. # Contribution (1,1,1)
  440. dx0 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D
  441. dy0 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D
  442. dz0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D
  443. attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0
  444. if attn0 > 0:
  445. attn0 *= attn0
  446. value += attn0 * attn0 * extrapolate(xsb + 1, ysb + 1, zsb + 1, dx0, dy0, dz0)
  447. else: # We're inside the octahedron (Rectified 3-Simplex) in between.
  448. # Decide between point (0,0,1) and (1,1,0) as closest
  449. p1 = xins + yins
  450. if p1 > 1:
  451. a_score = p1 - 1
  452. a_point = 0x03
  453. a_is_further_side = True
  454. else:
  455. a_score = 1 - p1
  456. a_point = 0x04
  457. a_is_further_side = False
  458. # Decide between point (0,1,0) and (1,0,1) as closest
  459. p2 = xins + zins
  460. if p2 > 1:
  461. b_score = p2 - 1
  462. b_point = 0x05
  463. b_is_further_side = True
  464. else:
  465. b_score = 1 - p2
  466. b_point = 0x02
  467. b_is_further_side = False
  468. # 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.
  469. p3 = yins + zins
  470. if p3 > 1:
  471. score = p3 - 1
  472. if a_score <= b_score and a_score < score:
  473. a_point = 0x06
  474. a_is_further_side = True
  475. elif a_score > b_score and b_score < score:
  476. b_point = 0x06
  477. b_is_further_side = True
  478. else:
  479. score = 1 - p3
  480. if a_score <= b_score and a_score < score:
  481. a_point = 0x01
  482. a_is_further_side = False
  483. elif a_score > b_score and b_score < score:
  484. b_point = 0x01
  485. b_is_further_side = False
  486. # Where each of the two closest points are determines how the extra two vertices are calculated.
  487. if a_is_further_side == b_is_further_side:
  488. if a_is_further_side: # Both closest points on (1,1,1) side
  489. # One of the two extra points is (1,1,1)
  490. dx_ext0 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D
  491. dy_ext0 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D
  492. dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D
  493. xsv_ext0 = xsb + 1
  494. ysv_ext0 = ysb + 1
  495. zsv_ext0 = zsb + 1
  496. # Other extra point is based on the shared axis.
  497. c = (a_point & b_point)
  498. if (c & 0x01) != 0:
  499. dx_ext1 = dx0 - 2 - 2 * SQUISH_CONSTANT_3D
  500. dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D
  501. dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D
  502. xsv_ext1 = xsb + 2
  503. ysv_ext1 = ysb
  504. zsv_ext1 = zsb
  505. elif (c & 0x02) != 0:
  506. dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D
  507. dy_ext1 = dy0 - 2 - 2 * SQUISH_CONSTANT_3D
  508. dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D
  509. xsv_ext1 = xsb
  510. ysv_ext1 = ysb + 2
  511. zsv_ext1 = zsb
  512. else:
  513. dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D
  514. dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D
  515. dz_ext1 = dz0 - 2 - 2 * SQUISH_CONSTANT_3D
  516. xsv_ext1 = xsb
  517. ysv_ext1 = ysb
  518. zsv_ext1 = zsb + 2
  519. else:# Both closest points on (0,0,0) side
  520. # One of the two extra points is (0,0,0)
  521. dx_ext0 = dx0
  522. dy_ext0 = dy0
  523. dz_ext0 = dz0
  524. xsv_ext0 = xsb
  525. ysv_ext0 = ysb
  526. zsv_ext0 = zsb
  527. # Other extra point is based on the omitted axis.
  528. c = (a_point | b_point)
  529. if (c & 0x01) == 0:
  530. dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_3D
  531. dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D
  532. dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D
  533. xsv_ext1 = xsb - 1
  534. ysv_ext1 = ysb + 1
  535. zsv_ext1 = zsb + 1
  536. elif (c & 0x02) == 0:
  537. dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D
  538. dy_ext1 = dy0 + 1 - SQUISH_CONSTANT_3D
  539. dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D
  540. xsv_ext1 = xsb + 1
  541. ysv_ext1 = ysb - 1
  542. zsv_ext1 = zsb + 1
  543. else:
  544. dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D
  545. dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D
  546. dz_ext1 = dz0 + 1 - SQUISH_CONSTANT_3D
  547. xsv_ext1 = xsb + 1
  548. ysv_ext1 = ysb + 1
  549. zsv_ext1 = zsb - 1
  550. else: # One point on (0,0,0) side, one point on (1,1,1) side
  551. if a_is_further_side:
  552. c1 = a_point
  553. c2 = b_point
  554. else:
  555. c1 = b_point
  556. c2 = a_point
  557. # One contribution is a _permutation of (1,1,-1)
  558. if (c1 & 0x01) == 0:
  559. dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_3D
  560. dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D
  561. dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D
  562. xsv_ext0 = xsb - 1
  563. ysv_ext0 = ysb + 1
  564. zsv_ext0 = zsb + 1
  565. elif (c1 & 0x02) == 0:
  566. dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D
  567. dy_ext0 = dy0 + 1 - SQUISH_CONSTANT_3D
  568. dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D
  569. xsv_ext0 = xsb + 1
  570. ysv_ext0 = ysb - 1
  571. zsv_ext0 = zsb + 1
  572. else:
  573. dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D
  574. dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D
  575. dz_ext0 = dz0 + 1 - SQUISH_CONSTANT_3D
  576. xsv_ext0 = xsb + 1
  577. ysv_ext0 = ysb + 1
  578. zsv_ext0 = zsb - 1
  579. # One contribution is a _permutation of (0,0,2)
  580. dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D
  581. dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D
  582. dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D
  583. xsv_ext1 = xsb
  584. ysv_ext1 = ysb
  585. zsv_ext1 = zsb
  586. if (c2 & 0x01) != 0:
  587. dx_ext1 -= 2
  588. xsv_ext1 += 2
  589. elif (c2 & 0x02) != 0:
  590. dy_ext1 -= 2
  591. ysv_ext1 += 2
  592. else:
  593. dz_ext1 -= 2
  594. zsv_ext1 += 2
  595. # Contribution (1,0,0)
  596. dx1 = dx0 - 1 - SQUISH_CONSTANT_3D
  597. dy1 = dy0 - 0 - SQUISH_CONSTANT_3D
  598. dz1 = dz0 - 0 - SQUISH_CONSTANT_3D
  599. attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1
  600. if attn1 > 0:
  601. attn1 *= attn1
  602. value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, dx1, dy1, dz1)
  603. # Contribution (0,1,0)
  604. dx2 = dx0 - 0 - SQUISH_CONSTANT_3D
  605. dy2 = dy0 - 1 - SQUISH_CONSTANT_3D
  606. dz2 = dz1
  607. attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2
  608. if attn2 > 0:
  609. attn2 *= attn2
  610. value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, dx2, dy2, dz2)
  611. # Contribution (0,0,1)
  612. dx3 = dx2
  613. dy3 = dy1
  614. dz3 = dz0 - 1 - SQUISH_CONSTANT_3D
  615. attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3
  616. if attn3 > 0:
  617. attn3 *= attn3
  618. value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, dx3, dy3, dz3)
  619. # Contribution (1,1,0)
  620. dx4 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D
  621. dy4 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D
  622. dz4 = dz0 - 0 - 2 * SQUISH_CONSTANT_3D
  623. attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4
  624. if attn4 > 0:
  625. attn4 *= attn4
  626. value += attn4 * attn4 * extrapolate(xsb + 1, ysb + 1, zsb + 0, dx4, dy4, dz4)
  627. # Contribution (1,0,1)
  628. dx5 = dx4
  629. dy5 = dy0 - 0 - 2 * SQUISH_CONSTANT_3D
  630. dz5 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D
  631. attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5
  632. if attn5 > 0:
  633. attn5 *= attn5
  634. value += attn5 * attn5 * extrapolate(xsb + 1, ysb + 0, zsb + 1, dx5, dy5, dz5)
  635. # Contribution (0,1,1)
  636. dx6 = dx0 - 0 - 2 * SQUISH_CONSTANT_3D
  637. dy6 = dy4
  638. dz6 = dz5
  639. attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6
  640. if attn6 > 0:
  641. attn6 *= attn6
  642. value += attn6 * attn6 * extrapolate(xsb + 0, ysb + 1, zsb + 1, dx6, dy6, dz6)
  643. # First extra vertex
  644. attn_ext0 = 2 - dx_ext0 * dx_ext0 - dy_ext0 * dy_ext0 - dz_ext0 * dz_ext0
  645. if attn_ext0 > 0:
  646. attn_ext0 *= attn_ext0
  647. value += attn_ext0 * attn_ext0 * extrapolate(xsv_ext0, ysv_ext0, zsv_ext0, dx_ext0, dy_ext0, dz_ext0)
  648. # Second extra vertex
  649. attn_ext1 = 2 - dx_ext1 * dx_ext1 - dy_ext1 * dy_ext1 - dz_ext1 * dz_ext1
  650. if attn_ext1 > 0:
  651. attn_ext1 *= attn_ext1
  652. value += attn_ext1 * attn_ext1 * extrapolate(xsv_ext1, ysv_ext1, zsv_ext1, dx_ext1, dy_ext1, dz_ext1)
  653. return value / NORM_CONSTANT_3D
  654. def noise4d(self, x, y, z, w):
  655. """
  656. Generate 4D OpenSimplex noise from X,Y,Z,W coordinates.
  657. """
  658. # Place input coordinates on simplectic honeycomb.
  659. stretch_offset = (x + y + z + w) * STRETCH_CONSTANT_4D
  660. xs = x + stretch_offset
  661. ys = y + stretch_offset
  662. zs = z + stretch_offset
  663. ws = w + stretch_offset
  664. # Floor to get simplectic honeycomb coordinates of rhombo-hypercube super-cell origin.
  665. xsb = floor(xs)
  666. ysb = floor(ys)
  667. zsb = floor(zs)
  668. wsb = floor(ws)
  669. # Skew out to get actual coordinates of stretched rhombo-hypercube origin. We'll need these later.
  670. squish_offset = (xsb + ysb + zsb + wsb) * SQUISH_CONSTANT_4D
  671. xb = xsb + squish_offset
  672. yb = ysb + squish_offset
  673. zb = zsb + squish_offset
  674. wb = wsb + squish_offset
  675. # Compute simplectic honeycomb coordinates relative to rhombo-hypercube origin.
  676. xins = xs - xsb
  677. yins = ys - ysb
  678. zins = zs - zsb
  679. wins = ws - wsb
  680. # Sum those together to get a value that determines which region we're in.
  681. in_sum = xins + yins + zins + wins
  682. # Positions relative to origin po.
  683. dx0 = x - xb
  684. dy0 = y - yb
  685. dz0 = z - zb
  686. dw0 = w - wb
  687. value = 0
  688. extrapolate = self._extrapolate4d
  689. if in_sum <= 1: # We're inside the pentachoron (4-Simplex) at (0,0,0,0)
  690. # Determine which two of (0,0,0,1), (0,0,1,0), (0,1,0,0), (1,0,0,0) are closest.
  691. a_po = 0x01
  692. a_score = xins
  693. b_po = 0x02
  694. b_score = yins
  695. if a_score >= b_score and zins > b_score:
  696. b_score = zins
  697. b_po = 0x04
  698. elif a_score < b_score and zins > a_score:
  699. a_score = zins
  700. a_po = 0x04
  701. if a_score >= b_score and wins > b_score:
  702. b_score = wins
  703. b_po = 0x08
  704. elif a_score < b_score and wins > a_score:
  705. a_score = wins
  706. a_po = 0x08
  707. # Now we determine the three lattice pos not part of the pentachoron that may contribute.
  708. # This depends on the closest two pentachoron vertices, including (0,0,0,0)
  709. uins = 1 - in_sum
  710. if uins > a_score or uins > b_score: # (0,0,0,0) is one of the closest two pentachoron vertices.
  711. c = b_po if (b_score > a_score) else a_po # Our other closest vertex is the closest out of a and b.
  712. if (c & 0x01) == 0:
  713. xsv_ext0 = xsb - 1
  714. xsv_ext1 = xsv_ext2 = xsb
  715. dx_ext0 = dx0 + 1
  716. dx_ext1 = dx_ext2 = dx0
  717. else:
  718. xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb + 1
  719. dx_ext0 = dx_ext1 = dx_ext2 = dx0 - 1
  720. if (c & 0x02) == 0:
  721. ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb
  722. dy_ext0 = dy_ext1 = dy_ext2 = dy0
  723. if (c & 0x01) == 0x01:
  724. ysv_ext0 -= 1
  725. dy_ext0 += 1
  726. else:
  727. ysv_ext1 -= 1
  728. dy_ext1 += 1
  729. else:
  730. ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1
  731. dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 1
  732. if (c & 0x04) == 0:
  733. zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb
  734. dz_ext0 = dz_ext1 = dz_ext2 = dz0
  735. if (c & 0x03) != 0:
  736. if (c & 0x03) == 0x03:
  737. zsv_ext0 -= 1
  738. dz_ext0 += 1
  739. else:
  740. zsv_ext1 -= 1
  741. dz_ext1 += 1
  742. else:
  743. zsv_ext2 -= 1
  744. dz_ext2 += 1
  745. else:
  746. zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1
  747. dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 1
  748. if (c & 0x08) == 0:
  749. wsv_ext0 = wsv_ext1 = wsb
  750. wsv_ext2 = wsb - 1
  751. dw_ext0 = dw_ext1 = dw0
  752. dw_ext2 = dw0 + 1
  753. else:
  754. wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb + 1
  755. dw_ext0 = dw_ext1 = dw_ext2 = dw0 - 1
  756. else: # (0,0,0,0) is not one of the closest two pentachoron vertices.
  757. c = (a_po | b_po) # Our three extra vertices are determined by the closest two.
  758. if (c & 0x01) == 0:
  759. xsv_ext0 = xsv_ext2 = xsb
  760. xsv_ext1 = xsb - 1
  761. dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_4D
  762. dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_4D
  763. dx_ext2 = dx0 - SQUISH_CONSTANT_4D
  764. else:
  765. xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb + 1
  766. dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
  767. dx_ext1 = dx_ext2 = dx0 - 1 - SQUISH_CONSTANT_4D
  768. if (c & 0x02) == 0:
  769. ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb
  770. dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_4D
  771. dy_ext1 = dy_ext2 = dy0 - SQUISH_CONSTANT_4D
  772. if (c & 0x01) == 0x01:
  773. ysv_ext1 -= 1
  774. dy_ext1 += 1
  775. else:
  776. ysv_ext2 -= 1
  777. dy_ext2 += 1
  778. else:
  779. ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1
  780. dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
  781. dy_ext1 = dy_ext2 = dy0 - 1 - SQUISH_CONSTANT_4D
  782. if (c & 0x04) == 0:
  783. zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb
  784. dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_4D
  785. dz_ext1 = dz_ext2 = dz0 - SQUISH_CONSTANT_4D
  786. if (c & 0x03) == 0x03:
  787. zsv_ext1 -= 1
  788. dz_ext1 += 1
  789. else:
  790. zsv_ext2 -= 1
  791. dz_ext2 += 1
  792. else:
  793. zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1
  794. dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
  795. dz_ext1 = dz_ext2 = dz0 - 1 - SQUISH_CONSTANT_4D
  796. if (c & 0x08) == 0:
  797. wsv_ext0 = wsv_ext1 = wsb
  798. wsv_ext2 = wsb - 1
  799. dw_ext0 = dw0 - 2 * SQUISH_CONSTANT_4D
  800. dw_ext1 = dw0 - SQUISH_CONSTANT_4D
  801. dw_ext2 = dw0 + 1 - SQUISH_CONSTANT_4D
  802. else:
  803. wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb + 1
  804. dw_ext0 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
  805. dw_ext1 = dw_ext2 = dw0 - 1 - SQUISH_CONSTANT_4D
  806. # Contribution (0,0,0,0)
  807. attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0 - dw0 * dw0
  808. if attn0 > 0:
  809. attn0 *= attn0
  810. value += attn0 * attn0 * extrapolate(xsb + 0, ysb + 0, zsb + 0, wsb + 0, dx0, dy0, dz0, dw0)
  811. # Contribution (1,0,0,0)
  812. dx1 = dx0 - 1 - SQUISH_CONSTANT_4D
  813. dy1 = dy0 - 0 - SQUISH_CONSTANT_4D
  814. dz1 = dz0 - 0 - SQUISH_CONSTANT_4D
  815. dw1 = dw0 - 0 - SQUISH_CONSTANT_4D
  816. attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1
  817. if attn1 > 0:
  818. attn1 *= attn1
  819. value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 0, dx1, dy1, dz1, dw1)
  820. # Contribution (0,1,0,0)
  821. dx2 = dx0 - 0 - SQUISH_CONSTANT_4D
  822. dy2 = dy0 - 1 - SQUISH_CONSTANT_4D
  823. dz2 = dz1
  824. dw2 = dw1
  825. attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2
  826. if attn2 > 0:
  827. attn2 *= attn2
  828. value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 0, dx2, dy2, dz2, dw2)
  829. # Contribution (0,0,1,0)
  830. dx3 = dx2
  831. dy3 = dy1
  832. dz3 = dz0 - 1 - SQUISH_CONSTANT_4D
  833. dw3 = dw1
  834. attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3
  835. if attn3 > 0:
  836. attn3 *= attn3
  837. value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 0, dx3, dy3, dz3, dw3)
  838. # Contribution (0,0,0,1)
  839. dx4 = dx2
  840. dy4 = dy1
  841. dz4 = dz1
  842. dw4 = dw0 - 1 - SQUISH_CONSTANT_4D
  843. attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4
  844. if attn4 > 0:
  845. attn4 *= attn4
  846. value += attn4 * attn4 * extrapolate(xsb + 0, ysb + 0, zsb + 0, wsb + 1, dx4, dy4, dz4, dw4)
  847. elif in_sum >= 3: # We're inside the pentachoron (4-Simplex) at (1,1,1,1)
  848. # Determine which two of (1,1,1,0), (1,1,0,1), (1,0,1,1), (0,1,1,1) are closest.
  849. a_po = 0x0E
  850. a_score = xins
  851. b_po = 0x0D
  852. b_score = yins
  853. if a_score <= b_score and zins < b_score:
  854. b_score = zins
  855. b_po = 0x0B
  856. elif a_score > b_score and zins < a_score:
  857. a_score = zins
  858. a_po = 0x0B
  859. if a_score <= b_score and wins < b_score:
  860. b_score = wins
  861. b_po = 0x07
  862. elif a_score > b_score and wins < a_score:
  863. a_score = wins
  864. a_po = 0x07
  865. # Now we determine the three lattice pos not part of the pentachoron that may contribute.
  866. # This depends on the closest two pentachoron vertices, including (0,0,0,0)
  867. uins = 4 - in_sum
  868. if uins < a_score or uins < b_score: # (1,1,1,1) is one of the closest two pentachoron vertices.
  869. c = b_po if (b_score < a_score) else a_po # Our other closest vertex is the closest out of a and b.
  870. if (c & 0x01) != 0:
  871. xsv_ext0 = xsb + 2
  872. xsv_ext1 = xsv_ext2 = xsb + 1
  873. dx_ext0 = dx0 - 2 - 4 * SQUISH_CONSTANT_4D
  874. dx_ext1 = dx_ext2 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D
  875. else:
  876. xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb
  877. dx_ext0 = dx_ext1 = dx_ext2 = dx0 - 4 * SQUISH_CONSTANT_4D
  878. if (c & 0x02) != 0:
  879. ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1
  880. dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D
  881. if (c & 0x01) != 0:
  882. ysv_ext1 += 1
  883. dy_ext1 -= 1
  884. else:
  885. ysv_ext0 += 1
  886. dy_ext0 -= 1
  887. else:
  888. ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb
  889. dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 4 * SQUISH_CONSTANT_4D
  890. if (c & 0x04) != 0:
  891. zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1
  892. dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D
  893. if (c & 0x03) != 0x03:
  894. if (c & 0x03) == 0:
  895. zsv_ext0 += 1
  896. dz_ext0 -= 1
  897. else:
  898. zsv_ext1 += 1
  899. dz_ext1 -= 1
  900. else:
  901. zsv_ext2 += 1
  902. dz_ext2 -= 1
  903. else:
  904. zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb
  905. dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 4 * SQUISH_CONSTANT_4D
  906. if (c & 0x08) != 0:
  907. wsv_ext0 = wsv_ext1 = wsb + 1
  908. wsv_ext2 = wsb + 2
  909. dw_ext0 = dw_ext1 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D
  910. dw_ext2 = dw0 - 2 - 4 * SQUISH_CONSTANT_4D
  911. else:
  912. wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb
  913. dw_ext0 = dw_ext1 = dw_ext2 = dw0 - 4 * SQUISH_CONSTANT_4D
  914. else: # (1,1,1,1) is not one of the closest two pentachoron vertices.
  915. c = (a_po & b_po) # Our three extra vertices are determined by the closest two.
  916. if (c & 0x01) != 0:
  917. xsv_ext0 = xsv_ext2 = xsb + 1
  918. xsv_ext1 = xsb + 2
  919. dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
  920. dx_ext1 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D
  921. dx_ext2 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D
  922. else:
  923. xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb
  924. dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_4D
  925. dx_ext1 = dx_ext2 = dx0 - 3 * SQUISH_CONSTANT_4D
  926. if (c & 0x02) != 0:
  927. ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1
  928. dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
  929. dy_ext1 = dy_ext2 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D
  930. if (c & 0x01) != 0:
  931. ysv_ext2 += 1
  932. dy_ext2 -= 1
  933. else:
  934. ysv_ext1 += 1
  935. dy_ext1 -= 1
  936. else:
  937. ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb
  938. dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_4D
  939. dy_ext1 = dy_ext2 = dy0 - 3 * SQUISH_CONSTANT_4D
  940. if (c & 0x04) != 0:
  941. zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1
  942. dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
  943. dz_ext1 = dz_ext2 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D
  944. if (c & 0x03) != 0:
  945. zsv_ext2 += 1
  946. dz_ext2 -= 1
  947. else:
  948. zsv_ext1 += 1
  949. dz_ext1 -= 1
  950. else:
  951. zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb
  952. dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_4D
  953. dz_ext1 = dz_ext2 = dz0 - 3 * SQUISH_CONSTANT_4D
  954. if (c & 0x08) != 0:
  955. wsv_ext0 = wsv_ext1 = wsb + 1
  956. wsv_ext2 = wsb + 2
  957. dw_ext0 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
  958. dw_ext1 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D
  959. dw_ext2 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D
  960. else:
  961. wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb
  962. dw_ext0 = dw0 - 2 * SQUISH_CONSTANT_4D
  963. dw_ext1 = dw_ext2 = dw0 - 3 * SQUISH_CONSTANT_4D
  964. # Contribution (1,1,1,0)
  965. dx4 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D
  966. dy4 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D
  967. dz4 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D
  968. dw4 = dw0 - 3 * SQUISH_CONSTANT_4D
  969. attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4
  970. if attn4 > 0:
  971. attn4 *= attn4
  972. value += attn4 * attn4 * extrapolate(xsb + 1, ysb + 1, zsb + 1, wsb + 0, dx4, dy4, dz4, dw4)
  973. # Contribution (1,1,0,1)
  974. dx3 = dx4
  975. dy3 = dy4
  976. dz3 = dz0 - 3 * SQUISH_CONSTANT_4D
  977. dw3 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D
  978. attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3
  979. if attn3 > 0:
  980. attn3 *= attn3
  981. value += attn3 * attn3 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 1, dx3, dy3, dz3, dw3)
  982. # Contribution (1,0,1,1)
  983. dx2 = dx4
  984. dy2 = dy0 - 3 * SQUISH_CONSTANT_4D
  985. dz2 = dz4
  986. dw2 = dw3
  987. attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2
  988. if attn2 > 0:
  989. attn2 *= attn2
  990. value += attn2 * attn2 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 1, dx2, dy2, dz2, dw2)
  991. # Contribution (0,1,1,1)
  992. dx1 = dx0 - 3 * SQUISH_CONSTANT_4D
  993. dz1 = dz4
  994. dy1 = dy4
  995. dw1 = dw3
  996. attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1
  997. if attn1 > 0:
  998. attn1 *= attn1
  999. value += attn1 * attn1 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 1, dx1, dy1, dz1, dw1)
  1000. # Contribution (1,1,1,1)
  1001. dx0 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D
  1002. dy0 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D
  1003. dz0 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D
  1004. dw0 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D
  1005. attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0 - dw0 * dw0
  1006. if attn0 > 0:
  1007. attn0 *= attn0
  1008. value += attn0 * attn0 * extrapolate(xsb + 1, ysb + 1, zsb + 1, wsb + 1, dx0, dy0, dz0, dw0)
  1009. elif in_sum <= 2: # We're inside the first dispentachoron (Rectified 4-Simplex)
  1010. a_is_bigger_side = True
  1011. b_is_bigger_side = True
  1012. # Decide between (1,1,0,0) and (0,0,1,1)
  1013. if xins + yins > zins + wins:
  1014. a_score = xins + yins
  1015. a_po = 0x03
  1016. else:
  1017. a_score = zins + wins
  1018. a_po = 0x0C
  1019. # Decide between (1,0,1,0) and (0,1,0,1)
  1020. if xins + zins > yins + wins:
  1021. b_score = xins + zins
  1022. b_po = 0x05
  1023. else:
  1024. b_score = yins + wins
  1025. b_po = 0x0A
  1026. # Closer between (1,0,0,1) and (0,1,1,0) will replace the further of a and b, if closer.
  1027. if xins + wins > yins + zins:
  1028. score = xins + wins
  1029. if a_score >= b_score and score > b_score:
  1030. b_score = score
  1031. b_po = 0x09
  1032. elif a_score < b_score and score > a_score:
  1033. a_score = score
  1034. a_po = 0x09
  1035. else:
  1036. score = yins + zins
  1037. if a_score >= b_score and score > b_score:
  1038. b_score = score
  1039. b_po = 0x06
  1040. elif a_score < b_score and score > a_score:
  1041. a_score = score
  1042. a_po = 0x06
  1043. # Decide if (1,0,0,0) is closer.
  1044. p1 = 2 - in_sum + xins
  1045. if a_score >= b_score and p1 > b_score:
  1046. b_score = p1
  1047. b_po = 0x01
  1048. b_is_bigger_side = False
  1049. elif a_score < b_score and p1 > a_score:
  1050. a_score = p1
  1051. a_po = 0x01
  1052. a_is_bigger_side = False
  1053. # Decide if (0,1,0,0) is closer.
  1054. p2 = 2 - in_sum + yins
  1055. if a_score >= b_score and p2 > b_score:
  1056. b_score = p2
  1057. b_po = 0x02
  1058. b_is_bigger_side = False
  1059. elif a_score < b_score and p2 > a_score:
  1060. a_score = p2
  1061. a_po = 0x02
  1062. a_is_bigger_side = False
  1063. # Decide if (0,0,1,0) is closer.
  1064. p3 = 2 - in_sum + zins
  1065. if a_score >= b_score and p3 > b_score:
  1066. b_score = p3
  1067. b_po = 0x04
  1068. b_is_bigger_side = False
  1069. elif a_score < b_score and p3 > a_score:
  1070. a_score = p3
  1071. a_po = 0x04
  1072. a_is_bigger_side = False
  1073. # Decide if (0,0,0,1) is closer.
  1074. p4 = 2 - in_sum + wins
  1075. if a_score >= b_score and p4 > b_score:
  1076. b_po = 0x08
  1077. b_is_bigger_side = False
  1078. elif a_score < b_score and p4 > a_score:
  1079. a_po = 0x08
  1080. a_is_bigger_side = False
  1081. # Where each of the two closest pos are determines how the extra three vertices are calculated.
  1082. if a_is_bigger_side == b_is_bigger_side:
  1083. if a_is_bigger_side: # Both closest pos on the bigger side
  1084. c1 = (a_po | b_po)
  1085. c2 = (a_po & b_po)
  1086. if (c1 & 0x01) == 0:
  1087. xsv_ext0 = xsb
  1088. xsv_ext1 = xsb - 1
  1089. dx_ext0 = dx0 - 3 * SQUISH_CONSTANT_4D
  1090. dx_ext1 = dx0 + 1 - 2 * SQUISH_CONSTANT_4D
  1091. else:
  1092. xsv_ext0 = xsv_ext1 = xsb + 1
  1093. dx_ext0 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D
  1094. dx_ext1 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
  1095. if (c1 & 0x02) == 0:
  1096. ysv_ext0 = ysb
  1097. ysv_ext1 = ysb - 1
  1098. dy_ext0 = dy0 - 3 * SQUISH_CONSTANT_4D
  1099. dy_ext1 = dy0 + 1 - 2 * SQUISH_CONSTANT_4D
  1100. else:
  1101. ysv_ext0 = ysv_ext1 = ysb + 1
  1102. dy_ext0 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D
  1103. dy_ext1 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
  1104. if (c1 & 0x04) == 0:
  1105. zsv_ext0 = zsb
  1106. zsv_ext1 = zsb - 1
  1107. dz_ext0 = dz0 - 3 * SQUISH_CONSTANT_4D
  1108. dz_ext1 = dz0 + 1 - 2 * SQUISH_CONSTANT_4D
  1109. else:
  1110. zsv_ext0 = zsv_ext1 = zsb + 1
  1111. dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D
  1112. dz_ext1 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
  1113. if (c1 & 0x08) == 0:
  1114. wsv_ext0 = wsb
  1115. wsv_ext1 = wsb - 1
  1116. dw_ext0 = dw0 - 3 * SQUISH_CONSTANT_4D
  1117. dw_ext1 = dw0 + 1 - 2 * SQUISH_CONSTANT_4D
  1118. else:
  1119. wsv_ext0 = wsv_ext1 = wsb + 1
  1120. dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D
  1121. dw_ext1 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
  1122. # One combination is a _permutation of (0,0,0,2) based on c2
  1123. xsv_ext2 = xsb
  1124. ysv_ext2 = ysb
  1125. zsv_ext2 = zsb
  1126. wsv_ext2 = wsb
  1127. dx_ext2 = dx0 - 2 * SQUISH_CONSTANT_4D
  1128. dy_ext2 = dy0 - 2 * SQUISH_CONSTANT_4D
  1129. dz_ext2 = dz0 - 2 * SQUISH_CONSTANT_4D
  1130. dw_ext2 = dw0 - 2 * SQUISH_CONSTANT_4D
  1131. if (c2 & 0x01) != 0:
  1132. xsv_ext2 += 2
  1133. dx_ext2 -= 2
  1134. elif (c2 & 0x02) != 0:
  1135. ysv_ext2 += 2
  1136. dy_ext2 -= 2
  1137. elif (c2 & 0x04) != 0:
  1138. zsv_ext2 += 2
  1139. dz_ext2 -= 2
  1140. else:
  1141. wsv_ext2 += 2
  1142. dw_ext2 -= 2
  1143. else: # Both closest pos on the smaller side
  1144. # One of the two extra pos is (0,0,0,0)
  1145. xsv_ext2 = xsb
  1146. ysv_ext2 = ysb
  1147. zsv_ext2 = zsb
  1148. wsv_ext2 = wsb
  1149. dx_ext2 = dx0
  1150. dy_ext2 = dy0
  1151. dz_ext2 = dz0
  1152. dw_ext2 = dw0
  1153. # Other two pos are based on the omitted axes.
  1154. c = (a_po | b_po)
  1155. if (c & 0x01) == 0:
  1156. xsv_ext0 = xsb - 1
  1157. xsv_ext1 = xsb
  1158. dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_4D
  1159. dx_ext1 = dx0 - SQUISH_CONSTANT_4D
  1160. else:
  1161. xsv_ext0 = xsv_ext1 = xsb + 1
  1162. dx_ext0 = dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_4D
  1163. if (c & 0x02) == 0:
  1164. ysv_ext0 = ysv_ext1 = ysb
  1165. dy_ext0 = dy_ext1 = dy0 - SQUISH_CONSTANT_4D
  1166. if (c & 0x01) == 0x01:
  1167. ysv_ext0 -= 1
  1168. dy_ext0 += 1
  1169. else:
  1170. ysv_ext1 -= 1
  1171. dy_ext1 += 1
  1172. else:
  1173. ysv_ext0 = ysv_ext1 = ysb + 1
  1174. dy_ext0 = dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_4D
  1175. if (c & 0x04) == 0:
  1176. zsv_ext0 = zsv_ext1 = zsb
  1177. dz_ext0 = dz_ext1 = dz0 - SQUISH_CONSTANT_4D
  1178. if (c & 0x03) == 0x03:
  1179. zsv_ext0 -= 1
  1180. dz_ext0 += 1
  1181. else:
  1182. zsv_ext1 -= 1
  1183. dz_ext1 += 1
  1184. else:
  1185. zsv_ext0 = zsv_ext1 = zsb + 1
  1186. dz_ext0 = dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_4D
  1187. if (c & 0x08) == 0:
  1188. wsv_ext0 = wsb
  1189. wsv_ext1 = wsb - 1
  1190. dw_ext0 = dw0 - SQUISH_CONSTANT_4D
  1191. dw_ext1 = dw0 + 1 - SQUISH_CONSTANT_4D
  1192. else:
  1193. wsv_ext0 = wsv_ext1 = wsb + 1
  1194. dw_ext0 = dw_ext1 = dw0 - 1 - SQUISH_CONSTANT_4D
  1195. else: # One po on each "side"
  1196. if a_is_bigger_side:
  1197. c1 = a_po
  1198. c2 = b_po
  1199. else:
  1200. c1 = b_po
  1201. c2 = a_po
  1202. # Two contributions are the bigger-sided po with each 0 replaced with -1.
  1203. if (c1 & 0x01) == 0:
  1204. xsv_ext0 = xsb - 1
  1205. xsv_ext1 = xsb
  1206. dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_4D
  1207. dx_ext1 = dx0 - SQUISH_CONSTANT_4D
  1208. else:
  1209. xsv_ext0 = xsv_ext1 = xsb + 1
  1210. dx_ext0 = dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_4D
  1211. if (c1 & 0x02) == 0:
  1212. ysv_ext0 = ysv_ext1 = ysb
  1213. dy_ext0 = dy_ext1 = dy0 - SQUISH_CONSTANT_4D
  1214. if (c1 & 0x01) == 0x01:
  1215. ysv_ext0 -= 1
  1216. dy_ext0 += 1
  1217. else:
  1218. ysv_ext1 -= 1
  1219. dy_ext1 += 1
  1220. else:
  1221. ysv_ext0 = ysv_ext1 = ysb + 1
  1222. dy_ext0 = dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_4D
  1223. if (c1 & 0x04) == 0:
  1224. zsv_ext0 = zsv_ext1 = zsb
  1225. dz_ext0 = dz_ext1 = dz0 - SQUISH_CONSTANT_4D
  1226. if (c1 & 0x03) == 0x03:
  1227. zsv_ext0 -= 1
  1228. dz_ext0 += 1
  1229. else:
  1230. zsv_ext1 -= 1
  1231. dz_ext1 += 1
  1232. else:
  1233. zsv_ext0 = zsv_ext1 = zsb + 1
  1234. dz_ext0 = dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_4D
  1235. if (c1 & 0x08) == 0:
  1236. wsv_ext0 = wsb
  1237. wsv_ext1 = wsb - 1
  1238. dw_ext0 = dw0 - SQUISH_CONSTANT_4D
  1239. dw_ext1 = dw0 + 1 - SQUISH_CONSTANT_4D
  1240. else:
  1241. wsv_ext0 = wsv_ext1 = wsb + 1
  1242. dw_ext0 = dw_ext1 = dw0 - 1 - SQUISH_CONSTANT_4D
  1243. # One contribution is a _permutation of (0,0,0,2) based on the smaller-sided po
  1244. xsv_ext2 = xsb
  1245. ysv_ext2 = ysb
  1246. zsv_ext2 = zsb
  1247. wsv_ext2 = wsb
  1248. dx_ext2 = dx0 - 2 * SQUISH_CONSTANT_4D
  1249. dy_ext2 = dy0 - 2 * SQUISH_CONSTANT_4D
  1250. dz_ext2 = dz0 - 2 * SQUISH_CONSTANT_4D
  1251. dw_ext2 = dw0 - 2 * SQUISH_CONSTANT_4D
  1252. if (c2 & 0x01) != 0:
  1253. xsv_ext2 += 2
  1254. dx_ext2 -= 2
  1255. elif (c2 & 0x02) != 0:
  1256. ysv_ext2 += 2
  1257. dy_ext2 -= 2
  1258. elif (c2 & 0x04) != 0:
  1259. zsv_ext2 += 2
  1260. dz_ext2 -= 2
  1261. else:
  1262. wsv_ext2 += 2
  1263. dw_ext2 -= 2
  1264. # Contribution (1,0,0,0)
  1265. dx1 = dx0 - 1 - SQUISH_CONSTANT_4D
  1266. dy1 = dy0 - 0 - SQUISH_CONSTANT_4D
  1267. dz1 = dz0 - 0 - SQUISH_CONSTANT_4D
  1268. dw1 = dw0 - 0 - SQUISH_CONSTANT_4D
  1269. attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1
  1270. if attn1 > 0:
  1271. attn1 *= attn1
  1272. value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 0, dx1, dy1, dz1, dw1)
  1273. # Contribution (0,1,0,0)
  1274. dx2 = dx0 - 0 - SQUISH_CONSTANT_4D
  1275. dy2 = dy0 - 1 - SQUISH_CONSTANT_4D
  1276. dz2 = dz1
  1277. dw2 = dw1
  1278. attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2
  1279. if attn2 > 0:
  1280. attn2 *= attn2
  1281. value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 0, dx2, dy2, dz2, dw2)
  1282. # Contribution (0,0,1,0)
  1283. dx3 = dx2
  1284. dy3 = dy1
  1285. dz3 = dz0 - 1 - SQUISH_CONSTANT_4D
  1286. dw3 = dw1
  1287. attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3
  1288. if attn3 > 0:
  1289. attn3 *= attn3
  1290. value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 0, dx3, dy3, dz3, dw3)
  1291. # Contribution (0,0,0,1)
  1292. dx4 = dx2
  1293. dy4 = dy1
  1294. dz4 = dz1
  1295. dw4 = dw0 - 1 - SQUISH_CONSTANT_4D
  1296. attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4
  1297. if attn4 > 0:
  1298. attn4 *= attn4
  1299. value += attn4 * attn4 * extrapolate(xsb + 0, ysb + 0, zsb + 0, wsb + 1, dx4, dy4, dz4, dw4)
  1300. # Contribution (1,1,0,0)
  1301. dx5 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
  1302. dy5 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
  1303. dz5 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D
  1304. dw5 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D
  1305. attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5 - dw5 * dw5
  1306. if attn5 > 0:
  1307. attn5 *= attn5
  1308. value += attn5 * attn5 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 0, dx5, dy5, dz5, dw5)
  1309. # Contribution (1,0,1,0)
  1310. dx6 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
  1311. dy6 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D
  1312. dz6 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
  1313. dw6 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D
  1314. attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6 - dw6 * dw6
  1315. if attn6 > 0:
  1316. attn6 *= attn6
  1317. value += attn6 * attn6 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 0, dx6, dy6, dz6, dw6)
  1318. # Contribution (1,0,0,1)
  1319. dx7 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
  1320. dy7 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D
  1321. dz7 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D
  1322. dw7 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
  1323. attn7 = 2 - dx7 * dx7 - dy7 * dy7 - dz7 * dz7 - dw7 * dw7
  1324. if attn7 > 0:
  1325. attn7 *= attn7
  1326. value += attn7 * attn7 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 1, dx7, dy7, dz7, dw7)
  1327. # Contribution (0,1,1,0)
  1328. dx8 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D
  1329. dy8 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
  1330. dz8 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
  1331. dw8 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D
  1332. attn8 = 2 - dx8 * dx8 - dy8 * dy8 - dz8 * dz8 - dw8 * dw8
  1333. if attn8 > 0:
  1334. attn8 *= attn8
  1335. value += attn8 * attn8 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 0, dx8, dy8, dz8, dw8)
  1336. # Contribution (0,1,0,1)
  1337. dx9 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D
  1338. dy9 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
  1339. dz9 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D
  1340. dw9 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
  1341. attn9 = 2 - dx9 * dx9 - dy9 * dy9 - dz9 * dz9 - dw9 * dw9
  1342. if attn9 > 0:
  1343. attn9 *= attn9
  1344. value += attn9 * attn9 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 1, dx9, dy9, dz9, dw9)
  1345. # Contribution (0,0,1,1)
  1346. dx10 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D
  1347. dy10 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D
  1348. dz10 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
  1349. dw10 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
  1350. attn10 = 2 - dx10 * dx10 - dy10 * dy10 - dz10 * dz10 - dw10 * dw10
  1351. if attn10 > 0:
  1352. attn10 *= attn10
  1353. value += attn10 * attn10 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 1, dx10, dy10, dz10, dw10)
  1354. else: # We're inside the second dispentachoron (Rectified 4-Simplex)
  1355. a_is_bigger_side = True
  1356. b_is_bigger_side = True
  1357. # Decide between (0,0,1,1) and (1,1,0,0)
  1358. if xins + yins < zins + wins:
  1359. a_score = xins + yins
  1360. a_po = 0x0C
  1361. else:
  1362. a_score = zins + wins
  1363. a_po = 0x03
  1364. # Decide between (0,1,0,1) and (1,0,1,0)
  1365. if xins + zins < yins + wins:
  1366. b_score = xins + zins
  1367. b_po = 0x0A
  1368. else:
  1369. b_score = yins + wins
  1370. b_po = 0x05
  1371. # Closer between (0,1,1,0) and (1,0,0,1) will replace the further of a and b, if closer.
  1372. if xins + wins < yins + zins:
  1373. score = xins + wins
  1374. if a_score <= b_score and score < b_score:
  1375. b_score = score
  1376. b_po = 0x06
  1377. elif a_score > b_score and score < a_score:
  1378. a_score = score
  1379. a_po = 0x06
  1380. else:
  1381. score = yins + zins
  1382. if a_score <= b_score and score < b_score:
  1383. b_score = score
  1384. b_po = 0x09
  1385. elif a_score > b_score and score < a_score:
  1386. a_score = score
  1387. a_po = 0x09
  1388. # Decide if (0,1,1,1) is closer.
  1389. p1 = 3 - in_sum + xins
  1390. if a_score <= b_score and p1 < b_score:
  1391. b_score = p1
  1392. b_po = 0x0E
  1393. b_is_bigger_side = False
  1394. elif a_score > b_score and p1 < a_score:
  1395. a_score = p1
  1396. a_po = 0x0E
  1397. a_is_bigger_side = False
  1398. # Decide if (1,0,1,1) is closer.
  1399. p2 = 3 - in_sum + yins
  1400. if a_score <= b_score and p2 < b_score:
  1401. b_score = p2
  1402. b_po = 0x0D
  1403. b_is_bigger_side = False
  1404. elif a_score > b_score and p2 < a_score:
  1405. a_score = p2
  1406. a_po = 0x0D
  1407. a_is_bigger_side = False
  1408. # Decide if (1,1,0,1) is closer.
  1409. p3 = 3 - in_sum + zins
  1410. if a_score <= b_score and p3 < b_score:
  1411. b_score = p3
  1412. b_po = 0x0B
  1413. b_is_bigger_side = False
  1414. elif a_score > b_score and p3 < a_score:
  1415. a_score = p3
  1416. a_po = 0x0B
  1417. a_is_bigger_side = False
  1418. # Decide if (1,1,1,0) is closer.
  1419. p4 = 3 - in_sum + wins
  1420. if a_score <= b_score and p4 < b_score:
  1421. b_po = 0x07
  1422. b_is_bigger_side = False
  1423. elif a_score > b_score and p4 < a_score:
  1424. a_po = 0x07
  1425. a_is_bigger_side = False
  1426. # Where each of the two closest pos are determines how the extra three vertices are calculated.
  1427. if a_is_bigger_side == b_is_bigger_side:
  1428. if a_is_bigger_side: # Both closest pos on the bigger side
  1429. c1 = (a_po & b_po)
  1430. c2 = (a_po | b_po)
  1431. # Two contributions are _permutations of (0,0,0,1) and (0,0,0,2) based on c1
  1432. xsv_ext0 = xsv_ext1 = xsb
  1433. ysv_ext0 = ysv_ext1 = ysb
  1434. zsv_ext0 = zsv_ext1 = zsb
  1435. wsv_ext0 = wsv_ext1 = wsb
  1436. dx_ext0 = dx0 - SQUISH_CONSTANT_4D
  1437. dy_ext0 = dy0 - SQUISH_CONSTANT_4D
  1438. dz_ext0 = dz0 - SQUISH_CONSTANT_4D
  1439. dw_ext0 = dw0 - SQUISH_CONSTANT_4D
  1440. dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_4D
  1441. dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_4D
  1442. dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_4D
  1443. dw_ext1 = dw0 - 2 * SQUISH_CONSTANT_4D
  1444. if (c1 & 0x01) != 0:
  1445. xsv_ext0 += 1
  1446. dx_ext0 -= 1
  1447. xsv_ext1 += 2
  1448. dx_ext1 -= 2
  1449. elif (c1 & 0x02) != 0:
  1450. ysv_ext0 += 1
  1451. dy_ext0 -= 1
  1452. ysv_ext1 += 2
  1453. dy_ext1 -= 2
  1454. elif (c1 & 0x04) != 0:
  1455. zsv_ext0 += 1
  1456. dz_ext0 -= 1
  1457. zsv_ext1 += 2
  1458. dz_ext1 -= 2
  1459. else:
  1460. wsv_ext0 += 1
  1461. dw_ext0 -= 1
  1462. wsv_ext1 += 2
  1463. dw_ext1 -= 2
  1464. # One contribution is a _permutation of (1,1,1,-1) based on c2
  1465. xsv_ext2 = xsb + 1
  1466. ysv_ext2 = ysb + 1
  1467. zsv_ext2 = zsb + 1
  1468. wsv_ext2 = wsb + 1
  1469. dx_ext2 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
  1470. dy_ext2 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
  1471. dz_ext2 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
  1472. dw_ext2 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
  1473. if (c2 & 0x01) == 0:
  1474. xsv_ext2 -= 2
  1475. dx_ext2 += 2
  1476. elif (c2 & 0x02) == 0:
  1477. ysv_ext2 -= 2
  1478. dy_ext2 += 2
  1479. elif (c2 & 0x04) == 0:
  1480. zsv_ext2 -= 2
  1481. dz_ext2 += 2
  1482. else:
  1483. wsv_ext2 -= 2
  1484. dw_ext2 += 2
  1485. else: # Both closest pos on the smaller side
  1486. # One of the two extra pos is (1,1,1,1)
  1487. xsv_ext2 = xsb + 1
  1488. ysv_ext2 = ysb + 1
  1489. zsv_ext2 = zsb + 1
  1490. wsv_ext2 = wsb + 1
  1491. dx_ext2 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D
  1492. dy_ext2 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D
  1493. dz_ext2 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D
  1494. dw_ext2 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D
  1495. # Other two pos are based on the shared axes.
  1496. c = (a_po & b_po)
  1497. if (c & 0x01) != 0:
  1498. xsv_ext0 = xsb + 2
  1499. xsv_ext1 = xsb + 1
  1500. dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D
  1501. dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D
  1502. else:
  1503. xsv_ext0 = xsv_ext1 = xsb
  1504. dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_4D
  1505. if (c & 0x02) != 0:
  1506. ysv_ext0 = ysv_ext1 = ysb + 1
  1507. dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D
  1508. if (c & 0x01) == 0:
  1509. ysv_ext0 += 1
  1510. dy_ext0 -= 1
  1511. else:
  1512. ysv_ext1 += 1
  1513. dy_ext1 -= 1
  1514. else:
  1515. ysv_ext0 = ysv_ext1 = ysb
  1516. dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_4D
  1517. if (c & 0x04) != 0:
  1518. zsv_ext0 = zsv_ext1 = zsb + 1
  1519. dz_ext0 = dz_ext1 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D
  1520. if (c & 0x03) == 0:
  1521. zsv_ext0 += 1
  1522. dz_ext0 -= 1
  1523. else:
  1524. zsv_ext1 += 1
  1525. dz_ext1 -= 1
  1526. else:
  1527. zsv_ext0 = zsv_ext1 = zsb
  1528. dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_4D
  1529. if (c & 0x08) != 0:
  1530. wsv_ext0 = wsb + 1
  1531. wsv_ext1 = wsb + 2
  1532. dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D
  1533. dw_ext1 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D
  1534. else:
  1535. wsv_ext0 = wsv_ext1 = wsb
  1536. dw_ext0 = dw_ext1 = dw0 - 3 * SQUISH_CONSTANT_4D
  1537. else: # One po on each "side"
  1538. if a_is_bigger_side:
  1539. c1 = a_po
  1540. c2 = b_po
  1541. else:
  1542. c1 = b_po
  1543. c2 = a_po
  1544. # Two contributions are the bigger-sided po with each 1 replaced with 2.
  1545. if (c1 & 0x01) != 0:
  1546. xsv_ext0 = xsb + 2
  1547. xsv_ext1 = xsb + 1
  1548. dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D
  1549. dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D
  1550. else:
  1551. xsv_ext0 = xsv_ext1 = xsb
  1552. dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_4D
  1553. if (c1 & 0x02) != 0:
  1554. ysv_ext0 = ysv_ext1 = ysb + 1
  1555. dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D
  1556. if (c1 & 0x01) == 0:
  1557. ysv_ext0 += 1
  1558. dy_ext0 -= 1
  1559. else:
  1560. ysv_ext1 += 1
  1561. dy_ext1 -= 1
  1562. else:
  1563. ysv_ext0 = ysv_ext1 = ysb
  1564. dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_4D
  1565. if (c1 & 0x04) != 0:
  1566. zsv_ext0 = zsv_ext1 = zsb + 1
  1567. dz_ext0 = dz_ext1 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D
  1568. if (c1 & 0x03) == 0:
  1569. zsv_ext0 += 1
  1570. dz_ext0 -= 1
  1571. else:
  1572. zsv_ext1 += 1
  1573. dz_ext1 -= 1
  1574. else:
  1575. zsv_ext0 = zsv_ext1 = zsb
  1576. dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_4D
  1577. if (c1 & 0x08) != 0:
  1578. wsv_ext0 = wsb + 1
  1579. wsv_ext1 = wsb + 2
  1580. dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D
  1581. dw_ext1 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D
  1582. else:
  1583. wsv_ext0 = wsv_ext1 = wsb
  1584. dw_ext0 = dw_ext1 = dw0 - 3 * SQUISH_CONSTANT_4D
  1585. # One contribution is a _permutation of (1,1,1,-1) based on the smaller-sided po
  1586. xsv_ext2 = xsb + 1
  1587. ysv_ext2 = ysb + 1
  1588. zsv_ext2 = zsb + 1
  1589. wsv_ext2 = wsb + 1
  1590. dx_ext2 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
  1591. dy_ext2 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
  1592. dz_ext2 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
  1593. dw_ext2 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
  1594. if (c2 & 0x01) == 0:
  1595. xsv_ext2 -= 2
  1596. dx_ext2 += 2
  1597. elif (c2 & 0x02) == 0:
  1598. ysv_ext2 -= 2
  1599. dy_ext2 += 2
  1600. elif (c2 & 0x04) == 0:
  1601. zsv_ext2 -= 2
  1602. dz_ext2 += 2
  1603. else:
  1604. wsv_ext2 -= 2
  1605. dw_ext2 += 2
  1606. # Contribution (1,1,1,0)
  1607. dx4 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D
  1608. dy4 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D
  1609. dz4 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D
  1610. dw4 = dw0 - 3 * SQUISH_CONSTANT_4D
  1611. attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4
  1612. if attn4 > 0:
  1613. attn4 *= attn4
  1614. value += attn4 * attn4 * extrapolate(xsb + 1, ysb + 1, zsb + 1, wsb + 0, dx4, dy4, dz4, dw4)
  1615. # Contribution (1,1,0,1)
  1616. dx3 = dx4
  1617. dy3 = dy4
  1618. dz3 = dz0 - 3 * SQUISH_CONSTANT_4D
  1619. dw3 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D
  1620. attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3
  1621. if attn3 > 0:
  1622. attn3 *= attn3
  1623. value += attn3 * attn3 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 1, dx3, dy3, dz3, dw3)
  1624. # Contribution (1,0,1,1)
  1625. dx2 = dx4
  1626. dy2 = dy0 - 3 * SQUISH_CONSTANT_4D
  1627. dz2 = dz4
  1628. dw2 = dw3
  1629. attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2
  1630. if attn2 > 0:
  1631. attn2 *= attn2
  1632. value += attn2 * attn2 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 1, dx2, dy2, dz2, dw2)
  1633. # Contribution (0,1,1,1)
  1634. dx1 = dx0 - 3 * SQUISH_CONSTANT_4D
  1635. dz1 = dz4
  1636. dy1 = dy4
  1637. dw1 = dw3
  1638. attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1
  1639. if attn1 > 0:
  1640. attn1 *= attn1
  1641. value += attn1 * attn1 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 1, dx1, dy1, dz1, dw1)
  1642. # Contribution (1,1,0,0)
  1643. dx5 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
  1644. dy5 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
  1645. dz5 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D
  1646. dw5 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D
  1647. attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5 - dw5 * dw5
  1648. if attn5 > 0:
  1649. attn5 *= attn5
  1650. value += attn5 * attn5 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 0, dx5, dy5, dz5, dw5)
  1651. # Contribution (1,0,1,0)
  1652. dx6 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
  1653. dy6 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D
  1654. dz6 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
  1655. dw6 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D
  1656. attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6 - dw6 * dw6
  1657. if attn6 > 0:
  1658. attn6 *= attn6
  1659. value += attn6 * attn6 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 0, dx6, dy6, dz6, dw6)
  1660. # Contribution (1,0,0,1)
  1661. dx7 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
  1662. dy7 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D
  1663. dz7 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D
  1664. dw7 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
  1665. attn7 = 2 - dx7 * dx7 - dy7 * dy7 - dz7 * dz7 - dw7 * dw7
  1666. if attn7 > 0:
  1667. attn7 *= attn7
  1668. value += attn7 * attn7 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 1, dx7, dy7, dz7, dw7)
  1669. # Contribution (0,1,1,0)
  1670. dx8 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D
  1671. dy8 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
  1672. dz8 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
  1673. dw8 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D
  1674. attn8 = 2 - dx8 * dx8 - dy8 * dy8 - dz8 * dz8 - dw8 * dw8
  1675. if attn8 > 0:
  1676. attn8 *= attn8
  1677. value += attn8 * attn8 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 0, dx8, dy8, dz8, dw8)
  1678. # Contribution (0,1,0,1)
  1679. dx9 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D
  1680. dy9 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
  1681. dz9 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D
  1682. dw9 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
  1683. attn9 = 2 - dx9 * dx9 - dy9 * dy9 - dz9 * dz9 - dw9 * dw9
  1684. if attn9 > 0:
  1685. attn9 *= attn9
  1686. value += attn9 * attn9 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 1, dx9, dy9, dz9, dw9)
  1687. # Contribution (0,0,1,1)
  1688. dx10 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D
  1689. dy10 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D
  1690. dz10 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
  1691. dw10 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
  1692. attn10 = 2 - dx10 * dx10 - dy10 * dy10 - dz10 * dz10 - dw10 * dw10
  1693. if attn10 > 0:
  1694. attn10 *= attn10
  1695. value += attn10 * attn10 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 1, dx10, dy10, dz10, dw10)
  1696. # First extra vertex
  1697. attn_ext0 = 2 - dx_ext0 * dx_ext0 - dy_ext0 * dy_ext0 - dz_ext0 * dz_ext0 - dw_ext0 * dw_ext0
  1698. if attn_ext0 > 0:
  1699. attn_ext0 *= attn_ext0
  1700. value += attn_ext0 * attn_ext0 * extrapolate(xsv_ext0, ysv_ext0, zsv_ext0, wsv_ext0, dx_ext0, dy_ext0, dz_ext0, dw_ext0)
  1701. # Second extra vertex
  1702. attn_ext1 = 2 - dx_ext1 * dx_ext1 - dy_ext1 * dy_ext1 - dz_ext1 * dz_ext1 - dw_ext1 * dw_ext1
  1703. if attn_ext1 > 0:
  1704. attn_ext1 *= attn_ext1
  1705. value += attn_ext1 * attn_ext1 * extrapolate(xsv_ext1, ysv_ext1, zsv_ext1, wsv_ext1, dx_ext1, dy_ext1, dz_ext1, dw_ext1)
  1706. # Third extra vertex
  1707. attn_ext2 = 2 - dx_ext2 * dx_ext2 - dy_ext2 * dy_ext2 - dz_ext2 * dz_ext2 - dw_ext2 * dw_ext2
  1708. if attn_ext2 > 0:
  1709. attn_ext2 *= attn_ext2
  1710. value += attn_ext2 * attn_ext2 * extrapolate(xsv_ext2, ysv_ext2, zsv_ext2, wsv_ext2, dx_ext2, dy_ext2, dz_ext2, dw_ext2)
  1711. return value / NORM_CONSTANT_4D