1// MIT License
2//
3// Copyright(c) 2020 Jordan Peck (jordan.me2@gmail.com)
4// Copyright(c) 2020 Contributors
5//
6// Permission is hereby granted, free of charge, to any person obtaining a copy
7// of this software and associated documentation files(the "Software"), to deal
8// in the Software without restriction, including without limitation the rights
9// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
10// copies of the Software, and to permit persons to whom the Software is
11// furnished to do so, subject to the following conditions :
12//
13// The above copyright notice and this permission notice shall be included in all
14// copies or substantial portions of the Software.
15//
16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
19// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22// SOFTWARE.
23//
24// .'',;:cldxkO00KKXXNNWWWNNXKOkxdollcc::::::;:::ccllloooolllllllllooollc:,'... ...........',;cldxkO000Okxdlc::;;;,,;;;::cclllllll
25// ..',;:ldxO0KXXNNNNNNNNXXK0kxdolcc::::::;;;,,,,,,;;;;;;;;;;:::cclllllc:;'.... ...........',;:ldxO0KXXXK0Okxdolc::;;;;::cllodddddo
26// ...',:loxO0KXNNNNNXXKK0Okxdolc::;::::::::;;;,,'''''.....''',;:clllllc:;,'............''''''''',;:loxO0KXNNNNNXK0Okxdollccccllodxxxxxxd
27// ....';:ldkO0KXXXKK00Okxdolcc:;;;;;::cclllcc:;;,''..... ....',;clooddolcc:;;;;,,;;;;;::::;;;;;;:cloxk0KXNWWWWWWNXKK0Okxddoooddxxkkkkkxx
28// .....';:ldxkOOOOOkxxdolcc:;;;,,,;;:cllooooolcc:;'... ..,:codxkkkxddooollloooooooollcc:::::clodkO0KXNWWWWWWNNXK00Okxxxxxxxxkkkkxxx
29// . ....';:cloddddo___________,,,,;;:clooddddoolc:,... ..,:ldx__00OOOkkk___kkkkkkxxdollc::::cclodkO0KXXNNNNNNXXK0OOkxxxxxxxxxxxxddd
30// .......',;:cccc:| |,,,;;:cclooddddoll:;'.. ..';cox| \KKK000| |KK00OOkxdocc___;::clldxxkO0KKKKK00Okkxdddddddddddddddoo
31// .......'',,,,,''| ________|',,;;::cclloooooolc:;'......___:ldk| \KK000| |XKKK0Okxolc| |;;::cclodxxkkkkxxdoolllcclllooodddooooo
32// ''......''''....| | ....'',,,,;;;::cclloooollc:;,''.'| |oxk| \OOO0| |KKK00Oxdoll|___|;;;;;::ccllllllcc::;;,,;;;:cclloooooooo
33// ;;,''.......... | |_____',,;;;____:___cllo________.___| |___| \xkk| |KK_______ool___:::;________;;;_______...'',;;:ccclllloo
34// c:;,''......... | |:::/ ' |lo/ | | \dx| |0/ \d| |cc/ |'/ \......',,;;:ccllo
35// ol:;,'..........| _____|ll/ __ |o/ ______|____ ___| | \o| |/ ___ \| |o/ ______|/ ___ \ .......'',;:clo
36// dlc;,...........| |::clooo| / | |x\___ \KXKKK0| |dol| |\ \| | | | | |d\___ \..| | / / ....',:cl
37// xoc;'... .....'| |llodddd| \__| |_____\ \KKK0O| |lc:| |'\ | |___| | |_____\ \.| |_/___/... ...',;:c
38// dlc;'... ....',;| |oddddddo\ | |Okkx| |::;| |..\ |\ /| | | \ |... ....',;:c
39// ol:,'.......',:c|___|xxxddollc\_____,___|_________/ddoll|___|,,,|___|...\_____|:\ ______/l|___|_________/...\________|'........',;::cc
40// c:;'.......';:codxxkkkkxxolc::;::clodxkOO0OOkkxdollc::;;,,''''',,,,''''''''''',,'''''',;:loxkkOOkxol:;,'''',,;:ccllcc:;,'''''',;::ccll
41// ;,'.......',:codxkOO0OOkxdlc:;,,;;:cldxxkkxxdolc:;;,,''.....'',;;:::;;,,,'''''........,;cldkO0KK0Okdoc::;;::cloodddoolc:;;;;;::ccllooo
42// .........',;:lodxOO0000Okdoc:,,',,;:clloddoolc:;,''.......'',;:clooollc:;;,,''.......',:ldkOKXNNXX0Oxdolllloddxxxxxxdolccccccllooodddd
43// . .....';:cldxkO0000Okxol:;,''',,;::cccc:;,,'.......'',;:cldxxkkxxdolc:;;,'.......';coxOKXNWWWNXKOkxddddxxkkkkkkxdoollllooddxxxxkkk
44// ....',;:codxkO000OOxdoc:;,''',,,;;;;,''.......',,;:clodkO00000Okxolc::;,,''..',;:ldxOKXNWWWNNK0OkkkkkkkkkkkxxddooooodxxkOOOOO000
45// ....',;;clodxkkOOOkkdolc:;,,,,,,,,'..........,;:clodxkO0KKXKK0Okxdolcc::;;,,,;;:codkO0XXNNNNXKK0OOOOOkkkkxxdoollloodxkO0KKKXXXXX
46//
47// VERSION: 1.0.1
48// https://github.com/Auburn/FastNoise
49
50#ifndef FASTNOISELITE_H
51#define FASTNOISELITE_H
52
53#include <cmath>
54
55namespace fastnoiselite{
56
57class FastNoiseLite
58{
59public:
60 enum NoiseType
61 {
62 NoiseType_OpenSimplex2,
63 NoiseType_OpenSimplex2S,
64 NoiseType_Cellular,
65 NoiseType_Perlin,
66 NoiseType_ValueCubic,
67 NoiseType_Value
68 };
69
70 enum RotationType3D
71 {
72 RotationType3D_None,
73 RotationType3D_ImproveXYPlanes,
74 RotationType3D_ImproveXZPlanes
75 };
76
77 enum FractalType
78 {
79 FractalType_None,
80 FractalType_FBm,
81 FractalType_Ridged,
82 FractalType_PingPong,
83 FractalType_DomainWarpProgressive,
84 FractalType_DomainWarpIndependent
85 };
86
87 enum CellularDistanceFunction
88 {
89 CellularDistanceFunction_Euclidean,
90 CellularDistanceFunction_EuclideanSq,
91 CellularDistanceFunction_Manhattan,
92 CellularDistanceFunction_Hybrid
93 };
94
95 enum CellularReturnType
96 {
97 CellularReturnType_CellValue,
98 CellularReturnType_Distance,
99 CellularReturnType_Distance2,
100 CellularReturnType_Distance2Add,
101 CellularReturnType_Distance2Sub,
102 CellularReturnType_Distance2Mul,
103 CellularReturnType_Distance2Div
104 };
105
106 enum DomainWarpType
107 {
108 DomainWarpType_OpenSimplex2,
109 DomainWarpType_OpenSimplex2Reduced,
110 DomainWarpType_BasicGrid
111 };
112
113 /// <summary>
114 /// Create new FastNoise object with optional seed
115 /// </summary>
116 FastNoiseLite(int seed = 1337)
117 {
118 mSeed = seed;
119 mFrequency = 0.01f;
120 mNoiseType = NoiseType_OpenSimplex2;
121 mRotationType3D = RotationType3D_None;
122 mTransformType3D = TransformType3D_DefaultOpenSimplex2;
123
124 mFractalType = FractalType_None;
125 mOctaves = 3;
126 mLacunarity = 2.0f;
127 mGain = 0.5f;
128 mWeightedStrength = 0.0f;
129 mPingPongStrength = 2.0f;
130
131 mFractalBounding = 1 / 1.75f;
132
133 mCellularDistanceFunction = CellularDistanceFunction_EuclideanSq;
134 mCellularReturnType = CellularReturnType_Distance;
135 mCellularJitterModifier = 1.0f;
136
137 mDomainWarpType = DomainWarpType_OpenSimplex2;
138 mWarpTransformType3D = TransformType3D_DefaultOpenSimplex2;
139 mDomainWarpAmp = 1.0f;
140 }
141
142 /// <summary>
143 /// Sets seed used for all noise types
144 /// </summary>
145 /// <remarks>
146 /// Default: 1337
147 /// </remarks>
148 void SetSeed(int seed) { mSeed = seed; }
149
150 /// <summary>
151 /// Sets frequency for all noise types
152 /// </summary>
153 /// <remarks>
154 /// Default: 0.01
155 /// </remarks>
156 void SetFrequency(float frequency) { mFrequency = frequency; }
157
158 /// <summary>
159 /// Sets noise algorithm used for GetNoise(...)
160 /// </summary>
161 /// <remarks>
162 /// Default: OpenSimplex2
163 /// </remarks>
164 void SetNoiseType(NoiseType noiseType)
165 {
166 mNoiseType = noiseType;
167 UpdateTransformType3D();
168 }
169
170 /// <summary>
171 /// Sets domain rotation type for 3D Noise and 3D DomainWarp.
172 /// Can aid in reducing directional artifacts when sampling a 2D plane in 3D
173 /// </summary>
174 /// <remarks>
175 /// Default: None
176 /// </remarks>
177 void SetRotationType3D(RotationType3D rotationType3D)
178 {
179 mRotationType3D = rotationType3D;
180 UpdateTransformType3D();
181 UpdateWarpTransformType3D();
182 }
183
184 /// <summary>
185 /// Sets method for combining octaves in all fractal noise types
186 /// </summary>
187 /// <remarks>
188 /// Default: None
189 /// Note: FractalType_DomainWarp... only affects DomainWarp(...)
190 /// </remarks>
191 void SetFractalType(FractalType fractalType) { mFractalType = fractalType; }
192
193 /// <summary>
194 /// Sets octave count for all fractal noise types
195 /// </summary>
196 /// <remarks>
197 /// Default: 3
198 /// </remarks>
199 void SetFractalOctaves(int octaves)
200 {
201 mOctaves = octaves;
202 CalculateFractalBounding();
203 }
204
205 /// <summary>
206 /// Sets octave lacunarity for all fractal noise types
207 /// </summary>
208 /// <remarks>
209 /// Default: 2.0
210 /// </remarks>
211 void SetFractalLacunarity(float lacunarity) { mLacunarity = lacunarity; }
212
213 /// <summary>
214 /// Sets octave gain for all fractal noise types
215 /// </summary>
216 /// <remarks>
217 /// Default: 0.5
218 /// </remarks>
219 void SetFractalGain(float gain)
220 {
221 mGain = gain;
222 CalculateFractalBounding();
223 }
224
225 /// <summary>
226 /// Sets octave weighting for all none DomainWarp fratal types
227 /// </summary>
228 /// <remarks>
229 /// Default: 0.0
230 /// Note: Keep between 0...1 to maintain -1...1 output bounding
231 /// </remarks>
232 void SetFractalWeightedStrength(float weightedStrength) { mWeightedStrength = weightedStrength; }
233
234 /// <summary>
235 /// Sets strength of the fractal ping pong effect
236 /// </summary>
237 /// <remarks>
238 /// Default: 2.0
239 /// </remarks>
240 void SetFractalPingPongStrength(float pingPongStrength) { mPingPongStrength = pingPongStrength; }
241
242
243 /// <summary>
244 /// Sets distance function used in cellular noise calculations
245 /// </summary>
246 /// <remarks>
247 /// Default: Distance
248 /// </remarks>
249 void SetCellularDistanceFunction(CellularDistanceFunction cellularDistanceFunction) { mCellularDistanceFunction = cellularDistanceFunction; }
250
251 /// <summary>
252 /// Sets return type from cellular noise calculations
253 /// </summary>
254 /// <remarks>
255 /// Default: EuclideanSq
256 /// </remarks>
257 void SetCellularReturnType(CellularReturnType cellularReturnType) { mCellularReturnType = cellularReturnType; }
258
259 /// <summary>
260 /// Sets the maximum distance a cellular point can move from it's grid position
261 /// </summary>
262 /// <remarks>
263 /// Default: 1.0
264 /// Note: Setting this higher than 1 will cause artifacts
265 /// </remarks>
266 void SetCellularJitter(float cellularJitter) { mCellularJitterModifier = cellularJitter; }
267
268
269 /// <summary>
270 /// Sets the warp algorithm when using DomainWarp(...)
271 /// </summary>
272 /// <remarks>
273 /// Default: OpenSimplex2
274 /// </remarks>
275 void SetDomainWarpType(DomainWarpType domainWarpType)
276 {
277 mDomainWarpType = domainWarpType;
278 UpdateWarpTransformType3D();
279 }
280
281
282 /// <summary>
283 /// Sets the maximum warp distance from original position when using DomainWarp(...)
284 /// </summary>
285 /// <remarks>
286 /// Default: 1.0
287 /// </remarks>
288 void SetDomainWarpAmp(float domainWarpAmp) { mDomainWarpAmp = domainWarpAmp; }
289
290
291 /// <summary>
292 /// 2D noise at given position using current settings
293 /// </summary>
294 /// <returns>
295 /// Noise output bounded between -1...1
296 /// </returns>
297 template <typename FNfloat>
298 float GetNoise(FNfloat x, FNfloat y) const
299 {
300 Arguments_must_be_floating_point_values<FNfloat>();
301
302 TransformNoiseCoordinate(x, y);
303
304 switch (mFractalType)
305 {
306 default:
307 return GenNoiseSingle(mSeed, x, y);
308 case FractalType_FBm:
309 return GenFractalFBm(x, y);
310 case FractalType_Ridged:
311 return GenFractalRidged(x, y);
312 case FractalType_PingPong:
313 return GenFractalPingPong(x, y);
314 }
315 }
316
317 /// <summary>
318 /// 3D noise at given position using current settings
319 /// </summary>
320 /// <returns>
321 /// Noise output bounded between -1...1
322 /// </returns>
323 template <typename FNfloat>
324 float GetNoise(FNfloat x, FNfloat y, FNfloat z) const
325 {
326 Arguments_must_be_floating_point_values<FNfloat>();
327
328 TransformNoiseCoordinate(x, y, z);
329
330 switch (mFractalType)
331 {
332 default:
333 return GenNoiseSingle(mSeed, x, y, z);
334 case FractalType_FBm:
335 return GenFractalFBm(x, y, z);
336 case FractalType_Ridged:
337 return GenFractalRidged(x, y, z);
338 case FractalType_PingPong:
339 return GenFractalPingPong(x, y, z);
340 }
341 }
342
343
344 /// <summary>
345 /// 2D warps the input position using current domain warp settings
346 /// </summary>
347 /// <example>
348 /// Example usage with GetNoise
349 /// <code>DomainWarp(x, y)
350 /// noise = GetNoise(x, y)</code>
351 /// </example>
352 template <typename FNfloat>
353 void DomainWarp(FNfloat& x, FNfloat& y) const
354 {
355 Arguments_must_be_floating_point_values<FNfloat>();
356
357 switch (mFractalType)
358 {
359 default:
360 DomainWarpSingle(x, y);
361 break;
362 case FractalType_DomainWarpProgressive:
363 DomainWarpFractalProgressive(x, y);
364 break;
365 case FractalType_DomainWarpIndependent:
366 DomainWarpFractalIndependent(x, y);
367 break;
368 }
369 }
370
371 /// <summary>
372 /// 3D warps the input position using current domain warp settings
373 /// </summary>
374 /// <example>
375 /// Example usage with GetNoise
376 /// <code>DomainWarp(x, y, z)
377 /// noise = GetNoise(x, y, z)</code>
378 /// </example>
379 template <typename FNfloat>
380 void DomainWarp(FNfloat& x, FNfloat& y, FNfloat& z) const
381 {
382 Arguments_must_be_floating_point_values<FNfloat>();
383
384 switch (mFractalType)
385 {
386 default:
387 DomainWarpSingle(x, y, z);
388 break;
389 case FractalType_DomainWarpProgressive:
390 DomainWarpFractalProgressive(x, y, z);
391 break;
392 case FractalType_DomainWarpIndependent:
393 DomainWarpFractalIndependent(x, y, z);
394 break;
395 }
396 }
397
398private:
399 template <typename T>
400 struct Arguments_must_be_floating_point_values;
401
402 enum TransformType3D
403 {
404 TransformType3D_None,
405 TransformType3D_ImproveXYPlanes,
406 TransformType3D_ImproveXZPlanes,
407 TransformType3D_DefaultOpenSimplex2
408 };
409
410 int mSeed;
411 float mFrequency;
412 NoiseType mNoiseType;
413 RotationType3D mRotationType3D;
414 TransformType3D mTransformType3D;
415
416 FractalType mFractalType;
417 int mOctaves;
418 float mLacunarity;
419 float mGain;
420 float mWeightedStrength;
421 float mPingPongStrength;
422
423 float mFractalBounding;
424
425 CellularDistanceFunction mCellularDistanceFunction;
426 CellularReturnType mCellularReturnType;
427 float mCellularJitterModifier;
428
429 DomainWarpType mDomainWarpType;
430 TransformType3D mWarpTransformType3D;
431 float mDomainWarpAmp;
432
433
434 template <typename T>
435 struct Lookup
436 {
437 static const T Gradients2D[];
438 static const T Gradients3D[];
439 static const T RandVecs2D[];
440 static const T RandVecs3D[];
441 };
442
443 static float FastMin(float a, float b) { return a < b ? a : b; }
444
445 static float FastMax(float a, float b) { return a > b ? a : b; }
446
447 static float FastAbs(float f) { return f < 0 ? -f : f; }
448
449 static float FastSqrt(float f) { return sqrtf(f); }
450
451 template <typename FNfloat>
452 static int FastFloor(FNfloat f) { return f >= 0 ? (int)f : (int)f - 1; }
453
454 template <typename FNfloat>
455 static int FastRound(FNfloat f) { return f >= 0 ? (int)(f + 0.5f) : (int)(f - 0.5f); }
456
457 static float Lerp(float a, float b, float t) { return a + t * (b - a); }
458
459 static float InterpHermite(float t) { return t * t * (3 - 2 * t); }
460
461 static float InterpQuintic(float t) { return t * t * t * (t * (t * 6 - 15) + 10); }
462
463 static float CubicLerp(float a, float b, float c, float d, float t)
464 {
465 float p = (d - c) - (a - b);
466 return t * t * t * p + t * t * ((a - b) - p) + t * (c - a) + b;
467 }
468
469 static float PingPong(float t)
470 {
471 t -= (int)(t * 0.5f) * 2;
472 return t < 1 ? t : 2 - t;
473 }
474
475 void CalculateFractalBounding()
476 {
477 float gain = FastAbs(mGain);
478 float amp = gain;
479 float ampFractal = 1.0f;
480 for (int i = 1; i < mOctaves; i++)
481 {
482 ampFractal += amp;
483 amp *= gain;
484 }
485 mFractalBounding = 1 / ampFractal;
486 }
487
488 // Hashing
489 static const int PrimeX = 501125321;
490 static const int PrimeY = 1136930381;
491 static const int PrimeZ = 1720413743;
492
493 static int Hash(int seed, int xPrimed, int yPrimed)
494 {
495 int hash = seed ^ xPrimed ^ yPrimed;
496
497 hash *= 0x27d4eb2d;
498 return hash;
499 }
500
501
502 static int Hash(int seed, int xPrimed, int yPrimed, int zPrimed)
503 {
504 int hash = seed ^ xPrimed ^ yPrimed ^ zPrimed;
505
506 hash *= 0x27d4eb2d;
507 return hash;
508 }
509
510
511 static float ValCoord(int seed, int xPrimed, int yPrimed)
512 {
513 int hash = Hash(seed, xPrimed, yPrimed);
514
515 hash *= hash;
516 hash ^= hash << 19;
517 return hash * (1 / 2147483648.0f);
518 }
519
520
521 static float ValCoord(int seed, int xPrimed, int yPrimed, int zPrimed)
522 {
523 int hash = Hash(seed, xPrimed, yPrimed, zPrimed);
524
525 hash *= hash;
526 hash ^= hash << 19;
527 return hash * (1 / 2147483648.0f);
528 }
529
530
531 float GradCoord(int seed, int xPrimed, int yPrimed, float xd, float yd) const
532 {
533 int hash = Hash(seed, xPrimed, yPrimed);
534 hash ^= hash >> 15;
535 hash &= 127 << 1;
536
537 float xg = Lookup<float>::Gradients2D[hash];
538 float yg = Lookup<float>::Gradients2D[hash | 1];
539
540 return xd * xg + yd * yg;
541 }
542
543
544 float GradCoord(int seed, int xPrimed, int yPrimed, int zPrimed, float xd, float yd, float zd) const
545 {
546 int hash = Hash(seed, xPrimed, yPrimed, zPrimed);
547 hash ^= hash >> 15;
548 hash &= 63 << 2;
549
550 float xg = Lookup<float>::Gradients3D[hash];
551 float yg = Lookup<float>::Gradients3D[hash | 1];
552 float zg = Lookup<float>::Gradients3D[hash | 2];
553
554 return xd * xg + yd * yg + zd * zg;
555 }
556
557
558 void GradCoordOut(int seed, int xPrimed, int yPrimed, float& xo, float& yo) const
559 {
560 int hash = Hash(seed, xPrimed, yPrimed) & (255 << 1);
561
562 xo = Lookup<float>::RandVecs2D[hash];
563 yo = Lookup<float>::RandVecs2D[hash | 1];
564 }
565
566
567 void GradCoordOut(int seed, int xPrimed, int yPrimed, int zPrimed, float& xo, float& yo, float& zo) const
568 {
569 int hash = Hash(seed, xPrimed, yPrimed, zPrimed) & (255 << 2);
570
571 xo = Lookup<float>::RandVecs3D[hash];
572 yo = Lookup<float>::RandVecs3D[hash | 1];
573 zo = Lookup<float>::RandVecs3D[hash | 2];
574 }
575
576
577 void GradCoordDual(int seed, int xPrimed, int yPrimed, float xd, float yd, float& xo, float& yo) const
578 {
579 int hash = Hash(seed, xPrimed, yPrimed);
580 int index1 = hash & (127 << 1);
581 int index2 = (hash >> 7) & (255 << 1);
582
583 float xg = Lookup<float>::Gradients2D[index1];
584 float yg = Lookup<float>::Gradients2D[index1 | 1];
585 float value = xd * xg + yd * yg;
586
587 float xgo = Lookup<float>::RandVecs2D[index2];
588 float ygo = Lookup<float>::RandVecs2D[index2 | 1];
589
590 xo = value * xgo;
591 yo = value * ygo;
592 }
593
594
595 void GradCoordDual(int seed, int xPrimed, int yPrimed, int zPrimed, float xd, float yd, float zd, float& xo, float& yo, float& zo) const
596 {
597 int hash = Hash(seed, xPrimed, yPrimed, zPrimed);
598 int index1 = hash & (63 << 2);
599 int index2 = (hash >> 6) & (255 << 2);
600
601 float xg = Lookup<float>::Gradients3D[index1];
602 float yg = Lookup<float>::Gradients3D[index1 | 1];
603 float zg = Lookup<float>::Gradients3D[index1 | 2];
604 float value = xd * xg + yd * yg + zd * zg;
605
606 float xgo = Lookup<float>::RandVecs3D[index2];
607 float ygo = Lookup<float>::RandVecs3D[index2 | 1];
608 float zgo = Lookup<float>::RandVecs3D[index2 | 2];
609
610 xo = value * xgo;
611 yo = value * ygo;
612 zo = value * zgo;
613 }
614
615
616 // Generic noise gen
617
618 template <typename FNfloat>
619 float GenNoiseSingle(int seed, FNfloat x, FNfloat y) const
620 {
621 switch (mNoiseType)
622 {
623 case NoiseType_OpenSimplex2:
624 return SingleSimplex(seed, x, y);
625 case NoiseType_OpenSimplex2S:
626 return SingleOpenSimplex2S(seed, x, y);
627 case NoiseType_Cellular:
628 return SingleCellular(seed, x, y);
629 case NoiseType_Perlin:
630 return SinglePerlin(seed, x, y);
631 case NoiseType_ValueCubic:
632 return SingleValueCubic(seed, x, y);
633 case NoiseType_Value:
634 return SingleValue(seed, x, y);
635 default:
636 return 0;
637 }
638 }
639
640 template <typename FNfloat>
641 float GenNoiseSingle(int seed, FNfloat x, FNfloat y, FNfloat z) const
642 {
643 switch (mNoiseType)
644 {
645 case NoiseType_OpenSimplex2:
646 return SingleOpenSimplex2(seed, x, y, z);
647 case NoiseType_OpenSimplex2S:
648 return SingleOpenSimplex2S(seed, x, y, z);
649 case NoiseType_Cellular:
650 return SingleCellular(seed, x, y, z);
651 case NoiseType_Perlin:
652 return SinglePerlin(seed, x, y, z);
653 case NoiseType_ValueCubic:
654 return SingleValueCubic(seed, x, y, z);
655 case NoiseType_Value:
656 return SingleValue(seed, x, y, z);
657 default:
658 return 0;
659 }
660 }
661
662
663 // Noise Coordinate Transforms (frequency, and possible skew or rotation)
664
665 template <typename FNfloat>
666 void TransformNoiseCoordinate(FNfloat& x, FNfloat& y) const
667 {
668 x *= mFrequency;
669 y *= mFrequency;
670
671 switch (mNoiseType)
672 {
673 case NoiseType_OpenSimplex2:
674 case NoiseType_OpenSimplex2S:
675 {
676 const FNfloat SQRT3 = (FNfloat)1.7320508075688772935274463415059;
677 const FNfloat F2 = 0.5f * (SQRT3 - 1);
678 FNfloat t = (x + y) * F2;
679 x += t;
680 y += t;
681 }
682 break;
683 default:
684 break;
685 }
686 }
687
688 template <typename FNfloat>
689 void TransformNoiseCoordinate(FNfloat& x, FNfloat& y, FNfloat& z) const
690 {
691 x *= mFrequency;
692 y *= mFrequency;
693 z *= mFrequency;
694
695 switch (mTransformType3D)
696 {
697 case TransformType3D_ImproveXYPlanes:
698 {
699 FNfloat xy = x + y;
700 FNfloat s2 = xy * -(FNfloat)0.211324865405187;
701 z *= (FNfloat)0.577350269189626;
702 x += s2 - z;
703 y = y + s2 - z;
704 z += xy * (FNfloat)0.577350269189626;
705 }
706 break;
707 case TransformType3D_ImproveXZPlanes:
708 {
709 FNfloat xz = x + z;
710 FNfloat s2 = xz * -(FNfloat)0.211324865405187;
711 y *= (FNfloat)0.577350269189626;
712 x += s2 - y;
713 z += s2 - y;
714 y += xz * (FNfloat)0.577350269189626;
715 }
716 break;
717 case TransformType3D_DefaultOpenSimplex2:
718 {
719 const FNfloat R3 = (FNfloat)(2.0 / 3.0);
720 FNfloat r = (x + y + z) * R3; // Rotation, not skew
721 x = r - x;
722 y = r - y;
723 z = r - z;
724 }
725 break;
726 default:
727 break;
728 }
729 }
730
731 void UpdateTransformType3D()
732 {
733 switch (mRotationType3D)
734 {
735 case RotationType3D_ImproveXYPlanes:
736 mTransformType3D = TransformType3D_ImproveXYPlanes;
737 break;
738 case RotationType3D_ImproveXZPlanes:
739 mTransformType3D = TransformType3D_ImproveXZPlanes;
740 break;
741 default:
742 switch (mNoiseType)
743 {
744 case NoiseType_OpenSimplex2:
745 case NoiseType_OpenSimplex2S:
746 mTransformType3D = TransformType3D_DefaultOpenSimplex2;
747 break;
748 default:
749 mTransformType3D = TransformType3D_None;
750 break;
751 }
752 break;
753 }
754 }
755
756
757 // Domain Warp Coordinate Transforms
758
759 template <typename FNfloat>
760 void TransformDomainWarpCoordinate(FNfloat& x, FNfloat& y) const
761 {
762 switch (mDomainWarpType)
763 {
764 case DomainWarpType_OpenSimplex2:
765 case DomainWarpType_OpenSimplex2Reduced:
766 {
767 const FNfloat SQRT3 = (FNfloat)1.7320508075688772935274463415059;
768 const FNfloat F2 = 0.5f * (SQRT3 - 1);
769 FNfloat t = (x + y) * F2;
770 x += t;
771 y += t;
772 }
773 break;
774 default:
775 break;
776 }
777 }
778
779 template <typename FNfloat>
780 void TransformDomainWarpCoordinate(FNfloat& x, FNfloat& y, FNfloat& z) const
781 {
782 switch (mWarpTransformType3D)
783 {
784 case TransformType3D_ImproveXYPlanes:
785 {
786 FNfloat xy = x + y;
787 FNfloat s2 = xy * -(FNfloat)0.211324865405187;
788 z *= (FNfloat)0.577350269189626;
789 x += s2 - z;
790 y = y + s2 - z;
791 z += xy * (FNfloat)0.577350269189626;
792 }
793 break;
794 case TransformType3D_ImproveXZPlanes:
795 {
796 FNfloat xz = x + z;
797 FNfloat s2 = xz * -(FNfloat)0.211324865405187;
798 y *= (FNfloat)0.577350269189626;
799 x += s2 - y;
800 z += s2 - y;
801 y += xz * (FNfloat)0.577350269189626;
802 }
803 break;
804 case TransformType3D_DefaultOpenSimplex2:
805 {
806 const FNfloat R3 = (FNfloat)(2.0 / 3.0);
807 FNfloat r = (x + y + z) * R3; // Rotation, not skew
808 x = r - x;
809 y = r - y;
810 z = r - z;
811 }
812 break;
813 default:
814 break;
815 }
816 }
817
818 void UpdateWarpTransformType3D()
819 {
820 switch (mRotationType3D)
821 {
822 case RotationType3D_ImproveXYPlanes:
823 mWarpTransformType3D = TransformType3D_ImproveXYPlanes;
824 break;
825 case RotationType3D_ImproveXZPlanes:
826 mWarpTransformType3D = TransformType3D_ImproveXZPlanes;
827 break;
828 default:
829 switch (mDomainWarpType)
830 {
831 case DomainWarpType_OpenSimplex2:
832 case DomainWarpType_OpenSimplex2Reduced:
833 mWarpTransformType3D = TransformType3D_DefaultOpenSimplex2;
834 break;
835 default:
836 mWarpTransformType3D = TransformType3D_None;
837 break;
838 }
839 break;
840 }
841 }
842
843
844 // Fractal FBm
845
846 template <typename FNfloat>
847 float GenFractalFBm(FNfloat x, FNfloat y) const
848 {
849 int seed = mSeed;
850 float sum = 0;
851 float amp = mFractalBounding;
852
853 for (int i = 0; i < mOctaves; i++)
854 {
855 float noise = GenNoiseSingle(seed++, x, y);
856 sum += noise * amp;
857 amp *= Lerp(1.0f, FastMin(noise + 1, 2) * 0.5f, mWeightedStrength);
858
859 x *= mLacunarity;
860 y *= mLacunarity;
861 amp *= mGain;
862 }
863
864 return sum;
865 }
866
867 template <typename FNfloat>
868 float GenFractalFBm(FNfloat x, FNfloat y, FNfloat z) const
869 {
870 int seed = mSeed;
871 float sum = 0;
872 float amp = mFractalBounding;
873
874 for (int i = 0; i < mOctaves; i++)
875 {
876 float noise = GenNoiseSingle(seed++, x, y, z);
877 sum += noise * amp;
878 amp *= Lerp(1.0f, (noise + 1) * 0.5f, mWeightedStrength);
879
880 x *= mLacunarity;
881 y *= mLacunarity;
882 z *= mLacunarity;
883 amp *= mGain;
884 }
885
886 return sum;
887 }
888
889
890 // Fractal Ridged
891
892 template <typename FNfloat>
893 float GenFractalRidged(FNfloat x, FNfloat y) const
894 {
895 int seed = mSeed;
896 float sum = 0;
897 float amp = mFractalBounding;
898
899 for (int i = 0; i < mOctaves; i++)
900 {
901 float noise = FastAbs(GenNoiseSingle(seed++, x, y));
902 sum += (noise * -2 + 1) * amp;
903 amp *= Lerp(1.0f, 1 - noise, mWeightedStrength);
904
905 x *= mLacunarity;
906 y *= mLacunarity;
907 amp *= mGain;
908 }
909
910 return sum;
911 }
912
913 template <typename FNfloat>
914 float GenFractalRidged(FNfloat x, FNfloat y, FNfloat z) const
915 {
916 int seed = mSeed;
917 float sum = 0;
918 float amp = mFractalBounding;
919
920 for (int i = 0; i < mOctaves; i++)
921 {
922 float noise = FastAbs(GenNoiseSingle(seed++, x, y, z));
923 sum += (noise * -2 + 1) * amp;
924 amp *= Lerp(1.0f, 1 - noise, mWeightedStrength);
925
926 x *= mLacunarity;
927 y *= mLacunarity;
928 z *= mLacunarity;
929 amp *= mGain;
930 }
931
932 return sum;
933 }
934
935
936 // Fractal PingPong
937
938 template <typename FNfloat>
939 float GenFractalPingPong(FNfloat x, FNfloat y) const
940 {
941 int seed = mSeed;
942 float sum = 0;
943 float amp = mFractalBounding;
944
945 for (int i = 0; i < mOctaves; i++)
946 {
947 float noise = PingPong((GenNoiseSingle(seed++, x, y) + 1) * mPingPongStrength);
948 sum += (noise - 0.5f) * 2 * amp;
949 amp *= Lerp(1.0f, noise, mWeightedStrength);
950
951 x *= mLacunarity;
952 y *= mLacunarity;
953 amp *= mGain;
954 }
955
956 return sum;
957 }
958
959 template <typename FNfloat>
960 float GenFractalPingPong(FNfloat x, FNfloat y, FNfloat z) const
961 {
962 int seed = mSeed;
963 float sum = 0;
964 float amp = mFractalBounding;
965
966 for (int i = 0; i < mOctaves; i++)
967 {
968 float noise = PingPong((GenNoiseSingle(seed++, x, y, z) + 1) * mPingPongStrength);
969 sum += (noise - 0.5f) * 2 * amp;
970 amp *= Lerp(1.0f, noise, mWeightedStrength);
971
972 x *= mLacunarity;
973 y *= mLacunarity;
974 z *= mLacunarity;
975 amp *= mGain;
976 }
977
978 return sum;
979 }
980
981
982 // Simplex/OpenSimplex2 Noise
983
984 template <typename FNfloat>
985 float SingleSimplex(int seed, FNfloat x, FNfloat y) const
986 {
987 // 2D OpenSimplex2 case uses the same algorithm as ordinary Simplex.
988
989 const float SQRT3 = 1.7320508075688772935274463415059f;
990 const float G2 = (3 - SQRT3) / 6;
991
992 /*
993 * --- Skew moved to TransformNoiseCoordinate method ---
994 * const FNfloat F2 = 0.5f * (SQRT3 - 1);
995 * FNfloat s = (x + y) * F2;
996 * x += s; y += s;
997 */
998
999 int i = FastFloor(x);
1000 int j = FastFloor(y);
1001 float xi = (float)(x - i);
1002 float yi = (float)(y - j);
1003
1004 float t = (xi + yi) * G2;
1005 float x0 = (float)(xi - t);
1006 float y0 = (float)(yi - t);
1007
1008 i *= PrimeX;
1009 j *= PrimeY;
1010
1011 float n0, n1, n2;
1012
1013 float a = 0.5f - x0 * x0 - y0 * y0;
1014 if (a <= 0) n0 = 0;
1015 else
1016 {
1017 n0 = (a * a) * (a * a) * GradCoord(seed, i, j, x0, y0);
1018 }
1019
1020 float c = (float)(2 * (1 - 2 * G2) * (1 / G2 - 2)) * t + ((float)(-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a);
1021 if (c <= 0) n2 = 0;
1022 else
1023 {
1024 float x2 = x0 + (2 * (float)G2 - 1);
1025 float y2 = y0 + (2 * (float)G2 - 1);
1026 n2 = (c * c) * (c * c) * GradCoord(seed, i + PrimeX, j + PrimeY, x2, y2);
1027 }
1028
1029 if (y0 > x0)
1030 {
1031 float x1 = x0 + (float)G2;
1032 float y1 = y0 + ((float)G2 - 1);
1033 float b = 0.5f - x1 * x1 - y1 * y1;
1034 if (b <= 0) n1 = 0;
1035 else
1036 {
1037 n1 = (b * b) * (b * b) * GradCoord(seed, i, j + PrimeY, x1, y1);
1038 }
1039 }
1040 else
1041 {
1042 float x1 = x0 + ((float)G2 - 1);
1043 float y1 = y0 + (float)G2;
1044 float b = 0.5f - x1 * x1 - y1 * y1;
1045 if (b <= 0) n1 = 0;
1046 else
1047 {
1048 n1 = (b * b) * (b * b) * GradCoord(seed, i + PrimeX, j, x1, y1);
1049 }
1050 }
1051
1052 return (n0 + n1 + n2) * 99.83685446303647f;
1053 }
1054
1055 template <typename FNfloat>
1056 float SingleOpenSimplex2(int seed, FNfloat x, FNfloat y, FNfloat z) const
1057 {
1058 // 3D OpenSimplex2 case uses two offset rotated cube grids.
1059
1060 /*
1061 * --- Rotation moved to TransformNoiseCoordinate method ---
1062 * const FNfloat R3 = (FNfloat)(2.0 / 3.0);
1063 * FNfloat r = (x + y + z) * R3; // Rotation, not skew
1064 * x = r - x; y = r - y; z = r - z;
1065 */
1066
1067 int i = FastRound(x);
1068 int j = FastRound(y);
1069 int k = FastRound(z);
1070 float x0 = (float)(x - i);
1071 float y0 = (float)(y - j);
1072 float z0 = (float)(z - k);
1073
1074 int xNSign = (int)(-1.0f - x0) | 1;
1075 int yNSign = (int)(-1.0f - y0) | 1;
1076 int zNSign = (int)(-1.0f - z0) | 1;
1077
1078 float ax0 = xNSign * -x0;
1079 float ay0 = yNSign * -y0;
1080 float az0 = zNSign * -z0;
1081
1082 i *= PrimeX;
1083 j *= PrimeY;
1084 k *= PrimeZ;
1085
1086 float value = 0;
1087 float a = (0.6f - x0 * x0) - (y0 * y0 + z0 * z0);
1088
1089 for (int l = 0; ; l++)
1090 {
1091 if (a > 0)
1092 {
1093 value += (a * a) * (a * a) * GradCoord(seed, i, j, k, x0, y0, z0);
1094 }
1095
1096 float b = a + 1;
1097 int i1 = i;
1098 int j1 = j;
1099 int k1 = k;
1100 float x1 = x0;
1101 float y1 = y0;
1102 float z1 = z0;
1103
1104 if (ax0 >= ay0 && ax0 >= az0)
1105 {
1106 x1 += xNSign;
1107 b -= xNSign * 2 * x1;
1108 i1 -= xNSign * PrimeX;
1109 }
1110 else if (ay0 > ax0 && ay0 >= az0)
1111 {
1112 y1 += yNSign;
1113 b -= yNSign * 2 * y1;
1114 j1 -= yNSign * PrimeY;
1115 }
1116 else
1117 {
1118 z1 += zNSign;
1119 b -= zNSign * 2 * z1;
1120 k1 -= zNSign * PrimeZ;
1121 }
1122
1123 if (b > 0)
1124 {
1125 value += (b * b) * (b * b) * GradCoord(seed, i1, j1, k1, x1, y1, z1);
1126 }
1127
1128 if (l == 1) break;
1129
1130 ax0 = 0.5f - ax0;
1131 ay0 = 0.5f - ay0;
1132 az0 = 0.5f - az0;
1133
1134 x0 = xNSign * ax0;
1135 y0 = yNSign * ay0;
1136 z0 = zNSign * az0;
1137
1138 a += (0.75f - ax0) - (ay0 + az0);
1139
1140 i += (xNSign >> 1) & PrimeX;
1141 j += (yNSign >> 1) & PrimeY;
1142 k += (zNSign >> 1) & PrimeZ;
1143
1144 xNSign = -xNSign;
1145 yNSign = -yNSign;
1146 zNSign = -zNSign;
1147
1148 seed = ~seed;
1149 }
1150
1151 return value * 32.69428253173828125f;
1152 }
1153
1154
1155 // OpenSimplex2S Noise
1156
1157 template <typename FNfloat>
1158 float SingleOpenSimplex2S(int seed, FNfloat x, FNfloat y) const
1159 {
1160 // 2D OpenSimplex2S case is a modified 2D simplex noise.
1161
1162 const FNfloat SQRT3 = (FNfloat)1.7320508075688772935274463415059;
1163 const FNfloat G2 = (3 - SQRT3) / 6;
1164
1165 /*
1166 * --- Skew moved to TransformNoiseCoordinate method ---
1167 * const FNfloat F2 = 0.5f * (SQRT3 - 1);
1168 * FNfloat s = (x + y) * F2;
1169 * x += s; y += s;
1170 */
1171
1172 int i = FastFloor(x);
1173 int j = FastFloor(y);
1174 float xi = (float)(x - i);
1175 float yi = (float)(y - j);
1176
1177 i *= PrimeX;
1178 j *= PrimeY;
1179 int i1 = i + PrimeX;
1180 int j1 = j + PrimeY;
1181
1182 float t = (xi + yi) * (float)G2;
1183 float x0 = xi - t;
1184 float y0 = yi - t;
1185
1186 float a0 = (2.0f / 3.0f) - x0 * x0 - y0 * y0;
1187 float value = (a0 * a0) * (a0 * a0) * GradCoord(seed, i, j, x0, y0);
1188
1189 float a1 = (float)(2 * (1 - 2 * G2) * (1 / G2 - 2)) * t + ((float)(-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a0);
1190 float x1 = x0 - (float)(1 - 2 * G2);
1191 float y1 = y0 - (float)(1 - 2 * G2);
1192 value += (a1 * a1) * (a1 * a1) * GradCoord(seed, i1, j1, x1, y1);
1193
1194 // Nested conditionals were faster than compact bit logic/arithmetic.
1195 float xmyi = xi - yi;
1196 if (t > G2)
1197 {
1198 if (xi + xmyi > 1)
1199 {
1200 float x2 = x0 + (float)(3 * G2 - 2);
1201 float y2 = y0 + (float)(3 * G2 - 1);
1202 float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
1203 if (a2 > 0)
1204 {
1205 value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i + (PrimeX << 1), j + PrimeY, x2, y2);
1206 }
1207 }
1208 else
1209 {
1210 float x2 = x0 + (float)G2;
1211 float y2 = y0 + (float)(G2 - 1);
1212 float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
1213 if (a2 > 0)
1214 {
1215 value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i, j + PrimeY, x2, y2);
1216 }
1217 }
1218
1219 if (yi - xmyi > 1)
1220 {
1221 float x3 = x0 + (float)(3 * G2 - 1);
1222 float y3 = y0 + (float)(3 * G2 - 2);
1223 float a3 = (2.0f / 3.0f) - x3 * x3 - y3 * y3;
1224 if (a3 > 0)
1225 {
1226 value += (a3 * a3) * (a3 * a3) * GradCoord(seed, i + PrimeX, j + (PrimeY << 1), x3, y3);
1227 }
1228 }
1229 else
1230 {
1231 float x3 = x0 + (float)(G2 - 1);
1232 float y3 = y0 + (float)G2;
1233 float a3 = (2.0f / 3.0f) - x3 * x3 - y3 * y3;
1234 if (a3 > 0)
1235 {
1236 value += (a3 * a3) * (a3 * a3) * GradCoord(seed, i + PrimeX, j, x3, y3);
1237 }
1238 }
1239 }
1240 else
1241 {
1242 if (xi + xmyi < 0)
1243 {
1244 float x2 = x0 + (float)(1 - G2);
1245 float y2 = y0 - (float)G2;
1246 float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
1247 if (a2 > 0)
1248 {
1249 value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i - PrimeX, j, x2, y2);
1250 }
1251 }
1252 else
1253 {
1254 float x2 = x0 + (float)(G2 - 1);
1255 float y2 = y0 + (float)G2;
1256 float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
1257 if (a2 > 0)
1258 {
1259 value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i + PrimeX, j, x2, y2);
1260 }
1261 }
1262
1263 if (yi < xmyi)
1264 {
1265 float x2 = x0 - (float)G2;
1266 float y2 = y0 - (float)(G2 - 1);
1267 float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
1268 if (a2 > 0)
1269 {
1270 value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i, j - PrimeY, x2, y2);
1271 }
1272 }
1273 else
1274 {
1275 float x2 = x0 + (float)G2;
1276 float y2 = y0 + (float)(G2 - 1);
1277 float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
1278 if (a2 > 0)
1279 {
1280 value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i, j + PrimeY, x2, y2);
1281 }
1282 }
1283 }
1284
1285 return value * 18.24196194486065f;
1286 }
1287
1288 template <typename FNfloat>
1289 float SingleOpenSimplex2S(int seed, FNfloat x, FNfloat y, FNfloat z) const
1290 {
1291 // 3D OpenSimplex2S case uses two offset rotated cube grids.
1292
1293 /*
1294 * --- Rotation moved to TransformNoiseCoordinate method ---
1295 * const FNfloat R3 = (FNfloat)(2.0 / 3.0);
1296 * FNfloat r = (x + y + z) * R3; // Rotation, not skew
1297 * x = r - x; y = r - y; z = r - z;
1298 */
1299
1300 int i = FastFloor(x);
1301 int j = FastFloor(y);
1302 int k = FastFloor(z);
1303 float xi = (float)(x - i);
1304 float yi = (float)(y - j);
1305 float zi = (float)(z - k);
1306
1307 i *= PrimeX;
1308 j *= PrimeY;
1309 k *= PrimeZ;
1310 int seed2 = seed + 1293373;
1311
1312 int xNMask = (int)(-0.5f - xi);
1313 int yNMask = (int)(-0.5f - yi);
1314 int zNMask = (int)(-0.5f - zi);
1315
1316 float x0 = xi + xNMask;
1317 float y0 = yi + yNMask;
1318 float z0 = zi + zNMask;
1319 float a0 = 0.75f - x0 * x0 - y0 * y0 - z0 * z0;
1320 float value = (a0 * a0) * (a0 * a0) * GradCoord(seed,
1321 i + (xNMask & PrimeX), j + (yNMask & PrimeY), k + (zNMask & PrimeZ), x0, y0, z0);
1322
1323 float x1 = xi - 0.5f;
1324 float y1 = yi - 0.5f;
1325 float z1 = zi - 0.5f;
1326 float a1 = 0.75f - x1 * x1 - y1 * y1 - z1 * z1;
1327 value += (a1 * a1) * (a1 * a1) * GradCoord(seed2,
1328 i + PrimeX, j + PrimeY, k + PrimeZ, x1, y1, z1);
1329
1330 float xAFlipMask0 = ((xNMask | 1) << 1) * x1;
1331 float yAFlipMask0 = ((yNMask | 1) << 1) * y1;
1332 float zAFlipMask0 = ((zNMask | 1) << 1) * z1;
1333 float xAFlipMask1 = (-2 - (xNMask << 2)) * x1 - 1.0f;
1334 float yAFlipMask1 = (-2 - (yNMask << 2)) * y1 - 1.0f;
1335 float zAFlipMask1 = (-2 - (zNMask << 2)) * z1 - 1.0f;
1336
1337 bool skip5 = false;
1338 float a2 = xAFlipMask0 + a0;
1339 if (a2 > 0)
1340 {
1341 float x2 = x0 - (xNMask | 1);
1342 float y2 = y0;
1343 float z2 = z0;
1344 value += (a2 * a2) * (a2 * a2) * GradCoord(seed,
1345 i + (~xNMask & PrimeX), j + (yNMask & PrimeY), k + (zNMask & PrimeZ), x2, y2, z2);
1346 }
1347 else
1348 {
1349 float a3 = yAFlipMask0 + zAFlipMask0 + a0;
1350 if (a3 > 0)
1351 {
1352 float x3 = x0;
1353 float y3 = y0 - (yNMask | 1);
1354 float z3 = z0 - (zNMask | 1);
1355 value += (a3 * a3) * (a3 * a3) * GradCoord(seed,
1356 i + (xNMask & PrimeX), j + (~yNMask & PrimeY), k + (~zNMask & PrimeZ), x3, y3, z3);
1357 }
1358
1359 float a4 = xAFlipMask1 + a1;
1360 if (a4 > 0)
1361 {
1362 float x4 = (xNMask | 1) + x1;
1363 float y4 = y1;
1364 float z4 = z1;
1365 value += (a4 * a4) * (a4 * a4) * GradCoord(seed2,
1366 i + (xNMask & (PrimeX * 2)), j + PrimeY, k + PrimeZ, x4, y4, z4);
1367 skip5 = true;
1368 }
1369 }
1370
1371 bool skip9 = false;
1372 float a6 = yAFlipMask0 + a0;
1373 if (a6 > 0)
1374 {
1375 float x6 = x0;
1376 float y6 = y0 - (yNMask | 1);
1377 float z6 = z0;
1378 value += (a6 * a6) * (a6 * a6) * GradCoord(seed,
1379 i + (xNMask & PrimeX), j + (~yNMask & PrimeY), k + (zNMask & PrimeZ), x6, y6, z6);
1380 }
1381 else
1382 {
1383 float a7 = xAFlipMask0 + zAFlipMask0 + a0;
1384 if (a7 > 0)
1385 {
1386 float x7 = x0 - (xNMask | 1);
1387 float y7 = y0;
1388 float z7 = z0 - (zNMask | 1);
1389 value += (a7 * a7) * (a7 * a7) * GradCoord(seed,
1390 i + (~xNMask & PrimeX), j + (yNMask & PrimeY), k + (~zNMask & PrimeZ), x7, y7, z7);
1391 }
1392
1393 float a8 = yAFlipMask1 + a1;
1394 if (a8 > 0)
1395 {
1396 float x8 = x1;
1397 float y8 = (yNMask | 1) + y1;
1398 float z8 = z1;
1399 value += (a8 * a8) * (a8 * a8) * GradCoord(seed2,
1400 i + PrimeX, j + (yNMask & (PrimeY << 1)), k + PrimeZ, x8, y8, z8);
1401 skip9 = true;
1402 }
1403 }
1404
1405 bool skipD = false;
1406 float aA = zAFlipMask0 + a0;
1407 if (aA > 0)
1408 {
1409 float xA = x0;
1410 float yA = y0;
1411 float zA = z0 - (zNMask | 1);
1412 value += (aA * aA) * (aA * aA) * GradCoord(seed,
1413 i + (xNMask & PrimeX), j + (yNMask & PrimeY), k + (~zNMask & PrimeZ), xA, yA, zA);
1414 }
1415 else
1416 {
1417 float aB = xAFlipMask0 + yAFlipMask0 + a0;
1418 if (aB > 0)
1419 {
1420 float xB = x0 - (xNMask | 1);
1421 float yB = y0 - (yNMask | 1);
1422 float zB = z0;
1423 value += (aB * aB) * (aB * aB) * GradCoord(seed,
1424 i + (~xNMask & PrimeX), j + (~yNMask & PrimeY), k + (zNMask & PrimeZ), xB, yB, zB);
1425 }
1426
1427 float aC = zAFlipMask1 + a1;
1428 if (aC > 0)
1429 {
1430 float xC = x1;
1431 float yC = y1;
1432 float zC = (zNMask | 1) + z1;
1433 value += (aC * aC) * (aC * aC) * GradCoord(seed2,
1434 i + PrimeX, j + PrimeY, k + (zNMask & (PrimeZ << 1)), xC, yC, zC);
1435 skipD = true;
1436 }
1437 }
1438
1439 if (!skip5)
1440 {
1441 float a5 = yAFlipMask1 + zAFlipMask1 + a1;
1442 if (a5 > 0)
1443 {
1444 float x5 = x1;
1445 float y5 = (yNMask | 1) + y1;
1446 float z5 = (zNMask | 1) + z1;
1447 value += (a5 * a5) * (a5 * a5) * GradCoord(seed2,
1448 i + PrimeX, j + (yNMask & (PrimeY << 1)), k + (zNMask & (PrimeZ << 1)), x5, y5, z5);
1449 }
1450 }
1451
1452 if (!skip9)
1453 {
1454 float a9 = xAFlipMask1 + zAFlipMask1 + a1;
1455 if (a9 > 0)
1456 {
1457 float x9 = (xNMask | 1) + x1;
1458 float y9 = y1;
1459 float z9 = (zNMask | 1) + z1;
1460 value += (a9 * a9) * (a9 * a9) * GradCoord(seed2,
1461 i + (xNMask & (PrimeX * 2)), j + PrimeY, k + (zNMask & (PrimeZ << 1)), x9, y9, z9);
1462 }
1463 }
1464
1465 if (!skipD)
1466 {
1467 float aD = xAFlipMask1 + yAFlipMask1 + a1;
1468 if (aD > 0)
1469 {
1470 float xD = (xNMask | 1) + x1;
1471 float yD = (yNMask | 1) + y1;
1472 float zD = z1;
1473 value += (aD * aD) * (aD * aD) * GradCoord(seed2,
1474 i + (xNMask & (PrimeX << 1)), j + (yNMask & (PrimeY << 1)), k + PrimeZ, xD, yD, zD);
1475 }
1476 }
1477
1478 return value * 9.046026385208288f;
1479 }
1480
1481
1482 // Cellular Noise
1483
1484 template <typename FNfloat>
1485 float SingleCellular(int seed, FNfloat x, FNfloat y) const
1486 {
1487 int xr = FastRound(x);
1488 int yr = FastRound(y);
1489
1490 float distance0 = 1e10f;
1491 float distance1 = 1e10f;
1492 int closestHash = 0;
1493
1494 float cellularJitter = 0.43701595f * mCellularJitterModifier;
1495
1496 int xPrimed = (xr - 1) * PrimeX;
1497 int yPrimedBase = (yr - 1) * PrimeY;
1498
1499 switch (mCellularDistanceFunction)
1500 {
1501 default:
1502 case CellularDistanceFunction_Euclidean:
1503 case CellularDistanceFunction_EuclideanSq:
1504 for (int xi = xr - 1; xi <= xr + 1; xi++)
1505 {
1506 int yPrimed = yPrimedBase;
1507
1508 for (int yi = yr - 1; yi <= yr + 1; yi++)
1509 {
1510 int hash = Hash(seed, xPrimed, yPrimed);
1511 int idx = hash & (255 << 1);
1512
1513 float vecX = (float)(xi - x) + Lookup<float>::RandVecs2D[idx] * cellularJitter;
1514 float vecY = (float)(yi - y) + Lookup<float>::RandVecs2D[idx | 1] * cellularJitter;
1515
1516 float newDistance = vecX * vecX + vecY * vecY;
1517
1518 distance1 = FastMax(FastMin(distance1, newDistance), distance0);
1519 if (newDistance < distance0)
1520 {
1521 distance0 = newDistance;
1522 closestHash = hash;
1523 }
1524 yPrimed += PrimeY;
1525 }
1526 xPrimed += PrimeX;
1527 }
1528 break;
1529 case CellularDistanceFunction_Manhattan:
1530 for (int xi = xr - 1; xi <= xr + 1; xi++)
1531 {
1532 int yPrimed = yPrimedBase;
1533
1534 for (int yi = yr - 1; yi <= yr + 1; yi++)
1535 {
1536 int hash = Hash(seed, xPrimed, yPrimed);
1537 int idx = hash & (255 << 1);
1538
1539 float vecX = (float)(xi - x) + Lookup<float>::RandVecs2D[idx] * cellularJitter;
1540 float vecY = (float)(yi - y) + Lookup<float>::RandVecs2D[idx | 1] * cellularJitter;
1541
1542 float newDistance = FastAbs(vecX) + FastAbs(vecY);
1543
1544 distance1 = FastMax(FastMin(distance1, newDistance), distance0);
1545 if (newDistance < distance0)
1546 {
1547 distance0 = newDistance;
1548 closestHash = hash;
1549 }
1550 yPrimed += PrimeY;
1551 }
1552 xPrimed += PrimeX;
1553 }
1554 break;
1555 case CellularDistanceFunction_Hybrid:
1556 for (int xi = xr - 1; xi <= xr + 1; xi++)
1557 {
1558 int yPrimed = yPrimedBase;
1559
1560 for (int yi = yr - 1; yi <= yr + 1; yi++)
1561 {
1562 int hash = Hash(seed, xPrimed, yPrimed);
1563 int idx = hash & (255 << 1);
1564
1565 float vecX = (float)(xi - x) + Lookup<float>::RandVecs2D[idx] * cellularJitter;
1566 float vecY = (float)(yi - y) + Lookup<float>::RandVecs2D[idx | 1] * cellularJitter;
1567
1568 float newDistance = (FastAbs(vecX) + FastAbs(vecY)) + (vecX * vecX + vecY * vecY);
1569
1570 distance1 = FastMax(FastMin(distance1, newDistance), distance0);
1571 if (newDistance < distance0)
1572 {
1573 distance0 = newDistance;
1574 closestHash = hash;
1575 }
1576 yPrimed += PrimeY;
1577 }
1578 xPrimed += PrimeX;
1579 }
1580 break;
1581 }
1582
1583 if (mCellularDistanceFunction == CellularDistanceFunction_Euclidean && mCellularReturnType >= CellularReturnType_Distance)
1584 {
1585 distance0 = FastSqrt(distance0);
1586
1587 if (mCellularReturnType >= CellularReturnType_Distance2)
1588 {
1589 distance1 = FastSqrt(distance1);
1590 }
1591 }
1592
1593 switch (mCellularReturnType)
1594 {
1595 case CellularReturnType_CellValue:
1596 return closestHash * (1 / 2147483648.0f);
1597 case CellularReturnType_Distance:
1598 return distance0 - 1;
1599 case CellularReturnType_Distance2:
1600 return distance1 - 1;
1601 case CellularReturnType_Distance2Add:
1602 return (distance1 + distance0) * 0.5f - 1;
1603 case CellularReturnType_Distance2Sub:
1604 return distance1 - distance0 - 1;
1605 case CellularReturnType_Distance2Mul:
1606 return distance1 * distance0 * 0.5f - 1;
1607 case CellularReturnType_Distance2Div:
1608 return distance0 / distance1 - 1;
1609 default:
1610 return 0;
1611 }
1612 }
1613
1614// GCC raises warnings when integer overflows occur, which are needed for hashing here.
1615#if defined(__GNUC__) && !defined(__clang__)
1616#pragma GCC diagnostic push
1617#pragma GCC diagnostic ignored "-Waggressive-loop-optimizations"
1618#endif
1619
1620 template <typename FNfloat>
1621 float SingleCellular(int seed, FNfloat x, FNfloat y, FNfloat z) const
1622 {
1623 int xr = FastRound(x);
1624 int yr = FastRound(y);
1625 int zr = FastRound(z);
1626
1627 float distance0 = 1e10f;
1628 float distance1 = 1e10f;
1629 int closestHash = 0;
1630
1631 float cellularJitter = 0.39614353f * mCellularJitterModifier;
1632
1633 int xPrimed = (xr - 1) * PrimeX;
1634 int yPrimedBase = (yr - 1) * PrimeY;
1635 int zPrimedBase = (zr - 1) * PrimeZ;
1636
1637 switch (mCellularDistanceFunction)
1638 {
1639 case CellularDistanceFunction_Euclidean:
1640 case CellularDistanceFunction_EuclideanSq:
1641 for (int xi = xr - 1; xi <= xr + 1; xi++)
1642 {
1643 int yPrimed = yPrimedBase;
1644
1645 for (int yi = yr - 1; yi <= yr + 1; yi++)
1646 {
1647 int zPrimed = zPrimedBase;
1648
1649 for (int zi = zr - 1; zi <= zr + 1; zi++)
1650 {
1651 int hash = Hash(seed, xPrimed, yPrimed, zPrimed);
1652 int idx = hash & (255 << 2);
1653
1654 float vecX = (float)(xi - x) + Lookup<float>::RandVecs3D[idx] * cellularJitter;
1655 float vecY = (float)(yi - y) + Lookup<float>::RandVecs3D[idx | 1] * cellularJitter;
1656 float vecZ = (float)(zi - z) + Lookup<float>::RandVecs3D[idx | 2] * cellularJitter;
1657
1658 float newDistance = vecX * vecX + vecY * vecY + vecZ * vecZ;
1659
1660 distance1 = FastMax(FastMin(distance1, newDistance), distance0);
1661 if (newDistance < distance0)
1662 {
1663 distance0 = newDistance;
1664 closestHash = hash;
1665 }
1666 zPrimed += PrimeZ;
1667 }
1668 yPrimed += PrimeY;
1669 }
1670 xPrimed += PrimeX;
1671 }
1672 break;
1673 case CellularDistanceFunction_Manhattan:
1674 for (int xi = xr - 1; xi <= xr + 1; xi++)
1675 {
1676 int yPrimed = yPrimedBase;
1677
1678 for (int yi = yr - 1; yi <= yr + 1; yi++)
1679 {
1680 int zPrimed = zPrimedBase;
1681
1682 for (int zi = zr - 1; zi <= zr + 1; zi++)
1683 {
1684 int hash = Hash(seed, xPrimed, yPrimed, zPrimed);
1685 int idx = hash & (255 << 2);
1686
1687 float vecX = (float)(xi - x) + Lookup<float>::RandVecs3D[idx] * cellularJitter;
1688 float vecY = (float)(yi - y) + Lookup<float>::RandVecs3D[idx | 1] * cellularJitter;
1689 float vecZ = (float)(zi - z) + Lookup<float>::RandVecs3D[idx | 2] * cellularJitter;
1690
1691 float newDistance = FastAbs(vecX) + FastAbs(vecY) + FastAbs(vecZ);
1692
1693 distance1 = FastMax(FastMin(distance1, newDistance), distance0);
1694 if (newDistance < distance0)
1695 {
1696 distance0 = newDistance;
1697 closestHash = hash;
1698 }
1699 zPrimed += PrimeZ;
1700 }
1701 yPrimed += PrimeY;
1702 }
1703 xPrimed += PrimeX;
1704 }
1705 break;
1706 case CellularDistanceFunction_Hybrid:
1707 for (int xi = xr - 1; xi <= xr + 1; xi++)
1708 {
1709 int yPrimed = yPrimedBase;
1710
1711 for (int yi = yr - 1; yi <= yr + 1; yi++)
1712 {
1713 int zPrimed = zPrimedBase;
1714
1715 for (int zi = zr - 1; zi <= zr + 1; zi++)
1716 {
1717 int hash = Hash(seed, xPrimed, yPrimed, zPrimed);
1718 int idx = hash & (255 << 2);
1719
1720 float vecX = (float)(xi - x) + Lookup<float>::RandVecs3D[idx] * cellularJitter;
1721 float vecY = (float)(yi - y) + Lookup<float>::RandVecs3D[idx | 1] * cellularJitter;
1722 float vecZ = (float)(zi - z) + Lookup<float>::RandVecs3D[idx | 2] * cellularJitter;
1723
1724 float newDistance = (FastAbs(vecX) + FastAbs(vecY) + FastAbs(vecZ)) + (vecX * vecX + vecY * vecY + vecZ * vecZ);
1725
1726 distance1 = FastMax(FastMin(distance1, newDistance), distance0);
1727 if (newDistance < distance0)
1728 {
1729 distance0 = newDistance;
1730 closestHash = hash;
1731 }
1732 zPrimed += PrimeZ;
1733 }
1734 yPrimed += PrimeY;
1735 }
1736 xPrimed += PrimeX;
1737 }
1738 break;
1739 default:
1740 break;
1741 }
1742
1743 if (mCellularDistanceFunction == CellularDistanceFunction_Euclidean && mCellularReturnType >= CellularReturnType_Distance)
1744 {
1745 distance0 = FastSqrt(distance0);
1746
1747 if (mCellularReturnType >= CellularReturnType_Distance2)
1748 {
1749 distance1 = FastSqrt(distance1);
1750 }
1751 }
1752
1753 switch (mCellularReturnType)
1754 {
1755 case CellularReturnType_CellValue:
1756 return closestHash * (1 / 2147483648.0f);
1757 case CellularReturnType_Distance:
1758 return distance0 - 1;
1759 case CellularReturnType_Distance2:
1760 return distance1 - 1;
1761 case CellularReturnType_Distance2Add:
1762 return (distance1 + distance0) * 0.5f - 1;
1763 case CellularReturnType_Distance2Sub:
1764 return distance1 - distance0 - 1;
1765 case CellularReturnType_Distance2Mul:
1766 return distance1 * distance0 * 0.5f - 1;
1767 case CellularReturnType_Distance2Div:
1768 return distance0 / distance1 - 1;
1769 default:
1770 return 0;
1771 }
1772 }
1773
1774#if defined(__GNUC__) && !defined(__clang__)
1775#pragma GCC diagnostic pop
1776#endif
1777
1778 // Perlin Noise
1779
1780 template <typename FNfloat>
1781 float SinglePerlin(int seed, FNfloat x, FNfloat y) const
1782 {
1783 int x0 = FastFloor(x);
1784 int y0 = FastFloor(y);
1785
1786 float xd0 = (float)(x - x0);
1787 float yd0 = (float)(y - y0);
1788 float xd1 = xd0 - 1;
1789 float yd1 = yd0 - 1;
1790
1791 float xs = InterpQuintic(xd0);
1792 float ys = InterpQuintic(yd0);
1793
1794 x0 *= PrimeX;
1795 y0 *= PrimeY;
1796 int x1 = x0 + PrimeX;
1797 int y1 = y0 + PrimeY;
1798
1799 float xf0 = Lerp(GradCoord(seed, x0, y0, xd0, yd0), GradCoord(seed, x1, y0, xd1, yd0), xs);
1800 float xf1 = Lerp(GradCoord(seed, x0, y1, xd0, yd1), GradCoord(seed, x1, y1, xd1, yd1), xs);
1801
1802 return Lerp(xf0, xf1, ys) * 1.4247691104677813f;
1803 }
1804
1805 template <typename FNfloat>
1806 float SinglePerlin(int seed, FNfloat x, FNfloat y, FNfloat z) const
1807 {
1808 int x0 = FastFloor(x);
1809 int y0 = FastFloor(y);
1810 int z0 = FastFloor(z);
1811
1812 float xd0 = (float)(x - x0);
1813 float yd0 = (float)(y - y0);
1814 float zd0 = (float)(z - z0);
1815 float xd1 = xd0 - 1;
1816 float yd1 = yd0 - 1;
1817 float zd1 = zd0 - 1;
1818
1819 float xs = InterpQuintic(xd0);
1820 float ys = InterpQuintic(yd0);
1821 float zs = InterpQuintic(zd0);
1822
1823 x0 *= PrimeX;
1824 y0 *= PrimeY;
1825 z0 *= PrimeZ;
1826 int x1 = x0 + PrimeX;
1827 int y1 = y0 + PrimeY;
1828 int z1 = z0 + PrimeZ;
1829
1830 float xf00 = Lerp(GradCoord(seed, x0, y0, z0, xd0, yd0, zd0), GradCoord(seed, x1, y0, z0, xd1, yd0, zd0), xs);
1831 float xf10 = Lerp(GradCoord(seed, x0, y1, z0, xd0, yd1, zd0), GradCoord(seed, x1, y1, z0, xd1, yd1, zd0), xs);
1832 float xf01 = Lerp(GradCoord(seed, x0, y0, z1, xd0, yd0, zd1), GradCoord(seed, x1, y0, z1, xd1, yd0, zd1), xs);
1833 float xf11 = Lerp(GradCoord(seed, x0, y1, z1, xd0, yd1, zd1), GradCoord(seed, x1, y1, z1, xd1, yd1, zd1), xs);
1834
1835 float yf0 = Lerp(xf00, xf10, ys);
1836 float yf1 = Lerp(xf01, xf11, ys);
1837
1838 return Lerp(yf0, yf1, zs) * 0.964921414852142333984375f;
1839 }
1840
1841
1842 // Value Cubic Noise
1843
1844 template <typename FNfloat>
1845 float SingleValueCubic(int seed, FNfloat x, FNfloat y) const
1846 {
1847 int x1 = FastFloor(x);
1848 int y1 = FastFloor(y);
1849
1850 float xs = (float)(x - x1);
1851 float ys = (float)(y - y1);
1852
1853 x1 *= PrimeX;
1854 y1 *= PrimeY;
1855 int x0 = x1 - PrimeX;
1856 int y0 = y1 - PrimeY;
1857 int x2 = x1 + PrimeX;
1858 int y2 = y1 + PrimeY;
1859 int x3 = x1 + (int)((long)PrimeX << 1);
1860 int y3 = y1 + (int)((long)PrimeY << 1);
1861
1862 return CubicLerp(
1863 CubicLerp(ValCoord(seed, x0, y0), ValCoord(seed, x1, y0), ValCoord(seed, x2, y0), ValCoord(seed, x3, y0),
1864 xs),
1865 CubicLerp(ValCoord(seed, x0, y1), ValCoord(seed, x1, y1), ValCoord(seed, x2, y1), ValCoord(seed, x3, y1),
1866 xs),
1867 CubicLerp(ValCoord(seed, x0, y2), ValCoord(seed, x1, y2), ValCoord(seed, x2, y2), ValCoord(seed, x3, y2),
1868 xs),
1869 CubicLerp(ValCoord(seed, x0, y3), ValCoord(seed, x1, y3), ValCoord(seed, x2, y3), ValCoord(seed, x3, y3),
1870 xs),
1871 ys) * (1 / (1.5f * 1.5f));
1872 }
1873
1874 template <typename FNfloat>
1875 float SingleValueCubic(int seed, FNfloat x, FNfloat y, FNfloat z) const
1876 {
1877 int x1 = FastFloor(x);
1878 int y1 = FastFloor(y);
1879 int z1 = FastFloor(z);
1880
1881 float xs = (float)(x - x1);
1882 float ys = (float)(y - y1);
1883 float zs = (float)(z - z1);
1884
1885 x1 *= PrimeX;
1886 y1 *= PrimeY;
1887 z1 *= PrimeZ;
1888
1889 int x0 = x1 - PrimeX;
1890 int y0 = y1 - PrimeY;
1891 int z0 = z1 - PrimeZ;
1892 int x2 = x1 + PrimeX;
1893 int y2 = y1 + PrimeY;
1894 int z2 = z1 + PrimeZ;
1895 int x3 = x1 + (int)((long)PrimeX << 1);
1896 int y3 = y1 + (int)((long)PrimeY << 1);
1897 int z3 = z1 + (int)((long)PrimeZ << 1);
1898
1899
1900 return CubicLerp(
1901 CubicLerp(
1902 CubicLerp(ValCoord(seed, x0, y0, z0), ValCoord(seed, x1, y0, z0), ValCoord(seed, x2, y0, z0), ValCoord(seed, x3, y0, z0), xs),
1903 CubicLerp(ValCoord(seed, x0, y1, z0), ValCoord(seed, x1, y1, z0), ValCoord(seed, x2, y1, z0), ValCoord(seed, x3, y1, z0), xs),
1904 CubicLerp(ValCoord(seed, x0, y2, z0), ValCoord(seed, x1, y2, z0), ValCoord(seed, x2, y2, z0), ValCoord(seed, x3, y2, z0), xs),
1905 CubicLerp(ValCoord(seed, x0, y3, z0), ValCoord(seed, x1, y3, z0), ValCoord(seed, x2, y3, z0), ValCoord(seed, x3, y3, z0), xs),
1906 ys),
1907 CubicLerp(
1908 CubicLerp(ValCoord(seed, x0, y0, z1), ValCoord(seed, x1, y0, z1), ValCoord(seed, x2, y0, z1), ValCoord(seed, x3, y0, z1), xs),
1909 CubicLerp(ValCoord(seed, x0, y1, z1), ValCoord(seed, x1, y1, z1), ValCoord(seed, x2, y1, z1), ValCoord(seed, x3, y1, z1), xs),
1910 CubicLerp(ValCoord(seed, x0, y2, z1), ValCoord(seed, x1, y2, z1), ValCoord(seed, x2, y2, z1), ValCoord(seed, x3, y2, z1), xs),
1911 CubicLerp(ValCoord(seed, x0, y3, z1), ValCoord(seed, x1, y3, z1), ValCoord(seed, x2, y3, z1), ValCoord(seed, x3, y3, z1), xs),
1912 ys),
1913 CubicLerp(
1914 CubicLerp(ValCoord(seed, x0, y0, z2), ValCoord(seed, x1, y0, z2), ValCoord(seed, x2, y0, z2), ValCoord(seed, x3, y0, z2), xs),
1915 CubicLerp(ValCoord(seed, x0, y1, z2), ValCoord(seed, x1, y1, z2), ValCoord(seed, x2, y1, z2), ValCoord(seed, x3, y1, z2), xs),
1916 CubicLerp(ValCoord(seed, x0, y2, z2), ValCoord(seed, x1, y2, z2), ValCoord(seed, x2, y2, z2), ValCoord(seed, x3, y2, z2), xs),
1917 CubicLerp(ValCoord(seed, x0, y3, z2), ValCoord(seed, x1, y3, z2), ValCoord(seed, x2, y3, z2), ValCoord(seed, x3, y3, z2), xs),
1918 ys),
1919 CubicLerp(
1920 CubicLerp(ValCoord(seed, x0, y0, z3), ValCoord(seed, x1, y0, z3), ValCoord(seed, x2, y0, z3), ValCoord(seed, x3, y0, z3), xs),
1921 CubicLerp(ValCoord(seed, x0, y1, z3), ValCoord(seed, x1, y1, z3), ValCoord(seed, x2, y1, z3), ValCoord(seed, x3, y1, z3), xs),
1922 CubicLerp(ValCoord(seed, x0, y2, z3), ValCoord(seed, x1, y2, z3), ValCoord(seed, x2, y2, z3), ValCoord(seed, x3, y2, z3), xs),
1923 CubicLerp(ValCoord(seed, x0, y3, z3), ValCoord(seed, x1, y3, z3), ValCoord(seed, x2, y3, z3), ValCoord(seed, x3, y3, z3), xs),
1924 ys),
1925 zs) * (1 / (1.5f * 1.5f * 1.5f));
1926 }
1927
1928
1929 // Value Noise
1930
1931 template <typename FNfloat>
1932 float SingleValue(int seed, FNfloat x, FNfloat y) const
1933 {
1934 int x0 = FastFloor(x);
1935 int y0 = FastFloor(y);
1936
1937 float xs = InterpHermite((float)(x - x0));
1938 float ys = InterpHermite((float)(y - y0));
1939
1940 x0 *= PrimeX;
1941 y0 *= PrimeY;
1942 int x1 = x0 + PrimeX;
1943 int y1 = y0 + PrimeY;
1944
1945 float xf0 = Lerp(ValCoord(seed, x0, y0), ValCoord(seed, x1, y0), xs);
1946 float xf1 = Lerp(ValCoord(seed, x0, y1), ValCoord(seed, x1, y1), xs);
1947
1948 return Lerp(xf0, xf1, ys);
1949 }
1950
1951 template <typename FNfloat>
1952 float SingleValue(int seed, FNfloat x, FNfloat y, FNfloat z) const
1953 {
1954 int x0 = FastFloor(x);
1955 int y0 = FastFloor(y);
1956 int z0 = FastFloor(z);
1957
1958 float xs = InterpHermite((float)(x - x0));
1959 float ys = InterpHermite((float)(y - y0));
1960 float zs = InterpHermite((float)(z - z0));
1961
1962 x0 *= PrimeX;
1963 y0 *= PrimeY;
1964 z0 *= PrimeZ;
1965 int x1 = x0 + PrimeX;
1966 int y1 = y0 + PrimeY;
1967 int z1 = z0 + PrimeZ;
1968
1969 float xf00 = Lerp(ValCoord(seed, x0, y0, z0), ValCoord(seed, x1, y0, z0), xs);
1970 float xf10 = Lerp(ValCoord(seed, x0, y1, z0), ValCoord(seed, x1, y1, z0), xs);
1971 float xf01 = Lerp(ValCoord(seed, x0, y0, z1), ValCoord(seed, x1, y0, z1), xs);
1972 float xf11 = Lerp(ValCoord(seed, x0, y1, z1), ValCoord(seed, x1, y1, z1), xs);
1973
1974 float yf0 = Lerp(xf00, xf10, ys);
1975 float yf1 = Lerp(xf01, xf11, ys);
1976
1977 return Lerp(yf0, yf1, zs);
1978 }
1979
1980
1981 // Domain Warp
1982
1983 template <typename FNfloat>
1984 void DoSingleDomainWarp(int seed, float amp, float freq, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr) const
1985 {
1986 switch (mDomainWarpType)
1987 {
1988 case DomainWarpType_OpenSimplex2:
1989 SingleDomainWarpSimplexGradient(seed, amp * 38.283687591552734375f, freq, x, y, xr, yr, false);
1990 break;
1991 case DomainWarpType_OpenSimplex2Reduced:
1992 SingleDomainWarpSimplexGradient(seed, amp * 16.0f, freq, x, y, xr, yr, true);
1993 break;
1994 case DomainWarpType_BasicGrid:
1995 SingleDomainWarpBasicGrid(seed, amp, freq, x, y, xr, yr);
1996 break;
1997 }
1998 }
1999
2000 template <typename FNfloat>
2001 void DoSingleDomainWarp(int seed, float amp, float freq, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr) const
2002 {
2003 switch (mDomainWarpType)
2004 {
2005 case DomainWarpType_OpenSimplex2:
2006 SingleDomainWarpOpenSimplex2Gradient(seed, amp * 32.69428253173828125f, freq, x, y, z, xr, yr, zr, false);
2007 break;
2008 case DomainWarpType_OpenSimplex2Reduced:
2009 SingleDomainWarpOpenSimplex2Gradient(seed, amp * 7.71604938271605f, freq, x, y, z, xr, yr, zr, true);
2010 break;
2011 case DomainWarpType_BasicGrid:
2012 SingleDomainWarpBasicGrid(seed, amp, freq, x, y, z, xr, yr, zr);
2013 break;
2014 }
2015 }
2016
2017
2018 // Domain Warp Single Wrapper
2019
2020 template <typename FNfloat>
2021 void DomainWarpSingle(FNfloat& x, FNfloat& y) const
2022 {
2023 int seed = mSeed;
2024 float amp = mDomainWarpAmp * mFractalBounding;
2025 float freq = mFrequency;
2026
2027 FNfloat xs = x;
2028 FNfloat ys = y;
2029 TransformDomainWarpCoordinate(xs, ys);
2030
2031 DoSingleDomainWarp(seed, amp, freq, xs, ys, x, y);
2032 }
2033
2034 template <typename FNfloat>
2035 void DomainWarpSingle(FNfloat& x, FNfloat& y, FNfloat& z) const
2036 {
2037 int seed = mSeed;
2038 float amp = mDomainWarpAmp * mFractalBounding;
2039 float freq = mFrequency;
2040
2041 FNfloat xs = x;
2042 FNfloat ys = y;
2043 FNfloat zs = z;
2044 TransformDomainWarpCoordinate(xs, ys, zs);
2045
2046 DoSingleDomainWarp(seed, amp, freq, xs, ys, zs, x, y, z);
2047 }
2048
2049
2050 // Domain Warp Fractal Progressive
2051
2052 template <typename FNfloat>
2053 void DomainWarpFractalProgressive(FNfloat& x, FNfloat& y) const
2054 {
2055 int seed = mSeed;
2056 float amp = mDomainWarpAmp * mFractalBounding;
2057 float freq = mFrequency;
2058
2059 for (int i = 0; i < mOctaves; i++)
2060 {
2061 FNfloat xs = x;
2062 FNfloat ys = y;
2063 TransformDomainWarpCoordinate(xs, ys);
2064
2065 DoSingleDomainWarp(seed, amp, freq, xs, ys, x, y);
2066
2067 seed++;
2068 amp *= mGain;
2069 freq *= mLacunarity;
2070 }
2071 }
2072
2073 template <typename FNfloat>
2074 void DomainWarpFractalProgressive(FNfloat& x, FNfloat& y, FNfloat& z) const
2075 {
2076 int seed = mSeed;
2077 float amp = mDomainWarpAmp * mFractalBounding;
2078 float freq = mFrequency;
2079
2080 for (int i = 0; i < mOctaves; i++)
2081 {
2082 FNfloat xs = x;
2083 FNfloat ys = y;
2084 FNfloat zs = z;
2085 TransformDomainWarpCoordinate(xs, ys, zs);
2086
2087 DoSingleDomainWarp(seed, amp, freq, xs, ys, zs, x, y, z);
2088
2089 seed++;
2090 amp *= mGain;
2091 freq *= mLacunarity;
2092 }
2093 }
2094
2095
2096 // Domain Warp Fractal Independant
2097
2098 template <typename FNfloat>
2099 void DomainWarpFractalIndependent(FNfloat& x, FNfloat& y) const
2100 {
2101 FNfloat xs = x;
2102 FNfloat ys = y;
2103 TransformDomainWarpCoordinate(xs, ys);
2104
2105 int seed = mSeed;
2106 float amp = mDomainWarpAmp * mFractalBounding;
2107 float freq = mFrequency;
2108
2109 for (int i = 0; i < mOctaves; i++)
2110 {
2111 DoSingleDomainWarp(seed, amp, freq, xs, ys, x, y);
2112
2113 seed++;
2114 amp *= mGain;
2115 freq *= mLacunarity;
2116 }
2117 }
2118
2119 template <typename FNfloat>
2120 void DomainWarpFractalIndependent(FNfloat& x, FNfloat& y, FNfloat& z) const
2121 {
2122 FNfloat xs = x;
2123 FNfloat ys = y;
2124 FNfloat zs = z;
2125 TransformDomainWarpCoordinate(xs, ys, zs);
2126
2127 int seed = mSeed;
2128 float amp = mDomainWarpAmp * mFractalBounding;
2129 float freq = mFrequency;
2130
2131 for (int i = 0; i < mOctaves; i++)
2132 {
2133 DoSingleDomainWarp(seed, amp, freq, xs, ys, zs, x, y, z);
2134
2135 seed++;
2136 amp *= mGain;
2137 freq *= mLacunarity;
2138 }
2139 }
2140
2141
2142 // Domain Warp Basic Grid
2143
2144 template <typename FNfloat>
2145 void SingleDomainWarpBasicGrid(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr) const
2146 {
2147 FNfloat xf = x * frequency;
2148 FNfloat yf = y * frequency;
2149
2150 int x0 = FastFloor(xf);
2151 int y0 = FastFloor(yf);
2152
2153 float xs = InterpHermite((float)(xf - x0));
2154 float ys = InterpHermite((float)(yf - y0));
2155
2156 x0 *= PrimeX;
2157 y0 *= PrimeY;
2158 int x1 = x0 + PrimeX;
2159 int y1 = y0 + PrimeY;
2160
2161 int hash0 = Hash(seed, x0, y0) & (255 << 1);
2162 int hash1 = Hash(seed, x1, y0) & (255 << 1);
2163
2164 float lx0x = Lerp(Lookup<float>::RandVecs2D[hash0], Lookup<float>::RandVecs2D[hash1], xs);
2165 float ly0x = Lerp(Lookup<float>::RandVecs2D[hash0 | 1], Lookup<float>::RandVecs2D[hash1 | 1], xs);
2166
2167 hash0 = Hash(seed, x0, y1) & (255 << 1);
2168 hash1 = Hash(seed, x1, y1) & (255 << 1);
2169
2170 float lx1x = Lerp(Lookup<float>::RandVecs2D[hash0], Lookup<float>::RandVecs2D[hash1], xs);
2171 float ly1x = Lerp(Lookup<float>::RandVecs2D[hash0 | 1], Lookup<float>::RandVecs2D[hash1 | 1], xs);
2172
2173 xr += Lerp(lx0x, lx1x, ys) * warpAmp;
2174 yr += Lerp(ly0x, ly1x, ys) * warpAmp;
2175 }
2176
2177 template <typename FNfloat>
2178 void SingleDomainWarpBasicGrid(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr) const
2179 {
2180 FNfloat xf = x * frequency;
2181 FNfloat yf = y * frequency;
2182 FNfloat zf = z * frequency;
2183
2184 int x0 = FastFloor(xf);
2185 int y0 = FastFloor(yf);
2186 int z0 = FastFloor(zf);
2187
2188 float xs = InterpHermite((float)(xf - x0));
2189 float ys = InterpHermite((float)(yf - y0));
2190 float zs = InterpHermite((float)(zf - z0));
2191
2192 x0 *= PrimeX;
2193 y0 *= PrimeY;
2194 z0 *= PrimeZ;
2195 int x1 = x0 + PrimeX;
2196 int y1 = y0 + PrimeY;
2197 int z1 = z0 + PrimeZ;
2198
2199 int hash0 = Hash(seed, x0, y0, z0) & (255 << 2);
2200 int hash1 = Hash(seed, x1, y0, z0) & (255 << 2);
2201
2202 float lx0x = Lerp(Lookup<float>::RandVecs3D[hash0], Lookup<float>::RandVecs3D[hash1], xs);
2203 float ly0x = Lerp(Lookup<float>::RandVecs3D[hash0 | 1], Lookup<float>::RandVecs3D[hash1 | 1], xs);
2204 float lz0x = Lerp(Lookup<float>::RandVecs3D[hash0 | 2], Lookup<float>::RandVecs3D[hash1 | 2], xs);
2205
2206 hash0 = Hash(seed, x0, y1, z0) & (255 << 2);
2207 hash1 = Hash(seed, x1, y1, z0) & (255 << 2);
2208
2209 float lx1x = Lerp(Lookup<float>::RandVecs3D[hash0], Lookup<float>::RandVecs3D[hash1], xs);
2210 float ly1x = Lerp(Lookup<float>::RandVecs3D[hash0 | 1], Lookup<float>::RandVecs3D[hash1 | 1], xs);
2211 float lz1x = Lerp(Lookup<float>::RandVecs3D[hash0 | 2], Lookup<float>::RandVecs3D[hash1 | 2], xs);
2212
2213 float lx0y = Lerp(lx0x, lx1x, ys);
2214 float ly0y = Lerp(ly0x, ly1x, ys);
2215 float lz0y = Lerp(lz0x, lz1x, ys);
2216
2217 hash0 = Hash(seed, x0, y0, z1) & (255 << 2);
2218 hash1 = Hash(seed, x1, y0, z1) & (255 << 2);
2219
2220 lx0x = Lerp(Lookup<float>::RandVecs3D[hash0], Lookup<float>::RandVecs3D[hash1], xs);
2221 ly0x = Lerp(Lookup<float>::RandVecs3D[hash0 | 1], Lookup<float>::RandVecs3D[hash1 | 1], xs);
2222 lz0x = Lerp(Lookup<float>::RandVecs3D[hash0 | 2], Lookup<float>::RandVecs3D[hash1 | 2], xs);
2223
2224 hash0 = Hash(seed, x0, y1, z1) & (255 << 2);
2225 hash1 = Hash(seed, x1, y1, z1) & (255 << 2);
2226
2227 lx1x = Lerp(Lookup<float>::RandVecs3D[hash0], Lookup<float>::RandVecs3D[hash1], xs);
2228 ly1x = Lerp(Lookup<float>::RandVecs3D[hash0 | 1], Lookup<float>::RandVecs3D[hash1 | 1], xs);
2229 lz1x = Lerp(Lookup<float>::RandVecs3D[hash0 | 2], Lookup<float>::RandVecs3D[hash1 | 2], xs);
2230
2231 xr += Lerp(lx0y, Lerp(lx0x, lx1x, ys), zs) * warpAmp;
2232 yr += Lerp(ly0y, Lerp(ly0x, ly1x, ys), zs) * warpAmp;
2233 zr += Lerp(lz0y, Lerp(lz0x, lz1x, ys), zs) * warpAmp;
2234 }
2235
2236
2237 // Domain Warp Simplex/OpenSimplex2
2238
2239 template <typename FNfloat>
2240 void SingleDomainWarpSimplexGradient(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr, bool outGradOnly) const
2241 {
2242 const float SQRT3 = 1.7320508075688772935274463415059f;
2243 const float G2 = (3 - SQRT3) / 6;
2244
2245 x *= frequency;
2246 y *= frequency;
2247
2248 /*
2249 * --- Skew moved to TransformNoiseCoordinate method ---
2250 * const FNfloat F2 = 0.5f * (SQRT3 - 1);
2251 * FNfloat s = (x + y) * F2;
2252 * x += s; y += s;
2253 */
2254
2255 int i = FastFloor(x);
2256 int j = FastFloor(y);
2257 float xi = (float)(x - i);
2258 float yi = (float)(y - j);
2259
2260 float t = (xi + yi) * G2;
2261 float x0 = (float)(xi - t);
2262 float y0 = (float)(yi - t);
2263
2264 i *= PrimeX;
2265 j *= PrimeY;
2266
2267 float vx, vy;
2268 vx = vy = 0;
2269
2270 float a = 0.5f - x0 * x0 - y0 * y0;
2271 if (a > 0)
2272 {
2273 float aaaa = (a * a) * (a * a);
2274 float xo, yo;
2275 if (outGradOnly)
2276 GradCoordOut(seed, i, j, xo, yo);
2277 else
2278 GradCoordDual(seed, i, j, x0, y0, xo, yo);
2279 vx += aaaa * xo;
2280 vy += aaaa * yo;
2281 }
2282
2283 float c = (float)(2 * (1 - 2 * G2) * (1 / G2 - 2)) * t + ((float)(-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a);
2284 if (c > 0)
2285 {
2286 float x2 = x0 + (2 * (float)G2 - 1);
2287 float y2 = y0 + (2 * (float)G2 - 1);
2288 float cccc = (c * c) * (c * c);
2289 float xo, yo;
2290 if (outGradOnly)
2291 GradCoordOut(seed, i + PrimeX, j + PrimeY, xo, yo);
2292 else
2293 GradCoordDual(seed, i + PrimeX, j + PrimeY, x2, y2, xo, yo);
2294 vx += cccc * xo;
2295 vy += cccc * yo;
2296 }
2297
2298 if (y0 > x0)
2299 {
2300 float x1 = x0 + (float)G2;
2301 float y1 = y0 + ((float)G2 - 1);
2302 float b = 0.5f - x1 * x1 - y1 * y1;
2303 if (b > 0)
2304 {
2305 float bbbb = (b * b) * (b * b);
2306 float xo, yo;
2307 if (outGradOnly)
2308 GradCoordOut(seed, i, j + PrimeY, xo, yo);
2309 else
2310 GradCoordDual(seed, i, j + PrimeY, x1, y1, xo, yo);
2311 vx += bbbb * xo;
2312 vy += bbbb * yo;
2313 }
2314 }
2315 else
2316 {
2317 float x1 = x0 + ((float)G2 - 1);
2318 float y1 = y0 + (float)G2;
2319 float b = 0.5f - x1 * x1 - y1 * y1;
2320 if (b > 0)
2321 {
2322 float bbbb = (b * b) * (b * b);
2323 float xo, yo;
2324 if (outGradOnly)
2325 GradCoordOut(seed, i + PrimeX, j, xo, yo);
2326 else
2327 GradCoordDual(seed, i + PrimeX, j, x1, y1, xo, yo);
2328 vx += bbbb * xo;
2329 vy += bbbb * yo;
2330 }
2331 }
2332
2333 xr += vx * warpAmp;
2334 yr += vy * warpAmp;
2335 }
2336
2337 template <typename FNfloat>
2338 void SingleDomainWarpOpenSimplex2Gradient(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr, bool outGradOnly) const
2339 {
2340 x *= frequency;
2341 y *= frequency;
2342 z *= frequency;
2343
2344 /*
2345 * --- Rotation moved to TransformDomainWarpCoordinate method ---
2346 * const FNfloat R3 = (FNfloat)(2.0 / 3.0);
2347 * FNfloat r = (x + y + z) * R3; // Rotation, not skew
2348 * x = r - x; y = r - y; z = r - z;
2349 */
2350
2351 int i = FastRound(x);
2352 int j = FastRound(y);
2353 int k = FastRound(z);
2354 float x0 = (float)x - i;
2355 float y0 = (float)y - j;
2356 float z0 = (float)z - k;
2357
2358 int xNSign = (int)(-x0 - 1.0f) | 1;
2359 int yNSign = (int)(-y0 - 1.0f) | 1;
2360 int zNSign = (int)(-z0 - 1.0f) | 1;
2361
2362 float ax0 = xNSign * -x0;
2363 float ay0 = yNSign * -y0;
2364 float az0 = zNSign * -z0;
2365
2366 i *= PrimeX;
2367 j *= PrimeY;
2368 k *= PrimeZ;
2369
2370 float vx, vy, vz;
2371 vx = vy = vz = 0;
2372
2373 float a = (0.6f - x0 * x0) - (y0 * y0 + z0 * z0);
2374 for (int l = 0; l < 2; l++)
2375 {
2376 if (a > 0)
2377 {
2378 float aaaa = (a * a) * (a * a);
2379 float xo, yo, zo;
2380 if (outGradOnly)
2381 GradCoordOut(seed, i, j, k, xo, yo, zo);
2382 else
2383 GradCoordDual(seed, i, j, k, x0, y0, z0, xo, yo, zo);
2384 vx += aaaa * xo;
2385 vy += aaaa * yo;
2386 vz += aaaa * zo;
2387 }
2388
2389 float b = a + 1;
2390 int i1 = i;
2391 int j1 = j;
2392 int k1 = k;
2393 float x1 = x0;
2394 float y1 = y0;
2395 float z1 = z0;
2396
2397 if (ax0 >= ay0 && ax0 >= az0)
2398 {
2399 x1 += xNSign;
2400 b -= xNSign * 2 * x1;
2401 i1 -= xNSign * PrimeX;
2402 }
2403 else if (ay0 > ax0 && ay0 >= az0)
2404 {
2405 y1 += yNSign;
2406 b -= yNSign * 2 * y1;
2407 j1 -= yNSign * PrimeY;
2408 }
2409 else
2410 {
2411 z1 += zNSign;
2412 b -= zNSign * 2 * z1;
2413 k1 -= zNSign * PrimeZ;
2414 }
2415
2416 if (b > 0)
2417 {
2418 float bbbb = (b * b) * (b * b);
2419 float xo, yo, zo;
2420 if (outGradOnly)
2421 GradCoordOut(seed, i1, j1, k1, xo, yo, zo);
2422 else
2423 GradCoordDual(seed, i1, j1, k1, x1, y1, z1, xo, yo, zo);
2424 vx += bbbb * xo;
2425 vy += bbbb * yo;
2426 vz += bbbb * zo;
2427 }
2428
2429 if (l == 1) break;
2430
2431 ax0 = 0.5f - ax0;
2432 ay0 = 0.5f - ay0;
2433 az0 = 0.5f - az0;
2434
2435 x0 = xNSign * ax0;
2436 y0 = yNSign * ay0;
2437 z0 = zNSign * az0;
2438
2439 a += (0.75f - ax0) - (ay0 + az0);
2440
2441 i += (xNSign >> 1) & PrimeX;
2442 j += (yNSign >> 1) & PrimeY;
2443 k += (zNSign >> 1) & PrimeZ;
2444
2445 xNSign = -xNSign;
2446 yNSign = -yNSign;
2447 zNSign = -zNSign;
2448
2449 seed += 1293373;
2450 }
2451
2452 xr += vx * warpAmp;
2453 yr += vy * warpAmp;
2454 zr += vz * warpAmp;
2455 }
2456};
2457
2458template <>
2459struct FastNoiseLite::Arguments_must_be_floating_point_values<float> {};
2460template <>
2461struct FastNoiseLite::Arguments_must_be_floating_point_values<double> {};
2462template <>
2463struct FastNoiseLite::Arguments_must_be_floating_point_values<long double> {};
2464
2465template <typename T>
2466const T FastNoiseLite::Lookup<T>::Gradients2D[] =
2467{
2468 0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f,
2469 0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f,
2470 0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f,
2471 -0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f,
2472 -0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f,
2473 -0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f,
2474 0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f,
2475 0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f,
2476 0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f,
2477 -0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f,
2478 -0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f,
2479 -0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f,
2480 0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f,
2481 0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f,
2482 0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f,
2483 -0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f,
2484 -0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f,
2485 -0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f,
2486 0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f,
2487 0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f,
2488 0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f,
2489 -0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f,
2490 -0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f,
2491 -0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f,
2492 0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f,
2493 0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f,
2494 0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f,
2495 -0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f,
2496 -0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f,
2497 -0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f,
2498 0.38268343236509f, 0.923879532511287f, 0.923879532511287f, 0.38268343236509f, 0.923879532511287f, -0.38268343236509f, 0.38268343236509f, -0.923879532511287f,
2499 -0.38268343236509f, -0.923879532511287f, -0.923879532511287f, -0.38268343236509f, -0.923879532511287f, 0.38268343236509f, -0.38268343236509f, 0.923879532511287f,
2500};
2501
2502template <typename T>
2503const T FastNoiseLite::Lookup<T>::RandVecs2D[] =
2504{
2505 -0.2700222198f, -0.9628540911f, 0.3863092627f, -0.9223693152f, 0.04444859006f, -0.999011673f, -0.5992523158f, -0.8005602176f, -0.7819280288f, 0.6233687174f, 0.9464672271f, 0.3227999196f, -0.6514146797f, -0.7587218957f, 0.9378472289f, 0.347048376f,
2506 -0.8497875957f, -0.5271252623f, -0.879042592f, 0.4767432447f, -0.892300288f, -0.4514423508f, -0.379844434f, -0.9250503802f, -0.9951650832f, 0.0982163789f, 0.7724397808f, -0.6350880136f, 0.7573283322f, -0.6530343002f, -0.9928004525f, -0.119780055f,
2507 -0.0532665713f, 0.9985803285f, 0.9754253726f, -0.2203300762f, -0.7665018163f, 0.6422421394f, 0.991636706f, 0.1290606184f, -0.994696838f, 0.1028503788f, -0.5379205513f, -0.84299554f, 0.5022815471f, -0.8647041387f, 0.4559821461f, -0.8899889226f,
2508 -0.8659131224f, -0.5001944266f, 0.0879458407f, -0.9961252577f, -0.5051684983f, 0.8630207346f, 0.7753185226f, -0.6315704146f, -0.6921944612f, 0.7217110418f, -0.5191659449f, -0.8546734591f, 0.8978622882f, -0.4402764035f, -0.1706774107f, 0.9853269617f,
2509 -0.9353430106f, -0.3537420705f, -0.9992404798f, 0.03896746794f, -0.2882064021f, -0.9575683108f, -0.9663811329f, 0.2571137995f, -0.8759714238f, -0.4823630009f, -0.8303123018f, -0.5572983775f, 0.05110133755f, -0.9986934731f, -0.8558373281f, -0.5172450752f,
2510 0.09887025282f, 0.9951003332f, 0.9189016087f, 0.3944867976f, -0.2439375892f, -0.9697909324f, -0.8121409387f, -0.5834613061f, -0.9910431363f, 0.1335421355f, 0.8492423985f, -0.5280031709f, -0.9717838994f, -0.2358729591f, 0.9949457207f, 0.1004142068f,
2511 0.6241065508f, -0.7813392434f, 0.662910307f, 0.7486988212f, -0.7197418176f, 0.6942418282f, -0.8143370775f, -0.5803922158f, 0.104521054f, -0.9945226741f, -0.1065926113f, -0.9943027784f, 0.445799684f, -0.8951327509f, 0.105547406f, 0.9944142724f,
2512 -0.992790267f, 0.1198644477f, -0.8334366408f, 0.552615025f, 0.9115561563f, -0.4111755999f, 0.8285544909f, -0.5599084351f, 0.7217097654f, -0.6921957921f, 0.4940492677f, -0.8694339084f, -0.3652321272f, -0.9309164803f, -0.9696606758f, 0.2444548501f,
2513 0.08925509731f, -0.996008799f, 0.5354071276f, -0.8445941083f, -0.1053576186f, 0.9944343981f, -0.9890284586f, 0.1477251101f, 0.004856104961f, 0.9999882091f, 0.9885598478f, 0.1508291331f, 0.9286129562f, -0.3710498316f, -0.5832393863f, -0.8123003252f,
2514 0.3015207509f, 0.9534596146f, -0.9575110528f, 0.2883965738f, 0.9715802154f, -0.2367105511f, 0.229981792f, 0.9731949318f, 0.955763816f, -0.2941352207f, 0.740956116f, 0.6715534485f, -0.9971513787f, -0.07542630764f, 0.6905710663f, -0.7232645452f,
2515 -0.290713703f, -0.9568100872f, 0.5912777791f, -0.8064679708f, -0.9454592212f, -0.325740481f, 0.6664455681f, 0.74555369f, 0.6236134912f, 0.7817328275f, 0.9126993851f, -0.4086316587f, -0.8191762011f, 0.5735419353f, -0.8812745759f, -0.4726046147f,
2516 0.9953313627f, 0.09651672651f, 0.9855650846f, -0.1692969699f, -0.8495980887f, 0.5274306472f, 0.6174853946f, -0.7865823463f, 0.8508156371f, 0.52546432f, 0.9985032451f, -0.05469249926f, 0.1971371563f, -0.9803759185f, 0.6607855748f, -0.7505747292f,
2517 -0.03097494063f, 0.9995201614f, -0.6731660801f, 0.739491331f, -0.7195018362f, -0.6944905383f, 0.9727511689f, 0.2318515979f, 0.9997059088f, -0.0242506907f, 0.4421787429f, -0.8969269532f, 0.9981350961f, -0.061043673f, -0.9173660799f, -0.3980445648f,
2518 -0.8150056635f, -0.5794529907f, -0.8789331304f, 0.4769450202f, 0.0158605829f, 0.999874213f, -0.8095464474f, 0.5870558317f, -0.9165898907f, -0.3998286786f, -0.8023542565f, 0.5968480938f, -0.5176737917f, 0.8555780767f, -0.8154407307f, -0.5788405779f,
2519 0.4022010347f, -0.9155513791f, -0.9052556868f, -0.4248672045f, 0.7317445619f, 0.6815789728f, -0.5647632201f, -0.8252529947f, -0.8403276335f, -0.5420788397f, -0.9314281527f, 0.363925262f, 0.5238198472f, 0.8518290719f, 0.7432803869f, -0.6689800195f,
2520 -0.985371561f, -0.1704197369f, 0.4601468731f, 0.88784281f, 0.825855404f, 0.5638819483f, 0.6182366099f, 0.7859920446f, 0.8331502863f, -0.553046653f, 0.1500307506f, 0.9886813308f, -0.662330369f, -0.7492119075f, -0.668598664f, 0.743623444f,
2521 0.7025606278f, 0.7116238924f, -0.5419389763f, -0.8404178401f, -0.3388616456f, 0.9408362159f, 0.8331530315f, 0.5530425174f, -0.2989720662f, -0.9542618632f, 0.2638522993f, 0.9645630949f, 0.124108739f, -0.9922686234f, -0.7282649308f, -0.6852956957f,
2522 0.6962500149f, 0.7177993569f, -0.9183535368f, 0.3957610156f, -0.6326102274f, -0.7744703352f, -0.9331891859f, -0.359385508f, -0.1153779357f, -0.9933216659f, 0.9514974788f, -0.3076565421f, -0.08987977445f, -0.9959526224f, 0.6678496916f, 0.7442961705f,
2523 0.7952400393f, -0.6062947138f, -0.6462007402f, -0.7631674805f, -0.2733598753f, 0.9619118351f, 0.9669590226f, -0.254931851f, -0.9792894595f, 0.2024651934f, -0.5369502995f, -0.8436138784f, -0.270036471f, -0.9628500944f, -0.6400277131f, 0.7683518247f,
2524 -0.7854537493f, -0.6189203566f, 0.06005905383f, -0.9981948257f, -0.02455770378f, 0.9996984141f, -0.65983623f, 0.751409442f, -0.6253894466f, -0.7803127835f, -0.6210408851f, -0.7837781695f, 0.8348888491f, 0.5504185768f, -0.1592275245f, 0.9872419133f,
2525 0.8367622488f, 0.5475663786f, -0.8675753916f, -0.4973056806f, -0.2022662628f, -0.9793305667f, 0.9399189937f, 0.3413975472f, 0.9877404807f, -0.1561049093f, -0.9034455656f, 0.4287028224f, 0.1269804218f, -0.9919052235f, -0.3819600854f, 0.924178821f,
2526 0.9754625894f, 0.2201652486f, -0.3204015856f, -0.9472818081f, -0.9874760884f, 0.1577687387f, 0.02535348474f, -0.9996785487f, 0.4835130794f, -0.8753371362f, -0.2850799925f, -0.9585037287f, -0.06805516006f, -0.99768156f, -0.7885244045f, -0.6150034663f,
2527 0.3185392127f, -0.9479096845f, 0.8880043089f, 0.4598351306f, 0.6476921488f, -0.7619021462f, 0.9820241299f, 0.1887554194f, 0.9357275128f, -0.3527237187f, -0.8894895414f, 0.4569555293f, 0.7922791302f, 0.6101588153f, 0.7483818261f, 0.6632681526f,
2528 -0.7288929755f, -0.6846276581f, 0.8729032783f, -0.4878932944f, 0.8288345784f, 0.5594937369f, 0.08074567077f, 0.9967347374f, 0.9799148216f, -0.1994165048f, -0.580730673f, -0.8140957471f, -0.4700049791f, -0.8826637636f, 0.2409492979f, 0.9705377045f,
2529 0.9437816757f, -0.3305694308f, -0.8927998638f, -0.4504535528f, -0.8069622304f, 0.5906030467f, 0.06258973166f, 0.9980393407f, -0.9312597469f, 0.3643559849f, 0.5777449785f, 0.8162173362f, -0.3360095855f, -0.941858566f, 0.697932075f, -0.7161639607f,
2530 -0.002008157227f, -0.9999979837f, -0.1827294312f, -0.9831632392f, -0.6523911722f, 0.7578824173f, -0.4302626911f, -0.9027037258f, -0.9985126289f, -0.05452091251f, -0.01028102172f, -0.9999471489f, -0.4946071129f, 0.8691166802f, -0.2999350194f, 0.9539596344f,
2531 0.8165471961f, 0.5772786819f, 0.2697460475f, 0.962931498f, -0.7306287391f, -0.6827749597f, -0.7590952064f, -0.6509796216f, -0.907053853f, 0.4210146171f, -0.5104861064f, -0.8598860013f, 0.8613350597f, 0.5080373165f, 0.5007881595f, -0.8655698812f,
2532 -0.654158152f, 0.7563577938f, -0.8382755311f, -0.545246856f, 0.6940070834f, 0.7199681717f, 0.06950936031f, 0.9975812994f, 0.1702942185f, -0.9853932612f, 0.2695973274f, 0.9629731466f, 0.5519612192f, -0.8338697815f, 0.225657487f, -0.9742067022f,
2533 0.4215262855f, -0.9068161835f, 0.4881873305f, -0.8727388672f, -0.3683854996f, -0.9296731273f, -0.9825390578f, 0.1860564427f, 0.81256471f, 0.5828709909f, 0.3196460933f, -0.9475370046f, 0.9570913859f, 0.2897862643f, -0.6876655497f, -0.7260276109f,
2534 -0.9988770922f, -0.047376731f, -0.1250179027f, 0.992154486f, -0.8280133617f, 0.560708367f, 0.9324863769f, -0.3612051451f, 0.6394653183f, 0.7688199442f, -0.01623847064f, -0.9998681473f, -0.9955014666f, -0.09474613458f, -0.81453315f, 0.580117012f,
2535 0.4037327978f, -0.9148769469f, 0.9944263371f, 0.1054336766f, -0.1624711654f, 0.9867132919f, -0.9949487814f, -0.100383875f, -0.6995302564f, 0.7146029809f, 0.5263414922f, -0.85027327f, -0.5395221479f, 0.841971408f, 0.6579370318f, 0.7530729462f,
2536 0.01426758847f, -0.9998982128f, -0.6734383991f, 0.7392433447f, 0.639412098f, -0.7688642071f, 0.9211571421f, 0.3891908523f, -0.146637214f, -0.9891903394f, -0.782318098f, 0.6228791163f, -0.5039610839f, -0.8637263605f, -0.7743120191f, -0.6328039957f,
2537};
2538
2539template <typename T>
2540const T FastNoiseLite::Lookup<T>::Gradients3D[] =
2541{
2542 0, 1, 1, 0, 0,-1, 1, 0, 0, 1,-1, 0, 0,-1,-1, 0,
2543 1, 0, 1, 0, -1, 0, 1, 0, 1, 0,-1, 0, -1, 0,-1, 0,
2544 1, 1, 0, 0, -1, 1, 0, 0, 1,-1, 0, 0, -1,-1, 0, 0,
2545 0, 1, 1, 0, 0,-1, 1, 0, 0, 1,-1, 0, 0,-1,-1, 0,
2546 1, 0, 1, 0, -1, 0, 1, 0, 1, 0,-1, 0, -1, 0,-1, 0,
2547 1, 1, 0, 0, -1, 1, 0, 0, 1,-1, 0, 0, -1,-1, 0, 0,
2548 0, 1, 1, 0, 0,-1, 1, 0, 0, 1,-1, 0, 0,-1,-1, 0,
2549 1, 0, 1, 0, -1, 0, 1, 0, 1, 0,-1, 0, -1, 0,-1, 0,
2550 1, 1, 0, 0, -1, 1, 0, 0, 1,-1, 0, 0, -1,-1, 0, 0,
2551 0, 1, 1, 0, 0,-1, 1, 0, 0, 1,-1, 0, 0,-1,-1, 0,
2552 1, 0, 1, 0, -1, 0, 1, 0, 1, 0,-1, 0, -1, 0,-1, 0,
2553 1, 1, 0, 0, -1, 1, 0, 0, 1,-1, 0, 0, -1,-1, 0, 0,
2554 0, 1, 1, 0, 0,-1, 1, 0, 0, 1,-1, 0, 0,-1,-1, 0,
2555 1, 0, 1, 0, -1, 0, 1, 0, 1, 0,-1, 0, -1, 0,-1, 0,
2556 1, 1, 0, 0, -1, 1, 0, 0, 1,-1, 0, 0, -1,-1, 0, 0,
2557 1, 1, 0, 0, 0,-1, 1, 0, -1, 1, 0, 0, 0,-1,-1, 0
2558};
2559
2560template <typename T>
2561const T FastNoiseLite::Lookup<T>::RandVecs3D[] =
2562{
2563 -0.7292736885f, -0.6618439697f, 0.1735581948f, 0, 0.790292081f, -0.5480887466f, -0.2739291014f, 0, 0.7217578935f, 0.6226212466f, -0.3023380997f, 0, 0.565683137f, -0.8208298145f, -0.0790000257f, 0, 0.760049034f, -0.5555979497f, -0.3370999617f, 0, 0.3713945616f, 0.5011264475f, 0.7816254623f, 0, -0.1277062463f, -0.4254438999f, -0.8959289049f, 0, -0.2881560924f, -0.5815838982f, 0.7607405838f, 0,
2564 0.5849561111f, -0.662820239f, -0.4674352136f, 0, 0.3307171178f, 0.0391653737f, 0.94291689f, 0, 0.8712121778f, -0.4113374369f, -0.2679381538f, 0, 0.580981015f, 0.7021915846f, 0.4115677815f, 0, 0.503756873f, 0.6330056931f, -0.5878203852f, 0, 0.4493712205f, 0.601390195f, 0.6606022552f, 0, -0.6878403724f, 0.09018890807f, -0.7202371714f, 0, -0.5958956522f, -0.6469350577f, 0.475797649f, 0,
2565 -0.5127052122f, 0.1946921978f, -0.8361987284f, 0, -0.9911507142f, -0.05410276466f, -0.1212153153f, 0, -0.2149721042f, 0.9720882117f, -0.09397607749f, 0, -0.7518650936f, -0.5428057603f, 0.3742469607f, 0, 0.5237068895f, 0.8516377189f, -0.02107817834f, 0, 0.6333504779f, 0.1926167129f, -0.7495104896f, 0, -0.06788241606f, 0.3998305789f, 0.9140719259f, 0, -0.5538628599f, -0.4729896695f, -0.6852128902f, 0,
2566 -0.7261455366f, -0.5911990757f, 0.3509933228f, 0, -0.9229274737f, -0.1782808786f, 0.3412049336f, 0, -0.6968815002f, 0.6511274338f, 0.3006480328f, 0, 0.9608044783f, -0.2098363234f, -0.1811724921f, 0, 0.06817146062f, -0.9743405129f, 0.2145069156f, 0, -0.3577285196f, -0.6697087264f, -0.6507845481f, 0, -0.1868621131f, 0.7648617052f, -0.6164974636f, 0, -0.6541697588f, 0.3967914832f, 0.6439087246f, 0,
2567 0.6993340405f, -0.6164538506f, 0.3618239211f, 0, -0.1546665739f, 0.6291283928f, 0.7617583057f, 0, -0.6841612949f, -0.2580482182f, -0.6821542638f, 0, 0.5383980957f, 0.4258654885f, 0.7271630328f, 0, -0.5026987823f, -0.7939832935f, -0.3418836993f, 0, 0.3202971715f, 0.2834415347f, 0.9039195862f, 0, 0.8683227101f, -0.0003762656404f, -0.4959995258f, 0, 0.791120031f, -0.08511045745f, 0.6057105799f, 0,
2568 -0.04011016052f, -0.4397248749f, 0.8972364289f, 0, 0.9145119872f, 0.3579346169f, -0.1885487608f, 0, -0.9612039066f, -0.2756484276f, 0.01024666929f, 0, 0.6510361721f, -0.2877799159f, -0.7023778346f, 0, -0.2041786351f, 0.7365237271f, 0.644859585f, 0, -0.7718263711f, 0.3790626912f, 0.5104855816f, 0, -0.3060082741f, -0.7692987727f, 0.5608371729f, 0, 0.454007341f, -0.5024843065f, 0.7357899537f, 0,
2569 0.4816795475f, 0.6021208291f, -0.6367380315f, 0, 0.6961980369f, -0.3222197429f, 0.641469197f, 0, -0.6532160499f, -0.6781148932f, 0.3368515753f, 0, 0.5089301236f, -0.6154662304f, -0.6018234363f, 0, -0.1635919754f, -0.9133604627f, -0.372840892f, 0, 0.52408019f, -0.8437664109f, 0.1157505864f, 0, 0.5902587356f, 0.4983817807f, -0.6349883666f, 0, 0.5863227872f, 0.494764745f, 0.6414307729f, 0,
2570 0.6779335087f, 0.2341345225f, 0.6968408593f, 0, 0.7177054546f, -0.6858979348f, 0.120178631f, 0, -0.5328819713f, -0.5205125012f, 0.6671608058f, 0, -0.8654874251f, -0.0700727088f, -0.4960053754f, 0, -0.2861810166f, 0.7952089234f, 0.5345495242f, 0, -0.04849529634f, 0.9810836427f, -0.1874115585f, 0, -0.6358521667f, 0.6058348682f, 0.4781800233f, 0, 0.6254794696f, -0.2861619734f, 0.7258696564f, 0,
2571 -0.2585259868f, 0.5061949264f, -0.8227581726f, 0, 0.02136306781f, 0.5064016808f, -0.8620330371f, 0, 0.200111773f, 0.8599263484f, 0.4695550591f, 0, 0.4743561372f, 0.6014985084f, -0.6427953014f, 0, 0.6622993731f, -0.5202474575f, -0.5391679918f, 0, 0.08084972818f, -0.6532720452f, 0.7527940996f, 0, -0.6893687501f, 0.0592860349f, 0.7219805347f, 0, -0.1121887082f, -0.9673185067f, 0.2273952515f, 0,
2572 0.7344116094f, 0.5979668656f, -0.3210532909f, 0, 0.5789393465f, -0.2488849713f, 0.7764570201f, 0, 0.6988182827f, 0.3557169806f, -0.6205791146f, 0, -0.8636845529f, -0.2748771249f, -0.4224826141f, 0, -0.4247027957f, -0.4640880967f, 0.777335046f, 0, 0.5257722489f, -0.8427017621f, 0.1158329937f, 0, 0.9343830603f, 0.316302472f, -0.1639543925f, 0, -0.1016836419f, -0.8057303073f, -0.5834887393f, 0,
2573 -0.6529238969f, 0.50602126f, -0.5635892736f, 0, -0.2465286165f, -0.9668205684f, -0.06694497494f, 0, -0.9776897119f, -0.2099250524f, -0.007368825344f, 0, 0.7736893337f, 0.5734244712f, 0.2694238123f, 0, -0.6095087895f, 0.4995678998f, 0.6155736747f, 0, 0.5794535482f, 0.7434546771f, 0.3339292269f, 0, -0.8226211154f, 0.08142581855f, 0.5627293636f, 0, -0.510385483f, 0.4703667658f, 0.7199039967f, 0,
2574 -0.5764971849f, -0.07231656274f, -0.8138926898f, 0, 0.7250628871f, 0.3949971505f, -0.5641463116f, 0, -0.1525424005f, 0.4860840828f, -0.8604958341f, 0, -0.5550976208f, -0.4957820792f, 0.667882296f, 0, -0.1883614327f, 0.9145869398f, 0.357841725f, 0, 0.7625556724f, -0.5414408243f, -0.3540489801f, 0, -0.5870231946f, -0.3226498013f, -0.7424963803f, 0, 0.3051124198f, 0.2262544068f, -0.9250488391f, 0,
2575 0.6379576059f, 0.577242424f, -0.5097070502f, 0, -0.5966775796f, 0.1454852398f, -0.7891830656f, 0, -0.658330573f, 0.6555487542f, -0.3699414651f, 0, 0.7434892426f, 0.2351084581f, 0.6260573129f, 0, 0.5562114096f, 0.8264360377f, -0.0873632843f, 0, -0.3028940016f, -0.8251527185f, 0.4768419182f, 0, 0.1129343818f, -0.985888439f, -0.1235710781f, 0, 0.5937652891f, -0.5896813806f, 0.5474656618f, 0,
2576 0.6757964092f, -0.5835758614f, -0.4502648413f, 0, 0.7242302609f, -0.1152719764f, 0.6798550586f, 0, -0.9511914166f, 0.0753623979f, -0.2992580792f, 0, 0.2539470961f, -0.1886339355f, 0.9486454084f, 0, 0.571433621f, -0.1679450851f, -0.8032795685f, 0, -0.06778234979f, 0.3978269256f, 0.9149531629f, 0, 0.6074972649f, 0.733060024f, -0.3058922593f, 0, -0.5435478392f, 0.1675822484f, 0.8224791405f, 0,
2577 -0.5876678086f, -0.3380045064f, -0.7351186982f, 0, -0.7967562402f, 0.04097822706f, -0.6029098428f, 0, -0.1996350917f, 0.8706294745f, 0.4496111079f, 0, -0.02787660336f, -0.9106232682f, -0.4122962022f, 0, -0.7797625996f, -0.6257634692f, 0.01975775581f, 0, -0.5211232846f, 0.7401644346f, -0.4249554471f, 0, 0.8575424857f, 0.4053272873f, -0.3167501783f, 0, 0.1045223322f, 0.8390195772f, -0.5339674439f, 0,
2578 0.3501822831f, 0.9242524096f, -0.1520850155f, 0, 0.1987849858f, 0.07647613266f, 0.9770547224f, 0, 0.7845996363f, 0.6066256811f, -0.1280964233f, 0, 0.09006737436f, -0.9750989929f, -0.2026569073f, 0, -0.8274343547f, -0.542299559f, 0.1458203587f, 0, -0.3485797732f, -0.415802277f, 0.840000362f, 0, -0.2471778936f, -0.7304819962f, -0.6366310879f, 0, -0.3700154943f, 0.8577948156f, 0.3567584454f, 0,
2579 0.5913394901f, -0.548311967f, -0.5913303597f, 0, 0.1204873514f, -0.7626472379f, -0.6354935001f, 0, 0.616959265f, 0.03079647928f, 0.7863922953f, 0, 0.1258156836f, -0.6640829889f, -0.7369967419f, 0, -0.6477565124f, -0.1740147258f, -0.7417077429f, 0, 0.6217889313f, -0.7804430448f, -0.06547655076f, 0, 0.6589943422f, -0.6096987708f, 0.4404473475f, 0, -0.2689837504f, -0.6732403169f, -0.6887635427f, 0,
2580 -0.3849775103f, 0.5676542638f, 0.7277093879f, 0, 0.5754444408f, 0.8110471154f, -0.1051963504f, 0, 0.9141593684f, 0.3832947817f, 0.131900567f, 0, -0.107925319f, 0.9245493968f, 0.3654593525f, 0, 0.377977089f, 0.3043148782f, 0.8743716458f, 0, -0.2142885215f, -0.8259286236f, 0.5214617324f, 0, 0.5802544474f, 0.4148098596f, -0.7008834116f, 0, -0.1982660881f, 0.8567161266f, -0.4761596756f, 0,
2581 -0.03381553704f, 0.3773180787f, -0.9254661404f, 0, -0.6867922841f, -0.6656597827f, 0.2919133642f, 0, 0.7731742607f, -0.2875793547f, -0.5652430251f, 0, -0.09655941928f, 0.9193708367f, -0.3813575004f, 0, 0.2715702457f, -0.9577909544f, -0.09426605581f, 0, 0.2451015704f, -0.6917998565f, -0.6792188003f, 0, 0.977700782f, -0.1753855374f, 0.1155036542f, 0, -0.5224739938f, 0.8521606816f, 0.02903615945f, 0,
2582 -0.7734880599f, -0.5261292347f, 0.3534179531f, 0, -0.7134492443f, -0.269547243f, 0.6467878011f, 0, 0.1644037271f, 0.5105846203f, -0.8439637196f, 0, 0.6494635788f, 0.05585611296f, 0.7583384168f, 0, -0.4711970882f, 0.5017280509f, -0.7254255765f, 0, -0.6335764307f, -0.2381686273f, -0.7361091029f, 0, -0.9021533097f, -0.270947803f, -0.3357181763f, 0, -0.3793711033f, 0.872258117f, 0.3086152025f, 0,
2583 -0.6855598966f, -0.3250143309f, 0.6514394162f, 0, 0.2900942212f, -0.7799057743f, -0.5546100667f, 0, -0.2098319339f, 0.85037073f, 0.4825351604f, 0, -0.4592603758f, 0.6598504336f, -0.5947077538f, 0, 0.8715945488f, 0.09616365406f, -0.4807031248f, 0, -0.6776666319f, 0.7118504878f, -0.1844907016f, 0, 0.7044377633f, 0.312427597f, 0.637304036f, 0, -0.7052318886f, -0.2401093292f, -0.6670798253f, 0,
2584 0.081921007f, -0.7207336136f, -0.6883545647f, 0, -0.6993680906f, -0.5875763221f, -0.4069869034f, 0, -0.1281454481f, 0.6419895885f, 0.7559286424f, 0, -0.6337388239f, -0.6785471501f, -0.3714146849f, 0, 0.5565051903f, -0.2168887573f, -0.8020356851f, 0, -0.5791554484f, 0.7244372011f, -0.3738578718f, 0, 0.1175779076f, -0.7096451073f, 0.6946792478f, 0, -0.6134619607f, 0.1323631078f, 0.7785527795f, 0,
2585 0.6984635305f, -0.02980516237f, -0.715024719f, 0, 0.8318082963f, -0.3930171956f, 0.3919597455f, 0, 0.1469576422f, 0.05541651717f, -0.9875892167f, 0, 0.708868575f, -0.2690503865f, 0.6520101478f, 0, 0.2726053183f, 0.67369766f, -0.68688995f, 0, -0.6591295371f, 0.3035458599f, -0.6880466294f, 0, 0.4815131379f, -0.7528270071f, 0.4487723203f, 0, 0.9430009463f, 0.1675647412f, -0.2875261255f, 0,
2586 0.434802957f, 0.7695304522f, -0.4677277752f, 0, 0.3931996188f, 0.594473625f, 0.7014236729f, 0, 0.7254336655f, -0.603925654f, 0.3301814672f, 0, 0.7590235227f, -0.6506083235f, 0.02433313207f, 0, -0.8552768592f, -0.3430042733f, 0.3883935666f, 0, -0.6139746835f, 0.6981725247f, 0.3682257648f, 0, -0.7465905486f, -0.5752009504f, 0.3342849376f, 0, 0.5730065677f, 0.810555537f, -0.1210916791f, 0,
2587 -0.9225877367f, -0.3475211012f, -0.167514036f, 0, -0.7105816789f, -0.4719692027f, -0.5218416899f, 0, -0.08564609717f, 0.3583001386f, 0.929669703f, 0, -0.8279697606f, -0.2043157126f, 0.5222271202f, 0, 0.427944023f, 0.278165994f, 0.8599346446f, 0, 0.5399079671f, -0.7857120652f, -0.3019204161f, 0, 0.5678404253f, -0.5495413974f, -0.6128307303f, 0, -0.9896071041f, 0.1365639107f, -0.04503418428f, 0,
2588 -0.6154342638f, -0.6440875597f, 0.4543037336f, 0, 0.1074204368f, -0.7946340692f, 0.5975094525f, 0, -0.3595449969f, -0.8885529948f, 0.28495784f, 0, -0.2180405296f, 0.1529888965f, 0.9638738118f, 0, -0.7277432317f, -0.6164050508f, -0.3007234646f, 0, 0.7249729114f, -0.00669719484f, 0.6887448187f, 0, -0.5553659455f, -0.5336586252f, 0.6377908264f, 0, 0.5137558015f, 0.7976208196f, -0.3160000073f, 0,
2589 -0.3794024848f, 0.9245608561f, -0.03522751494f, 0, 0.8229248658f, 0.2745365933f, -0.4974176556f, 0, -0.5404114394f, 0.6091141441f, 0.5804613989f, 0, 0.8036581901f, -0.2703029469f, 0.5301601931f, 0, 0.6044318879f, 0.6832968393f, 0.4095943388f, 0, 0.06389988817f, 0.9658208605f, -0.2512108074f, 0, 0.1087113286f, 0.7402471173f, -0.6634877936f, 0, -0.713427712f, -0.6926784018f, 0.1059128479f, 0,
2590 0.6458897819f, -0.5724548511f, -0.5050958653f, 0, -0.6553931414f, 0.7381471625f, 0.159995615f, 0, 0.3910961323f, 0.9188871375f, -0.05186755998f, 0, -0.4879022471f, -0.5904376907f, 0.6429111375f, 0, 0.6014790094f, 0.7707441366f, -0.2101820095f, 0, -0.5677173047f, 0.7511360995f, 0.3368851762f, 0, 0.7858573506f, 0.226674665f, 0.5753666838f, 0, -0.4520345543f, -0.604222686f, -0.6561857263f, 0,
2591 0.002272116345f, 0.4132844051f, -0.9105991643f, 0, -0.5815751419f, -0.5162925989f, 0.6286591339f, 0, -0.03703704785f, 0.8273785755f, 0.5604221175f, 0, -0.5119692504f, 0.7953543429f, -0.3244980058f, 0, -0.2682417366f, -0.9572290247f, -0.1084387619f, 0, -0.2322482736f, -0.9679131102f, -0.09594243324f, 0, 0.3554328906f, -0.8881505545f, 0.2913006227f, 0, 0.7346520519f, -0.4371373164f, 0.5188422971f, 0,
2592 0.9985120116f, 0.04659011161f, -0.02833944577f, 0, -0.3727687496f, -0.9082481361f, 0.1900757285f, 0, 0.91737377f, -0.3483642108f, 0.1925298489f, 0, 0.2714911074f, 0.4147529736f, -0.8684886582f, 0, 0.5131763485f, -0.7116334161f, 0.4798207128f, 0, -0.8737353606f, 0.18886992f, -0.4482350644f, 0, 0.8460043821f, -0.3725217914f, 0.3814499973f, 0, 0.8978727456f, -0.1780209141f, -0.4026575304f, 0,
2593 0.2178065647f, -0.9698322841f, -0.1094789531f, 0, -0.1518031304f, -0.7788918132f, -0.6085091231f, 0, -0.2600384876f, -0.4755398075f, -0.8403819825f, 0, 0.572313509f, -0.7474340931f, -0.3373418503f, 0, -0.7174141009f, 0.1699017182f, -0.6756111411f, 0, -0.684180784f, 0.02145707593f, -0.7289967412f, 0, -0.2007447902f, 0.06555605789f, -0.9774476623f, 0, -0.1148803697f, -0.8044887315f, 0.5827524187f, 0,
2594 -0.7870349638f, 0.03447489231f, 0.6159443543f, 0, -0.2015596421f, 0.6859872284f, 0.6991389226f, 0, -0.08581082512f, -0.10920836f, -0.9903080513f, 0, 0.5532693395f, 0.7325250401f, -0.396610771f, 0, -0.1842489331f, -0.9777375055f, -0.1004076743f, 0, 0.0775473789f, -0.9111505856f, 0.4047110257f, 0, 0.1399838409f, 0.7601631212f, -0.6344734459f, 0, 0.4484419361f, -0.845289248f, 0.2904925424f, 0
2595};
2596
2597}
2598#endif // namespace fastnoiselite
2599