# OpenSimplexNoise

a guest
Mar 2nd, 2019
190
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1.
2. '/*
3. ' * OpenSimplex Noise in FreeBASIC.
4. ' * by Kurt Spencer
5. ' *
6. ' * v1.1 (October 5, 2014)
7. ' * - Added 2D and 4D implementations.
8. ' * - Proper gradient sets for all dimensions, from a
9. ' *   dimensionally-generalizable scheme with an actual
10. ' *   rhyme and reason behind it.
11. ' * - Removed default permutation array in favor of
12. ' *   default seed.
13. ' * - Changed seed-based constructor to be independent
14. ' *   of any particular randomization library, so results
15. ' *   will be the same when ported to other languages.
16. ' */
17.
18. type OpenSimplexNoise extends INoise
19.     Public:
20.     Declare Constructor()
21.     Declare Constructor(seed As LongInt)
22.     Declare Destructor()
23.     Declare Function noise(x As Double ,y As double) As Double
24.     Declare Function noise(x As Double ,y As Double, z As double) As Double
25.     Declare Function noise(x As Double ,y As double, z As Double, w As Double) As Double
26.     Private:
27.     Declare Function fastfloor(x As double) As Integer
28.     Declare Function extrapolate2(xsb As Integer, ysb As Integer, dx As Double, dy As Double) As Double
29.     Declare Function extrapolate3(xsb As Integer, ysb As Integer, zsb As Integer, dx As Double, dy As Double, dz As Double)As Double
30.     Declare Function extrapolate4(xsb As integer, ysb As Integer, zsb As Integer, wsb As Integer, dx As Double, dy As Double, dz As Double, dw As Double)As Double
31.
32.     dim as double STRETCH_CONSTANT_2D = -0.211324865405187    ''(1/sqr(2+1)-1)/2
33.     dim As double SQUISH_CONSTANT_2D = 0.366025403784439      ''(sqr(2+1)-1)/2
34.     dim As double STRETCH_CONSTANT_3D = -1.0 / 6.0              ''(1/sqr(3+1)-1)/3
35.     dim As double SQUISH_CONSTANT_3D = 1.0 / 3.0                ''(sqr(3+1)-1)/3
36.     dim As double STRETCH_CONSTANT_4D = -0.138196601125011    ''(1/sqr(4+1)-1)/4
37.     dim As double SQUISH_CONSTANT_4D = 0.309016994374947      ''(sqr(4+1)-1)/4
38.
39.     dim As double NORM_CONSTANT_2D = 47
40.     dim As double NORM_CONSTANT_3D = 103
41.     dim As double NORM_CONSTANT_4D = 30
42.
43.     dim as uLongint DEFAULT_SEED = 0
44.
45.     Dim As Short Ptr perm
46.     Dim As Short ptr permGradIndex3D
47.
48.     ''Gradients for 2D. They approximate the directions to the
49.     ''vertices of an octagon from the center.
50.     Dim As byte gradients2D(8,2) = {_
51.     {5,  2},   {2,  5},_
52.     {-5,  2},   {-2,  5},_
53.     {5, -2},    {2, -5},_
54.     {-5, -2},   {-2, -5} _
55.     }
56.
57.     ''Gradients for 3D. They approximate the directions to the
58.     ''vertices of a rhombicuboctahedron from the center, skewed so
59.     ''that the triangular and square facets can be inscribed inside
60.     ''circles of the same radius.
61.     Dim As byte gradients3D(24,3) = {_
62.     {-11,  4,  4},    { -4,  11,  4},   { -4,  4,  11},_
63.     {11,  4,  4},     { 4,  11,  4},    { 4,  4,  11},_
64.     {-11, -4,  4},    { -4, -11,  4},   { -4, -4,  11},_
65.     {11, -4,  4},      {4, -11,  4},     {4, -4,  11},_
66.     {-11,  4, -4},    { -4,  11, -4},   {-4,  4, -11},_
67.     {11,  4, -4},      {4,  11, -4},    { 4,  4, -11},_
68.     {-11, -4, -4},    {-4, -11, -4},    {-4, -4, -11},_
69.     {11, -4, -4},      {4, -11, -4},    { 4, -4, -11} _
70.     }
71.
72.     ''Gradients for 4D. They approximate the directions to the
73.     ''vertices of a disprismatotesseractihexadecachoron from the center,
74.     ''skewed so that the tetrahedral and cubic facets can be inscribed inside
75.     ''spheres of the same radius.
76.     Dim As Byte gradients4D(64,4) = {_
77.     {3,  1,  1,  1},     { 1,  3,  1,  1},     { 1,  1,  3,  1},     { 1,  1,  1,  3},_
78.     {-3,  1,  1,  1},    { -1,  3,  1,  1},    { -1,  1,  3,  1},    { -1,  1,  1,  3},_
79.     {3, -1,  1,  1},     { 1, -3,  1,  1},     { 1, -1,  3,  1},     { 1, -1,  1,  3},_
80.     {-3, -1,  1,  1},    { -1, -3,  1,  1},    { -1, -1,  3,  1},    { -1, -1,  1,  3},_
81.     {3,  1, -1,  1},     { 1,  3, -1,  1},     { 1,  1, -3,  1},     { 1,  1, -1,  3},_
82.     {-3,  1, -1,  1},    { -1,  3, -1,  1},    { -1,  1, -3,  1},    { -1,  1, -1,  3},_
83.     {3, -1, -1,  1},     { 1, -3, -1,  1},     { 1, -1, -3,  1},     { 1, -1, -1,  3},_
84.     {-3, -1, -1,  1},    { -1, -3, -1,  1},    { -1, -1, -3,  1},    { -1, -1, -1,  3},_
85.     {3,  1,  1, -1},      {1,  3,  1, -1},     { 1,  1,  3, -1},     { 1,  1,  1, -3},_
86.     {-3,  1,  1, -1},     {-1,  3,  1, -1},    { -1,  1,  3, -1},    { -1,  1,  1, -3},_
87.     {3, -1,  1, -1},      {1, -3,  1, -1},     { 1, -1,  3, -1},     { 1, -1,  1, -3},_
88.     {-3, -1,  1, -1},     {-1, -3,  1, -1},    { -1, -1,  3, -1},    { -1, -1,  1, -3},_
89.     {3,  1, -1, -1},      {1,  3, -1, -1},     { 1,  1, -3, -1},     { 1,  1, -1, -3},_
90.     {-3,  1, -1, -1},    { -1,  3, -1, -1},    { -1,  1, -3, -1},    { -1,  1, -1, -3},_
91.     {3, -1, -1, -1},     { 1, -3, -1, -1},     { 1, -1, -3, -1},     { 1, -1, -1, -3}, _
92.     {-3, -1, -1, -1},     {-1, -3, -1, -1},    { -1, -1, -3, -1},    { -1, -1, -1, -3} _
93.     }
94. End type
95.
96.
97. Constructor OpenSimplexNoise()
98. Dim seed As ULongInt=DEFAULT_SEED
99. perm = new Short[256]
101. Dim As Short Ptr source = new Short[256]
102. for i As Integer=0 To 255
103.     source[i] = i
104. next
105. seed = seed * 6364136223846793005ull + 1442695040888963407ull
106. seed = seed * 6364136223846793005ull + 1442695040888963407ull
107. seed = seed * 6364136223846793005ull + 1442695040888963407ull
108. for i As Integer=255 To 0 Step -1
109.     seed = seed * 6364136223846793005ull + 1442695040888963407ull
110.     Dim As integer r = Int((seed + 31) Mod (i + 1))
111.     if (r < 0) Then
112.         r += (i + 1)
113.     EndIf
114.     perm[i] = source[r]
115.     permGradIndex3D[i] = Cast(Short,((perm[i] Mod (24)) ))
116.     source[r] = source[i]
117. Next
118. Delete [] source
119. source=0
120. End Constructor
121.
122. ''Initializes the class using a permutation array generated from a 64-bit seed.
123. ''Generates a proper permutation (i.e. doesn't merely perform N successive pair swaps on a base array)
124. ''Uses a simple 64-bit LCG.
125. Constructor OpenSimplexNoise(seed As LongInt)
126. perm = new short[256]
128. Dim As Short Ptr source = new short[256]
129. for i As UInteger=0 To 255
130.     source[i] = i
131. next
132. seed = seed * 6364136223846793005ull + 1442695040888963407ull
133. seed = seed * 6364136223846793005ull + 1442695040888963407ull
134. seed = seed * 6364136223846793005ull + 1442695040888963407ull
135. for i As Integer=255 To 0 Step -1
136.     seed = seed * 6364136223846793005ull + 1442695040888963407ull
137.     Dim As integer r = Int((seed + 31) Mod (i + 1))
138.     if (r < 0) Then
139.         r += (i + 1)
140.     EndIf
141.     perm[i] = source[r]
142.     permGradIndex3D[i] = cast(short,((perm[i] Mod (24)) ))
143.     source[r] = source[i]
144. Next
145. Delete [] source
146. source=0
147. End Constructor
148. Destructor OpenSimplexNoise()
149. Delete [] perm
150. perm=0
153. End Destructor
154. Function OpenSimplexNoise.fastfloor(x As double) As Integer
155.     return IIf(x>=0,Int(x) , Int(x-1))
156. End Function
157. Function OpenSimplexNoise.extrapolate2(xsb As Integer, ysb As Integer, dx As Double, dy As Double) As Double
158.     Dim As integer index = perm[(perm[xsb and &hFF] + ysb) and &hFF] Mod 8
160. End Function
161.
162. Function OpenSimplexNoise.extrapolate3(xsb As Integer, ysb As Integer, zsb As Integer, dx As Double, dy As Double, dz As Double)As Double
163.     Dim As integer index = permGradIndex3D[(perm[(perm[xsb And &hFF] + ysb) And &hFF] + zsb) And &hFF] Mod 24
165. End Function
166.
167. Function OpenSimplexNoise.extrapolate4(xsb As integer, ysb As Integer, zsb As Integer, wsb As Integer, dx As Double, dy As Double, dz As Double, dw As Double)As Double
168.     Dim As integer index = perm[(perm[(perm[(perm[xsb And &hFF] + ysb) And &hFF] + zsb) and &hFF] + wsb) And &hFF] Mod 64
169.     return gradients4D(index,0) * dx + gradients4D(index , 1) * dy + gradients4D(index , 2) * dz + gradients4D(index , 3) * dw
170. End function
171.
172. ''2D OpenSimplex Noise.
173. function  OpenSimplexNoise.noise(x As Double ,y As double) As Double
174.
175.     ''Place input coordinates onto grid.
176.     Dim As Double stretchOffset = (x + y) * STRETCH_CONSTANT_2D
177.     Dim As Double xs = x + stretchOffset
178.     Dim As Double ys = y + stretchOffset
179.
180.     ''Floor to get grid coordinates of rhombus (stretched square) super-cell origin.
181.     Dim As Integer xsb = fastFloor(xs)
182.     Dim As Integer ysb = fastFloor(ys)
183.
184.     ''Skew out to get actual coordinates of rhombus origin. We'll need these later.
185.     Dim As Double squishOffset = (xsb + ysb) * SQUISH_CONSTANT_2D
186.     Dim As Double xb = xsb + squishOffset
187.     Dim As Double yb = ysb + squishOffset
188.
189.     ''Compute grid coordinates relative to rhombus origin.
190.     Dim As Double xins = xs - xsb
191.     Dim As Double yins = ys - ysb
192.
193.     ''Sum those together to get a value that determines which region we're in.
194.     Dim As Double inSum = xins + yins
195.
196.     ''Positions relative to origin point.
197.     Dim As Double dx0 = x - xb
198.     Dim As Double dy0 = y - yb
199.
200.     ''We'll be defining these inside the next block and using them afterwards.
201.     Dim As Double dx_ext, dy_ext
202.     Dim As Integer xsv_ext, ysv_ext
203.
204.     Dim As Double value = 0
205.
206.     ''Contribution (1,0)
207.     Dim As Double dx1 = dx0 - 1.0 - SQUISH_CONSTANT_2D
208.     Dim As Double dy1 = dy0 - 0.0 - SQUISH_CONSTANT_2D
209.     Dim As Double attn1 = 2.0 - (dx1 * dx1) - (dy1 * dy1)
210.     if (attn1 > 0.0) Then
211.         attn1 *= attn1
212.         value += (attn1 * attn1) * extrapolate2(xsb + 1, ysb + 0, dx1, dy1)
213.     EndIf
214.
215.     ''Contribution (0,1)
216.     Dim As Double dx2 = dx0 - 0.0 - SQUISH_CONSTANT_2D
217.     Dim As Double dy2 = dy0 - 1.0 - SQUISH_CONSTANT_2D
218.     Dim As Double attn2 = 2.0 - dx2 * dx2 - dy2 * dy2
219.     if (attn2 > 0) Then
220.         attn2 *= attn2
221.         value += (attn2 * attn2) * extrapolate2(xsb + 0, ysb + 1, dx2, dy2)
222.     endif
223.
224.     if (inSum <= 1.0) then ''We're inside the triangle (2-Simplex) at (0,0)
225.         Dim As Double zins = 1.0 - inSum
226.         if ((zins > xins) or (zins > yins)) then ''(0,0) is one of the closest two triangular vertices
227.             if (xins > yins) Then
228.                 xsv_ext = xsb + 1.0
229.                 ysv_ext = ysb - 1.0
230.                 dx_ext = dx0 - 1.0
231.                 dy_ext = dy0 + 1.0
232.             else
233.                 xsv_ext = xsb - 1.0
234.                 ysv_ext = ysb + 1.0
235.                 dx_ext = dx0 + 1.0
236.                 dy_ext = dy0 - 1.0
237.             EndIf
238.         Else ''(1,0) and (0,1) are the closest two vertices.
239.             xsv_ext = xsb + 1.0
240.             ysv_ext = ysb + 1.0
241.             dx_ext = dx0 - 1.0 - 2.0 * SQUISH_CONSTANT_2D
242.             dy_ext = dy0 - 1.0 - 2.0 * SQUISH_CONSTANT_2D
243.         EndIf
244.     else ''We're inside the triangle (2-Simplex) at (1,1)
245.         Dim As Double zins = 2.0 - inSum
246.         if ((zins < xins) or (zins < yins)) Then ''(0,0) is one of the closest two triangular vertices
247.             if (xins > yins) Then
248.                 xsv_ext = xsb + 2.0
249.                 ysv_ext = ysb + 0.0
250.                 dx_ext = dx0 - 2.0 - 2.0 * SQUISH_CONSTANT_2D
251.                 dy_ext = dy0 + 0.0 - 2.0 * SQUISH_CONSTANT_2D
252.             Else
253.                 xsv_ext = xsb + 0.0
254.                 ysv_ext = ysb + 2.0
255.                 dx_ext = dx0 + 0.0 - 2.0 * SQUISH_CONSTANT_2D
256.                 dy_ext = dy0 - 2.0 - 2.0 * SQUISH_CONSTANT_2D
257.             endif
258.         else  ''(1,0) and (0,1) are the closest two vertices.
259.             dx_ext = dx0
260.             dy_ext = dy0
261.             xsv_ext = xsb
262.             ysv_ext = ysb
263.         EndIf
264.         xsb += 1.0
265.         ysb += 1.0
266.         dx0 = dx0 - 1.0 - 2.0 * SQUISH_CONSTANT_2D
267.         dy0 = dy0 - 1.0 - 2.0 * SQUISH_CONSTANT_2D
268.     EndIf
269.
270.     ''Contribution (0,0) or (1,1)
271.     Dim As Double attn0 = 2.0 - dx0 * dx0 - dy0 * dy0
272.     if (attn0 > 0.0) Then
273.         attn0 *= attn0
274.         value += (attn0 * attn0) * extrapolate2(xsb, ysb, dx0, dy0)
275.     EndIf
276.
277.     ''Extra Vertex
278.     Dim As Double attn_ext = 2.0 - dx_ext * dx_ext - dy_ext * dy_ext
279.     if (attn_ext > 0.0)Then
280.         attn_ext *= attn_ext
281.         value += (attn_ext * attn_ext) * extrapolate2(xsv_ext, ysv_ext, dx_ext, dy_ext)
282.     endif
283.     value/=NORM_CONSTANT_2D
284.     return value
285. End Function
286.
287. ''3D OpenSimplex Noise.
288. Function OpenSimplexNoise.noise(x As Double ,y As Double, z As double) As Double
289.
290.     ''Place input coordinates on simplectic honeycomb.
291.     Dim As Double stretchOffset = (x + y + z) * STRETCH_CONSTANT_3D
292.     Dim As Double xs = x + stretchOffset
293.     Dim As Double ys = y + stretchOffset
294.     Dim As Double zs = z + stretchOffset
295.
296.     ''Floor to get simplectic honeycomb coordinates of rhombohedron (stretched cube) super-cell origin.
297.     Dim As integer xsb = fastFloor(xs)
298.     Dim As Integer ysb = fastFloor(ys)
299.     Dim As Integer zsb = fastFloor(zs)
300.
301.     ''Skew out to get actual coordinates of rhombohedron origin. We'll need these later.
302.     Dim As Double squishOffset = (xsb + ysb + zsb) * SQUISH_CONSTANT_3D
303.     Dim As Double xb = xsb + squishOffset
304.     Dim As Double yb = ysb + squishOffset
305.     Dim As Double zb = zsb + squishOffset
306.
307.     ''Compute simplectic honeycomb coordinates relative to rhombohedral origin.
308.     Dim As Double xins = xs - xsb
309.     Dim As Double yins = ys - ysb
310.     Dim As Double zins = zs - zsb
311.
312.     ''Sum those together to get a value that determines which region we're in.
313.     Dim As Double inSum = xins + yins + zins
314.
315.     ''Positions relative to origin point.
316.     Dim As Double dx0 = x - xb
317.     Dim As Double dy0 = y - yb
318.     Dim As Double dz0 = z - zb
319.
320.     ''We'll be defining these inside the next block and using them afterwards.
321.     Dim As Double dx_ext0, dy_ext0, dz_ext0
322.     Dim As Double dx_ext1, dy_ext1, dz_ext1
323.     Dim As Integer xsv_ext0, ysv_ext0, zsv_ext0
324.     Dim As Integer xsv_ext1, ysv_ext1, zsv_ext1
325.
326.     Dim As Double value = 0
327.     if (inSum <= 1) Then ''We're inside the tetrahedron (3-Simplex) at (0,0,0)
328.
329.         ''Determine which two of (0,0,1), (0,1,0), (1,0,0) are closest.
330.         Dim As Byte aPoint = &h01
331.         Dim As Double aScore = xins
332.         Dim As Byte bPoint = &h02
333.         Dim As Double bScore = yins
334.         if (aScore >= bScore And zins > bScore) Then
335.             bScore = zins
336.             bPoint = &h04
337.         elseif (aScore < bScore and zins > aScore) Then
338.             aScore = zins
339.             aPoint = &h04
340.         endif
341.
342.         ''Now we determine the two lattice points not part of the tetrahedron that may contribute.
343.         ''This depends on the closest two tetrahedral vertices, including (0,0,0)
344.         Dim As Double wins = 1 - inSum
345.         if (wins > aScore Or wins > bScore) Then ''(0,0,0) is one of the closest two tetrahedral vertices.
346.             Dim As Byte c = iif(bScore > aScore , bPoint , aPoint) ''Our other closest vertex is the closest out of a and b.
347.
348.             if ((c and &h01) = 0) Then
349.                 xsv_ext0 = xsb - 1
350.                 xsv_ext1 = xsb
351.                 dx_ext0 = dx0 + 1
352.                 dx_ext1 = dx0
353.             Else
354.                 xsv_ext0 = xsv_ext1 = xsb + 1
355.                 dx_ext0 = dx_ext1 = dx0 - 1
356.             endif
357.
358.             if ((c and &h02) = 0) Then
359.                 ysv_ext0 = ysv_ext1 = ysb
360.                 dy_ext0 = dy_ext1 = dy0
361.                 if ((c and &h01) = 0) Then
362.                     ysv_ext1 -= 1
363.                     dy_ext1 += 1
364.                 Else
365.                     ysv_ext0 -= 1
366.                     dy_ext0 += 1
367.                 endif
368.             Else
369.                 ysv_ext0 = ysv_ext1 = ysb + 1
370.                 dy_ext0 = dy_ext1 = dy0 - 1
371.             EndIf
372.
373.             if ((c and &h04) = 0) then
374.                 zsv_ext0 = zsb
375.                 zsv_ext1 = zsb - 1
376.                 dz_ext0 = dz0
377.                 dz_ext1 = dz0 + 1
378.             Else
379.                 zsv_ext0 = zsv_ext1 = zsb + 1
380.                 dz_ext0 = dz_ext1 = dz0 - 1
381.             EndIf
382.         Else ''(0,0,0) is not one of the closest two tetrahedral vertices.
383.             Dim As Byte c = aPoint And bPoint'cast(Byte,(aPoint or bPoint)) ''Our two extra vertices are determined by the closest two.
384.
385.             if ((c and &h01) = 0) Then
386.                 xsv_ext0 = xsb
387.                 xsv_ext1 = xsb - 1
388.                 dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_3D
389.                 dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_3D
390.             Else
391.                 xsv_ext0 = xsv_ext1 = xsb + 1
392.                 dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D
393.                 dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D
394.             EndIf
395.
396.             if ((c and &h02) = 0) Then
397.                 ysv_ext0 = ysb
398.                 ysv_ext1 = ysb - 1
399.                 dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_3D
400.                 dy_ext1 = dy0 + 1 - SQUISH_CONSTANT_3D
401.             Else
402.                 ysv_ext0 = ysv_ext1 = ysb + 1
403.                 dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D
404.                 dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D
405.             EndIf
406.
407.             if ((c and &h04) = 0) Then
408.                 zsv_ext0 = zsb
409.                 zsv_ext1 = zsb - 1
410.                 dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_3D
411.                 dz_ext1 = dz0 + 1 - SQUISH_CONSTANT_3D
412.             Else
413.                 zsv_ext0 = zsv_ext1 = zsb + 1
414.                 dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D
415.                 dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D
416.             endif
417.         endif
418.
419.         ''Contribution (0,0,0)
420.         Dim As Double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0
421.         if (attn0 > 0) Then
422.             attn0 *= attn0
423.             value += attn0 * attn0 * extrapolate3(xsb + 0, ysb + 0, zsb + 0, dx0, dy0, dz0)
424.         endif
425.
426.         ''Contribution (1,0,0)
427.         Dim As Double dx1 = dx0 - 1 - SQUISH_CONSTANT_3D
428.         Dim As Double dy1 = dy0 - 0 - SQUISH_CONSTANT_3D
429.         Dim As Double dz1 = dz0 - 0 - SQUISH_CONSTANT_3D
430.         Dim As Double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1
431.         if (attn1 > 0) Then
432.             attn1 *= attn1
433.             value += attn1 * attn1 * extrapolate3(xsb + 1, ysb + 0, zsb + 0, dx1, dy1, dz1)
434.         EndIf
435.
436.         ''Contribution (0,1,0)
437.         Dim As Double dx2 = dx0 - 0 - SQUISH_CONSTANT_3D
438.         Dim As Double dy2 = dy0 - 1 - SQUISH_CONSTANT_3D
439.         Dim As Double dz2 = dz1
440.         Dim As Double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2
441.         if (attn2 > 0) Then
442.             attn2 *= attn2
443.             value += attn2 * attn2 * extrapolate3(xsb + 0, ysb + 1, zsb + 0, dx2, dy2, dz2)
444.         EndIf
445.
446.         ''Contribution (0,0,1)
447.         Dim As Double dx3 = dx2
448.         Dim As Double dy3 = dy1
449.         Dim As Double dz3 = dz0 - 1 - SQUISH_CONSTANT_3D
450.         Dim As Double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3
451.         if (attn3 > 0) Then
452.             attn3 *= attn3
453.             value += attn3 * attn3 * extrapolate3(xsb + 0, ysb + 0, zsb + 1, dx3, dy3, dz3)
454.         EndIf
455.     ElseIf (inSum >= 2) Then ''We're inside the tetrahedron (3-Simplex) at (1,1,1)
456.
457.         ''Determine which two tetrahedral vertices are the closest, out of (1,1,0), (1,0,1), (0,1,1) but not (1,1,1).
458.         Dim As Byte aPoint = &h06
459.         Dim As Double aScore = xins
460.         Dim As Byte bPoint = &h05
461.         Dim As Double bScore = yins
462.         if (aScore <= bScore And zins < bScore) Then
463.             bScore = zins
464.             bPoint = &h03
465.         elseif (aScore > bScore And zins < aScore) Then
466.             aScore = zins
467.             aPoint = &h03
468.         endif
469.
470.         ''Now we determine the two lattice points not part of the tetrahedron that may contribute.
471.         ''This depends on the closest two tetrahedral vertices, including (1,1,1)
472.         Dim As Double wins = 3 - inSum
473.         if (wins < aScore Or wins < bScore) Then ''(1,1,1) is one of the closest two tetrahedral vertices.
474.             Dim As uByte c = iif(bScore < aScore , bPoint , aPoint) ''Our other closest vertex is the closest out of a and b.
475.
476.             if ((c and &h01) <> 0) then
477.                 xsv_ext0 = xsb + 2
478.                 xsv_ext1 = xsb + 1
479.                 dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_3D
480.                 dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D
481.             Else
482.                 xsv_ext0 = xsv_ext1 = xsb
483.                 dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_3D
484.             EndIf
485.
486.             if ((c and &h02) <> 0) Then
487.                 ysv_ext0 = ysv_ext1 = ysb + 1
488.                 dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D
489.                 if ((c and &h01) <> 0) Then
490.                     ysv_ext1 += 1
491.                     dy_ext1 -= 1
492.                 Else
493.                     ysv_ext0 += 1
494.                     dy_ext0 -= 1
495.                 EndIf
496.             Else
497.                 ysv_ext0 = ysv_ext1 = ysb
498.                 dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_3D
499.             endif
500.
501.             if ((c and &h04) <> 0) Then
502.                 zsv_ext0 = zsb + 1
503.                 zsv_ext1 = zsb + 2
504.                 dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D
505.                 dz_ext1 = dz0 - 2 - 3 * SQUISH_CONSTANT_3D
506.             Else
507.                 zsv_ext0 = zsv_ext1 = zsb
508.                 dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_3D
509.             EndIf
510.         Else ''(1,1,1) is not one of the closest two tetrahedral vertices.
511.             Dim As Byte c = aPoint And bPoint'cast(byte,(aPoint And bPoint)) ''Our two extra vertices are determined by the closest two.
512.
513.             if ((c and &h01) <> 0) Then
514.                 xsv_ext0 = xsb + 1
515.                 xsv_ext1 = xsb + 2
516.                 dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D
517.                 dx_ext1 = dx0 - 2 - 2 * SQUISH_CONSTANT_3D
518.             Else
519.                 xsv_ext0 = xsv_ext1 = xsb
520.                 dx_ext0 = dx0 - SQUISH_CONSTANT_3D
521.                 dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D
522.             EndIf
523.
524.             if ((c and &h02) <> 0) Then
525.                 ysv_ext0 = ysb + 1
526.                 ysv_ext1 = ysb + 2
527.                 dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D
528.                 dy_ext1 = dy0 - 2 - 2 * SQUISH_CONSTANT_3D
529.             Else
530.                 ysv_ext0 = ysv_ext1 = ysb
531.                 dy_ext0 = dy0 - SQUISH_CONSTANT_3D
532.                 dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D
533.             EndIf
534.
535.             if ((c and &h04) <> 0) Then
536.                 zsv_ext0 = zsb + 1
537.                 zsv_ext1 = zsb + 2
538.                 dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D
539.                 dz_ext1 = dz0 - 2 - 2 * SQUISH_CONSTANT_3D
540.             Else
541.                 zsv_ext0 = zsv_ext1 = zsb
542.                 dz_ext0 = dz0 - SQUISH_CONSTANT_3D
543.                 dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D
544.             EndIf
545.         endif
546.
547.         ''Contribution (1,1,0)
548.         Dim As Double dx3 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D
549.         Dim As Double dy3 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D
550.         Dim As Double dz3 = dz0 - 0 - 2 * SQUISH_CONSTANT_3D
551.         Dim As Double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3
552.         if (attn3 > 0) Then
553.             attn3 *= attn3
554.             value += attn3 * attn3 * extrapolate3(xsb + 1, ysb + 1, zsb + 0, dx3, dy3, dz3)
555.         EndIf
556.
557.         ''Contribution (1,0,1)
558.         Dim As Double dx2 = dx3
559.         Dim As Double dy2 = dy0 - 0 - 2 * SQUISH_CONSTANT_3D
560.         Dim As Double dz2 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D
561.         Dim As Double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2
562.         if (attn2 > 0) Then
563.             attn2 *= attn2
564.             value += attn2 * attn2 * extrapolate3(xsb + 1, ysb + 0, zsb + 1, dx2, dy2, dz2)
565.         EndIf
566.
567.         ''Contribution (0,1,1)
568.         Dim As Double dx1 = dx0 - 0 - 2 * SQUISH_CONSTANT_3D
569.         Dim As Double dy1 = dy3
570.         Dim As Double dz1 = dz2
571.         Dim As Double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1
572.         if (attn1 > 0) Then
573.             attn1 *= attn1
574.             value += attn1 * attn1 * extrapolate3(xsb + 0, ysb + 1, zsb + 1, dx1, dy1, dz1)
575.         endif
576.
577.         ''Contribution (1,1,1)
578.         dx0 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D
579.         dy0 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D
580.         dz0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D
581.         Dim As Double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0
582.         if (attn0 > 0) Then
583.             attn0 *= attn0
584.             value += attn0 * attn0 * extrapolate3(xsb + 1, ysb + 1, zsb + 1, dx0, dy0, dz0)
585.         EndIf
586.     Else  ''We're inside the octahedron (Rectified 3-Simplex) in between.
587.         Dim As Double aScore
588.         Dim As Byte aPoint
589.         Dim As boolean aIsFurtherSide=FALSE
590.         Dim As Double bScore
591.         Dim As Byte bPoint
592.         Dim As boolean bIsFurtherSide=FALSE
593.
594.         ''Decide between point (0,0,1) and (1,1,0) as closest
595.         Dim As Double p1 = xins + yins
596.         if (p1 > 1) Then
597.             aScore = p1 - 1
598.             aPoint = &h03
599.             aIsFurtherSide = TRUE
600.         Else
601.             aScore = 1 - p1
602.             aPoint = &h04
603.             aIsFurtherSide = FALSE
604.         EndIf
605.
606.         ''Decide between point (0,1,0) and (1,0,1) as closest
607.         Dim As Double p2 = xins + zins
608.         if (p2 > 1) Then
609.             bScore = p2 - 1
610.             bPoint = &h05
611.             bIsFurtherSide = TRUE
612.         else
613.             bScore = 1 - p2
614.             bPoint = &h02
615.             bIsFurtherSide = FALSE
616.         EndIf
617.
618.         ''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.
619.         Dim As Double p3 = yins + zins
620.         if (p3 > 1) Then
621.             Dim As Double score = p3 - 1
622.             if (aScore <= bScore And aScore < score) Then
623.                 aScore = score
624.                 aPoint = &h06
625.                 aIsFurtherSide = TRUE
626.             elseif (aScore > bScore And bScore < score) Then
627.                 bScore = score
628.                 bPoint = &h06
629.                 bIsFurtherSide = TRUE
630.             EndIf
631.         Else
632.             Dim As Double score = 1 - p3
633.             if (aScore <= bScore And aScore < score) Then
634.                 aScore = score
635.                 aPoint = &h01
636.                 aIsFurtherSide = FALSE
637.             ElseIf (aScore > bScore And bScore < score) Then
638.                 bScore = score
639.                 bPoint = &h01
640.                 bIsFurtherSide = FALSE
641.             EndIf
642.         endif
643.
644.         ''Where each of the two closest points are determines how the extra two vertices are calculated.
645.         if (aIsFurtherSide = bIsFurtherSide) Then
646.             if (aIsFurtherSide) Then ''Both closest points on (1,1,1) side
647.
648.                 ''One of the two extra points is (1,1,1)
649.                 dx_ext0 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D
650.                 dy_ext0 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D
651.                 dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D
652.                 xsv_ext0 = xsb + 1
653.                 ysv_ext0 = ysb + 1
654.                 zsv_ext0 = zsb + 1
655.
656.                 ''Other extra point is based on the shared axis.
657.                 Dim As Byte c = aPoint And bPoint'cast(byte,(aPoint And bPoint))
658.                 if ((c and &h01) <> 0) Then
659.                     dx_ext1 = dx0 - 2 - 2 * SQUISH_CONSTANT_3D
660.                     dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D
661.                     dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D
662.                     xsv_ext1 = xsb + 2
663.                     ysv_ext1 = ysb
664.                     zsv_ext1 = zsb
665.                 elseif ((c and &h02) <> 0) Then
666.                     dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D
667.                     dy_ext1 = dy0 - 2 - 2 * SQUISH_CONSTANT_3D
668.                     dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D
669.                     xsv_ext1 = xsb
670.                     ysv_ext1 = ysb + 2
671.                     zsv_ext1 = zsb
672.                 Else
673.                     dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D
674.                     dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D
675.                     dz_ext1 = dz0 - 2 - 2 * SQUISH_CONSTANT_3D
676.                     xsv_ext1 = xsb
677.                     ysv_ext1 = ysb
678.                     zsv_ext1 = zsb + 2
679.                 EndIf
680.             Else''Both closest points on (0,0,0) side
681.
682.                 ''One of the two extra points is (0,0,0)
683.                 dx_ext0 = dx0
684.                 dy_ext0 = dy0
685.                 dz_ext0 = dz0
686.                 xsv_ext0 = xsb
687.                 ysv_ext0 = ysb
688.                 zsv_ext0 = zsb
689.
690.                 ''Other extra point is based on the omitted axis.
691.                 Dim As Byte c = aPoint And bPoint'cast(byte,(aPoint or bPoint))
692.                 if ((c and &h01) = 0) Then
693.                     dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_3D
694.                     dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D
695.                     dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D
696.                     xsv_ext1 = xsb - 1
697.                     ysv_ext1 = ysb + 1
698.                     zsv_ext1 = zsb + 1
699.                 ElseIf ((c and &h02) = 0) then
700.                     dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D
701.                     dy_ext1 = dy0 + 1 - SQUISH_CONSTANT_3D
702.                     dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D
703.                     xsv_ext1 = xsb + 1
704.                     ysv_ext1 = ysb - 1
705.                     zsv_ext1 = zsb + 1
706.                 Else
707.                     dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D
708.                     dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D
709.                     dz_ext1 = dz0 + 1 - SQUISH_CONSTANT_3D
710.                     xsv_ext1 = xsb + 1
711.                     ysv_ext1 = ysb + 1
712.                     zsv_ext1 = zsb - 1
713.                 EndIf
714.             EndIf
715.         Else ''One point on (0,0,0) side, one point on (1,1,1) side
716.             Dim As Byte c1, c2
717.             if (aIsFurtherSide) Then
718.                 c1 = aPoint
719.                 c2 = bPoint
720.             Else
721.                 c1 = bPoint
722.                 c2 = aPoint
723.             endif
724.
725.             ''One contribution is a permutation of (1,1,-1)
726.             if ((c1 and &h01) = 0) Then
727.                 dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_3D
728.                 dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D
729.                 dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D
730.                 xsv_ext0 = xsb - 1
731.                 ysv_ext0 = ysb + 1
732.                 zsv_ext0 = zsb + 1
733.             elseif ((c1 and &h02) = 0) Then
734.                 dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D
735.                 dy_ext0 = dy0 + 1 - SQUISH_CONSTANT_3D
736.                 dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D
737.                 xsv_ext0 = xsb + 1
738.                 ysv_ext0 = ysb - 1
739.                 zsv_ext0 = zsb + 1
740.             Else
741.                 dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D
742.                 dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D
743.                 dz_ext0 = dz0 + 1 - SQUISH_CONSTANT_3D
744.                 xsv_ext0 = xsb + 1
745.                 ysv_ext0 = ysb + 1
746.                 zsv_ext0 = zsb - 1
747.             endif
748.
749.             ''One contribution is a permutation of (0,0,2)
750.             dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D
751.             dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D
752.             dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D
753.             xsv_ext1 = xsb
754.             ysv_ext1 = ysb
755.             zsv_ext1 = zsb
756.             if ((c2 and &h01) <> 0) Then
757.                 dx_ext1 -= 2
758.                 xsv_ext1 += 2
759.             elseif ((c2 and &h02) <> 0) Then
760.                 dy_ext1 -= 2
761.                 ysv_ext1 += 2
762.             Else
763.                 dz_ext1 -= 2
764.                 zsv_ext1 += 2
765.             EndIf
766.         endif
767.
768.         ''Contribution (1,0,0)
769.         Dim As Double dx1 = dx0 - 1 - SQUISH_CONSTANT_3D
770.         Dim As Double dy1 = dy0 - 0 - SQUISH_CONSTANT_3D
771.         Dim As Double dz1 = dz0 - 0 - SQUISH_CONSTANT_3D
772.         Dim As Double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1
773.         if (attn1 > 0) Then
774.             attn1 *= attn1
775.             value += attn1 * attn1 * extrapolate3(xsb + 1, ysb + 0, zsb + 0, dx1, dy1, dz1)
776.         EndIf
777.
778.         ''Contribution (0,1,0)
779.         Dim As Double dx2 = dx0 - 0 - SQUISH_CONSTANT_3D
780.         Dim As Double dy2 = dy0 - 1 - SQUISH_CONSTANT_3D
781.         Dim As Double dz2 = dz1
782.         Dim As Double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2
783.         if (attn2 > 0) Then
784.             attn2 *= attn2
785.             value += attn2 * attn2 * extrapolate3(xsb + 0, ysb + 1, zsb + 0, dx2, dy2, dz2)
786.         EndIf
787.
788.         ''Contribution (0,0,1)
789.         Dim As Double dx3 = dx2
790.         Dim As Double dy3 = dy1
791.         Dim As Double dz3 = dz0 - 1 - SQUISH_CONSTANT_3D
792.         Dim As Double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3
793.         if (attn3 > 0) Then
794.             attn3 *= attn3
795.             value += attn3 * attn3 * extrapolate3(xsb + 0, ysb + 0, zsb + 1, dx3, dy3, dz3)
796.         EndIf
797.
798.         ''Contribution (1,1,0)
799.         Dim As Double dx4 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D
800.         Dim As Double dy4 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D
801.         Dim As Double dz4 = dz0 - 0 - 2 * SQUISH_CONSTANT_3D
802.         Dim As Double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4
803.         if (attn4 > 0) Then
804.             attn4 *= attn4
805.             value += attn4 * attn4 * extrapolate3(xsb + 1, ysb + 1, zsb + 0, dx4, dy4, dz4)
806.         EndIf
807.
808.         ''Contribution (1,0,1)
809.         Dim As Double dx5 = dx4
810.         Dim As Double dy5 = dy0 - 0 - 2 * SQUISH_CONSTANT_3D
811.         Dim As Double dz5 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D
812.         Dim As Double attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5
813.         if (attn5 > 0) Then
814.             attn5 *= attn5
815.             value += attn5 * attn5 * extrapolate3(xsb + 1, ysb + 0, zsb + 1, dx5, dy5, dz5)
816.         EndIf
817.
818.         ''Contribution (0,1,1)
819.         Dim As Double dx6 = dx0 - 0 - 2 * SQUISH_CONSTANT_3D
820.         Dim As Double dy6 = dy4
821.         Dim As Double dz6 = dz5
822.         Dim As Double attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6
823.         if (attn6 > 0) Then
824.             attn6 *= attn6
825.             value += attn6 * attn6 * extrapolate3(xsb + 0, ysb + 1, zsb + 1, dx6, dy6, dz6)
826.         endif
827.     EndIf
828.
829.     ''First extra vertex
830.     Dim As Double attn_ext0 = 2 - dx_ext0 * dx_ext0 - dy_ext0 * dy_ext0 - dz_ext0 * dz_ext0
831.     if (attn_ext0 > 0) then
832.         attn_ext0 *= attn_ext0
833.         value += attn_ext0 * attn_ext0 * extrapolate3(xsv_ext0, ysv_ext0, zsv_ext0, dx_ext0, dy_ext0, dz_ext0)
834.     EndIf
835.
836.     ''Second extra vertex
837.     Dim As Double attn_ext1 = 2 - dx_ext1 * dx_ext1 - dy_ext1 * dy_ext1 - dz_ext1 * dz_ext1
838.     if (attn_ext1 > 0) Then
839.         attn_ext1 *= attn_ext1
840.         value += attn_ext1 * attn_ext1 * extrapolate3(xsv_ext1, ysv_ext1, zsv_ext1, dx_ext1, dy_ext1, dz_ext1)
841.     EndIf
842.     value/=NORM_CONSTANT_3D
843.     return value
844. End Function
845.
846. ''4D OpenSimplex Noise.
847. Function OpenSimplexNoise.noise(x As Double ,y As double, z As Double, w As Double) As Double
848.
849.     ''Place input coordinates on simplectic honeycomb.
850.     Dim As Double stretchOffset = (x + y + z + w) * STRETCH_CONSTANT_4D
851.     Dim As Double xs = x + stretchOffset
852.     Dim As Double ys = y + stretchOffset
853.     Dim As Double zs = z + stretchOffset
854.     Dim As Double ws = w + stretchOffset
855.
856.     ''Floor to get simplectic honeycomb coordinates of rhombo-hypercube super-cell origin.
857.     Dim As Integer xsb = fastFloor(xs)
858.     Dim As Integer ysb = fastFloor(ys)
859.     Dim As Integer zsb = fastFloor(zs)
860.     Dim As Integer wsb = fastFloor(ws)
861.
862.     ''Skew out to get actual coordinates of stretched rhombo-hypercube origin. We'll need these later.
863.     Dim As Double squishOffset = (xsb + ysb + zsb + wsb) * SQUISH_CONSTANT_4D
864.     Dim As Double xb = xsb + squishOffset
865.     Dim As Double yb = ysb + squishOffset
866.     Dim As Double zb = zsb + squishOffset
867.     Dim As Double wb = wsb + squishOffset
868.
869.     ''Compute simplectic honeycomb coordinates relative to rhombo-hypercube origin.
870.     Dim As Double xins = xs - xsb
871.     Dim As Double yins = ys - ysb
872.     Dim As Double zins = zs - zsb
873.     Dim As Double wins = ws - wsb
874.
875.     ''Sum those together to get a value that determines which region we're in.
876.     Dim As Double inSum = xins + yins + zins + wins
877.
878.     ''Positions relative to origin point.
879.     Dim As Double dx0 = x - xb
880.     Dim As Double dy0 = y - yb
881.     Dim As Double dz0 = z - zb
882.     Dim As Double dw0 = w - wb
883.
884.     ''We'll be defining these inside the next block and using them afterwards.
885.     Dim As Double dx_ext0, dy_ext0, dz_ext0, dw_ext0
886.     Dim As Double dx_ext1, dy_ext1, dz_ext1, dw_ext1
887.     Dim As Double dx_ext2, dy_ext2, dz_ext2, dw_ext2
888.     Dim As Integer xsv_ext0, ysv_ext0, zsv_ext0, wsv_ext0
889.     Dim As Integer xsv_ext1, ysv_ext1, zsv_ext1, wsv_ext1
890.     Dim As Integer xsv_ext2, ysv_ext2, zsv_ext2, wsv_ext2
891.
892.     Dim As Double value = 0
893.     if (inSum <= 1) Then ''We're inside the pentachoron (4-Simplex) at (0,0,0,0)
894.
895.         ''Determine which two of (0,0,0,1), (0,0,1,0), (0,1,0,0), (1,0,0,0) are closest.
896.         Dim As Byte aPoint = &h01
897.         Dim As Double aScore = xins
898.         Dim As Byte bPoint = &h02
899.         Dim As Double bScore = yins
900.         if (aScore >= bScore And zins > bScore) Then
901.             bScore = zins
902.             bPoint = &h04
903.         elseif (aScore < bScore And zins > aScore) Then
904.             aScore = zins
905.             aPoint = &h04
906.         EndIf
907.         if (aScore >= bScore And wins > bScore) Then
908.             bScore = wins
909.             bPoint = &h08
910.         ElseIf (aScore < bScore And wins > aScore) then
911.             aScore = wins
912.             aPoint = &h08
913.         endif
914.
915.         ''Now we determine the three lattice points not part of the pentachoron that may contribute.
916.         ''This depends on the closest two pentachoron vertices, including (0,0,0,0)
917.         Dim As Double uins = 1 - inSum
918.         if (uins > aScore Or uins > bScore) Then ''(0,0,0,0) is one of the closest two pentachoron vertices.
919.             Dim As Byte c = iif(bScore > aScore , bPoint , aPoint) ''Our other closest vertex is the closest out of a and b.
920.             if ((c and &h01) = 0) Then
921.                 xsv_ext0 = xsb - 1
922.                 xsv_ext1 = xsv_ext2 = xsb
923.                 dx_ext0 = dx0 + 1
924.                 dx_ext1 = dx_ext2 = dx0
925.             Else
926.                 xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb + 1
927.                 dx_ext0 = dx_ext1 = dx_ext2 = dx0 - 1
928.             EndIf
929.
930.             if ((c and &h02) = 0) Then
931.                 ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb
932.                 dy_ext0 = dy_ext1 = dy_ext2 = dy0
933.                 if ((c and &h01) = &h01) Then
934.                     ysv_ext0 -= 1
935.                     dy_ext0 += 1
936.                 Else
937.                     ysv_ext1 -= 1
938.                     dy_ext1 += 1
939.                 EndIf
940.             Else
941.                 ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1
942.                 dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 1
943.             EndIf
944.
945.             if ((c and &h04) = 0) Then
946.                 zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb
947.                 dz_ext0 = dz_ext1 = dz_ext2 = dz0
948.                 if ((c and &h03) <> 0) Then
949.                     if ((c and &h03) = &h03) Then
950.                         zsv_ext0 -= 1
951.                         dz_ext0 += 1
952.                     Else
953.                         zsv_ext1 -= 1
954.                         dz_ext1 += 1
955.                     EndIf
956.                 Else
957.                     zsv_ext2 -= 1
958.                     dz_ext2 += 1
959.                 EndIf
960.             Else
961.                 zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1
962.                 dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 1
963.             EndIf
964.
965.             if ((c and &h08) = 0) Then
966.                 wsv_ext0 = wsv_ext1 = wsb
967.                 wsv_ext2 = wsb - 1
968.                 dw_ext0 = dw_ext1 = dw0
969.                 dw_ext2 = dw0 + 1
970.             Else
971.                 wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb + 1
972.                 dw_ext0 = dw_ext1 = dw_ext2 = dw0 - 1
973.             EndIf
974.         Else ''(0,0,0,0) is not one of the closest two pentachoron vertices.
975.             Dim As Byte c = cast(Byte,(aPoint or bPoint)) ''Our three extra vertices are determined by the closest two.
976.
977.             if ((c and &h01) = 0) Then
978.                 xsv_ext0 = xsv_ext2 = xsb
979.                 xsv_ext1 = xsb - 1
980.                 dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_4D
981.                 dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_4D
982.                 dx_ext2 = dx0 - SQUISH_CONSTANT_4D
983.             Else
984.                 xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb + 1
985.                 dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
986.                 dx_ext1 = dx_ext2 = dx0 - 1 - SQUISH_CONSTANT_4D
987.             EndIf
988.
989.             if ((c and &h02) = 0) Then
990.                 ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb
991.                 dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_4D
992.                 dy_ext1 = dy_ext2 = dy0 - SQUISH_CONSTANT_4D
993.                 if ((c and &h01) = &h01) Then
994.                     ysv_ext1 -= 1
995.                     dy_ext1 += 1
996.                 Else
997.                     ysv_ext2 -= 1
998.                     dy_ext2 += 1
999.                 EndIf
1000.             Else
1001.                 ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1
1002.                 dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
1003.                 dy_ext1 = dy_ext2 = dy0 - 1 - SQUISH_CONSTANT_4D
1004.             EndIf
1005.
1006.             if ((c and &h04) = 0) Then
1007.                 zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb
1008.                 dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_4D
1009.                 dz_ext1 = dz_ext2 = dz0 - SQUISH_CONSTANT_4D
1010.                 if ((c and &h03) = &h03) Then
1011.                     zsv_ext1 -= 1
1012.                     dz_ext1 += 1
1013.                 Else
1014.                     zsv_ext2 -= 1
1015.                     dz_ext2 += 1
1016.                 EndIf
1017.             Else
1018.                 zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1
1019.                 dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
1020.                 dz_ext1 = dz_ext2 = dz0 - 1 - SQUISH_CONSTANT_4D
1021.             EndIf
1022.
1023.             if ((c and &h08) = 0) Then
1024.                 wsv_ext0 = wsv_ext1 = wsb
1025.                 wsv_ext2 = wsb - 1
1026.                 dw_ext0 = dw0 - 2 * SQUISH_CONSTANT_4D
1027.                 dw_ext1 = dw0 - SQUISH_CONSTANT_4D
1028.                 dw_ext2 = dw0 + 1 - SQUISH_CONSTANT_4D
1029.             Else
1030.                 wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb + 1
1031.                 dw_ext0 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
1032.                 dw_ext1 = dw_ext2 = dw0 - 1 - SQUISH_CONSTANT_4D
1033.             EndIf
1034.         endif
1035.
1036.         ''Contribution (0,0,0,0)
1037.         Dim As Double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0 - dw0 * dw0
1038.         if (attn0 > 0) Then
1039.             attn0 *= attn0
1040.             value += attn0 * attn0 * extrapolate4(xsb + 0, ysb + 0, zsb + 0, wsb + 0, dx0, dy0, dz0, dw0)
1041.         EndIf
1042.
1043.         ''Contribution (1,0,0,0)
1044.         Dim As Double dx1 = dx0 - 1 - SQUISH_CONSTANT_4D
1045.         Dim As Double dy1 = dy0 - 0 - SQUISH_CONSTANT_4D
1046.         Dim As Double dz1 = dz0 - 0 - SQUISH_CONSTANT_4D
1047.         Dim As Double dw1 = dw0 - 0 - SQUISH_CONSTANT_4D
1048.         Dim As Double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1
1049.         if (attn1 > 0) Then
1050.             attn1 *= attn1
1051.             value += attn1 * attn1 * extrapolate4(xsb + 1, ysb + 0, zsb + 0, wsb + 0, dx1, dy1, dz1, dw1)
1052.         EndIf
1053.
1054.         ''Contribution (0,1,0,0)
1055.         Dim As Double dx2 = dx0 - 0 - SQUISH_CONSTANT_4D
1056.         Dim As Double dy2 = dy0 - 1 - SQUISH_CONSTANT_4D
1057.         Dim As Double dz2 = dz1
1058.         Dim As Double dw2 = dw1
1059.         Dim As Double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2
1060.         if (attn2 > 0) Then
1061.             attn2 *= attn2
1062.             value += attn2 * attn2 * extrapolate4(xsb + 0, ysb + 1, zsb + 0, wsb + 0, dx2, dy2, dz2, dw2)
1063.         EndIf
1064.
1065.         ''Contribution (0,0,1,0)
1066.         Dim As Double dx3 = dx2
1067.         Dim As Double dy3 = dy1
1068.         Dim As Double dz3 = dz0 - 1 - SQUISH_CONSTANT_4D
1069.         Dim As Double dw3 = dw1
1070.         Dim As Double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3
1071.         if (attn3 > 0) Then
1072.             attn3 *= attn3
1073.             value += attn3 * attn3 * extrapolate4(xsb + 0, ysb + 0, zsb + 1, wsb + 0, dx3, dy3, dz3, dw3)
1074.         EndIf
1075.
1076.         ''Contribution (0,0,0,1)
1077.         Dim As Double dx4 = dx2
1078.         Dim As Double dy4 = dy1
1079.         Dim As Double dz4 = dz1
1080.         Dim As Double dw4 = dw0 - 1 - SQUISH_CONSTANT_4D
1081.         Dim As Double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4
1082.         if (attn4 > 0) Then
1083.             attn4 *= attn4
1084.             value += attn4 * attn4 * extrapolate4(xsb + 0, ysb + 0, zsb + 0, wsb + 1, dx4, dy4, dz4, dw4)
1085.         EndIf
1086.     Elseif (inSum >= 3) Then ''We're inside the pentachoron (4-Simplex) at (1,1,1,1)
1087.         ''Determine which two of (1,1,1,0), (1,1,0,1), (1,0,1,1), (0,1,1,1) are closest.
1088.         Dim As Byte aPoint = &h0E
1089.         Dim As Double aScore = xins
1090.         Dim As Byte bPoint = &h0D
1091.         Dim As Double bScore = yins
1092.         if (aScore <= bScore And zins < bScore) Then
1093.             bScore = zins
1094.             bPoint = &h0B
1095.         ElseIf (aScore > bScore And zins < aScore) then
1096.             aScore = zins
1097.             aPoint = &h0B
1098.         EndIf
1099.         if (aScore <= bScore And wins < bScore) Then
1100.             bScore = wins
1101.             bPoint = &h07
1102.         ElseIf (aScore > bScore And wins < aScore) then
1103.             aScore = wins
1104.             aPoint = &h07
1105.         EndIf
1106.
1107.         ''Now we determine the three lattice points not part of the pentachoron that may contribute.
1108.         ''This depends on the closest two pentachoron vertices, including (0,0,0,0)
1109.         Dim As Double uins = 4 - inSum
1110.         if (uins < aScore Or uins < bScore) Then ''(1,1,1,1) is one of the closest two pentachoron vertices.
1111.             Dim As Byte c = iif(bScore < aScore , bPoint , aPoint) ''Our other closest vertex is the closest out of a and b.
1112.
1113.             if ((c and &h01) <> 0) Then
1114.                 xsv_ext0 = xsb + 2
1115.                 xsv_ext1 = xsv_ext2 = xsb + 1
1116.                 dx_ext0 = dx0 - 2 - 4 * SQUISH_CONSTANT_4D
1117.                 dx_ext1 = dx_ext2 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D
1118.             Else
1119.                 xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb
1120.                 dx_ext0 = dx_ext1 = dx_ext2 = dx0 - 4 * SQUISH_CONSTANT_4D
1121.             EndIf
1122.
1123.             if ((c and &h02) <> 0) Then
1124.                 ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1
1125.                 dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D
1126.                 if ((c and &h01) <> 0) Then
1127.                     ysv_ext1 += 1
1128.                     dy_ext1 -= 1
1129.                 Else
1130.                     ysv_ext0 += 1
1131.                     dy_ext0 -= 1
1132.                 EndIf
1133.             Else
1134.                 ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb
1135.                 dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 4 * SQUISH_CONSTANT_4D
1136.             EndIf
1137.
1138.             if ((c and &h04) <> 0) Then
1139.                 zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1
1140.                 dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D
1141.                 if ((c and &h03) <> &h03) Then
1142.                     if ((c and &h03) = 0) Then
1143.                         zsv_ext0 += 1
1144.                         dz_ext0 -= 1
1145.                     Else
1146.                         zsv_ext1 += 1
1147.                         dz_ext1 -= 1
1148.                     EndIf
1149.                 Else
1150.                     zsv_ext2 += 1
1151.                     dz_ext2 -= 1
1152.                 EndIf
1153.             Else
1154.                 zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb
1155.                 dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 4 * SQUISH_CONSTANT_4D
1156.             EndIf
1157.
1158.             if ((c and &h08) <> 0) Then
1159.                 wsv_ext0 = wsv_ext1 = wsb + 1
1160.                 wsv_ext2 = wsb + 2
1161.                 dw_ext0 = dw_ext1 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D
1162.                 dw_ext2 = dw0 - 2 - 4 * SQUISH_CONSTANT_4D
1163.             Else
1164.                 wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb
1165.                 dw_ext0 = dw_ext1 = dw_ext2 = dw0 - 4 * SQUISH_CONSTANT_4D
1166.             EndIf
1167.         Else ''(1,1,1,1) is not one of the closest two pentachoron vertices.
1168.             Dim As Byte c = cast(Byte,(aPoint And bPoint)) ''Our three extra vertices are determined by the closest two.
1169.
1170.             if ((c and &h01) <> 0) Then
1171.                 xsv_ext0 = xsv_ext2 = xsb + 1
1172.                 xsv_ext1 = xsb + 2
1173.                 dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
1174.                 dx_ext1 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D
1175.                 dx_ext2 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D
1176.             Else
1177.                 xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb
1178.                 dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_4D
1179.                 dx_ext1 = dx_ext2 = dx0 - 3 * SQUISH_CONSTANT_4D
1180.             EndIf
1181.
1182.             if ((c and &h02) <> 0) Then
1183.                 ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1
1184.                 dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
1185.                 dy_ext1 = dy_ext2 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D
1186.                 if ((c and &h01) <> 0) Then
1187.                     ysv_ext2 += 1
1188.                     dy_ext2 -= 1
1189.                 Else
1190.                     ysv_ext1 += 1
1191.                     dy_ext1 -= 1
1192.                 EndIf
1193.             Else
1194.                 ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb
1195.                 dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_4D
1196.                 dy_ext1 = dy_ext2 = dy0 - 3 * SQUISH_CONSTANT_4D
1197.             EndIf
1198.
1199.             if ((c and &h04) <> 0) Then
1200.                 zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1
1201.                 dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
1202.                 dz_ext1 = dz_ext2 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D
1203.                 if ((c and &h03) <> 0) Then
1204.                     zsv_ext2 += 1
1205.                     dz_ext2 -= 1
1206.                 Else
1207.                     zsv_ext1 += 1
1208.                     dz_ext1 -= 1
1209.                 EndIf
1210.             Else
1211.                 zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb
1212.                 dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_4D
1213.                 dz_ext1 = dz_ext2 = dz0 - 3 * SQUISH_CONSTANT_4D
1214.             EndIf
1215.
1216.             if ((c and &h08) <> 0) Then
1217.                 wsv_ext0 = wsv_ext1 = wsb + 1
1218.                 wsv_ext2 = wsb + 2
1219.                 dw_ext0 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
1220.                 dw_ext1 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D
1221.                 dw_ext2 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D
1222.             Else
1223.                 wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb
1224.                 dw_ext0 = dw0 - 2 * SQUISH_CONSTANT_4D
1225.                 dw_ext1 = dw_ext2 = dw0 - 3 * SQUISH_CONSTANT_4D
1226.             EndIf
1227.         endif
1228.
1229.         ''Contribution (1,1,1,0)
1230.         Dim As Double dx4 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D
1231.         Dim As Double dy4 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D
1232.         Dim As Double dz4 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D
1233.         Dim As Double dw4 = dw0 - 3 * SQUISH_CONSTANT_4D
1234.         Dim As Double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4
1235.         if (attn4 > 0) Then
1236.             attn4 *= attn4
1237.             value += attn4 * attn4 * extrapolate4(xsb + 1, ysb + 1, zsb + 1, wsb + 0, dx4, dy4, dz4, dw4)
1238.         EndIf
1239.
1240.         ''Contribution (1,1,0,1)
1241.         Dim As Double dx3 = dx4
1242.         Dim As Double dy3 = dy4
1243.         Dim As Double dz3 = dz0 - 3 * SQUISH_CONSTANT_4D
1244.         Dim As Double dw3 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D
1245.         Dim As Double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3
1246.         if (attn3 > 0) Then
1247.             attn3 *= attn3
1248.             value += attn3 * attn3 * extrapolate4(xsb + 1, ysb + 1, zsb + 0, wsb + 1, dx3, dy3, dz3, dw3)
1249.         EndIf
1250.
1251.         ''Contribution (1,0,1,1)
1252.         Dim As Double dx2 = dx4
1253.         Dim As Double dy2 = dy0 - 3 * SQUISH_CONSTANT_4D
1254.         Dim As Double dz2 = dz4
1255.         Dim As Double dw2 = dw3
1256.         Dim As Double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2
1257.         if (attn2 > 0) Then
1258.             attn2 *= attn2
1259.             value += attn2 * attn2 * extrapolate4(xsb + 1, ysb + 0, zsb + 1, wsb + 1, dx2, dy2, dz2, dw2)
1260.         EndIf
1261.
1262.         ''Contribution (0,1,1,1)
1263.         Dim As Double dx1 = dx0 - 3 * SQUISH_CONSTANT_4D
1264.         Dim As Double dz1 = dz4
1265.         Dim As Double dy1 = dy4
1266.         Dim As Double dw1 = dw3
1267.         Dim As Double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1
1268.         if (attn1 > 0) Then
1269.             attn1 *= attn1
1270.             value += attn1 * attn1 * extrapolate4(xsb + 0, ysb + 1, zsb + 1, wsb + 1, dx1, dy1, dz1, dw1)
1271.         EndIf
1272.
1273.         ''Contribution (1,1,1,1)
1274.         dx0 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D
1275.         dy0 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D
1276.         dz0 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D
1277.         dw0 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D
1278.         Dim As Double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0 - dw0 * dw0
1279.         if (attn0 > 0) Then
1280.             attn0 *= attn0
1281.             value += attn0 * attn0 * extrapolate4(xsb + 1, ysb + 1, zsb + 1, wsb + 1, dx0, dy0, dz0, dw0)
1282.         EndIf
1283.     ElseIf (inSum <= 2) then ''We're inside the first dispentachoron (Rectified 4-Simplex)
1284.         Dim As Double aScore
1285.         Dim As Byte aPoint
1286.         Dim As boolean aIsBiggerSide = TRUE
1287.         Dim As Double bScore
1288.         Dim As Byte bPoint
1289.         Dim As boolean bIsBiggerSide = TRUE
1290.
1291.         ''Decide between (1,1,0,0) and (0,0,1,1)
1292.         if (xins + yins > zins + wins) Then
1293.             aScore = xins + yins
1294.             aPoint = &h03
1295.         Else
1296.             aScore = zins + wins
1297.             aPoint = &h0C
1298.         EndIf
1299.
1300.         ''Decide between (1,0,1,0) and (0,1,0,1)
1301.         if (xins + zins > yins + wins) Then
1302.             bScore = xins + zins
1303.             bPoint = &h05
1304.         Else
1305.             bScore = yins + wins
1306.             bPoint = &h0A
1307.         EndIf
1308.
1309.         ''Closer between (1,0,0,1) and (0,1,1,0) will replace the further of a and b, if closer.
1310.         if (xins + wins > yins + zins) Then
1311.             Dim As Double score = xins + wins
1312.             if (aScore >= bScore And score > bScore) Then
1313.                 bScore = score
1314.                 bPoint = &h09
1315.             ElseIf (aScore < bScore And score > aScore) then
1316.                 aScore = score
1317.                 aPoint = &h09
1318.             EndIf
1319.         Else
1320.             Dim As Double score = yins + zins
1321.             if (aScore >= bScore And score > bScore) Then
1322.                 bScore = score
1323.                 bPoint = &h06
1324.             ElseIf (aScore < bScore And score > aScore) then
1325.                 aScore = score
1326.                 aPoint = &h06
1327.             EndIf
1328.         EndIf
1329.
1330.         ''Decide if (1,0,0,0) is closer.
1331.         Dim As Double p1 = 2 - inSum + xins
1332.         if (aScore >= bScore And p1 > bScore) Then
1333.             bScore = p1
1334.             bPoint = &h01
1335.             bIsBiggerSide = FALSE
1336.         ElseIf (aScore < bScore And p1 > aScore) then
1337.             aScore = p1
1338.             aPoint = &h01
1339.             aIsBiggerSide = FALSE
1340.         EndIf
1341.
1342.         ''Decide if (0,1,0,0) is closer.
1343.         Dim As Double p2 = 2 - inSum + yins
1344.         if (aScore >= bScore And p2 > bScore) Then
1345.             bScore = p2
1346.             bPoint = &h02
1347.             bIsBiggerSide = FALSE
1348.         ElseIf (aScore < bScore And p2 > aScore) Then
1349.             aScore = p2
1350.             aPoint = &h02
1351.             aIsBiggerSide = FALSE
1352.         EndIf
1353.
1354.         ''Decide if (0,0,1,0) is closer.
1355.         Dim As Double p3 = 2 - inSum + zins
1356.         if (aScore >= bScore And p3 > bScore) Then
1357.             bScore = p3
1358.             bPoint = &h04
1359.             bIsBiggerSide = FALSE
1360.         elseif (aScore < bScore And p3 > aScore) Then
1361.             aScore = p3
1362.             aPoint = &h04
1363.             aIsBiggerSide = FALSE
1364.         EndIf
1365.
1366.         ''Decide if (0,0,0,1) is closer.
1367.         Dim As Double p4 = 2 - inSum + wins
1368.         if (aScore >= bScore And p4 > bScore) Then
1369.             bScore = p4
1370.             bPoint = &h08
1371.             bIsBiggerSide = FALSE
1372.         ElseIf (aScore < bScore And p4 > aScore) then
1373.             aScore = p4
1374.             aPoint = &h08
1375.             aIsBiggerSide = FALSE
1376.         endif
1377.
1378.         ''Where each of the two closest points are determines how the extra three vertices are calculated.
1379.         if (aIsBiggerSide = bIsBiggerSide) Then
1380.             if (aIsBiggerSide) then ''Both closest points on the bigger side
1381.                 Dim As Byte c1 = Cast(Byte,(aPoint or bPoint))
1382.                 Dim As Byte c2 = cast(Byte,(aPoint And bPoint))
1383.                 if ((c1 and &h01) = 0) Then
1384.                     xsv_ext0 = xsb
1385.                     xsv_ext1 = xsb - 1
1386.                     dx_ext0 = dx0 - 3 * SQUISH_CONSTANT_4D
1387.                     dx_ext1 = dx0 + 1 - 2 * SQUISH_CONSTANT_4D
1388.                 Else
1389.                     xsv_ext0 = xsv_ext1 = xsb + 1
1390.                     dx_ext0 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D
1391.                     dx_ext1 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
1392.                 EndIf
1393.
1394.                 if ((c1 and &h02) = 0) Then
1395.                     ysv_ext0 = ysb
1396.                     ysv_ext1 = ysb - 1
1397.                     dy_ext0 = dy0 - 3 * SQUISH_CONSTANT_4D
1398.                     dy_ext1 = dy0 + 1 - 2 * SQUISH_CONSTANT_4D
1399.                 Else
1400.                     ysv_ext0 = ysv_ext1 = ysb + 1
1401.                     dy_ext0 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D
1402.                     dy_ext1 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
1403.                 endif
1404.
1405.                 if ((c1 and &h04) = 0) Then
1406.                     zsv_ext0 = zsb
1407.                     zsv_ext1 = zsb - 1
1408.                     dz_ext0 = dz0 - 3 * SQUISH_CONSTANT_4D
1409.                     dz_ext1 = dz0 + 1 - 2 * SQUISH_CONSTANT_4D
1410.                 Else
1411.                     zsv_ext0 = zsv_ext1 = zsb + 1
1412.                     dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D
1413.                     dz_ext1 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
1414.                 EndIf
1415.
1416.                 if ((c1 and &h08) = 0) Then
1417.                     wsv_ext0 = wsb
1418.                     wsv_ext1 = wsb - 1
1419.                     dw_ext0 = dw0 - 3 * SQUISH_CONSTANT_4D
1420.                     dw_ext1 = dw0 + 1 - 2 * SQUISH_CONSTANT_4D
1421.                 Else
1422.                     wsv_ext0 = wsv_ext1 = wsb + 1
1423.                     dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D
1424.                     dw_ext1 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
1425.                 endif
1426.
1427.                 ''One combination is a permutation of (0,0,0,2) based on c2
1428.                 xsv_ext2 = xsb
1429.                 ysv_ext2 = ysb
1430.                 zsv_ext2 = zsb
1431.                 wsv_ext2 = wsb
1432.                 dx_ext2 = dx0 - 2 * SQUISH_CONSTANT_4D
1433.                 dy_ext2 = dy0 - 2 * SQUISH_CONSTANT_4D
1434.                 dz_ext2 = dz0 - 2 * SQUISH_CONSTANT_4D
1435.                 dw_ext2 = dw0 - 2 * SQUISH_CONSTANT_4D
1436.                 if ((c2 and &h01) <> 0) Then
1437.                     xsv_ext2 += 2
1438.                     dx_ext2 -= 2
1439.                 ElseIf ((c2 and &h02) <> 0) Then
1440.                     ysv_ext2 += 2
1441.                     dy_ext2 -= 2
1442.                 ElseIf ((c2 and &h04) <> 0) then
1443.                     zsv_ext2 += 2
1444.                     dz_ext2 -= 2
1445.                 Else
1446.                     wsv_ext2 += 2
1447.                     dw_ext2 -= 2
1448.                 endif
1449.
1450.             Else ''Both closest points on the smaller side
1451.                 ''One of the two extra points is (0,0,0,0)
1452.                 xsv_ext2 = xsb
1453.                 ysv_ext2 = ysb
1454.                 zsv_ext2 = zsb
1455.                 wsv_ext2 = wsb
1456.                 dx_ext2 = dx0
1457.                 dy_ext2 = dy0
1458.                 dz_ext2 = dz0
1459.                 dw_ext2 = dw0
1460.
1461.                 ''Other two points are based on the omitted axes.
1462.                 Dim As Byte c = cast(Byte,(aPoint or bPoint))
1463.
1464.                 if ((c and &h01) = 0) Then
1465.                     xsv_ext0 = xsb - 1
1466.                     xsv_ext1 = xsb
1467.                     dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_4D
1468.                     dx_ext1 = dx0 - SQUISH_CONSTANT_4D
1469.                 Else
1470.                     xsv_ext0 = xsv_ext1 = xsb + 1
1471.                     dx_ext0 = dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_4D
1472.                 EndIf
1473.
1474.                 if ((c and &h02) = 0) Then
1475.                     ysv_ext0 = ysv_ext1 = ysb
1476.                     dy_ext0 = dy_ext1 = dy0 - SQUISH_CONSTANT_4D
1477.                     if ((c and &h01) = &h01) Then
1478.                         ysv_ext0 -= 1
1479.                         dy_ext0 += 1
1480.                     Else
1481.                         ysv_ext1 -= 1
1482.                         dy_ext1 += 1
1483.                     EndIf
1484.                 Else
1485.                     ysv_ext0 = ysv_ext1 = ysb + 1
1486.                     dy_ext0 = dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_4D
1487.                 EndIf
1488.
1489.                 if ((c and &h04) = 0) Then
1490.                     zsv_ext0 = zsv_ext1 = zsb
1491.                     dz_ext0 = dz_ext1 = dz0 - SQUISH_CONSTANT_4D
1492.                     if ((c and &h03) = &h03) Then
1493.                         zsv_ext0 -= 1
1494.                         dz_ext0 += 1
1495.                     Else
1496.                         zsv_ext1 -= 1
1497.                         dz_ext1 += 1
1498.                     EndIf
1499.                 Else
1500.                     zsv_ext0 = zsv_ext1 = zsb + 1
1501.                     dz_ext0 = dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_4D
1502.                 EndIf
1503.
1504.                 if ((c and &h08) = 0) Then
1505.                     wsv_ext0 = wsb
1506.                     wsv_ext1 = wsb - 1
1507.                     dw_ext0 = dw0 - SQUISH_CONSTANT_4D
1508.                     dw_ext1 = dw0 + 1 - SQUISH_CONSTANT_4D
1509.                 Else
1510.                     wsv_ext0 = wsv_ext1 = wsb + 1
1511.                     dw_ext0 = dw_ext1 = dw0 - 1 - SQUISH_CONSTANT_4D
1512.                 EndIf
1513.
1514.             EndIf
1515.         Else ''One point on each "side"
1516.             Dim As Byte c1, c2
1517.             if (aIsBiggerSide) Then
1518.                 c1 = aPoint
1519.                 c2 = bPoint
1520.             Else
1521.                 c1 = bPoint
1522.                 c2 = aPoint
1523.             EndIf
1524.
1525.             ''Two contributions are the bigger-sided point with each 0 replaced with -1.
1526.             if ((c1 and &h01) = 0) Then
1527.                 xsv_ext0 = xsb - 1
1528.                 xsv_ext1 = xsb
1529.                 dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_4D
1530.                 dx_ext1 = dx0 - SQUISH_CONSTANT_4D
1531.             Else
1532.                 xsv_ext0 = xsv_ext1 = xsb + 1
1533.                 dx_ext0 = dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_4D
1534.             EndIf
1535.
1536.             if ((c1 and &h02) = 0) Then
1537.                 ysv_ext0 = ysv_ext1 = ysb
1538.                 dy_ext0 = dy_ext1 = dy0 - SQUISH_CONSTANT_4D
1539.                 if ((c1 and &h01) = &h01) Then
1540.                     ysv_ext0 -= 1
1541.                     dy_ext0 += 1
1542.                 Else
1543.                     ysv_ext1 -= 1
1544.                     dy_ext1 += 1
1545.                 EndIf
1546.             Else
1547.                 ysv_ext0 = ysv_ext1 = ysb + 1
1548.                 dy_ext0 = dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_4D
1549.             EndIf
1550.
1551.             if ((c1 and &h04) = 0) Then
1552.                 zsv_ext0 = zsv_ext1 = zsb
1553.                 dz_ext0 = dz_ext1 = dz0 - SQUISH_CONSTANT_4D
1554.                 if ((c1 and &h03) = &h03) Then
1555.                     zsv_ext0 -= 1
1556.                     dz_ext0 += 1
1557.                 Else
1558.                     zsv_ext1 -= 1
1559.                     dz_ext1 += 1
1560.                 EndIf
1561.             Else
1562.                 zsv_ext0 = zsv_ext1 = zsb + 1
1563.                 dz_ext0 = dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_4D
1564.             EndIf
1565.
1566.             if ((c1 and &h08) = 0) Then
1567.                 wsv_ext0 = wsb
1568.                 wsv_ext1 = wsb - 1
1569.                 dw_ext0 = dw0 - SQUISH_CONSTANT_4D
1570.                 dw_ext1 = dw0 + 1 - SQUISH_CONSTANT_4D
1571.             Else
1572.                 wsv_ext0 = wsv_ext1 = wsb + 1
1573.                 dw_ext0 = dw_ext1 = dw0 - 1 - SQUISH_CONSTANT_4D
1574.             EndIf
1575.
1576.             ''One contribution is a permutation of (0,0,0,2) based on the smaller-sided point
1577.             xsv_ext2 = xsb
1578.             ysv_ext2 = ysb
1579.             zsv_ext2 = zsb
1580.             wsv_ext2 = wsb
1581.             dx_ext2 = dx0 - 2 * SQUISH_CONSTANT_4D
1582.             dy_ext2 = dy0 - 2 * SQUISH_CONSTANT_4D
1583.             dz_ext2 = dz0 - 2 * SQUISH_CONSTANT_4D
1584.             dw_ext2 = dw0 - 2 * SQUISH_CONSTANT_4D
1585.             if ((c2 and &h01) <> 0) Then
1586.                 xsv_ext2 += 2
1587.                 dx_ext2 -= 2
1588.             ElseIf ((c2 and &h02) <> 0) Then
1589.                 ysv_ext2 += 2
1590.                 dy_ext2 -= 2
1591.             elseif ((c2 and &h04) <> 0) Then
1592.                 zsv_ext2 += 2
1593.                 dz_ext2 -= 2
1594.             Else
1595.                 wsv_ext2 += 2
1596.                 dw_ext2 -= 2
1597.             EndIf
1598.         EndIf
1599.
1600.         ''Contribution (1,0,0,0)
1601.         Dim As Double dx1 = dx0 - 1 - SQUISH_CONSTANT_4D
1602.         Dim As Double dy1 = dy0 - 0 - SQUISH_CONSTANT_4D
1603.         Dim As Double dz1 = dz0 - 0 - SQUISH_CONSTANT_4D
1604.         Dim As Double dw1 = dw0 - 0 - SQUISH_CONSTANT_4D
1605.         Dim As Double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1
1606.         if (attn1 > 0) Then
1607.             attn1 *= attn1
1608.             value += attn1 * attn1 * extrapolate4(xsb + 1, ysb + 0, zsb + 0, wsb + 0, dx1, dy1, dz1, dw1)
1609.         EndIf
1610.
1611.         ''Contribution (0,1,0,0)
1612.         Dim As Double dx2 = dx0 - 0 - SQUISH_CONSTANT_4D
1613.         Dim As Double dy2 = dy0 - 1 - SQUISH_CONSTANT_4D
1614.         Dim As Double dz2 = dz1
1615.         Dim As Double dw2 = dw1
1616.         Dim As Double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2
1617.         if (attn2 > 0) Then
1618.             attn2 *= attn2
1619.             value += attn2 * attn2 * extrapolate4(xsb + 0, ysb + 1, zsb + 0, wsb + 0, dx2, dy2, dz2, dw2)
1620.         EndIf
1621.
1622.         ''Contribution (0,0,1,0)
1623.         Dim As Double dx3 = dx2
1624.         Dim As Double dy3 = dy1
1625.         Dim As Double dz3 = dz0 - 1 - SQUISH_CONSTANT_4D
1626.         Dim As Double dw3 = dw1
1627.         Dim As Double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3
1628.         if (attn3 > 0) Then
1629.             attn3 *= attn3
1630.             value += attn3 * attn3 * extrapolate4(xsb + 0, ysb + 0, zsb + 1, wsb + 0, dx3, dy3, dz3, dw3)
1631.         EndIf
1632.
1633.         ''Contribution (0,0,0,1)
1634.         Dim As Double dx4 = dx2
1635.         Dim As Double dy4 = dy1
1636.         Dim As Double dz4 = dz1
1637.         Dim As Double dw4 = dw0 - 1 - SQUISH_CONSTANT_4D
1638.         Dim As Double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4
1639.         if (attn4 > 0) Then
1640.             attn4 *= attn4
1641.             value += attn4 * attn4 * extrapolate4(xsb + 0, ysb + 0, zsb + 0, wsb + 1, dx4, dy4, dz4, dw4)
1642.         EndIf
1643.
1644.         ''Contribution (1,1,0,0)
1645.         Dim As Double dx5 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
1646.         Dim As Double dy5 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
1647.         Dim As Double dz5 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D
1648.         Dim As Double dw5 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D
1649.         Dim As Double attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5 - dw5 * dw5
1650.         if (attn5 > 0) Then
1651.             attn5 *= attn5
1652.             value += attn5 * attn5 * extrapolate4(xsb + 1, ysb + 1, zsb + 0, wsb + 0, dx5, dy5, dz5, dw5)
1653.         EndIf
1654.
1655.         ''Contribution (1,0,1,0)
1656.         Dim As Double dx6 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
1657.         Dim As Double dy6 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D
1658.         Dim As Double dz6 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
1659.         Dim As Double dw6 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D
1660.         Dim As Double attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6 - dw6 * dw6
1661.         if (attn6 > 0) Then
1662.             attn6 *= attn6
1663.             value += attn6 * attn6 * extrapolate4(xsb + 1, ysb + 0, zsb + 1, wsb + 0, dx6, dy6, dz6, dw6)
1664.         EndIf
1665.
1666.         ''Contribution (1,0,0,1)
1667.         Dim As Double dx7 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
1668.         Dim As Double dy7 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D
1669.         Dim As Double dz7 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D
1670.         Dim As Double dw7 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
1671.         Dim As Double attn7 = 2 - dx7 * dx7 - dy7 * dy7 - dz7 * dz7 - dw7 * dw7
1672.         if (attn7 > 0) Then
1673.             attn7 *= attn7
1674.             value += attn7 * attn7 * extrapolate4(xsb + 1, ysb + 0, zsb + 0, wsb + 1, dx7, dy7, dz7, dw7)
1675.         EndIf
1676.
1677.         ''Contribution (0,1,1,0)
1678.         Dim As Double dx8 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D
1679.         Dim As Double dy8 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
1680.         Dim As Double dz8 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
1681.         Dim As Double dw8 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D
1682.         Dim As Double attn8 = 2 - dx8 * dx8 - dy8 * dy8 - dz8 * dz8 - dw8 * dw8
1683.         if (attn8 > 0) Then
1684.             attn8 *= attn8
1685.             value += attn8 * attn8 * extrapolate4(xsb + 0, ysb + 1, zsb + 1, wsb + 0, dx8, dy8, dz8, dw8)
1686.         EndIf
1687.
1688.         ''Contribution (0,1,0,1)
1689.         Dim As Double dx9 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D
1690.         Dim As Double dy9 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
1691.         Dim As Double dz9 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D
1692.         Dim As Double dw9 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
1693.         Dim As Double attn9 = 2 - dx9 * dx9 - dy9 * dy9 - dz9 * dz9 - dw9 * dw9
1694.         if (attn9 > 0) Then
1695.             attn9 *= attn9
1696.             value += attn9 * attn9 * extrapolate4(xsb + 0, ysb + 1, zsb + 0, wsb + 1, dx9, dy9, dz9, dw9)
1697.         EndIf
1698.
1699.         ''Contribution (0,0,1,1)
1700.         Dim As Double dx10 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D
1701.         Dim As Double dy10 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D
1702.         Dim As Double dz10 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
1703.         Dim As Double dw10 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
1704.         Dim As Double attn10 = 2 - dx10 * dx10 - dy10 * dy10 - dz10 * dz10 - dw10 * dw10
1705.         if (attn10 > 0) Then
1706.             attn10 *= attn10
1707.             value += attn10 * attn10 * extrapolate4(xsb + 0, ysb + 0, zsb + 1, wsb + 1, dx10, dy10, dz10, dw10)
1708.         EndIf
1709.     Else ''We're inside the second dispentachoron (Rectified 4-Simplex)
1710.         Dim As Double aScore
1711.         Dim As Byte aPoint
1712.         Dim As boolean aIsBiggerSide = TRUE
1713.         Dim As Double bScore
1714.         Dim As Byte bPoint
1715.         Dim As boolean bIsBiggerSide = TRUE
1716.
1717.         ''Decide between (0,0,1,1) and (1,1,0,0)
1718.         if (xins + yins < zins + wins) Then
1719.             aScore = xins + yins
1720.             aPoint = &h0C
1721.         Else
1722.             aScore = zins + wins
1723.             aPoint = &h03
1724.         EndIf
1725.
1726.         ''Decide between (0,1,0,1) and (1,0,1,0)
1727.         if (xins + zins < yins + wins) Then
1728.             bScore = xins + zins
1729.             bPoint = &h0A
1730.         Else
1731.             bScore = yins + wins
1732.             bPoint = &h05
1733.         EndIf
1734.
1735.         ''Closer between (0,1,1,0) and (1,0,0,1) will replace the further of a and b, if closer.
1736.         if (xins + wins < yins + zins) Then
1737.             Dim As Double score = xins + wins
1738.             if (aScore <= bScore And score < bScore) Then
1739.                 bScore = score
1740.                 bPoint = &h06
1741.             ElseIf (aScore > bScore And score < aScore) Then
1742.                 aScore = score
1743.                 aPoint = &h06
1744.             EndIf
1745.         Else
1746.             Dim As Double score = yins + zins
1747.             if (aScore <= bScore And score < bScore) Then
1748.                 bScore = score
1749.                 bPoint = &h09
1750.             elseif (aScore > bScore And score < aScore) Then
1751.                 aScore = score
1752.                 aPoint = &h09
1753.             EndIf
1754.         EndIf
1755.
1756.         ''Decide if (0,1,1,1) is closer.
1757.         Dim As Double p1 = 3 - inSum + xins
1758.         if (aScore <= bScore And p1 < bScore) Then
1759.             bScore = p1
1760.             bPoint = &h0E
1761.             bIsBiggerSide = FALSE
1762.         ElseIf (aScore > bScore And p1 < aScore) Then
1763.             aScore = p1
1764.             aPoint = &h0E
1765.             aIsBiggerSide = FALSE
1766.         EndIf
1767.
1768.         ''Decide if (1,0,1,1) is closer.
1769.         Dim As Double p2 = 3 - inSum + yins
1770.         if (aScore <= bScore And p2 < bScore) Then
1771.             bScore = p2
1772.             bPoint = &h0D
1773.             bIsBiggerSide = FALSE
1774.         ElseIf (aScore > bScore And p2 < aScore) Then
1775.             aScore = p2
1776.             aPoint = &h0D
1777.             aIsBiggerSide = FALSE
1778.         EndIf
1779.
1780.         ''Decide if (1,1,0,1) is closer.
1781.         Dim As Double p3 = 3 - inSum + zins
1782.         if (aScore <= bScore And p3 < bScore) Then
1783.             bScore = p3
1784.             bPoint = &h0B
1785.             bIsBiggerSide = FALSE
1786.         ElseIf (aScore > bScore And p3 < aScore) Then
1787.             aScore = p3
1788.             aPoint = &h0B
1789.             aIsBiggerSide = FALSE
1790.         EndIf
1791.
1792.         ''Decide if (1,1,1,0) is closer.
1793.         Dim As Double p4 = 3 - inSum + wins
1794.         if (aScore <= bScore And p4 < bScore) Then
1795.             bScore = p4
1796.             bPoint = &h07
1797.             bIsBiggerSide = FALSE
1798.         elseif (aScore > bScore and p4 < aScore) Then
1799.             aScore = p4
1800.             aPoint = &h07
1801.             aIsBiggerSide = FALSE
1802.         EndIf
1803.
1804.         ''Where each of the two closest points are determines how the extra three vertices are calculated.
1805.         if (aIsBiggerSide = bIsBiggerSide) Then
1806.             if (aIsBiggerSide) Then ''Both closest points on the bigger side
1807.                 Dim As Byte c1 = Cast(Byte,(aPoint And bPoint))
1808.                 Dim As Byte c2 = cast(Byte,(aPoint or bPoint))
1809.
1810.                 ''Two contributions are permutations of (0,0,0,1) and (0,0,0,2) based on c1
1811.                 xsv_ext0 = xsv_ext1 = xsb
1812.                 ysv_ext0 = ysv_ext1 = ysb
1813.                 zsv_ext0 = zsv_ext1 = zsb
1814.                 wsv_ext0 = wsv_ext1 = wsb
1815.                 dx_ext0 = dx0 - SQUISH_CONSTANT_4D
1816.                 dy_ext0 = dy0 - SQUISH_CONSTANT_4D
1817.                 dz_ext0 = dz0 - SQUISH_CONSTANT_4D
1818.                 dw_ext0 = dw0 - SQUISH_CONSTANT_4D
1819.                 dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_4D
1820.                 dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_4D
1821.                 dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_4D
1822.                 dw_ext1 = dw0 - 2 * SQUISH_CONSTANT_4D
1823.                 if ((c1 and &h01) <> 0) Then
1824.                     xsv_ext0 += 1
1825.                     dx_ext0 -= 1
1826.                     xsv_ext1 += 2
1827.                     dx_ext1 -= 2
1828.                 ElseIf ((c1 and &h02) <> 0) Then
1829.                     ysv_ext0 += 1
1830.                     dy_ext0 -= 1
1831.                     ysv_ext1 += 2
1832.                     dy_ext1 -= 2
1833.                 ElseIf ((c1 and &h04) <> 0) Then
1834.                     zsv_ext0 += 1
1835.                     dz_ext0 -= 1
1836.                     zsv_ext1 += 2
1837.                     dz_ext1 -= 2
1838.                 Else
1839.                     wsv_ext0 += 1
1840.                     dw_ext0 -= 1
1841.                     wsv_ext1 += 2
1842.                     dw_ext1 -= 2
1843.                 EndIf
1844.
1845.                 ''One contribution is a permutation of (1,1,1,-1) based on c2
1846.                 xsv_ext2 = xsb + 1
1847.                 ysv_ext2 = ysb + 1
1848.                 zsv_ext2 = zsb + 1
1849.                 wsv_ext2 = wsb + 1
1850.                 dx_ext2 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
1851.                 dy_ext2 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
1852.                 dz_ext2 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
1853.                 dw_ext2 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
1854.                 if ((c2 and &h01) = 0) Then
1855.                     xsv_ext2 -= 2
1856.                     dx_ext2 += 2
1857.                 ElseIf ((c2 and &h02) = 0) Then
1858.                     ysv_ext2 -= 2
1859.                     dy_ext2 += 2
1860.                 ElseIf ((c2 and &h04) = 0) Then
1861.                     zsv_ext2 -= 2
1862.                     dz_ext2 += 2
1863.                 Else
1864.                     wsv_ext2 -= 2
1865.                     dw_ext2 += 2
1866.                 EndIf
1867.             Else ''Both closest points on the smaller side
1868.                 ''One of the two extra points is (1,1,1,1)
1869.                 xsv_ext2 = xsb + 1
1870.                 ysv_ext2 = ysb + 1
1871.                 zsv_ext2 = zsb + 1
1872.                 wsv_ext2 = wsb + 1
1873.                 dx_ext2 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D
1874.                 dy_ext2 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D
1875.                 dz_ext2 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D
1876.                 dw_ext2 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D
1877.
1878.                 ''Other two points are based on the shared axes.
1879.                 Dim As Byte c = cast(Byte,(aPoint And bPoint))
1880.
1881.                 if ((c and &h01) <> 0) Then
1882.                     xsv_ext0 = xsb + 2
1883.                     xsv_ext1 = xsb + 1
1884.                     dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D
1885.                     dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D
1886.                 Else
1887.                     xsv_ext0 = xsv_ext1 = xsb
1888.                     dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_4D
1889.                 EndIf
1890.
1891.                 if ((c and &h02) <> 0) Then
1892.                     ysv_ext0 = ysv_ext1 = ysb + 1
1893.                     dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D
1894.                     if ((c and &h01) = 0) Then
1895.                         ysv_ext0 += 1
1896.                         dy_ext0 -= 1
1897.                     Else
1898.                         ysv_ext1 += 1
1899.                         dy_ext1 -= 1
1900.                     EndIf
1901.                 Else
1902.                     ysv_ext0 = ysv_ext1 = ysb
1903.                     dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_4D
1904.                 EndIf
1905.
1906.                 if ((c and &h04) <> 0) Then
1907.                     zsv_ext0 = zsv_ext1 = zsb + 1
1908.                     dz_ext0 = dz_ext1 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D
1909.                     if ((c and &h03) = 0) Then
1910.                         zsv_ext0 += 1
1911.                         dz_ext0 -= 1
1912.                     Else
1913.                         zsv_ext1 += 1
1914.                         dz_ext1 -= 1
1915.                     EndIf
1916.                 Else
1917.                     zsv_ext0 = zsv_ext1 = zsb
1918.                     dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_4D
1919.                 EndIf
1920.
1921.                 if ((c and &h08) <> 0) Then
1922.                     wsv_ext0 = wsb + 1
1923.                     wsv_ext1 = wsb + 2
1924.                     dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D
1925.                     dw_ext1 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D
1926.                 Else
1927.                     wsv_ext0 = wsv_ext1 = wsb
1928.                     dw_ext0 = dw_ext1 = dw0 - 3 * SQUISH_CONSTANT_4D
1929.                 EndIf
1930.             EndIf
1931.         Else ''One point on each "side"
1932.             Dim As Byte c1, c2
1933.             if (aIsBiggerSide) Then
1934.                 c1 = aPoint
1935.                 c2 = bPoint
1936.             Else
1937.                 c1 = bPoint
1938.                 c2 = aPoint
1939.             EndIf
1940.
1941.             ''Two contributions are the bigger-sided point with each 1 replaced with 2.
1942.             if ((c1 and &h01) <> 0) Then
1943.                 xsv_ext0 = xsb + 2
1944.                 xsv_ext1 = xsb + 1
1945.                 dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D
1946.                 dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D
1947.             Else
1948.                 xsv_ext0 = xsv_ext1 = xsb
1949.                 dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_4D
1950.             EndIf
1951.
1952.             if ((c1 and &h02) <> 0) Then
1953.                 ysv_ext0 = ysv_ext1 = ysb + 1
1954.                 dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D
1955.                 if ((c1 and &h01) = 0) Then
1956.                     ysv_ext0 += 1
1957.                     dy_ext0 -= 1
1958.                 Else
1959.                     ysv_ext1 += 1
1960.                     dy_ext1 -= 1
1961.                 EndIf
1962.             Else
1963.                 ysv_ext0 = ysv_ext1 = ysb
1964.                 dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_4D
1965.             EndIf
1966.
1967.             if ((c1 and &h04) <> 0) Then
1968.                 zsv_ext0 = zsv_ext1 = zsb + 1
1969.                 dz_ext0 = dz_ext1 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D
1970.                 if ((c1 and &h03) = 0) Then
1971.                     zsv_ext0 += 1
1972.                     dz_ext0 -= 1
1973.                 Else
1974.                     zsv_ext1 += 1
1975.                     dz_ext1 -= 1
1976.                 EndIf
1977.             Else
1978.                 zsv_ext0 = zsv_ext1 = zsb
1979.                 dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_4D
1980.             EndIf
1981.
1982.             if ((c1 and &h08) <> 0) Then
1983.                 wsv_ext0 = wsb + 1
1984.                 wsv_ext1 = wsb + 2
1985.                 dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D
1986.                 dw_ext1 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D
1987.             Else
1988.                 wsv_ext0 = wsv_ext1 = wsb
1989.                 dw_ext0 = dw_ext1 = dw0 - 3 * SQUISH_CONSTANT_4D
1990.             EndIf
1991.
1992.             ''One contribution is a permutation of (1,1,1,-1) based on the smaller-sided point
1993.             xsv_ext2 = xsb + 1
1994.             ysv_ext2 = ysb + 1
1995.             zsv_ext2 = zsb + 1
1996.             wsv_ext2 = wsb + 1
1997.             dx_ext2 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
1998.             dy_ext2 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
1999.             dz_ext2 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
2000.             dw_ext2 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
2001.             if ((c2 and &h01) = 0) Then
2002.                 xsv_ext2 -= 2
2003.                 dx_ext2 += 2
2004.             ElseIf ((c2 and &h02) = 0) Then
2005.                 ysv_ext2 -= 2
2006.                 dy_ext2 += 2
2007.             ElseIf ((c2 And &h04) = 0) Then
2008.                 zsv_ext2 -= 2
2009.                 dz_ext2 += 2
2010.             else
2011.                 wsv_ext2 -= 2
2012.                 dw_ext2 += 2
2013.             EndIf
2014.         EndIf
2015.
2016.         ''Contribution (1,1,1,0)
2017.         Dim As Double dx4 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D
2018.         Dim As Double dy4 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D
2019.         Dim As Double dz4 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D
2020.         Dim As Double dw4 = dw0 - 3 * SQUISH_CONSTANT_4D
2021.         Dim As Double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4
2022.         if (attn4 > 0) Then
2023.             attn4 *= attn4
2024.             value += attn4 * attn4 * extrapolate4(xsb + 1, ysb + 1, zsb + 1, wsb + 0, dx4, dy4, dz4, dw4)
2025.         EndIf
2026.
2027.         ''Contribution (1,1,0,1)
2028.         Dim As Double dx3 = dx4
2029.         Dim As Double dy3 = dy4
2030.         Dim As Double dz3 = dz0 - 3 * SQUISH_CONSTANT_4D
2031.         Dim As Double dw3 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D
2032.         Dim As Double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3
2033.         if (attn3 > 0) Then
2034.             attn3 *= attn3
2035.             value += attn3 * attn3 * extrapolate4(xsb + 1, ysb + 1, zsb + 0, wsb + 1, dx3, dy3, dz3, dw3)
2036.         EndIf
2037.
2038.         ''Contribution (1,0,1,1)
2039.         Dim As Double dx2 = dx4
2040.         Dim As Double dy2 = dy0 - 3 * SQUISH_CONSTANT_4D
2041.         Dim As Double dz2 = dz4
2042.         Dim As Double dw2 = dw3
2043.         Dim As Double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2
2044.         if (attn2 > 0) Then
2045.             attn2 *= attn2
2046.             value += attn2 * attn2 * extrapolate4(xsb + 1, ysb + 0, zsb + 1, wsb + 1, dx2, dy2, dz2, dw2)
2047.         EndIf
2048.
2049.         ''Contribution (0,1,1,1)
2050.         Dim As Double dx1 = dx0 - 3 * SQUISH_CONSTANT_4D
2051.         Dim As Double dz1 = dz4
2052.         Dim As Double dy1 = dy4
2053.         Dim As Double dw1 = dw3
2054.         Dim As Double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1
2055.         if (attn1 > 0) Then
2056.             attn1 *= attn1
2057.             value += attn1 * attn1 * extrapolate4(xsb + 0, ysb + 1, zsb + 1, wsb + 1, dx1, dy1, dz1, dw1)
2058.         EndIf
2059.
2060.         ''Contribution (1,1,0,0)
2061.         Dim As Double dx5 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
2062.         Dim As Double dy5 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
2063.         Dim As Double dz5 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D
2064.         Dim As Double dw5 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D
2065.         Dim As Double attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5 - dw5 * dw5
2066.         if (attn5 > 0) Then
2067.             attn5 *= attn5
2068.             value += attn5 * attn5 * extrapolate4(xsb + 1, ysb + 1, zsb + 0, wsb + 0, dx5, dy5, dz5, dw5)
2069.         EndIf
2070.
2071.         ''Contribution (1,0,1,0)
2072.         Dim As Double dx6 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
2073.         Dim As Double dy6 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D
2074.         Dim As Double dz6 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
2075.         Dim As Double dw6 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D
2076.         Dim As Double attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6 - dw6 * dw6
2077.         if (attn6 > 0) Then
2078.             attn6 *= attn6
2079.             value += attn6 * attn6 * extrapolate4(xsb + 1, ysb + 0, zsb + 1, wsb + 0, dx6, dy6, dz6, dw6)
2080.         EndIf
2081.
2082.         ''Contribution (1,0,0,1)
2083.         Dim As Double dx7 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D
2084.         Dim As Double dy7 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D
2085.         Dim As Double dz7 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D
2086.         Dim As Double dw7 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
2087.         Dim As Double attn7 = 2 - dx7 * dx7 - dy7 * dy7 - dz7 * dz7 - dw7 * dw7
2088.         if (attn7 > 0) Then
2089.             attn7 *= attn7
2090.             value += attn7 * attn7 * extrapolate4(xsb + 1, ysb + 0, zsb + 0, wsb + 1, dx7, dy7, dz7, dw7)
2091.         EndIf
2092.
2093.         ''Contribution (0,1,1,0)
2094.         Dim As Double dx8 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D
2095.         Dim As Double dy8 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
2096.         Dim As Double dz8 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
2097.         Dim As Double dw8 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D
2098.         Dim As Double attn8 = 2 - dx8 * dx8 - dy8 * dy8 - dz8 * dz8 - dw8 * dw8
2099.         if (attn8 > 0) Then
2100.             attn8 *= attn8
2101.             value += attn8 * attn8 * extrapolate4(xsb + 0, ysb + 1, zsb + 1, wsb + 0, dx8, dy8, dz8, dw8)
2102.         EndIf
2103.
2104.         ''Contribution (0,1,0,1)
2105.         Dim As Double dx9 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D
2106.         Dim As Double dy9 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D
2107.         Dim As Double dz9 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D
2108.         Dim As Double dw9 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
2109.         Dim As Double attn9 = 2 - dx9 * dx9 - dy9 * dy9 - dz9 * dz9 - dw9 * dw9
2110.         if (attn9 > 0) Then
2111.             attn9 *= attn9
2112.             value += attn9 * attn9 * extrapolate4(xsb + 0, ysb + 1, zsb + 0, wsb + 1, dx9, dy9, dz9, dw9)
2113.         EndIf
2114.
2115.         ''Contribution (0,0,1,1)
2116.         Dim As Double dx10 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D
2117.         Dim As Double dy10 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D
2118.         Dim As Double dz10 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D
2119.         Dim As Double dw10 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D
2120.         Dim As Double attn10 = 2 - dx10 * dx10 - dy10 * dy10 - dz10 * dz10 - dw10 * dw10
2121.         if (attn10 > 0) Then
2122.             attn10 *= attn10
2123.             value += attn10 * attn10 * extrapolate4(xsb + 0, ysb + 0, zsb + 1, wsb + 1, dx10, dy10, dz10, dw10)
2124.         EndIf
2125.     EndIf
2126.
2127.     ''First extra vertex
2128.     Dim As Double attn_ext0 = 2 - dx_ext0 * dx_ext0 - dy_ext0 * dy_ext0 - dz_ext0 * dz_ext0 - dw_ext0 * dw_ext0
2129.     if (attn_ext0 > 0) then
2130.         attn_ext0 *= attn_ext0
2131.         value += attn_ext0 * attn_ext0 * extrapolate4(xsv_ext0, ysv_ext0, zsv_ext0, wsv_ext0, dx_ext0, dy_ext0, dz_ext0, dw_ext0)
2132.     EndIf
2133.
2134.     ''Second extra vertex
2135.     Dim As Double attn_ext1 = 2 - dx_ext1 * dx_ext1 - dy_ext1 * dy_ext1 - dz_ext1 * dz_ext1 - dw_ext1 * dw_ext1
2136.     if (attn_ext1 > 0) Then
2137.         attn_ext1 *= attn_ext1
2138.         value += attn_ext1 * attn_ext1 * extrapolate4(xsv_ext1, ysv_ext1, zsv_ext1, wsv_ext1, dx_ext1, dy_ext1, dz_ext1, dw_ext1)
2139.     EndIf
2140.
2141.     ''Third extra vertex
2142.     Dim As Double attn_ext2 = 2 - dx_ext2 * dx_ext2 - dy_ext2 * dy_ext2 - dz_ext2 * dz_ext2 - dw_ext2 * dw_ext2
2143.     if (attn_ext2 > 0) Then
2144.         attn_ext2 *= attn_ext2
2145.         value += attn_ext2 * attn_ext2 * extrapolate4(xsv_ext2, ysv_ext2, zsv_ext2, wsv_ext2, dx_ext2, dy_ext2, dz_ext2, dw_ext2)
2146.     EndIf
2147.     value/=NORM_CONSTANT_4D
2148.     return value
2149. End Function
RAW Paste Data