bracket_noise/
fastnoise.rs

1// A port of Auburn's FastNoise to Rust.
2// I really didn't like the noise libraries I could find, so I ported the one I like.
3// Original code: https://github.com/Auburns/FastNoise
4// The original is MIT licensed, so this is compatible.
5
6use bracket_random::prelude::RandomNumberGenerator;
7
8#[derive(Debug, PartialEq, Copy, Clone)]
9/// Type of noise to generate
10pub enum NoiseType {
11    Value,
12    ValueFractal,
13    Perlin,
14    PerlinFractal,
15    Simplex,
16    SimplexFractal,
17    Cellular,
18    WhiteNoise,
19    Cubic,
20    CubicFractal,
21}
22
23#[derive(Debug, PartialEq, Copy, Clone)]
24/// Interpolation function to use
25pub enum Interp {
26    Linear,
27    Hermite,
28    Quintic,
29}
30
31#[derive(Debug, PartialEq, Copy, Clone)]
32/// Fractal function to use
33pub enum FractalType {
34    FBM,
35    Billow,
36    RigidMulti,
37}
38
39#[derive(Debug, PartialEq, Copy, Clone)]
40/// Cellular noise distance function to use
41pub enum CellularDistanceFunction {
42    Euclidean,
43    Manhattan,
44    Natural,
45}
46
47#[derive(Debug, PartialEq, Copy, Clone)]
48/// What type of cellular noise result do you want
49pub enum CellularReturnType {
50    CellValue,
51    Distance,
52    Distance2,
53    Distance2Add,
54    Distance2Sub,
55    Distance2Mul,
56    Distance2Div,
57}
58
59pub struct FastNoise {
60    rng: RandomNumberGenerator,
61    seed: u64,
62    frequency: f32,
63    interp: Interp,
64    noise_type: NoiseType,
65    octaves: i32,
66    lacunarity: f32,
67    gain: f32,
68    fractal_type: FractalType,
69    cellular_distance_function: CellularDistanceFunction,
70    cellular_return_type: CellularReturnType,
71    cellular_distance_index: (i32, i32),
72    cellular_jitter: f32,
73    gradient_perturb_amp: f32,
74    perm: Vec<u8>,
75    perm12: Vec<u8>,
76    fractal_bounding: f32,
77}
78
79// Constants that used to be at the top
80const GRAD_X: [f32; 12] = [1.0, -1., 1., -1., 1., -1., 1., -1., 0., 0., 0., 0.];
81
82const GRAD_Y: [f32; 12] = [1., 1., -1., -1., 0., 0., 0., 0., 1., -1., 1., -1.];
83
84const GRAD_Z: [f32; 12] = [0., 0., 0., 0., 1., 1., -1., -1., 1., 1., -1., -1.];
85
86#[allow(dead_code)]
87const GRAD_4D: [f32; 128] = [
88    0., 1., 1., 1., 0., 1., 1., -1., 0., 1., -1., 1., 0., 1., -1., -1., 0., -1., 1., 1., 0., -1.,
89    1., -1., 0., -1., -1., 1., 0., -1., -1., -1., 1., 0., 1., 1., 1., 0., 1., -1., 1., 0., -1., 1.,
90    1., 0., -1., -1., -1., 0., 1., 1., -1., 0., 1., -1., -1., 0., -1., 1., -1., 0., -1., -1., 1.,
91    1., 0., 1., 1., 1., 0., -1., 1., -1., 0., 1., 1., -1., 0., -1., -1., 1., 0., 1., -1., 1., 0.,
92    -1., -1., -1., 0., 1., -1., -1., 0., -1., 1., 1., 1., 0., 1., 1., -1., 0., 1., -1., 1., 0., 1.,
93    -1., -1., 0., -1., 1., 1., 0., -1., 1., -1., 0., -1., -1., 1., 0., -1., -1., -1., 0.,
94];
95
96#[allow(clippy::unreadable_literal)]
97#[allow(clippy::excessive_precision)]
98const VAL_LUT: [f32; 256] = [
99    0.3490196078,
100    0.4352941176,
101    -0.4509803922,
102    0.6392156863,
103    0.5843137255,
104    -0.1215686275,
105    0.7176470588,
106    -0.1058823529,
107    0.3960784314,
108    0.0431372549,
109    -0.03529411765,
110    0.3176470588,
111    0.7254901961,
112    0.137254902,
113    0.8588235294,
114    -0.8196078431,
115    -0.7960784314,
116    -0.3333333333,
117    -0.6705882353,
118    -0.3882352941,
119    0.262745098,
120    0.3254901961,
121    -0.6470588235,
122    -0.9215686275,
123    -0.5294117647,
124    0.5294117647,
125    -0.4666666667,
126    0.8117647059,
127    0.3803921569,
128    0.662745098,
129    0.03529411765,
130    -0.6156862745,
131    -0.01960784314,
132    -0.3568627451,
133    -0.09019607843,
134    0.7490196078,
135    0.8352941176,
136    -0.4039215686,
137    -0.7490196078,
138    0.9529411765,
139    -0.0431372549,
140    -0.9294117647,
141    -0.6549019608,
142    0.9215686275,
143    -0.06666666667,
144    -0.4431372549,
145    0.4117647059,
146    -0.4196078431,
147    -0.7176470588,
148    -0.8117647059,
149    -0.2549019608,
150    0.4901960784,
151    0.9137254902,
152    0.7882352941,
153    -1.0,
154    -0.4745098039,
155    0.7960784314,
156    0.8509803922,
157    -0.6784313725,
158    0.4588235294,
159    1.0,
160    -0.1843137255,
161    0.4509803922,
162    0.1450980392,
163    -0.231372549,
164    -0.968627451,
165    -0.8588235294,
166    0.4274509804,
167    0.003921568627,
168    -0.003921568627,
169    0.2156862745,
170    0.5058823529,
171    0.7647058824,
172    0.2078431373,
173    -0.5921568627,
174    0.5764705882,
175    -0.1921568627,
176    -0.937254902,
177    0.08235294118,
178    -0.08235294118,
179    0.9058823529,
180    0.8274509804,
181    0.02745098039,
182    -0.168627451,
183    -0.7803921569,
184    0.1137254902,
185    -0.9450980392,
186    0.2,
187    0.01960784314,
188    0.5607843137,
189    0.2705882353,
190    0.4431372549,
191    -0.9607843137,
192    0.6156862745,
193    0.9294117647,
194    -0.07450980392,
195    0.3098039216,
196    0.9921568627,
197    -0.9137254902,
198    -0.2941176471,
199    -0.3411764706,
200    -0.6235294118,
201    -0.7647058824,
202    -0.8901960784,
203    0.05882352941,
204    0.2392156863,
205    0.7333333333,
206    0.6549019608,
207    0.2470588235,
208    0.231372549,
209    -0.3960784314,
210    -0.05098039216,
211    -0.2235294118,
212    -0.3725490196,
213    0.6235294118,
214    0.7019607843,
215    -0.8274509804,
216    0.4196078431,
217    0.07450980392,
218    0.8666666667,
219    -0.537254902,
220    -0.5058823529,
221    -0.8039215686,
222    0.09019607843,
223    -0.4823529412,
224    0.6705882353,
225    -0.7882352941,
226    0.09803921569,
227    -0.6078431373,
228    0.8039215686,
229    -0.6,
230    -0.3254901961,
231    -0.4117647059,
232    -0.01176470588,
233    0.4823529412,
234    0.168627451,
235    0.8745098039,
236    -0.3647058824,
237    -0.1607843137,
238    0.568627451,
239    -0.9921568627,
240    0.9450980392,
241    0.5137254902,
242    0.01176470588,
243    -0.1450980392,
244    -0.5529411765,
245    -0.5764705882,
246    -0.1137254902,
247    0.5215686275,
248    0.1607843137,
249    0.3725490196,
250    -0.2,
251    -0.7254901961,
252    0.631372549,
253    0.7098039216,
254    -0.568627451,
255    0.1294117647,
256    -0.3098039216,
257    0.7411764706,
258    -0.8509803922,
259    0.2549019608,
260    -0.6392156863,
261    -0.5607843137,
262    -0.3176470588,
263    0.937254902,
264    0.9843137255,
265    0.5921568627,
266    0.6941176471,
267    0.2862745098,
268    -0.5215686275,
269    0.1764705882,
270    0.537254902,
271    -0.4901960784,
272    -0.4588235294,
273    -0.2078431373,
274    -0.2156862745,
275    0.7725490196,
276    0.3647058824,
277    -0.2392156863,
278    0.2784313725,
279    -0.8823529412,
280    0.8980392157,
281    0.1215686275,
282    0.1058823529,
283    -0.8745098039,
284    -0.9843137255,
285    -0.7019607843,
286    0.9607843137,
287    0.2941176471,
288    0.3411764706,
289    0.1529411765,
290    0.06666666667,
291    -0.9764705882,
292    0.3019607843,
293    0.6470588235,
294    -0.5843137255,
295    0.05098039216,
296    -0.5137254902,
297    -0.137254902,
298    0.3882352941,
299    -0.262745098,
300    -0.3019607843,
301    -0.1764705882,
302    -0.7568627451,
303    0.1843137255,
304    -0.5450980392,
305    -0.4980392157,
306    -0.2784313725,
307    -0.9529411765,
308    -0.09803921569,
309    0.8901960784,
310    -0.2862745098,
311    -0.3803921569,
312    0.5529411765,
313    0.7803921569,
314    -0.8352941176,
315    0.6862745098,
316    0.7568627451,
317    0.4980392157,
318    -0.6862745098,
319    -0.8980392157,
320    -0.7725490196,
321    -0.7098039216,
322    -0.2470588235,
323    -0.9058823529,
324    0.9764705882,
325    0.1921568627,
326    0.8431372549,
327    -0.05882352941,
328    0.3568627451,
329    0.6078431373,
330    0.5450980392,
331    0.4039215686,
332    -0.7333333333,
333    -0.4274509804,
334    0.6,
335    0.6784313725,
336    -0.631372549,
337    -0.02745098039,
338    -0.1294117647,
339    0.3333333333,
340    -0.8431372549,
341    0.2235294118,
342    -0.3490196078,
343    -0.6941176471,
344    0.8823529412,
345    0.4745098039,
346    0.4666666667,
347    -0.7411764706,
348    -0.2705882353,
349    0.968627451,
350    0.8196078431,
351    -0.662745098,
352    -0.4352941176,
353    -0.8666666667,
354    -0.1529411765,
355];
356
357#[allow(clippy::unreadable_literal)]
358#[allow(clippy::excessive_precision)]
359const CELL_2D_X: [f32; 256] = [
360    -0.6440658039,
361    -0.08028078721,
362    0.9983546168,
363    0.9869492062,
364    0.9284746418,
365    0.6051097552,
366    -0.794167404,
367    -0.3488667991,
368    -0.943136526,
369    -0.9968171318,
370    0.8740961579,
371    0.1421139764,
372    0.4282553608,
373    -0.9986665833,
374    0.9996760121,
375    -0.06248383632,
376    0.7120139305,
377    0.8917660409,
378    0.1094842955,
379    -0.8730880804,
380    0.2594811489,
381    -0.6690063346,
382    -0.9996834972,
383    -0.8803608671,
384    -0.8166554937,
385    0.8955599676,
386    -0.9398321388,
387    0.07615451399,
388    -0.7147270565,
389    0.8707354457,
390    -0.9580008579,
391    0.4905965632,
392    0.786775944,
393    0.1079711577,
394    0.2686638979,
395    0.6113487322,
396    -0.530770584,
397    -0.7837268286,
398    -0.8558691039,
399    -0.5726093896,
400    -0.9830740914,
401    0.7087766359,
402    0.6807027153,
403    -0.08864708788,
404    0.6704485923,
405    -0.1350735482,
406    -0.9381333003,
407    0.9756655376,
408    0.4231433671,
409    -0.4959787385,
410    0.1005554325,
411    -0.7645857281,
412    -0.5859053796,
413    -0.9751154306,
414    -0.6972258572,
415    0.7907012002,
416    -0.9109899213,
417    -0.9584307894,
418    -0.8269529333,
419    0.2608264719,
420    -0.7773760119,
421    0.7606456974,
422    -0.8961083758,
423    -0.9838134719,
424    0.7338893576,
425    0.2161226729,
426    0.673509891,
427    -0.5512056873,
428    0.6899744332,
429    0.868004831,
430    0.5897430311,
431    -0.8950444221,
432    -0.3595752773,
433    0.8209486981,
434    -0.2912360132,
435    -0.9965011374,
436    0.9766994634,
437    0.738790822,
438    -0.4730947722,
439    0.8946479441,
440    -0.6943628971,
441    -0.6620468182,
442    -0.0887255502,
443    -0.7512250855,
444    -0.5322986898,
445    0.5226295385,
446    0.2296318375,
447    0.7915307344,
448    -0.2756485999,
449    -0.6900234522,
450    0.07090588086,
451    0.5981278485,
452    0.3033429312,
453    -0.7253142797,
454    -0.9855874307,
455    -0.1761843396,
456    -0.6438468325,
457    -0.9956136595,
458    0.8541580762,
459    -0.9999807666,
460    -0.02152416253,
461    -0.8705983095,
462    -0.1197138014,
463    -0.992107781,
464    -0.9091181546,
465    0.788610536,
466    -0.994636402,
467    0.4211256853,
468    0.3110430857,
469    -0.4031127839,
470    0.7610684239,
471    0.7685674467,
472    0.152271555,
473    -0.9364648723,
474    0.1681333739,
475    -0.3567427907,
476    -0.418445483,
477    -0.98774778,
478    0.8705250765,
479    -0.8911701067,
480    -0.7315350966,
481    0.6030885658,
482    -0.4149130821,
483    0.7585339481,
484    0.6963196535,
485    0.8332685012,
486    -0.8086815232,
487    0.7518116724,
488    -0.3490535894,
489    0.6972110903,
490    -0.8795676928,
491    -0.6442331882,
492    0.6610236811,
493    -0.9853565782,
494    -0.590338458,
495    0.09843602117,
496    0.5646534882,
497    -0.6023259233,
498    -0.3539248861,
499    0.5132728656,
500    0.9380385118,
501    -0.7599270056,
502    -0.7425936564,
503    -0.6679610562,
504    -0.3018497816,
505    0.814478266,
506    0.03777430269,
507    -0.7514235086,
508    0.9662556939,
509    -0.4720194901,
510    -0.435054126,
511    0.7091901235,
512    0.929379209,
513    0.9997434357,
514    0.8306320299,
515    -0.9434019629,
516    -0.133133759,
517    0.5048413216,
518    0.3711995273,
519    0.98552091,
520    0.7401857005,
521    -0.9999981398,
522    -0.2144033253,
523    0.4808624681,
524    -0.413835885,
525    0.644229305,
526    0.9626648696,
527    0.1833665934,
528    0.5794129,
529    0.01404446873,
530    0.4388494993,
531    0.5213612322,
532    -0.5281609948,
533    -0.9745306846,
534    -0.9904373013,
535    0.9100232252,
536    -0.9914057719,
537    0.7892627765,
538    0.3364421659,
539    -0.9416099764,
540    0.7802732656,
541    0.886302871,
542    0.6524471291,
543    0.5762186726,
544    -0.08987644664,
545    -0.2177026782,
546    -0.9720345052,
547    -0.05722538858,
548    0.8105983127,
549    0.3410261032,
550    0.6452309645,
551    -0.7810612152,
552    0.9989395718,
553    -0.808247815,
554    0.6370177929,
555    0.5844658772,
556    0.2054070861,
557    0.055960522,
558    -0.995827561,
559    0.893409165,
560    -0.931516824,
561    0.328969469,
562    -0.3193837488,
563    0.7314755657,
564    -0.7913517714,
565    -0.2204109786,
566    0.9955900414,
567    -0.7112353139,
568    -0.7935008741,
569    -0.9961918204,
570    -0.9714163995,
571    -0.9566188669,
572    0.2748495632,
573    -0.4681743221,
574    -0.9614449642,
575    0.585194072,
576    0.4532946061,
577    -0.9916113176,
578    0.942479587,
579    -0.9813704753,
580    -0.6538429571,
581    0.2923335053,
582    -0.2246660704,
583    -0.1800781949,
584    -0.9581216256,
585    0.552215082,
586    -0.9296791922,
587    0.643183699,
588    0.9997325981,
589    -0.4606920354,
590    -0.2148721265,
591    0.3482070809,
592    0.3075517813,
593    0.6274756393,
594    0.8910881765,
595    -0.6397771309,
596    -0.4479080125,
597    -0.5247665011,
598    -0.8386507094,
599    0.3901291416,
600    0.1458336921,
601    0.01624613149,
602    -0.8273199879,
603    0.5611100679,
604    -0.8380219841,
605    -0.9856122234,
606    -0.861398618,
607    0.6398413916,
608    0.2694510795,
609    0.4327334514,
610    -0.9960265354,
611    -0.939570655,
612    -0.8846996446,
613    0.7642113189,
614    -0.7002080528,
615    0.664508256,
616];
617
618#[allow(clippy::unreadable_literal)]
619#[allow(clippy::excessive_precision)]
620const CELL_2D_Y: [f32; 256] = [
621    0.7649700911,
622    0.9967722885,
623    0.05734160033,
624    -0.1610318741,
625    0.371395799,
626    -0.7961420628,
627    0.6076990492,
628    -0.9371723195,
629    0.3324056156,
630    0.07972205329,
631    -0.4857529277,
632    -0.9898503007,
633    0.9036577593,
634    0.05162417479,
635    -0.02545330525,
636    -0.998045976,
637    -0.7021653386,
638    -0.4524967717,
639    -0.9939885256,
640    -0.4875625128,
641    -0.9657481729,
642    -0.7432567015,
643    0.02515761212,
644    0.4743044842,
645    0.5771254669,
646    0.4449408324,
647    0.3416365773,
648    0.9970960285,
649    0.6994034849,
650    0.4917517499,
651    0.286765333,
652    0.8713868327,
653    0.6172387009,
654    0.9941540269,
655    0.9632339851,
656    -0.7913613129,
657    0.847515538,
658    0.6211056739,
659    0.5171924952,
660    -0.8198283277,
661    -0.1832084353,
662    0.7054329737,
663    0.7325597678,
664    0.9960630973,
665    0.7419559859,
666    0.9908355749,
667    -0.346274329,
668    0.2192641299,
669    -0.9060627411,
670    -0.8683346653,
671    0.9949314574,
672    -0.6445220433,
673    -0.8103794704,
674    -0.2216977607,
675    0.7168515217,
676    0.612202264,
677    -0.412428616,
678    0.285325116,
679    0.56227115,
680    -0.9653857009,
681    -0.6290361962,
682    0.6491672535,
683    0.443835306,
684    -0.1791955706,
685    -0.6792690269,
686    -0.9763662173,
687    0.7391782104,
688    0.8343693968,
689    0.7238337389,
690    0.4965557504,
691    0.8075909592,
692    -0.4459769977,
693    -0.9331160806,
694    -0.5710019572,
695    0.9566512346,
696    -0.08357920318,
697    0.2146116448,
698    -0.6739348049,
699    0.8810115417,
700    0.4467718167,
701    -0.7196250184,
702    -0.749462481,
703    0.9960561112,
704    0.6600461127,
705    -0.8465566164,
706    -0.8525598897,
707    -0.9732775654,
708    0.6111293616,
709    -0.9612584717,
710    -0.7237870097,
711    -0.9974830104,
712    -0.8014006968,
713    0.9528814544,
714    -0.6884178931,
715    -0.1691668301,
716    0.9843571905,
717    0.7651544003,
718    -0.09355982605,
719    -0.5200134429,
720    -0.006202125807,
721    -0.9997683284,
722    0.4919944954,
723    -0.9928084436,
724    -0.1253880012,
725    -0.4165383308,
726    -0.6148930171,
727    -0.1034332049,
728    -0.9070022917,
729    -0.9503958117,
730    0.9151503065,
731    -0.6486716073,
732    0.6397687707,
733    -0.9883386937,
734    0.3507613761,
735    0.9857642561,
736    -0.9342026446,
737    -0.9082419159,
738    0.1560587169,
739    0.4921240607,
740    -0.453669308,
741    0.6818037859,
742    0.7976742329,
743    0.9098610522,
744    0.651633524,
745    0.7177318024,
746    -0.5528685241,
747    0.5882467118,
748    0.6593778956,
749    0.9371027648,
750    -0.7168658839,
751    -0.4757737632,
752    0.7648291307,
753    0.7503650398,
754    0.1705063456,
755    -0.8071558121,
756    -0.9951433815,
757    -0.8253280792,
758    -0.7982502628,
759    0.9352738503,
760    0.8582254747,
761    -0.3465310238,
762    0.65000842,
763    -0.6697422351,
764    0.7441962291,
765    -0.9533555,
766    0.5801940659,
767    -0.9992862963,
768    -0.659820211,
769    0.2575848092,
770    0.881588113,
771    -0.9004043022,
772    -0.7050172826,
773    0.369126382,
774    -0.02265088836,
775    0.5568217228,
776    -0.3316515286,
777    0.991098079,
778    -0.863212164,
779    -0.9285531277,
780    0.1695539323,
781    -0.672402505,
782    -0.001928841934,
783    0.9767452145,
784    -0.8767960349,
785    0.9103515037,
786    -0.7648324016,
787    0.2706960452,
788    -0.9830446035,
789    0.8150341657,
790    -0.9999013716,
791    -0.8985605806,
792    0.8533360801,
793    0.8491442537,
794    -0.2242541966,
795    -0.1379635899,
796    -0.4145572694,
797    0.1308227633,
798    0.6140555916,
799    0.9417041303,
800    -0.336705587,
801    -0.6254387508,
802    0.4631060578,
803    -0.7578342456,
804    -0.8172955655,
805    -0.9959529228,
806    -0.9760151351,
807    0.2348380732,
808    -0.9983612848,
809    0.5856025746,
810    -0.9400538266,
811    -0.7639875669,
812    0.6244544645,
813    0.04604054566,
814    0.5888424828,
815    0.7708490978,
816    -0.8114182882,
817    0.9786766212,
818    -0.9984329822,
819    0.09125496582,
820    -0.4492438803,
821    -0.3636982357,
822    0.9443405575,
823    -0.9476254645,
824    -0.6818676535,
825    -0.6113610831,
826    0.9754070948,
827    -0.0938108173,
828    -0.7029540015,
829    -0.6085691109,
830    -0.08718862881,
831    -0.237381926,
832    0.2913423132,
833    0.9614872426,
834    0.8836361266,
835    -0.2749974196,
836    -0.8108932717,
837    -0.8913607575,
838    0.129255541,
839    -0.3342637104,
840    -0.1921249337,
841    -0.7566302845,
842    -0.9563164339,
843    -0.9744358146,
844    0.9836522982,
845    -0.2863615732,
846    0.8337016872,
847    0.3683701937,
848    0.7657119102,
849    -0.02312427772,
850    0.8875600535,
851    0.976642191,
852    0.9374176384,
853    0.9515313457,
854    -0.7786361937,
855    -0.4538302125,
856    -0.7685604874,
857    -0.8940796454,
858    -0.8512462154,
859    0.5446696133,
860    0.9207601495,
861    -0.9893091197,
862    -0.9998680229,
863    0.5617309299,
864    -0.8277411985,
865    0.545636467,
866    0.1690223212,
867    -0.5079295433,
868    0.7685069899,
869    -0.9630140787,
870    0.9015219132,
871    0.08905695279,
872    -0.3423550559,
873    -0.4661614943,
874    -0.6449659371,
875    0.7139388509,
876    0.7472809229,
877];
878
879#[allow(clippy::unreadable_literal)]
880#[allow(clippy::excessive_precision)]
881const CELL_3D_X: [f32; 256] = [
882    0.3752498686,
883    0.687188096,
884    0.2248135212,
885    0.6692006647,
886    -0.4376476931,
887    0.6139972552,
888    0.9494563929,
889    0.8065108882,
890    -0.2218812853,
891    0.8484661167,
892    0.5551817596,
893    0.2133903499,
894    0.5195126593,
895    -0.6440141975,
896    -0.5192897331,
897    -0.3697654077,
898    -0.07927779647,
899    0.4187757321,
900    -0.750078731,
901    0.6579554632,
902    -0.6859803838,
903    -0.6878407087,
904    0.9490848347,
905    0.5795829433,
906    -0.5325976529,
907    -0.1363699466,
908    0.417665879,
909    -0.9108236468,
910    0.4438605427,
911    0.819294887,
912    -0.4033873915,
913    -0.2817317705,
914    0.3969665622,
915    0.5323450134,
916    -0.6833017297,
917    0.3881436661,
918    -0.7119144767,
919    -0.2306979838,
920    -0.9398873022,
921    0.1701906676,
922    -0.4261839496,
923    -0.003712295499,
924    -0.734675004,
925    -0.3195046015,
926    0.7345307424,
927    0.9766246496,
928    -0.02003735175,
929    -0.4824156342,
930    0.4245892007,
931    0.9072427669,
932    0.593346808,
933    -0.8911762541,
934    -0.7657571834,
935    -0.5268198896,
936    -0.8801903279,
937    -0.6296409617,
938    -0.09492481344,
939    -0.4920470525,
940    0.7307666154,
941    -0.2514540636,
942    -0.3356210347,
943    -0.3522787894,
944    0.87847885,
945    -0.7424096346,
946    0.5757585274,
947    0.4519299338,
948    0.6420368628,
949    -0.1128478447,
950    0.499874883,
951    0.5291681739,
952    -0.5098837195,
953    0.5639583502,
954    -0.8456386526,
955    -0.9657134875,
956    -0.576437342,
957    -0.5666013014,
958    0.5667702405,
959    -0.481316582,
960    0.7313389916,
961    -0.3805628566,
962    -0.6512675909,
963    -0.2787156951,
964    0.8648059114,
965    -0.9730216276,
966    -0.8335820906,
967    0.2673159641,
968    0.231150148,
969    0.01286214638,
970    0.6774953261,
971    0.6542885718,
972    -0.02545450161,
973    0.2101238586,
974    -0.5572105885,
975    0.813705672,
976    -0.7546026951,
977    -0.2502500006,
978    -0.9979289381,
979    0.7024037039,
980    0.08990874624,
981    0.8170812432,
982    0.4226980265,
983    -0.2442153475,
984    -0.9183326731,
985    0.6068222411,
986    0.818676691,
987    -0.7236735282,
988    -0.5383903295,
989    -0.6269337242,
990    -0.0939331121,
991    0.9203878539,
992    -0.7256396824,
993    0.6292431149,
994    0.4234156978,
995    0.006685688024,
996    -0.2598694113,
997    0.6408036421,
998    0.05899871622,
999    0.7090281418,
1000    -0.5905222072,
1001    0.3128214264,
1002    -0.691925826,
1003    0.3634019349,
1004    -0.6772511147,
1005    -0.3204583896,
1006    -0.3906740409,
1007    -0.3342190395,
1008    -0.517779592,
1009    -0.6817711267,
1010    0.6422383105,
1011    0.4388482478,
1012    0.2968562611,
1013    -0.2019778353,
1014    0.6014865048,
1015    0.9519280722,
1016    0.3398889569,
1017    0.8179709354,
1018    0.2365522154,
1019    0.3262175096,
1020    -0.8060715954,
1021    -0.2068642503,
1022    0.6208057279,
1023    -0.5274282502,
1024    -0.3722334928,
1025    -0.8923412971,
1026    0.5341834201,
1027    -0.3663701513,
1028    -0.6114600319,
1029    0.5026307556,
1030    0.8396151729,
1031    0.9245042467,
1032    -0.7994843957,
1033    -0.5357200589,
1034    -0.6283359739,
1035    -0.61351886,
1036    -0.875632008,
1037    -0.5278879423,
1038    0.9087491985,
1039    -0.03500215466,
1040    -0.261365798,
1041    -0.579523541,
1042    -0.3765052689,
1043    -0.74398252,
1044    0.4257318052,
1045    -0.1214508921,
1046    0.8561809753,
1047    0.6802835104,
1048    -0.5452131039,
1049    -0.1997156478,
1050    0.4562348357,
1051    -0.811704301,
1052    0.67793962,
1053    -0.9237819106,
1054    0.6973511259,
1055    -0.5189506,
1056    0.5517320032,
1057    -0.396710831,
1058    0.5493762815,
1059    -0.2507853002,
1060    0.4788634005,
1061    0.387333516,
1062    -0.2176515694,
1063    0.6749832419,
1064    0.2148283022,
1065    -0.7521815872,
1066    0.4697000159,
1067    0.7890593699,
1068    -0.7606162952,
1069    0.01083397843,
1070    0.5254091908,
1071    -0.6748025877,
1072    0.751091524,
1073    0.05259056135,
1074    0.01889481232,
1075    -0.6037423727,
1076    -0.6542965129,
1077    0.08873301081,
1078    -0.6191345671,
1079    0.4331858488,
1080    -0.3858351946,
1081    -0.1429059747,
1082    0.4118221036,
1083    -0.6247153214,
1084    -0.611423014,
1085    0.5542939606,
1086    -0.9432768808,
1087    -0.4567870451,
1088    -0.7349133547,
1089    0.399304489,
1090    -0.7474927672,
1091    0.02589419753,
1092    0.783915821,
1093    0.6138668752,
1094    0.4276376047,
1095    -0.4347886353,
1096    0.02947841302,
1097    -0.833742746,
1098    0.3817221742,
1099    -0.8743368359,
1100    -0.3823443796,
1101    -0.6829243811,
1102    -0.3681903049,
1103    -0.367626833,
1104    -0.434583373,
1105    0.235891995,
1106    -0.6874880269,
1107    -0.5115661773,
1108    -0.5534962601,
1109    0.5632777056,
1110    0.686191532,
1111    -0.05095871588,
1112    -0.06865785057,
1113    -0.5975288531,
1114    -0.6429790056,
1115    -0.3729361548,
1116    0.2237917666,
1117    0.6046773225,
1118    -0.5041542295,
1119    -0.03972191174,
1120    0.7028828406,
1121    -0.5560856498,
1122    0.5898328456,
1123    -0.9308076766,
1124    0.4617069864,
1125    0.3190983137,
1126    0.9116567753,
1127    -0.45029554,
1128    0.3346334459,
1129    0.8525005645,
1130    0.2528483381,
1131    -0.8306630147,
1132    -0.6880390622,
1133    0.7448684026,
1134    -0.1963355843,
1135    -0.5900257974,
1136    0.9097057294,
1137    -0.2509196808,
1138];
1139
1140#[allow(clippy::unreadable_literal)]
1141#[allow(clippy::excessive_precision)]
1142const CELL_3D_Y: [f32; 256] = [
1143    -0.6760585049,
1144    -0.09136176499,
1145    0.1681325679,
1146    -0.6688468686,
1147    -0.4822753902,
1148    -0.7891068824,
1149    -0.1877509944,
1150    0.548470914,
1151    -0.463339443,
1152    -0.4050542082,
1153    0.3218158513,
1154    0.2546493823,
1155    -0.3753271935,
1156    0.4745384887,
1157    0.481254652,
1158    -0.8934416489,
1159    -0.6737085076,
1160    0.7469917228,
1161    0.3826230411,
1162    0.6751013678,
1163    -0.7248119515,
1164    -0.3224276742,
1165    -0.02076190936,
1166    -0.6404268166,
1167    -0.5292028444,
1168    0.7151414636,
1169    -0.6144655059,
1170    -0.369912124,
1171    0.6942067212,
1172    -0.4481558248,
1173    -0.6366894559,
1174    0.5956568471,
1175    0.564274539,
1176    0.7145584688,
1177    0.6871918316,
1178    0.5657918509,
1179    -0.6275978114,
1180    0.4146983062,
1181    0.2638993789,
1182    -0.792633138,
1183    0.5706133514,
1184    0.8606546462,
1185    0.6490900316,
1186    -0.8242699196,
1187    0.6765819124,
1188    0.1959534069,
1189    -0.8426769757,
1190    -0.5917672797,
1191    0.7517364266,
1192    0.03252559226,
1193    0.0883617105,
1194    0.4475064813,
1195    -0.1418643552,
1196    0.7343428473,
1197    0.3870192548,
1198    -0.7716703522,
1199    0.4839898327,
1200    0.7437439055,
1201    -0.5989573348,
1202    -0.8357068955,
1203    0.6086049038,
1204    0.9194627258,
1205    0.4718297238,
1206    -0.2650335884,
1207    -0.6470352599,
1208    -0.5555181303,
1209    0.1222351235,
1210    0.7802044684,
1211    -0.8636947022,
1212    -0.2341352163,
1213    0.683030874,
1214    -0.5005858287,
1215    0.2334616211,
1216    0.2576877608,
1217    0.6666816727,
1218    -0.7663996863,
1219    0.794201982,
1220    0.6189308788,
1221    0.6071033261,
1222    -0.4206058253,
1223    -0.3957336915,
1224    -0.8170257484,
1225    -0.1043240417,
1226    0.0002167596213,
1227    0.1816339018,
1228    -0.6838094939,
1229    -0.2495341969,
1230    -0.7116756954,
1231    -0.03361673621,
1232    -0.3350836431,
1233    0.2137186039,
1234    0.2557996786,
1235    0.7490117093,
1236    0.4942936549,
1237    -0.352686853,
1238    -0.3952445435,
1239    -0.0459964767,
1240    -0.7115787471,
1241    0.08022899756,
1242    0.5362268157,
1243    -0.8258613686,
1244    0.1114171723,
1245    0.3882823051,
1246    -0.7915404457,
1247    0.3250957662,
1248    0.6401346464,
1249    -0.2662724517,
1250    -0.6727907114,
1251    -0.994730818,
1252    -0.3596358977,
1253    0.2344610069,
1254    -0.6645215546,
1255    -0.7107590611,
1256    -0.4646617327,
1257    0.6717191355,
1258    0.5101893498,
1259    0.1185768238,
1260    0.236005093,
1261    -0.7811024061,
1262    0.5089325193,
1263    0.6073187658,
1264    -0.7930732557,
1265    -0.6822767155,
1266    0.3201532885,
1267    0.7545302807,
1268    0.1072664448,
1269    0.6784033173,
1270    -0.6595924967,
1271    0.7276509498,
1272    0.5586689436,
1273    -0.6498636788,
1274    0.6789333174,
1275    0.7105966551,
1276    -0.2872214155,
1277    0.496746217,
1278    -0.3880337977,
1279    0.7324070604,
1280    -0.9326634749,
1281    -0.5867839255,
1282    0.8003043651,
1283    -0.1631882481,
1284    -0.6796374681,
1285    -0.8066678503,
1286    0.4238177418,
1287    0.7715863549,
1288    0.5455367347,
1289    -0.03205115397,
1290    -0.6005545066,
1291    -0.5423640002,
1292    0.3569205906,
1293    -0.582071752,
1294    0.6407354361,
1295    0.7777142984,
1296    -0.09956428618,
1297    0.1100002681,
1298    0.8136349123,
1299    0.2923431904,
1300    0.9735794425,
1301    0.8324974864,
1302    -0.6179617717,
1303    -0.9248386523,
1304    -0.6448780771,
1305    -0.5274402761,
1306    -0.7862170565,
1307    0.2682099744,
1308    -0.5848777694,
1309    -0.6364561467,
1310    -0.7167402514,
1311    -0.8677012494,
1312    0.4205286707,
1313    -0.7007832749,
1314    0.243272451,
1315    -0.1899846085,
1316    -0.6146124977,
1317    -0.8093357692,
1318    -0.03545096987,
1319    -0.7191590868,
1320    0.7478645848,
1321    0.3623517328,
1322    0.8436992512,
1323    -0.2445711729,
1324    0.6897356637,
1325    -0.1708070787,
1326    0.4639272368,
1327    -0.7917186656,
1328    0.02980025428,
1329    0.6334156172,
1330    -0.9815544807,
1331    -0.2307217304,
1332    0.1080823318,
1333    0.5167601798,
1334    -0.845120016,
1335    0.441572562,
1336    0.5876789172,
1337    -0.6365908737,
1338    0.68350166,
1339    0.5849723959,
1340    0.1164114357,
1341    -0.7379813884,
1342    -0.9613237178,
1343    -0.9071943084,
1344    -0.7682111105,
1345    0.639074459,
1346    -0.619358298,
1347    0.2807257131,
1348    -0.01800868791,
1349    0.3776607289,
1350    0.7207567823,
1351    0.5536661486,
1352    -0.9974053117,
1353    -0.02047200006,
1354    -0.6739453804,
1355    -0.5607471297,
1356    0.8815553192,
1357    0.8275977415,
1358    0.3928902456,
1359    0.550991396,
1360    0.4247623676,
1361    -0.3436948871,
1362    -0.3653537677,
1363    0.3181702902,
1364    -0.6067173171,
1365    -0.8984128477,
1366    0.4220839766,
1367    0.7238407199,
1368    -0.7766913695,
1369    0.6460037842,
1370    0.2544775664,
1371    0.6488840578,
1372    0.805016833,
1373    -0.9183807036,
1374    0.4144046357,
1375    0.270587208,
1376    -0.8813684494,
1377    0.6985971877,
1378    -0.7795603017,
1379    -0.8624480731,
1380    0.5532697017,
1381    0.711179521,
1382    -0.7798160574,
1383    0.5225859041,
1384    0.1261859368,
1385    0.3398033582,
1386    -0.7472173667,
1387    -0.4032647119,
1388    -0.4246578154,
1389    0.8481212377,
1390    -0.2144838537,
1391    0.3431714491,
1392    0.5310188231,
1393    0.6682978632,
1394    0.3110433206,
1395    0.9263293599,
1396    -0.6155600569,
1397    0.07169784399,
1398    0.8985888773,
1399];
1400
1401#[allow(clippy::unreadable_literal)]
1402#[allow(clippy::excessive_precision)]
1403const CELL_3D_Z: [f32; 256] = [
1404    -0.6341391283,
1405    -0.7207118346,
1406    0.9597866014,
1407    0.3237504235,
1408    -0.7588642466,
1409    -0.01782410481,
1410    0.2515593809,
1411    0.2207257205,
1412    -0.8579541106,
1413    0.3406410681,
1414    0.7669470462,
1415    -0.9431957648,
1416    0.7676171537,
1417    -0.6000491115,
1418    -0.7062096948,
1419    0.2550207115,
1420    0.7347325213,
1421    0.5163625202,
1422    -0.5394270162,
1423    0.3336656285,
1424    -0.0638635111,
1425    -0.6503195787,
1426    0.3143356798,
1427    -0.5039217245,
1428    0.6605180464,
1429    -0.6855479011,
1430    -0.6693185756,
1431    0.1832083647,
1432    -0.5666258437,
1433    0.3576482138,
1434    -0.6571949095,
1435    -0.7522101635,
1436    -0.7238865886,
1437    0.4538887323,
1438    0.2467106257,
1439    0.7274778869,
1440    0.3151170655,
1441    -0.8802293764,
1442    -0.2167232729,
1443    0.5854637865,
1444    0.7019741052,
1445    0.5091756071,
1446    0.1973189533,
1447    0.46743546,
1448    0.05197599597,
1449    0.088354718,
1450    0.5380464843,
1451    -0.6458224544,
1452    -0.5045952393,
1453    0.419347884,
1454    0.8000823542,
1455    -0.07445020656,
1456    -0.6272881641,
1457    -0.428020311,
1458    -0.2747382083,
1459    -0.08987283726,
1460    0.8699098354,
1461    0.4524761885,
1462    -0.3274603257,
1463    0.4882262167,
1464    -0.7189983256,
1465    0.1746079907,
1466    0.0751772698,
1467    -0.6152927202,
1468    0.4998474673,
1469    -0.6979677227,
1470    0.7568667263,
1471    -0.6152612058,
1472    0.06447140991,
1473    -0.8155744872,
1474    -0.5229602449,
1475    0.6567836838,
1476    -0.4799905631,
1477    0.03153534591,
1478    0.4724992466,
1479    -0.3026458097,
1480    -0.2191225827,
1481    -0.620692287,
1482    0.3107552588,
1483    0.8235670294,
1484    0.6474915988,
1485    -0.5047637941,
1486    0.4911488878,
1487    -0.2307138167,
1488    -0.5216800015,
1489    0.6789305939,
1490    0.9403734863,
1491    0.702390397,
1492    0.7347584625,
1493    0.6779567958,
1494    0.9765635805,
1495    -0.9436177661,
1496    -0.358465925,
1497    -0.3058706624,
1498    0.5533414464,
1499    -0.8838306897,
1500    0.04496841812,
1501    0.01687374963,
1502    -0.9927133148,
1503    -0.211752318,
1504    0.3732015249,
1505    0.9632990593,
1506    -0.07682417004,
1507    -0.07232213047,
1508    0.4733721775,
1509    0.2579229713,
1510    0.7995216286,
1511    0.3928189967,
1512    0.04107517667,
1513    0.1534542912,
1514    0.6468965045,
1515    0.4030684878,
1516    -0.5617300988,
1517    -0.885463029,
1518    0.693729985,
1519    -0.5736527866,
1520    -0.9911905409,
1521    -0.66451538,
1522    0.2028855685,
1523    0.8019541421,
1524    -0.3903877149,
1525    -0.4888495114,
1526    -0.2753714057,
1527    -0.8915202143,
1528    0.5273119089,
1529    0.9363714773,
1530    -0.5212228249,
1531    -0.31642672,
1532    0.2409440761,
1533    -0.703776404,
1534    -0.6996810411,
1535    -0.7058714505,
1536    -0.3650566783,
1537    0.1064744278,
1538    0.7985729102,
1539    0.424680257,
1540    -0.6384535592,
1541    0.1540161646,
1542    -0.07702731943,
1543    -0.5627789132,
1544    -0.7667919169,
1545    -0.509815999,
1546    0.4590525092,
1547    0.1552595611,
1548    0.345402042,
1549    0.7537656024,
1550    0.7906259247,
1551    -0.6218493452,
1552    0.02979350071,
1553    -0.1337893489,
1554    -0.1483818606,
1555    0.549965562,
1556    0.01882482408,
1557    -0.7833783002,
1558    0.4702855809,
1559    0.2435827372,
1560    0.2978428332,
1561    0.2256499906,
1562    0.4885036897,
1563    0.5312962584,
1564    0.05401156992,
1565    0.1749922158,
1566    -0.7352273018,
1567    0.6058980284,
1568    0.4416079111,
1569    0.4417378638,
1570    0.5455879807,
1571    -0.6681295324,
1572    0.1973431441,
1573    0.4053292055,
1574    0.2220375492,
1575    0.2957118467,
1576    0.6910913512,
1577    0.5940890106,
1578    -0.2014135283,
1579    -0.9172588213,
1580    -0.4254361401,
1581    -0.6146586825,
1582    -0.7996193253,
1583    -0.3716777111,
1584    -0.9448876842,
1585    -0.2620349924,
1586    0.9615995749,
1587    -0.4679683524,
1588    0.3905937144,
1589    0.613593722,
1590    0.1422937358,
1591    0.1908754211,
1592    0.8189704912,
1593    -0.7300408736,
1594    -0.4108776451,
1595    -0.5319834504,
1596    -0.8970265651,
1597    -0.5386359045,
1598    0.4082255906,
1599    0.7245356676,
1600    0.5239080873,
1601    -0.8937552226,
1602    -0.553637673,
1603    0.2354455182,
1604    -0.0860293075,
1605    -0.1399373318,
1606    -0.4666323327,
1607    0.5560157407,
1608    0.1772619533,
1609    -0.8893937725,
1610    -0.5632714576,
1611    -0.5666264959,
1612    -0.3670263736,
1613    -0.06717242579,
1614    0.6205295181,
1615    -0.4110536264,
1616    0.7090054553,
1617    0.183899597,
1618    -0.5605470555,
1619    0.3879565548,
1620    0.7420893903,
1621    -0.2347595118,
1622    -0.8577217497,
1623    0.6325590203,
1624    -0.8736152276,
1625    0.7048011129,
1626    -0.06317948268,
1627    0.8753285574,
1628    -0.05843650473,
1629    -0.3674922622,
1630    -0.5256624401,
1631    0.7861039337,
1632    0.3287714416,
1633    0.5910593099,
1634    -0.3896960134,
1635    0.6864605361,
1636    0.7164918431,
1637    -0.290014277,
1638    -0.6796169617,
1639    0.1632515592,
1640    0.04485347486,
1641    0.8320545697,
1642    0.01339408056,
1643    -0.2874989857,
1644    0.615630723,
1645    0.3430367014,
1646    0.8193658136,
1647    -0.5829600957,
1648    0.07911697781,
1649    0.7854296063,
1650    -0.4107442306,
1651    0.4766964066,
1652    -0.9045999527,
1653    -0.1673856787,
1654    0.2828077348,
1655    -0.5902737632,
1656    -0.321506229,
1657    -0.5224513133,
1658    -0.4090169985,
1659    -0.3599685311,
1660];
1661
1662const FN_CELLULAR_INDEX_MAX: usize = 3;
1663const X_PRIME: i32 = 1619;
1664const Y_PRIME: i32 = 31337;
1665const Z_PRIME: i32 = 6971;
1666#[allow(dead_code)]
1667const W_PRIME: i32 = 1013;
1668const F3: f32 = 1.0 / 3.0;
1669const G3: f32 = 1.0 / 6.0;
1670#[allow(clippy::excessive_precision)]
1671#[allow(clippy::unreadable_literal)]
1672const SQRT3: f32 = 1.7320508075688772935274463415059;
1673const F2: f32 = 0.5 * (SQRT3 - 1.0);
1674const G2: f32 = (3.0 - SQRT3) / 6.0;
1675#[allow(dead_code)]
1676#[allow(clippy::excessive_precision)]
1677#[allow(clippy::unreadable_literal)]
1678const F4: f32 = (2.23606797749979 - 1.0) / 4.0;
1679#[allow(dead_code)]
1680#[allow(clippy::excessive_precision)]
1681#[allow(clippy::unreadable_literal)]
1682const G4: f32 = (5.0 - 2.23606797749979) / 20.0;
1683const CUBIC_3D_BOUNDING: f32 = 1.0 / (1.5 * 1.5 * 1.5);
1684const CUBIC_2D_BOUNDING: f32 = 1.0 / 1.5 * 1.5;
1685
1686// Utility functions
1687fn fast_floor(f: f32) -> i32 {
1688    if f >= 0.0 {
1689        f as i32
1690    } else {
1691        f as i32 - 1
1692    }
1693}
1694
1695fn fast_round(f: f32) -> i32 {
1696    if f >= 0.0 {
1697        (f + 0.5) as i32
1698    } else {
1699        (f - 0.5) as i32
1700    }
1701}
1702
1703#[allow(dead_code)]
1704fn fast_abs(i: i32) -> i32 {
1705    i32::abs(i)
1706}
1707
1708fn fast_abs_f(i: f32) -> f32 {
1709    f32::abs(i)
1710}
1711
1712fn lerp(a: f32, b: f32, t: f32) -> f32 {
1713    a + t * (b - a)
1714}
1715
1716fn interp_hermite_func(t: f32) -> f32 {
1717    t * t * (3. - 2. * t)
1718}
1719
1720fn interp_quintic_func(t: f32) -> f32 {
1721    t * t * t * (t * (t * 6. - 15.) + 10.)
1722}
1723
1724#[allow(clippy::many_single_char_names)]
1725fn cubic_lerp(a: f32, b: f32, c: f32, d: f32, t: f32) -> f32 {
1726    let p = (d - c) - (a - b);
1727    t * t * t * p + t * t * ((a - b) - p) + t * (c - a) + b
1728}
1729
1730#[allow(clippy::unreadable_literal)]
1731#[allow(clippy::new_without_default)]
1732impl FastNoise {
1733    /// Creates a new noise instance, using simplex noise defaults.
1734    pub fn new() -> FastNoise {
1735        let mut noise = FastNoise {
1736            rng: RandomNumberGenerator::seeded(1337),
1737            seed: 1337,
1738            frequency: 1.0,
1739            interp: Interp::Quintic,
1740            noise_type: NoiseType::Simplex,
1741            octaves: 3,
1742            lacunarity: 2.0,
1743            gain: 0.5,
1744            fractal_type: FractalType::FBM,
1745            cellular_distance_function: CellularDistanceFunction::Euclidean,
1746            cellular_return_type: CellularReturnType::CellValue,
1747            cellular_distance_index: (0, 1),
1748            cellular_jitter: 0.45,
1749            gradient_perturb_amp: 1.0,
1750            perm: vec![0; 512],
1751            perm12: vec![0; 512],
1752            fractal_bounding: 0.0,
1753        };
1754        noise.set_seed(1337);
1755        noise.calculate_fractal_bounding();
1756        noise
1757    }
1758
1759    /// Creates a new noise instance, using simplex noise defaults and specifying a random seed.
1760    pub fn seeded(seed: u64) -> FastNoise {
1761        let mut noise = FastNoise {
1762            rng: RandomNumberGenerator::seeded(seed),
1763            seed,
1764            frequency: 0.0,
1765            interp: Interp::Quintic,
1766            noise_type: NoiseType::Simplex,
1767            octaves: 3,
1768            lacunarity: 2.0,
1769            gain: 0.5,
1770            fractal_type: FractalType::FBM,
1771            cellular_distance_function: CellularDistanceFunction::Euclidean,
1772            cellular_return_type: CellularReturnType::CellValue,
1773            cellular_distance_index: (0, 1),
1774            cellular_jitter: 0.45,
1775            gradient_perturb_amp: 1.0,
1776            perm: vec![0; 512],
1777            perm12: vec![0; 512],
1778            fractal_bounding: 0.0,
1779        };
1780        noise.set_seed(seed);
1781        noise.calculate_fractal_bounding();
1782        noise
1783    }
1784
1785    /// Re-seeds the noise system with a new seed.
1786    pub fn set_seed(&mut self, seed: u64) {
1787        self.seed = seed;
1788        self.rng = RandomNumberGenerator::seeded(seed);
1789
1790        for i in 0..=255 {
1791            self.perm[i as usize] = i;
1792        }
1793
1794        for j in 0..256 {
1795            let rng = self.rng.next_u64() % (256 - j);
1796            let k = rng + j;
1797            let l = self.perm[j as usize];
1798            self.perm[j as usize] = self.perm[k as usize];
1799            self.perm[j as usize + 256] = self.perm[k as usize];
1800            self.perm[k as usize] = l;
1801            self.perm12[j as usize] = self.perm[j as usize] % 12;
1802            self.perm12[j as usize + 256] = self.perm[j as usize] % 12;
1803        }
1804    }
1805
1806    pub fn get_seed(&self) -> u64 {
1807        self.seed
1808    }
1809    pub fn set_frequency(&mut self, frequency: f32) {
1810        self.frequency = frequency
1811    }
1812    pub fn get_frequency(&self) -> f32 {
1813        self.frequency
1814    }
1815    pub fn set_interp(&mut self, interp: Interp) {
1816        self.interp = interp
1817    }
1818    pub fn get_interp(&self) -> Interp {
1819        self.interp
1820    }
1821    pub fn set_noise_type(&mut self, nt: NoiseType) {
1822        self.noise_type = nt
1823    }
1824    pub fn get_noise_type(&self) -> NoiseType {
1825        self.noise_type
1826    }
1827    pub fn set_fractal_octaves(&mut self, octaves: i32) {
1828        self.octaves = octaves;
1829        self.calculate_fractal_bounding();
1830    }
1831    pub fn get_fractal_octaves(&self) -> i32 {
1832        self.octaves
1833    }
1834    pub fn set_fractal_lacunarity(&mut self, lacunarity: f32) {
1835        self.lacunarity = lacunarity
1836    }
1837    pub fn get_fractal_lacunarity(&self) -> f32 {
1838        self.lacunarity
1839    }
1840    pub fn set_fractal_gain(&mut self, gain: f32) {
1841        self.gain = gain;
1842        self.calculate_fractal_bounding();
1843    }
1844    pub fn get_fractal_gain(&self) -> f32 {
1845        self.gain
1846    }
1847    pub fn set_fractal_type(&mut self, fractal_type: FractalType) {
1848        self.fractal_type = fractal_type
1849    }
1850    pub fn get_fractal_type(&self) -> FractalType {
1851        self.fractal_type
1852    }
1853    pub fn set_cellular_distance_function(
1854        &mut self,
1855        cellular_distance_function: CellularDistanceFunction,
1856    ) {
1857        self.cellular_distance_function = cellular_distance_function
1858    }
1859    pub fn get_cellular_distance_function(&self) -> CellularDistanceFunction {
1860        self.cellular_distance_function
1861    }
1862    pub fn set_cellular_return_type(&mut self, cellular_return_type: CellularReturnType) {
1863        self.cellular_return_type = cellular_return_type
1864    }
1865    pub fn get_cellular_return_type(&self) -> CellularReturnType {
1866        self.cellular_return_type
1867    }
1868    pub fn get_cellular_distance_indices(&self) -> (i32, i32) {
1869        self.cellular_distance_index
1870    }
1871    pub fn set_cellular_jitter(&mut self, jitter: f32) {
1872        self.cellular_jitter = jitter
1873    }
1874    pub fn get_cellular_jitter(&self) -> f32 {
1875        self.cellular_jitter
1876    }
1877    pub fn set_gradient_perterb_amp(&mut self, gradient_perturb_amp: f32) {
1878        self.gradient_perturb_amp = gradient_perturb_amp
1879    }
1880    pub fn get_gradient_perterb_amp(&self) -> f32 {
1881        self.gradient_perturb_amp
1882    }
1883
1884    fn calculate_fractal_bounding(&mut self) {
1885        let mut amp: f32 = self.gain;
1886        let mut amp_fractal: f32 = 1.0;
1887        for _ in 0..self.octaves {
1888            amp_fractal += amp;
1889            amp *= self.gain;
1890        }
1891        self.fractal_bounding = 1.0 / amp_fractal;
1892    }
1893
1894    pub fn set_cellular_distance_indices(&mut self, i1: i32, i2: i32) {
1895        self.cellular_distance_index.0 = i32::min(i1, i2);
1896        self.cellular_distance_index.1 = i32::max(i1, i2);
1897
1898        self.cellular_distance_index.0 = i32::min(
1899            i32::max(self.cellular_distance_index.0, 0),
1900            FN_CELLULAR_INDEX_MAX as i32,
1901        );
1902        self.cellular_distance_index.1 = i32::min(
1903            i32::max(self.cellular_distance_index.1, 0),
1904            FN_CELLULAR_INDEX_MAX as i32,
1905        );
1906    }
1907
1908    pub fn index2d_12(&self, offset: u8, x: i32, y: i32) -> u8 {
1909        self.perm12[(x & 0xff) as usize + self.perm[(y & 0xff) as usize + offset as usize] as usize]
1910    }
1911
1912    pub fn index3d_12(&self, offset: u8, x: i32, y: i32, z: i32) -> u8 {
1913        self.perm12[(x as usize & 0xff)
1914            + self.perm
1915                [(y as usize & 0xff) + self.perm[(z as usize & 0xff) + offset as usize] as usize]
1916                as usize]
1917    }
1918
1919    pub fn index4d_32(&self, offset: u8, x: i32, y: i32, z: i32, w: i32) -> u8 {
1920        self.perm[(x as usize & 0xff)
1921            + self.perm[(y as usize & 0xff)
1922                + self.perm[(z as usize & 0xff)
1923                    + self.perm[(w as usize & 0xff) + offset as usize] as usize]
1924                    as usize] as usize]
1925            & 31
1926    }
1927
1928    pub fn index2d_256(&self, offset: u8, x: i32, y: i32) -> u8 {
1929        self.perm[(x as usize & 0xff) + self.perm[(y as usize & 0xff) + offset as usize] as usize]
1930    }
1931
1932    pub fn index3d_256(&self, offset: u8, x: i32, y: i32, z: i32) -> u8 {
1933        self.perm[(x as usize & 0xff)
1934            + self.perm
1935                [(y as usize & 0xff) + self.perm[(z as usize & 0xff) + offset as usize] as usize]
1936                as usize]
1937    }
1938
1939    pub fn index4d_256(&self, offset: u8, x: i32, y: i32, z: i32, w: i32) -> u8 {
1940        self.perm[(x as usize & 0xff)
1941            + self.perm[(y as usize & 0xff)
1942                + self.perm[(z as usize & 0xff)
1943                    + self.perm[(w as usize & 0xff) + offset as usize] as usize]
1944                    as usize] as usize]
1945    }
1946
1947    fn val_coord_2d(&self, seed: i32, x: i32, y: i32) -> f32 {
1948        use std::num::Wrapping;
1949
1950        let mut n = Wrapping(seed);
1951        n ^= Wrapping(X_PRIME) * Wrapping(x);
1952        n ^= Wrapping(Y_PRIME) * Wrapping(y);
1953        (n * n * n * Wrapping(60493i32)).0 as f32 / 2147483648.0
1954    }
1955
1956    fn val_coord_3d(&self, seed: i32, x: i32, y: i32, z: i32) -> f32 {
1957        use std::num::Wrapping;
1958
1959        let mut n = Wrapping(seed);
1960        n ^= Wrapping(X_PRIME) * Wrapping(x);
1961        n ^= Wrapping(Y_PRIME) * Wrapping(y);
1962        n ^= Wrapping(Z_PRIME) * Wrapping(z);
1963
1964        (n * n * n * Wrapping(60493i32)).0 as f32 / 2147483648.0
1965    }
1966
1967    #[allow(dead_code)]
1968    #[allow(clippy::many_single_char_names)]
1969    fn val_coord_4d(&self, seed: i32, x: i32, y: i32, z: i32, w: i32) -> f32 {
1970        use std::num::Wrapping;
1971
1972        let mut n = Wrapping(seed);
1973        n ^= Wrapping(X_PRIME) * Wrapping(x);
1974        n ^= Wrapping(Y_PRIME) * Wrapping(y);
1975        n ^= Wrapping(Z_PRIME) * Wrapping(z);
1976        n ^= Wrapping(W_PRIME) * Wrapping(w);
1977
1978        (n * n * n * Wrapping(60493i32)).0 as f32 / 2147483648.0
1979    }
1980
1981    fn val_coord_2d_fast(&self, offset: u8, x: i32, y: i32) -> f32 {
1982        VAL_LUT[self.index2d_256(offset, x, y) as usize]
1983    }
1984    fn val_coord_3d_fast(&self, offset: u8, x: i32, y: i32, z: i32) -> f32 {
1985        VAL_LUT[self.index3d_256(offset, x, y, z) as usize]
1986    }
1987
1988    fn grad_coord_2d(&self, offset: u8, x: i32, y: i32, xd: f32, yd: f32) -> f32 {
1989        let lut_pos = self.index2d_12(offset, x, y) as usize;
1990        xd * GRAD_X[lut_pos] + yd * GRAD_Y[lut_pos]
1991    }
1992
1993    #[allow(clippy::too_many_arguments)]
1994    fn grad_coord_3d(&self, offset: u8, x: i32, y: i32, z: i32, xd: f32, yd: f32, zd: f32) -> f32 {
1995        let lut_pos = self.index3d_12(offset, x, y, z) as usize;
1996        xd * GRAD_X[lut_pos] + yd * GRAD_Y[lut_pos] + zd * GRAD_Z[lut_pos]
1997    }
1998
1999    #[allow(dead_code)]
2000    #[allow(clippy::too_many_arguments)]
2001    fn grad_coord_4d(
2002        &self,
2003        offset: u8,
2004        x: i32,
2005        y: i32,
2006        z: i32,
2007        w: i32,
2008        xd: f32,
2009        yd: f32,
2010        zd: f32,
2011        wd: f32,
2012    ) -> f32 {
2013        let lut_pos = self.index4d_32(offset, x, y, z, w) as usize;
2014        xd * GRAD_4D[lut_pos]
2015            + yd * GRAD_4D[lut_pos + 1]
2016            + zd * GRAD_4D[lut_pos + 2]
2017            + wd * GRAD_4D[lut_pos + 3]
2018    }
2019
2020    pub fn get_noise3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 {
2021        x *= self.frequency;
2022        y *= self.frequency;
2023        z *= self.frequency;
2024
2025        match self.noise_type {
2026            NoiseType::Value => self.single_value3d(0, x, y, z),
2027            NoiseType::ValueFractal => match self.fractal_type {
2028                FractalType::FBM => self.single_value_fractal_fbm3d(x, y, z),
2029                FractalType::Billow => self.single_value_fractal_billow3d(x, y, z),
2030                FractalType::RigidMulti => self.single_value_fractal_rigid_multi3d(x, y, z),
2031            },
2032            NoiseType::Perlin => self.single_perlin3d(0, x, y, z),
2033            NoiseType::PerlinFractal => match self.fractal_type {
2034                FractalType::FBM => self.single_perlin_fractal_fbm3d(x, y, z),
2035                FractalType::Billow => self.single_perlin_fractal_billow3d(x, y, z),
2036                FractalType::RigidMulti => self.single_perlin_fractal_rigid_multi3d(x, y, z),
2037            },
2038            NoiseType::Simplex => self.single_simplex3d(0, x, y, z),
2039            NoiseType::SimplexFractal => match self.fractal_type {
2040                FractalType::FBM => self.single_simplex_fractal_fbm3d(x, y, z),
2041                FractalType::Billow => self.single_simplex_fractal_billow3d(x, y, z),
2042                FractalType::RigidMulti => self.single_simplex_fractal_rigid_multi3d(x, y, z),
2043            },
2044            NoiseType::Cellular => match self.cellular_return_type {
2045                CellularReturnType::CellValue => self.single_cellular3d(x, y, z),
2046                CellularReturnType::Distance => self.single_cellular3d(x, y, z),
2047                _ => self.single_cellular_2edge3d(x, y, z),
2048            },
2049            NoiseType::WhiteNoise => self.get_white_noise3d(x, y, z),
2050            NoiseType::Cubic => self.single_cubic3d(0, x, y, z),
2051            NoiseType::CubicFractal => match self.fractal_type {
2052                FractalType::FBM => self.single_cubic_fractal_fbm3d(x, y, z),
2053                FractalType::Billow => self.single_cubic_fractal_billow3d(x, y, z),
2054                FractalType::RigidMulti => self.single_cubic_fractal_rigid_multi3d(x, y, z),
2055            },
2056        }
2057    }
2058
2059    pub fn get_noise(&self, mut x: f32, mut y: f32) -> f32 {
2060        x *= self.frequency;
2061        y *= self.frequency;
2062
2063        match self.noise_type {
2064            NoiseType::Value => self.single_value(0, x, y),
2065            NoiseType::ValueFractal => match self.fractal_type {
2066                FractalType::FBM => self.single_value_fractal_fbm(x, y),
2067                FractalType::Billow => self.single_value_fractal_billow(x, y),
2068                FractalType::RigidMulti => self.single_value_fractal_rigid_multi(x, y),
2069            },
2070            NoiseType::Perlin => self.single_perlin(0, x, y),
2071            NoiseType::PerlinFractal => match self.fractal_type {
2072                FractalType::FBM => self.single_perlin_fractal_fbm(x, y),
2073                FractalType::Billow => self.single_perlin_fractal_billow(x, y),
2074                FractalType::RigidMulti => self.single_perlin_fractal_rigid_multi(x, y),
2075            },
2076            NoiseType::Simplex => self.single_simplex(0, x, y),
2077            NoiseType::SimplexFractal => match self.fractal_type {
2078                FractalType::FBM => self.single_simplex_fractal_fbm(x, y),
2079                FractalType::Billow => self.single_simplex_fractal_billow(x, y),
2080                FractalType::RigidMulti => self.single_simplex_fractal_rigid_multi(x, y),
2081            },
2082            NoiseType::Cellular => match self.cellular_return_type {
2083                CellularReturnType::CellValue => self.single_cellular(x, y),
2084                CellularReturnType::Distance => self.single_cellular(x, y),
2085                _ => self.single_cellular_2edge(x, y),
2086            },
2087            NoiseType::WhiteNoise => self.get_white_noise(x, y),
2088            NoiseType::Cubic => self.single_cubic(0, x, y),
2089            NoiseType::CubicFractal => match self.fractal_type {
2090                FractalType::FBM => self.single_cubic_fractal_fbm(x, y),
2091                FractalType::Billow => self.single_cubic_fractal_billow(x, y),
2092                FractalType::RigidMulti => self.single_cubic_fractal_rigid_multi(x, y),
2093            },
2094        }
2095    }
2096
2097    #[allow(dead_code)]
2098    fn get_white_noise4d(&self, x: f32, y: f32, z: f32, w: f32) -> f32 {
2099        let xc: i32 = x.to_bits() as i32;
2100        let yc: i32 = y.to_bits() as i32;
2101        let zc: i32 = z.to_bits() as i32;
2102        let wc: i32 = w.to_bits() as i32;
2103
2104        self.val_coord_4d(
2105            self.seed as i32,
2106            xc ^ (xc as i32 >> 16),
2107            yc ^ (yc >> 16),
2108            zc ^ (zc >> 16),
2109            wc ^ (wc >> 16),
2110        )
2111    }
2112
2113    fn get_white_noise3d(&self, x: f32, y: f32, z: f32) -> f32 {
2114        let xc: i32 = x.to_bits() as i32;
2115        let yc: i32 = y.to_bits() as i32;
2116        let zc: i32 = z.to_bits() as i32;
2117
2118        self.val_coord_3d(
2119            self.seed as i32,
2120            xc ^ (xc >> 16),
2121            yc ^ (yc >> 16),
2122            zc ^ (zc >> 16),
2123        )
2124    }
2125
2126    fn get_white_noise(&self, x: f32, y: f32) -> f32 {
2127        let xc: i32 = x.to_bits() as i32;
2128        let yc: i32 = y.to_bits() as i32;
2129
2130        self.val_coord_2d(self.seed as i32, xc ^ (xc >> 16), yc ^ (yc >> 16))
2131    }
2132
2133    #[allow(dead_code)]
2134    fn get_white_noise_int4d(&self, x: i32, y: i32, z: i32, w: i32) -> f32 {
2135        self.val_coord_4d(self.seed as i32, x, y, z, w)
2136    }
2137
2138    #[allow(dead_code)]
2139    fn get_white_noise_int3d(&self, x: i32, y: i32, z: i32) -> f32 {
2140        self.val_coord_3d(self.seed as i32, x, y, z)
2141    }
2142
2143    #[allow(dead_code)]
2144    fn get_white_noise_int(&self, x: i32, y: i32) -> f32 {
2145        self.val_coord_2d(self.seed as i32, x, y)
2146    }
2147
2148    #[allow(dead_code)]
2149    // Value noise
2150    fn get_value_fractal3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 {
2151        x *= self.frequency;
2152        y *= self.frequency;
2153        z *= self.frequency;
2154
2155        match self.fractal_type {
2156            FractalType::FBM => self.single_value_fractal_fbm3d(x, y, z),
2157            FractalType::Billow => self.single_value_fractal_billow3d(x, y, z),
2158            FractalType::RigidMulti => self.single_value_fractal_rigid_multi3d(x, y, z),
2159        }
2160    }
2161
2162    #[allow(dead_code)]
2163    fn get_value_fractal(&self, mut x: f32, mut y: f32) -> f32 {
2164        x *= self.frequency;
2165        y *= self.frequency;
2166
2167        match self.fractal_type {
2168            FractalType::FBM => self.single_value_fractal_fbm(x, y),
2169            FractalType::Billow => self.single_value_fractal_billow(x, y),
2170            FractalType::RigidMulti => self.single_value_fractal_rigid_multi(x, y),
2171        }
2172    }
2173
2174    fn single_value_fractal_fbm3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 {
2175        let mut sum: f32 = self.single_value3d(self.perm[0], x, y, z);
2176        let mut amp = 1.0;
2177        let mut i = 1;
2178
2179        while i < self.octaves {
2180            x *= self.lacunarity;
2181            y *= self.lacunarity;
2182            z *= self.lacunarity;
2183
2184            amp *= self.gain;
2185            sum += self.single_value3d(self.perm[i as usize], x, y, z) * amp;
2186
2187            i += 1;
2188        }
2189
2190        sum * self.fractal_bounding
2191    }
2192
2193    fn single_value_fractal_billow3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 {
2194        let mut sum: f32 = fast_abs_f(self.single_value3d(self.perm[0], x, y, z)) * 2.0 - 1.0;
2195        let mut amp: f32 = 1.0;
2196        let mut i: i32 = 1;
2197
2198        while i < self.octaves {
2199            x *= self.lacunarity;
2200            y *= self.lacunarity;
2201            z *= self.lacunarity;
2202
2203            amp *= self.gain;
2204            sum +=
2205                (fast_abs_f(self.single_value3d(self.perm[i as usize], x, y, z)) * 2.0 - 1.0) * amp;
2206
2207            i += 1;
2208        }
2209
2210        sum * self.fractal_bounding
2211    }
2212
2213    fn single_value_fractal_rigid_multi3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 {
2214        let mut sum: f32 = 1.0 - fast_abs_f(self.single_value3d(self.perm[0], x, y, z));
2215        let mut amp: f32 = 1.0;
2216        let mut i = 1;
2217
2218        while i < self.octaves {
2219            x *= self.lacunarity;
2220            y *= self.lacunarity;
2221            z *= self.lacunarity;
2222
2223            amp *= self.gain;
2224            sum -= (1.0 - fast_abs_f(self.single_value3d(self.perm[i as usize], x, y, z))) * amp;
2225
2226            i += 1;
2227        }
2228        sum
2229    }
2230
2231    #[allow(dead_code)]
2232    fn get_value3d(&self, x: f32, y: f32, z: f32) -> f32 {
2233        self.single_value3d(
2234            0,
2235            x * self.frequency,
2236            y * self.frequency,
2237            z * self.frequency,
2238        )
2239    }
2240
2241    fn single_value3d(&self, offset: u8, x: f32, y: f32, z: f32) -> f32 {
2242        let x0 = fast_floor(x);
2243        let y0 = fast_floor(y);
2244        let z0 = fast_floor(z);
2245        let x1 = x0 + 1;
2246        let y1 = y0 + 1;
2247        let z1 = z0 + 1;
2248
2249        let xs: f32;
2250        let ys: f32;
2251        let zs: f32;
2252        match self.interp {
2253            Interp::Linear => {
2254                xs = x - x0 as f32;
2255                ys = y - y0 as f32;
2256                zs = z - z0 as f32;
2257            }
2258            Interp::Hermite => {
2259                xs = interp_hermite_func(x - x0 as f32);
2260                ys = interp_hermite_func(y - y0 as f32);
2261                zs = interp_hermite_func(z - z0 as f32);
2262            }
2263            Interp::Quintic => {
2264                xs = interp_quintic_func(x - x0 as f32);
2265                ys = interp_quintic_func(y - y0 as f32);
2266                zs = interp_quintic_func(z - z0 as f32);
2267            }
2268        }
2269
2270        let xf00: f32 = lerp(
2271            self.val_coord_3d_fast(offset, x0, y0, z0),
2272            self.val_coord_3d_fast(offset, x1, y0, z0),
2273            xs,
2274        );
2275        let xf10: f32 = lerp(
2276            self.val_coord_3d_fast(offset, x0, y1, z0),
2277            self.val_coord_3d_fast(offset, x1, y1, z0),
2278            xs,
2279        );
2280        let xf01: f32 = lerp(
2281            self.val_coord_3d_fast(offset, x0, y0, z1),
2282            self.val_coord_3d_fast(offset, x1, y0, z1),
2283            xs,
2284        );
2285        let xf11: f32 = lerp(
2286            self.val_coord_3d_fast(offset, x0, y1, z1),
2287            self.val_coord_3d_fast(offset, x1, y1, z1),
2288            xs,
2289        );
2290
2291        let yf0: f32 = lerp(xf00, xf10, ys);
2292        let yf1: f32 = lerp(xf01, xf11, ys);
2293
2294        lerp(yf0, yf1, zs)
2295    }
2296
2297    fn single_value_fractal_fbm(&self, mut x: f32, mut y: f32) -> f32 {
2298        let mut sum: f32 = self.single_value(self.perm[0], x, y);
2299        let mut amp: f32 = 1.0;
2300        let mut i = 1;
2301
2302        while i < self.octaves {
2303            x *= self.lacunarity;
2304            y *= self.lacunarity;
2305
2306            amp *= self.gain;
2307            sum += self.single_value(self.perm[i as usize], x, y) * amp;
2308            i += 1;
2309        }
2310
2311        sum * self.fractal_bounding
2312    }
2313
2314    fn single_value_fractal_billow(&self, mut x: f32, mut y: f32) -> f32 {
2315        let mut sum: f32 = fast_abs_f(self.single_value(self.perm[0], x, y)) * 2.0 - 1.0;
2316        let mut amp: f32 = 1.0;
2317        let mut i = 1;
2318
2319        while i < self.octaves {
2320            x *= self.lacunarity;
2321            y *= self.lacunarity;
2322            amp *= self.gain;
2323            sum += (fast_abs_f(self.single_value(self.perm[i as usize], x, y)) * 2.0 - 1.0) * amp;
2324            i += 1;
2325        }
2326
2327        sum * self.fractal_bounding
2328    }
2329
2330    fn single_value_fractal_rigid_multi(&self, mut x: f32, mut y: f32) -> f32 {
2331        let mut sum: f32 = 1.0 - fast_abs_f(self.single_value(self.perm[0], x, y));
2332        let mut amp: f32 = 1.0;
2333        let mut i = 1;
2334
2335        while i < self.octaves {
2336            x *= self.lacunarity;
2337            y *= self.lacunarity;
2338
2339            amp *= self.gain;
2340            sum -= (1.0 - fast_abs_f(self.single_value(self.perm[i as usize], x, y))) * amp;
2341            i += 1;
2342        }
2343
2344        sum
2345    }
2346
2347    #[allow(dead_code)]
2348    fn get_value(&self, x: f32, y: f32) -> f32 {
2349        self.single_value(0, x * self.frequency, y * self.frequency)
2350    }
2351
2352    fn single_value(&self, offset: u8, x: f32, y: f32) -> f32 {
2353        let x0 = fast_floor(x);
2354        let y0 = fast_floor(y);
2355        let x1 = x0 + 1;
2356        let y1 = y0 + 1;
2357
2358        let xs: f32;
2359        let ys: f32;
2360        match self.interp {
2361            Interp::Linear => {
2362                xs = x - x0 as f32;
2363                ys = y - y0 as f32;
2364            }
2365            Interp::Hermite => {
2366                xs = interp_hermite_func(x - x0 as f32);
2367                ys = interp_hermite_func(y - y0 as f32);
2368            }
2369            Interp::Quintic => {
2370                xs = interp_quintic_func(x - x0 as f32);
2371                ys = interp_quintic_func(y - y0 as f32);
2372            }
2373        }
2374
2375        let xf0 = lerp(
2376            self.val_coord_2d_fast(offset, x0, y0),
2377            self.val_coord_2d_fast(offset, x1, y0),
2378            xs,
2379        );
2380        let xf1 = lerp(
2381            self.val_coord_2d_fast(offset, x0, y1),
2382            self.val_coord_2d_fast(offset, x1, y1),
2383            xs,
2384        );
2385
2386        lerp(xf0, xf1, ys)
2387    }
2388
2389    // Perlin noise
2390
2391    #[allow(dead_code)]
2392    fn get_perlin_fractal3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 {
2393        x *= self.frequency;
2394        y *= self.frequency;
2395        z *= self.frequency;
2396
2397        match self.fractal_type {
2398            FractalType::FBM => self.single_perlin_fractal_fbm3d(x, y, z),
2399            FractalType::Billow => self.single_perlin_fractal_billow3d(x, y, z),
2400            FractalType::RigidMulti => self.single_perlin_fractal_rigid_multi3d(x, y, z),
2401        }
2402    }
2403
2404    fn single_perlin_fractal_fbm3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 {
2405        let mut sum: f32 = self.single_perlin3d(self.perm[0], x, y, z);
2406        let mut amp: f32 = 1.0;
2407        let mut i = 1;
2408
2409        while i < self.octaves {
2410            x *= self.lacunarity;
2411            y *= self.lacunarity;
2412            z *= self.lacunarity;
2413
2414            amp *= self.gain;
2415            sum += self.single_perlin3d(self.perm[i as usize], x, y, z) * amp;
2416            i += 1;
2417        }
2418
2419        sum * self.fractal_bounding
2420    }
2421
2422    fn single_perlin_fractal_billow3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 {
2423        let mut sum: f32 = fast_abs_f(self.single_perlin3d(self.perm[0], x, y, z)) * 2.0 - 1.0;
2424        let mut amp: f32 = 1.0;
2425        let mut i = 1;
2426
2427        while i < self.octaves {
2428            x *= self.lacunarity;
2429            y *= self.lacunarity;
2430            z *= self.lacunarity;
2431
2432            amp *= self.gain;
2433            sum += (fast_abs_f(self.single_perlin3d(self.perm[i as usize], x, y, z)) * 2.0 - 1.0)
2434                * amp;
2435            i += 1;
2436        }
2437
2438        sum * self.fractal_bounding
2439    }
2440
2441    fn single_perlin_fractal_rigid_multi3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 {
2442        let mut sum: f32 = 1.0 - fast_abs_f(self.single_perlin3d(self.perm[0], x, y, z));
2443        let mut amp: f32 = 1.0;
2444        let mut i = 1;
2445
2446        while i < self.octaves {
2447            x *= self.lacunarity;
2448            y *= self.lacunarity;
2449            z *= self.lacunarity;
2450
2451            amp *= self.gain;
2452            sum -= (1.0 - fast_abs_f(self.single_perlin3d(self.perm[i as usize], x, y, z))) * amp;
2453
2454            i += 1;
2455        }
2456
2457        sum
2458    }
2459
2460    #[allow(dead_code)]
2461    fn get_perlin3d(&self, x: f32, y: f32, z: f32) -> f32 {
2462        self.single_perlin3d(
2463            0,
2464            x * self.frequency,
2465            y * self.frequency,
2466            z * self.frequency,
2467        )
2468    }
2469
2470    fn single_perlin3d(&self, offset: u8, x: f32, y: f32, z: f32) -> f32 {
2471        let x0 = fast_floor(x);
2472        let y0 = fast_floor(y);
2473        let z0 = fast_floor(z);
2474        let x1 = x0 + 1;
2475        let y1 = y0 + 1;
2476        let z1 = z0 + 1;
2477
2478        let xs: f32;
2479        let ys: f32;
2480        let zs: f32;
2481
2482        match self.interp {
2483            Interp::Linear => {
2484                xs = x - x0 as f32;
2485                ys = y - y0 as f32;
2486                zs = z - z0 as f32;
2487            }
2488            Interp::Hermite => {
2489                xs = interp_hermite_func(x - x0 as f32);
2490                ys = interp_hermite_func(y - y0 as f32);
2491                zs = interp_hermite_func(z - z0 as f32);
2492            }
2493            Interp::Quintic => {
2494                xs = interp_quintic_func(x - x0 as f32);
2495                ys = interp_quintic_func(y - y0 as f32);
2496                zs = interp_quintic_func(z - z0 as f32);
2497            }
2498        }
2499
2500        let xd0 = x - x0 as f32;
2501        let yd0 = y - y0 as f32;
2502        let zd0 = z - z0 as f32;
2503        let xd1 = xd0 - 1.0;
2504        let yd1 = yd0 - 1.0;
2505        let zd1 = zd0 - 1.0;
2506
2507        let xf00 = lerp(
2508            self.grad_coord_3d(offset, x0, y0, z0, xd0, yd0, zd0),
2509            self.grad_coord_3d(offset, x1, y0, z0, xd1, yd0, zd0),
2510            xs,
2511        );
2512        let xf10 = lerp(
2513            self.grad_coord_3d(offset, x0, y1, z0, xd0, yd1, zd0),
2514            self.grad_coord_3d(offset, x1, y1, z0, xd1, yd1, zd0),
2515            xs,
2516        );
2517        let xf01 = lerp(
2518            self.grad_coord_3d(offset, x0, y0, z1, xd0, yd0, zd1),
2519            self.grad_coord_3d(offset, x1, y0, z1, xd1, yd0, zd1),
2520            xs,
2521        );
2522        let xf11 = lerp(
2523            self.grad_coord_3d(offset, x0, y1, z1, xd0, yd1, zd1),
2524            self.grad_coord_3d(offset, x1, y1, z1, xd1, yd1, zd1),
2525            xs,
2526        );
2527
2528        let yf0 = lerp(xf00, xf10, ys);
2529        let yf1 = lerp(xf01, xf11, ys);
2530
2531        lerp(yf0, yf1, zs)
2532    }
2533
2534    #[allow(dead_code)]
2535    fn get_perlin_fractal(&self, mut x: f32, mut y: f32) -> f32 {
2536        x *= self.frequency;
2537        y *= self.frequency;
2538
2539        match self.fractal_type {
2540            FractalType::FBM => self.single_perlin_fractal_fbm(x, y),
2541            FractalType::Billow => self.single_perlin_fractal_billow(x, y),
2542            FractalType::RigidMulti => self.single_perlin_fractal_rigid_multi(x, y),
2543        }
2544    }
2545
2546    fn single_perlin_fractal_fbm(&self, mut x: f32, mut y: f32) -> f32 {
2547        let mut sum = self.single_perlin(self.perm[0], x, y);
2548        let mut amp = 1.0;
2549        let mut i = 1;
2550
2551        while i < self.octaves {
2552            x *= self.lacunarity;
2553            y *= self.lacunarity;
2554
2555            amp *= self.gain;
2556            sum += self.single_perlin(self.perm[i as usize], x, y) * amp;
2557
2558            i += 1;
2559        }
2560
2561        sum * self.fractal_bounding
2562    }
2563
2564    fn single_perlin_fractal_billow(&self, mut x: f32, mut y: f32) -> f32 {
2565        let mut sum = fast_abs_f(self.single_perlin(self.perm[0], x, y)) * 2.0 - 1.0;
2566        let mut amp = 1.0;
2567        let mut i = 1;
2568
2569        while i < self.octaves {
2570            x *= self.lacunarity;
2571            y *= self.lacunarity;
2572
2573            amp *= self.gain;
2574            sum += (fast_abs_f(self.single_perlin(self.perm[i as usize], x, y)) * 2.0 - 1.0) * amp;
2575            i += 1;
2576        }
2577
2578        sum * self.fractal_bounding
2579    }
2580
2581    fn single_perlin_fractal_rigid_multi(&self, mut x: f32, mut y: f32) -> f32 {
2582        let mut sum = 1.0 - fast_abs_f(self.single_perlin(self.perm[0], x, y));
2583        let mut amp = 1.0;
2584        let mut i = 1;
2585
2586        while i < self.octaves {
2587            x *= self.lacunarity;
2588            y *= self.lacunarity;
2589
2590            amp *= self.gain;
2591            sum -= (1.0 - fast_abs_f(self.single_perlin(self.perm[i as usize], x, y))) * amp;
2592            i += 1;
2593        }
2594
2595        sum
2596    }
2597
2598    #[allow(dead_code)]
2599    fn get_perlin(&self, x: f32, y: f32) -> f32 {
2600        self.single_perlin(0, x * self.frequency, y * self.frequency)
2601    }
2602
2603    fn single_perlin(&self, offset: u8, x: f32, y: f32) -> f32 {
2604        let x0 = fast_floor(x);
2605        let y0 = fast_floor(y);
2606        let x1 = x0 + 1;
2607        let y1 = y0 + 1;
2608
2609        let xs: f32;
2610        let ys: f32;
2611
2612        match self.interp {
2613            Interp::Linear => {
2614                xs = x - x0 as f32;
2615                ys = y - y0 as f32;
2616            }
2617            Interp::Hermite => {
2618                xs = interp_hermite_func(x - x0 as f32);
2619                ys = interp_hermite_func(y - y0 as f32);
2620            }
2621            Interp::Quintic => {
2622                xs = interp_quintic_func(x - x0 as f32);
2623                ys = interp_quintic_func(y - y0 as f32);
2624            }
2625        }
2626
2627        let xd0 = x - x0 as f32;
2628        let yd0 = y - y0 as f32;
2629        let xd1 = xd0 - 1.0;
2630        let yd1 = yd0 - 1.0;
2631
2632        let xf0 = lerp(
2633            self.grad_coord_2d(offset, x0, y0, xd0, yd0),
2634            self.grad_coord_2d(offset, x1, y0, xd1, yd0),
2635            xs,
2636        );
2637        let xf1 = lerp(
2638            self.grad_coord_2d(offset, x0, y1, xd0, yd1),
2639            self.grad_coord_2d(offset, x1, y1, xd1, yd1),
2640            xs,
2641        );
2642
2643        lerp(xf0, xf1, ys)
2644    }
2645
2646    #[allow(dead_code)]
2647    // Simplex noise
2648    fn get_simplex_fractal3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 {
2649        x *= self.frequency;
2650        y *= self.frequency;
2651        z *= self.frequency;
2652
2653        match self.fractal_type {
2654            FractalType::FBM => self.single_simplex_fractal_fbm3d(x, y, z),
2655            FractalType::Billow => self.single_simplex_fractal_billow3d(x, y, z),
2656            FractalType::RigidMulti => self.single_simplex_fractal_rigid_multi3d(x, y, z),
2657        }
2658    }
2659
2660    fn single_simplex_fractal_fbm3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 {
2661        let mut sum = self.single_simplex3d(self.perm[0], x, y, z);
2662        let mut amp = 1.0;
2663        let mut i = 1;
2664
2665        while i < self.octaves {
2666            x *= self.lacunarity;
2667            y *= self.lacunarity;
2668            z *= self.lacunarity;
2669
2670            amp *= self.gain;
2671            sum += self.single_simplex3d(self.perm[i as usize], x, y, z) * amp;
2672            i += 1;
2673        }
2674
2675        sum * self.fractal_bounding
2676    }
2677
2678    fn single_simplex_fractal_billow3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 {
2679        let mut sum = fast_abs_f(self.single_simplex3d(self.perm[0], x, y, z)) * 2.0 - 1.0;
2680        let mut amp = 1.0;
2681        let mut i = 1;
2682
2683        while i < self.octaves {
2684            x *= self.lacunarity;
2685            y *= self.lacunarity;
2686            z *= self.lacunarity;
2687
2688            amp *= self.gain;
2689            sum += (fast_abs_f(self.single_simplex3d(self.perm[i as usize], x, y, z)) * 2.0 - 1.0)
2690                * amp;
2691            i += 1;
2692        }
2693
2694        sum * self.fractal_bounding
2695    }
2696
2697    fn single_simplex_fractal_rigid_multi3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 {
2698        let mut sum = 1.0 - fast_abs_f(self.single_simplex3d(self.perm[0], x, y, z));
2699        let mut amp = 1.0;
2700        let mut i = 1;
2701
2702        while i < self.octaves {
2703            x *= self.lacunarity;
2704            y *= self.lacunarity;
2705            z *= self.lacunarity;
2706
2707            amp *= self.gain;
2708            sum -= (1.0 - fast_abs_f(self.single_simplex3d(self.perm[i as usize], x, y, z))) * amp;
2709            i += 1;
2710        }
2711
2712        sum
2713    }
2714
2715    #[allow(dead_code)]
2716    fn get_simplex3d(&self, x: f32, y: f32, z: f32) -> f32 {
2717        self.single_simplex3d(
2718            0,
2719            x * self.frequency,
2720            y * self.frequency,
2721            z * self.frequency,
2722        )
2723    }
2724
2725    #[allow(clippy::many_single_char_names)]
2726    #[allow(clippy::collapsible_if)]
2727    #[allow(clippy::suspicious_else_formatting)]
2728    fn single_simplex3d(&self, offset: u8, x: f32, y: f32, z: f32) -> f32 {
2729        let mut t: f32 = (x + y + z) * F3;
2730        let i = fast_floor(x + t);
2731        let j = fast_floor(y + t);
2732        let k = fast_floor(z + t);
2733
2734        t = (i + j + k) as f32 * G3;
2735        let x0 = i as f32 - t;
2736        let y0 = j as f32 - t;
2737        let z0 = k as f32 - t;
2738
2739        let x0 = x - x0;
2740        let y0 = y - y0;
2741        let z0 = z - z0;
2742
2743        let i1: f32;
2744        let j1: f32;
2745        let k1: f32;
2746        let i2: f32;
2747        let j2: f32;
2748        let k2: f32;
2749
2750        if x0 >= y0 {
2751            if y0 >= z0 {
2752                i1 = 1.;
2753                j1 = 0.;
2754                k1 = 0.;
2755                i2 = 1.;
2756                j2 = 1.;
2757                k2 = 0.;
2758            } else if x0 >= z0 {
2759                i1 = 1.;
2760                j1 = 0.;
2761                k1 = 0.;
2762                i2 = 1.;
2763                j2 = 0.;
2764                k2 = 1.;
2765            } else
2766            // x0 < z0
2767            {
2768                i1 = 0.;
2769                j1 = 0.;
2770                k1 = 1.;
2771                i2 = 1.;
2772                j2 = 0.;
2773                k2 = 1.;
2774            }
2775        } else
2776        // x0 < y0
2777        {
2778            if y0 < z0 {
2779                i1 = 0.;
2780                j1 = 0.;
2781                k1 = 1.;
2782                i2 = 0.;
2783                j2 = 1.;
2784                k2 = 1.;
2785            } else if x0 < z0 {
2786                i1 = 0.;
2787                j1 = 1.;
2788                k1 = 0.;
2789                i2 = 0.;
2790                j2 = 1.;
2791                k2 = 1.;
2792            } else
2793            // x0 >= z0
2794            {
2795                i1 = 0.;
2796                j1 = 1.;
2797                k1 = 0.;
2798                i2 = 1.;
2799                j2 = 1.;
2800                k2 = 0.;
2801            }
2802        }
2803
2804        let x1 = x0 - i1 + G3;
2805        let y1 = y0 - j1 + G3;
2806        let z1 = z0 - k1 + G3;
2807        let x2 = x0 - i2 + 2.0 * G3;
2808        let y2 = y0 - j2 + 2.0 * G3;
2809        let z2 = z0 - k2 + 2.0 * G3;
2810        let x3 = x0 - 1. + 3.0 * G3;
2811        let y3 = y0 - 1. + 3.0 * G3;
2812        let z3 = z0 - 1. + 3.0 * G3;
2813
2814        let n0;
2815        let n1;
2816        let n2;
2817        let n3;
2818
2819        t = 0.6 - x0 * x0 - y0 * y0 - z0 * z0;
2820        if t < 0. {
2821            n0 = 0.;
2822        } else {
2823            t *= t;
2824            n0 = t * t * self.grad_coord_3d(offset, i, j, k, x0, y0, z0);
2825        }
2826
2827        t = 0.6 - x1 * x1 - y1 * y1 - z1 * z1;
2828        if t < 0. {
2829            n1 = 0.
2830        } else {
2831            t *= t;
2832            n1 = t
2833                * t
2834                * self.grad_coord_3d(
2835                    offset,
2836                    i + i1 as i32,
2837                    j + j1 as i32,
2838                    k + k1 as i32,
2839                    x1,
2840                    y1,
2841                    z1,
2842                );
2843        }
2844
2845        t = 0.6 - x2 * x2 - y2 * y2 - z2 * z2;
2846        if t < 0. {
2847            n2 = 0.
2848        } else {
2849            t *= t;
2850            n2 = t
2851                * t
2852                * self.grad_coord_3d(
2853                    offset,
2854                    i + i2 as i32,
2855                    j + j2 as i32,
2856                    k + k2 as i32,
2857                    x2,
2858                    y2,
2859                    z2,
2860                );
2861        }
2862
2863        t = 0.6 - x3 * x3 - y3 * y3 - z3 * z3;
2864        if t < 0. {
2865            n3 = 0.
2866        } else {
2867            t *= t;
2868            n3 = t * t * self.grad_coord_3d(offset, i + 1, j + 1, k + 1, x3, y3, z3);
2869        }
2870
2871        32.0 * (n0 + n1 + n2 + n3)
2872    }
2873
2874    #[allow(dead_code)]
2875    fn get_simplex_fractal(&self, mut x: f32, mut y: f32) -> f32 {
2876        x *= self.frequency;
2877        y *= self.frequency;
2878
2879        match self.fractal_type {
2880            FractalType::FBM => self.single_simplex_fractal_fbm(x, y),
2881            FractalType::Billow => self.single_simplex_fractal_billow(x, y),
2882            FractalType::RigidMulti => self.single_simplex_fractal_rigid_multi(x, y),
2883        }
2884    }
2885
2886    fn single_simplex_fractal_fbm(&self, mut x: f32, mut y: f32) -> f32 {
2887        let mut sum = self.single_simplex(self.perm[0], x, y);
2888        let mut amp = 1.0;
2889        let mut i = 1;
2890
2891        while i < self.octaves {
2892            x *= self.lacunarity;
2893            y *= self.lacunarity;
2894
2895            amp *= self.gain;
2896            sum += self.single_simplex(self.perm[i as usize], x, y) * amp;
2897            i += 1;
2898        }
2899
2900        sum * self.fractal_bounding
2901    }
2902
2903    fn single_simplex_fractal_billow(&self, mut x: f32, mut y: f32) -> f32 {
2904        let mut sum = fast_abs_f(self.single_simplex(self.perm[0], x, y)) * 2.0 - 1.0;
2905        let mut amp = 1.0;
2906        let mut i = 1;
2907
2908        while i < self.octaves {
2909            x *= self.lacunarity;
2910            y *= self.lacunarity;
2911
2912            amp *= self.gain;
2913            sum += (fast_abs_f(self.single_simplex(self.perm[i as usize], x, y)) * 2.0 - 1.0) * amp;
2914            i += 1;
2915        }
2916
2917        sum * self.fractal_bounding
2918    }
2919
2920    fn single_simplex_fractal_rigid_multi(&self, mut x: f32, mut y: f32) -> f32 {
2921        let mut sum = 1.0 - fast_abs_f(self.single_simplex(self.perm[0], x, y));
2922        let mut amp = 1.0;
2923        let mut i = 1;
2924
2925        while i < self.octaves {
2926            x *= self.lacunarity;
2927            y *= self.lacunarity;
2928
2929            amp *= self.gain;
2930            sum -= (1.0 - self.single_simplex(self.perm[i as usize], x, y)) * amp;
2931            i += 1;
2932        }
2933
2934        sum
2935    }
2936
2937    #[allow(dead_code)]
2938    fn single_simplex_fractal_blend(&self, mut x: f32, mut y: f32) -> f32 {
2939        let mut sum = self.single_simplex(self.perm[0], x, y);
2940        let mut amp = 1.0;
2941        let mut i = 1;
2942
2943        while i < self.octaves {
2944            x *= self.lacunarity;
2945            y *= self.lacunarity;
2946
2947            amp *= self.gain;
2948            sum += self.single_simplex(self.perm[i as usize], x, y) * amp + 1.0;
2949            i += 1;
2950        }
2951
2952        sum * self.fractal_bounding
2953    }
2954
2955    #[allow(dead_code)]
2956    fn get_simplex(&self, x: f32, y: f32) -> f32 {
2957        self.single_simplex(0, x * self.frequency, y * self.frequency)
2958    }
2959
2960    #[allow(clippy::many_single_char_names)]
2961    fn single_simplex(&self, offset: u8, x: f32, y: f32) -> f32 {
2962        let mut t: f32 = (x + y) * F2;
2963        let i = fast_floor(x + t);
2964        let j = fast_floor(y + t);
2965
2966        t = (i + j) as f32 * G2;
2967        let x0 = i as f32 - t;
2968        let y0 = j as f32 - t;
2969
2970        let x0 = x - x0;
2971        let y0 = y - y0;
2972
2973        let (i1, j1) = if x0 > y0 { (1, 0) } else { (0, 1) };
2974
2975        let x1 = x0 - i1 as f32 + G2;
2976        let y1 = y0 - j1 as f32 + G2;
2977        let x2 = x0 - 1.0 + 2.0 * G2;
2978        let y2 = y0 - 1.0 + 2.0 * G2;
2979
2980        let n0;
2981        let n1;
2982        let n2;
2983
2984        t = 0.5 - x0 * x0 - y0 * y0;
2985        if t < 0. {
2986            n0 = 0.
2987        } else {
2988            t *= t;
2989            n0 = t * t * self.grad_coord_2d(offset, i, j, x0, y0);
2990        }
2991
2992        t = 0.5 - x1 * x1 - y1 * y1;
2993        if t < 0. {
2994            n1 = 0.
2995        } else {
2996            t *= t;
2997            n1 = t * t * self.grad_coord_2d(offset, i + i1 as i32, j + j1 as i32, x1, y1);
2998        }
2999
3000        t = 0.5 - x2 * x2 - y2 * y2;
3001        if t < 0. {
3002            n2 = 0.
3003        } else {
3004            t *= t;
3005            n2 = t * t * self.grad_coord_2d(offset, i + 1, j + 1, x2, y2);
3006        }
3007
3008        70.0 * (n0 + n1 + n2)
3009    }
3010
3011    #[allow(dead_code)]
3012    fn get_simplex_4d(&self, x: f32, y: f32, z: f32, w: f32) -> f32 {
3013        self.single_simplex4d(
3014            0,
3015            x * self.frequency,
3016            y * self.frequency,
3017            z * self.frequency,
3018            w * self.frequency,
3019        )
3020    }
3021
3022    #[allow(dead_code)]
3023    fn greater_1_0(&self, n: i32, greater_than: i32) -> i32 {
3024        if n >= greater_than {
3025            1
3026        } else {
3027            0
3028        }
3029    }
3030
3031    #[allow(dead_code)]
3032    #[allow(clippy::many_single_char_names)]
3033    fn single_simplex4d(&self, offset: u8, x: f32, y: f32, z: f32, w: f32) -> f32 {
3034        let n0: f32;
3035        let n1: f32;
3036        let n2: f32;
3037        let n3: f32;
3038        let n4: f32;
3039
3040        let mut t = (x + y + z + w) * F4;
3041        let i = fast_floor(x + t) as f32;
3042        let j = fast_floor(y + t) as f32;
3043        let k = fast_floor(z + t) as f32;
3044        let l = fast_floor(w + t) as f32;
3045        t = (i + j + k + l) * G4;
3046        let x0 = i - t;
3047        let y0 = j - t;
3048        let z0 = k - t;
3049        let w0 = l - t;
3050        let x0 = x - x0;
3051        let y0 = y - y0;
3052        let z0 = z - z0;
3053        let w0 = w - w0;
3054
3055        let mut rankx = 0;
3056        let mut ranky = 0;
3057        let mut rankz = 0;
3058        let mut rankw = 0;
3059
3060        if x0 > y0 {
3061            rankx += 1;
3062        } else {
3063            ranky += 1;
3064        }
3065        if x0 > z0 {
3066            rankx += 1;
3067        } else {
3068            rankz += 1
3069        };
3070        if x0 > w0 {
3071            rankx += 1;
3072        } else {
3073            rankw += 1
3074        };
3075        if y0 > z0 {
3076            ranky += 1;
3077        } else {
3078            rankz += 1
3079        };
3080        if y0 > w0 {
3081            ranky += 1;
3082        } else {
3083            rankw += 1
3084        };
3085        if z0 > w0 {
3086            rankz += 1;
3087        } else {
3088            rankw += 1
3089        };
3090
3091        let i1 = self.greater_1_0(rankx, 3);
3092        let j1 = self.greater_1_0(ranky, 3);
3093        let k1 = self.greater_1_0(rankz, 3);
3094        let l1 = self.greater_1_0(rankw, 3);
3095
3096        let i2 = self.greater_1_0(rankx, 2);
3097        let j2 = self.greater_1_0(ranky, 2);
3098        let k2 = self.greater_1_0(rankz, 2);
3099        let l2 = self.greater_1_0(rankw, 2);
3100
3101        let i3 = self.greater_1_0(rankx, 1);
3102        let j3 = self.greater_1_0(ranky, 1);
3103        let k3 = self.greater_1_0(rankz, 1);
3104        let l3 = self.greater_1_0(rankw, 1);
3105
3106        let x1 = x0 - i1 as f32 + G4;
3107        let y1 = y0 - j1 as f32 + G4;
3108        let z1 = z0 - k1 as f32 + G4;
3109        let w1 = w0 - l1 as f32 + G4;
3110        let x2 = x0 - i2 as f32 + 2.0 * G4;
3111        let y2 = y0 - j2 as f32 + 2.0 * G4;
3112        let z2 = z0 - k2 as f32 + 2.0 * G4;
3113        let w2 = w0 - l2 as f32 + 2.0 * G4;
3114        let x3 = x0 - i3 as f32 + 3.0 * G4;
3115        let y3 = y0 - j3 as f32 + 3.0 * G4;
3116        let z3 = z0 - k3 as f32 + 3.0 * G4;
3117        let w3 = w0 - l3 as f32 + 3.0 * G4;
3118        let x4 = x0 - 1.0 + 4.0 * G4;
3119        let y4 = y0 - 1.0 + 4.0 * G4;
3120        let z4 = z0 - 1.0 + 4.0 * G4;
3121        let w4 = w0 - 1.0 + 4.0 * G4;
3122
3123        t = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0;
3124        if t < 0.0 {
3125            n0 = 0.;
3126        } else {
3127            t *= t;
3128            n0 = t
3129                * t
3130                * self.grad_coord_4d(
3131                    offset, i as i32, j as i32, k as i32, l as i32, x0, y0, z0, w0,
3132                );
3133        }
3134        t = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1;
3135        if t < 0.0 {
3136            n1 = 0.;
3137        } else {
3138            t *= t;
3139            n1 = t
3140                * t
3141                * self.grad_coord_4d(
3142                    offset,
3143                    i as i32 + i1,
3144                    j as i32 + j1,
3145                    k as i32 + k1,
3146                    l as i32 + l1,
3147                    x1,
3148                    y1,
3149                    z1,
3150                    w1,
3151                );
3152        }
3153        t = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2;
3154        if t < 0.0 {
3155            n2 = 0.;
3156        } else {
3157            t *= t;
3158            n2 = t
3159                * t
3160                * self.grad_coord_4d(
3161                    offset,
3162                    i as i32 + i2,
3163                    j as i32 + j2,
3164                    k as i32 + k2,
3165                    l as i32 + l2,
3166                    x2,
3167                    y2,
3168                    z2,
3169                    w2,
3170                );
3171        }
3172        t = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3;
3173        if t < 0.0 {
3174            n3 = 0.;
3175        } else {
3176            t *= t;
3177            n3 = t
3178                * t
3179                * self.grad_coord_4d(
3180                    offset,
3181                    i as i32 + i3,
3182                    j as i32 + j3,
3183                    k as i32 + k3,
3184                    l as i32 + l3,
3185                    x3,
3186                    y3,
3187                    z3,
3188                    w3,
3189                );
3190        }
3191        t = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4;
3192        if t < 0.0 {
3193            n4 = 0.;
3194        } else {
3195            t *= t;
3196            n4 = t
3197                * t
3198                * self.grad_coord_4d(
3199                    offset,
3200                    i as i32 + 1,
3201                    j as i32 + 1,
3202                    k as i32 + 1,
3203                    l as i32 + 1,
3204                    x4,
3205                    y4,
3206                    z4,
3207                    w4,
3208                );
3209        }
3210
3211        27.0 * (n0 + n1 + n2 + n3 + n4) as f32
3212    }
3213
3214    #[allow(dead_code)]
3215    // Cubic Noise
3216    fn get_cubic_fractal3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 {
3217        x *= self.frequency;
3218        y *= self.frequency;
3219        z *= self.frequency;
3220
3221        match self.fractal_type {
3222            FractalType::FBM => self.single_cubic_fractal_fbm3d(x, y, z),
3223            FractalType::Billow => self.single_cubic_fractal_billow3d(x, y, z),
3224            FractalType::RigidMulti => self.single_cubic_fractal_rigid_multi3d(x, y, z),
3225        }
3226    }
3227
3228    fn single_cubic_fractal_fbm3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 {
3229        let mut sum = self.single_cubic3d(self.perm[0], x, y, z);
3230        let mut amp = 1.0;
3231        let mut i = 1;
3232        while i < self.octaves {
3233            x *= self.lacunarity;
3234            y *= self.lacunarity;
3235            z *= self.lacunarity;
3236
3237            amp *= self.gain;
3238            sum += self.single_cubic3d(self.perm[i as usize], x, y, z) * amp;
3239            i += 1;
3240        }
3241
3242        sum * self.fractal_bounding
3243    }
3244
3245    fn single_cubic_fractal_billow3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 {
3246        let mut sum = fast_abs_f(self.single_cubic3d(self.perm[0], x, y, z)) * 2.0 - 1.0;
3247        let mut amp = 1.0;
3248        let mut i = 1;
3249        while i < self.octaves {
3250            x *= self.lacunarity;
3251            y *= self.lacunarity;
3252            z *= self.lacunarity;
3253
3254            amp *= self.gain;
3255            sum +=
3256                (fast_abs_f(self.single_cubic3d(self.perm[i as usize], x, y, z)) * 2.0 - 1.0) * amp;
3257            i += 1;
3258        }
3259
3260        sum * self.fractal_bounding
3261    }
3262
3263    fn single_cubic_fractal_rigid_multi3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 {
3264        let mut sum = 1.0 - fast_abs_f(self.single_cubic3d(self.perm[0], x, y, z));
3265        let mut amp = 1.0;
3266        let mut i = 1;
3267        while i < self.octaves {
3268            x *= self.lacunarity;
3269            y *= self.lacunarity;
3270            z *= self.lacunarity;
3271
3272            amp *= self.gain;
3273            sum -= (1.0 - fast_abs_f(self.single_cubic3d(self.perm[i as usize], x, y, z))) * amp;
3274            i += 1;
3275        }
3276
3277        sum
3278    }
3279
3280    #[allow(dead_code)]
3281    fn get_cubic3d(&self, x: f32, y: f32, z: f32) -> f32 {
3282        self.single_cubic3d(
3283            0,
3284            x * self.frequency,
3285            y * self.frequency,
3286            z * self.frequency,
3287        )
3288    }
3289
3290    fn single_cubic3d(&self, offset: u8, x: f32, y: f32, z: f32) -> f32 {
3291        let x1 = fast_floor(x);
3292        let y1 = fast_floor(y);
3293        let z1 = fast_floor(z);
3294
3295        let x0 = x1 - 1;
3296        let y0 = y1 - 1;
3297        let z0 = z1 - 1;
3298        let x2 = x1 + 1;
3299        let y2 = y1 + 1;
3300        let z2 = z1 + 1;
3301        let x3 = x1 + 2;
3302        let y3 = y1 + 2;
3303        let z3 = z1 + 2;
3304
3305        let xs = x - x1 as f32;
3306        let ys = y - y1 as f32;
3307        let zs = z - z1 as f32;
3308
3309        cubic_lerp(
3310            cubic_lerp(
3311                cubic_lerp(
3312                    self.val_coord_3d_fast(offset, x0, y0, z0),
3313                    self.val_coord_3d_fast(offset, x1, y0, z0),
3314                    self.val_coord_3d_fast(offset, x2, y0, z0),
3315                    self.val_coord_3d_fast(offset, x3, y0, z0),
3316                    xs,
3317                ),
3318                cubic_lerp(
3319                    self.val_coord_3d_fast(offset, x0, y1, z0),
3320                    self.val_coord_3d_fast(offset, x1, y1, z0),
3321                    self.val_coord_3d_fast(offset, x2, y1, z0),
3322                    self.val_coord_3d_fast(offset, x3, y1, z0),
3323                    xs,
3324                ),
3325                cubic_lerp(
3326                    self.val_coord_3d_fast(offset, x0, y2, z0),
3327                    self.val_coord_3d_fast(offset, x1, y2, z0),
3328                    self.val_coord_3d_fast(offset, x2, y2, z0),
3329                    self.val_coord_3d_fast(offset, x3, y2, z0),
3330                    xs,
3331                ),
3332                cubic_lerp(
3333                    self.val_coord_3d_fast(offset, x0, y3, z0),
3334                    self.val_coord_3d_fast(offset, x1, y3, z0),
3335                    self.val_coord_3d_fast(offset, x2, y3, z0),
3336                    self.val_coord_3d_fast(offset, x3, y3, z0),
3337                    xs,
3338                ),
3339                ys,
3340            ),
3341            cubic_lerp(
3342                cubic_lerp(
3343                    self.val_coord_3d_fast(offset, x0, y0, z1),
3344                    self.val_coord_3d_fast(offset, x1, y0, z1),
3345                    self.val_coord_3d_fast(offset, x2, y0, z1),
3346                    self.val_coord_3d_fast(offset, x3, y0, z1),
3347                    xs,
3348                ),
3349                cubic_lerp(
3350                    self.val_coord_3d_fast(offset, x0, y1, z1),
3351                    self.val_coord_3d_fast(offset, x1, y1, z1),
3352                    self.val_coord_3d_fast(offset, x2, y1, z1),
3353                    self.val_coord_3d_fast(offset, x3, y1, z1),
3354                    xs,
3355                ),
3356                cubic_lerp(
3357                    self.val_coord_3d_fast(offset, x0, y2, z1),
3358                    self.val_coord_3d_fast(offset, x1, y2, z1),
3359                    self.val_coord_3d_fast(offset, x2, y2, z1),
3360                    self.val_coord_3d_fast(offset, x3, y2, z1),
3361                    xs,
3362                ),
3363                cubic_lerp(
3364                    self.val_coord_3d_fast(offset, x0, y3, z1),
3365                    self.val_coord_3d_fast(offset, x1, y3, z1),
3366                    self.val_coord_3d_fast(offset, x2, y3, z1),
3367                    self.val_coord_3d_fast(offset, x3, y3, z1),
3368                    xs,
3369                ),
3370                ys,
3371            ),
3372            cubic_lerp(
3373                cubic_lerp(
3374                    self.val_coord_3d_fast(offset, x0, y0, z2),
3375                    self.val_coord_3d_fast(offset, x1, y0, z2),
3376                    self.val_coord_3d_fast(offset, x2, y0, z2),
3377                    self.val_coord_3d_fast(offset, x3, y0, z2),
3378                    xs,
3379                ),
3380                cubic_lerp(
3381                    self.val_coord_3d_fast(offset, x0, y1, z2),
3382                    self.val_coord_3d_fast(offset, x1, y1, z2),
3383                    self.val_coord_3d_fast(offset, x2, y1, z2),
3384                    self.val_coord_3d_fast(offset, x3, y1, z2),
3385                    xs,
3386                ),
3387                cubic_lerp(
3388                    self.val_coord_3d_fast(offset, x0, y2, z2),
3389                    self.val_coord_3d_fast(offset, x1, y2, z2),
3390                    self.val_coord_3d_fast(offset, x2, y2, z2),
3391                    self.val_coord_3d_fast(offset, x3, y2, z2),
3392                    xs,
3393                ),
3394                cubic_lerp(
3395                    self.val_coord_3d_fast(offset, x0, y3, z2),
3396                    self.val_coord_3d_fast(offset, x1, y3, z2),
3397                    self.val_coord_3d_fast(offset, x2, y3, z2),
3398                    self.val_coord_3d_fast(offset, x3, y3, z2),
3399                    xs,
3400                ),
3401                ys,
3402            ),
3403            cubic_lerp(
3404                cubic_lerp(
3405                    self.val_coord_3d_fast(offset, x0, y0, z3),
3406                    self.val_coord_3d_fast(offset, x1, y0, z3),
3407                    self.val_coord_3d_fast(offset, x2, y0, z3),
3408                    self.val_coord_3d_fast(offset, x3, y0, z3),
3409                    xs,
3410                ),
3411                cubic_lerp(
3412                    self.val_coord_3d_fast(offset, x0, y1, z3),
3413                    self.val_coord_3d_fast(offset, x1, y1, z3),
3414                    self.val_coord_3d_fast(offset, x2, y1, z3),
3415                    self.val_coord_3d_fast(offset, x3, y1, z3),
3416                    xs,
3417                ),
3418                cubic_lerp(
3419                    self.val_coord_3d_fast(offset, x0, y2, z3),
3420                    self.val_coord_3d_fast(offset, x1, y2, z3),
3421                    self.val_coord_3d_fast(offset, x2, y2, z3),
3422                    self.val_coord_3d_fast(offset, x3, y2, z3),
3423                    xs,
3424                ),
3425                cubic_lerp(
3426                    self.val_coord_3d_fast(offset, x0, y3, z3),
3427                    self.val_coord_3d_fast(offset, x1, y3, z3),
3428                    self.val_coord_3d_fast(offset, x2, y3, z3),
3429                    self.val_coord_3d_fast(offset, x3, y3, z3),
3430                    xs,
3431                ),
3432                ys,
3433            ),
3434            zs,
3435        ) * CUBIC_3D_BOUNDING
3436    }
3437
3438    #[allow(dead_code)]
3439    fn get_cubic_fractal(&self, mut x: f32, mut y: f32) -> f32 {
3440        x *= self.frequency;
3441        y *= self.frequency;
3442
3443        match self.fractal_type {
3444            FractalType::FBM => self.single_cubic_fractal_fbm(x, y),
3445            FractalType::Billow => self.single_cubic_fractal_billow(x, y),
3446            FractalType::RigidMulti => self.single_cubic_fractal_rigid_multi(x, y),
3447        }
3448    }
3449
3450    fn single_cubic_fractal_fbm(&self, mut x: f32, mut y: f32) -> f32 {
3451        let mut sum = self.single_cubic(self.perm[0], x, y);
3452        let mut amp = 1.0;
3453        let mut i = 1;
3454
3455        while i < self.octaves {
3456            x *= self.lacunarity;
3457            y *= self.lacunarity;
3458
3459            amp *= self.gain;
3460            sum += self.single_cubic(self.perm[i as usize], x, y) * amp;
3461            i += 1;
3462        }
3463
3464        sum * self.fractal_bounding
3465    }
3466
3467    fn single_cubic_fractal_billow(&self, mut x: f32, mut y: f32) -> f32 {
3468        let mut sum = fast_abs_f(self.single_cubic(self.perm[0], x, y)) * 2.0 - 1.0;
3469        let mut amp = 1.0;
3470        let mut i = 1;
3471
3472        while i < self.octaves {
3473            x *= self.lacunarity;
3474            y *= self.lacunarity;
3475
3476            amp *= self.gain;
3477            sum += (fast_abs_f(self.single_cubic(self.perm[i as usize], x, y)) * 2.0 - 1.0) * amp;
3478            i += 1;
3479        }
3480
3481        sum * self.fractal_bounding
3482    }
3483
3484    fn single_cubic_fractal_rigid_multi(&self, mut x: f32, mut y: f32) -> f32 {
3485        let mut sum = 1.0 - fast_abs_f(self.single_cubic(self.perm[0], x, y));
3486        let mut amp = 1.0;
3487        let mut i = 1;
3488
3489        while i < self.octaves {
3490            x *= self.lacunarity;
3491            y *= self.lacunarity;
3492
3493            amp *= self.gain;
3494            sum -= (1.0 - fast_abs_f(self.single_cubic(self.perm[i as usize], x, y))) * amp;
3495            i += 1;
3496        }
3497
3498        sum
3499    }
3500
3501    #[allow(dead_code)]
3502    fn get_cubic(&self, x: f32, y: f32) -> f32 {
3503        self.single_cubic(0, x * self.frequency, y * self.frequency)
3504    }
3505
3506    fn single_cubic(&self, offset: u8, x: f32, y: f32) -> f32 {
3507        let x1 = fast_floor(x);
3508        let y1 = fast_floor(y);
3509
3510        let x0 = x1 - 1;
3511        let y0 = y1 - 1;
3512        let x2 = x1 + 1;
3513        let y2 = y1 + 1;
3514        let x3 = x1 + 2;
3515        let y3 = y1 + 2;
3516
3517        let xs = x - x1 as f32;
3518        let ys = y - y1 as f32;
3519
3520        cubic_lerp(
3521            cubic_lerp(
3522                self.val_coord_2d_fast(offset, x0, y0),
3523                self.val_coord_2d_fast(offset, x1, y0),
3524                self.val_coord_2d_fast(offset, x2, y0),
3525                self.val_coord_2d_fast(offset, x3, y0),
3526                xs,
3527            ),
3528            cubic_lerp(
3529                self.val_coord_2d_fast(offset, x0, y1),
3530                self.val_coord_2d_fast(offset, x1, y1),
3531                self.val_coord_2d_fast(offset, x2, y1),
3532                self.val_coord_2d_fast(offset, x3, y1),
3533                xs,
3534            ),
3535            cubic_lerp(
3536                self.val_coord_2d_fast(offset, x0, y2),
3537                self.val_coord_2d_fast(offset, x1, y2),
3538                self.val_coord_2d_fast(offset, x2, y2),
3539                self.val_coord_2d_fast(offset, x3, y2),
3540                xs,
3541            ),
3542            cubic_lerp(
3543                self.val_coord_2d_fast(offset, x0, y3),
3544                self.val_coord_2d_fast(offset, x1, y3),
3545                self.val_coord_2d_fast(offset, x2, y3),
3546                self.val_coord_2d_fast(offset, x3, y3),
3547                xs,
3548            ),
3549            ys,
3550        ) * CUBIC_2D_BOUNDING
3551    }
3552
3553    #[allow(dead_code)]
3554    // Cellular Noise
3555    fn get_cellular3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 {
3556        x *= self.frequency;
3557        y *= self.frequency;
3558        z *= self.frequency;
3559
3560        match self.cellular_return_type {
3561            CellularReturnType::CellValue => self.single_cellular3d(x, y, z),
3562            CellularReturnType::Distance => self.single_cellular3d(x, y, z),
3563            _ => self.single_cellular_2edge3d(x, y, z),
3564        }
3565    }
3566
3567    fn single_cellular3d(&self, x: f32, y: f32, z: f32) -> f32 {
3568        let xr = fast_round(x);
3569        let yr = fast_round(y);
3570        let zr = fast_round(z);
3571
3572        let mut distance: f32 = 999999.0;
3573        let mut xc: i32 = 0;
3574        let mut yc: i32 = 0;
3575        let mut zc: i32 = 0;
3576
3577        match self.cellular_distance_function {
3578            CellularDistanceFunction::Euclidean => {
3579                for xi in xr - 1..xr + 2 {
3580                    for yi in yr - 1..yr + 2 {
3581                        for zi in zr - 1..zr + 2 {
3582                            let lut_pos: u8 = self.index3d_256(0, xi, yi, zi);
3583
3584                            let vec_x =
3585                                xi as f32 - x + CELL_3D_X[lut_pos as usize] * self.cellular_jitter;
3586                            let vec_y =
3587                                yi as f32 - y + CELL_3D_Y[lut_pos as usize] * self.cellular_jitter;
3588                            let vec_z =
3589                                zi as f32 - z + CELL_3D_Z[lut_pos as usize] * self.cellular_jitter;
3590
3591                            let new_distance = vec_x * vec_x + vec_y * vec_y + vec_z * vec_z;
3592
3593                            if new_distance < distance {
3594                                distance = new_distance;
3595                                xc = xi;
3596                                yc = yi;
3597                                zc = zi;
3598                            }
3599                        }
3600                    }
3601                }
3602            }
3603            CellularDistanceFunction::Manhattan => {
3604                for xi in xr - 1..xr + 2 {
3605                    for yi in yr - 1..yr + 2 {
3606                        for zi in zr - 1..zr + 2 {
3607                            let lut_pos: u8 = self.index3d_256(0, xi, yi, zi);
3608
3609                            let vec_x =
3610                                xi as f32 - x + CELL_3D_X[lut_pos as usize] * self.cellular_jitter;
3611                            let vec_y =
3612                                yi as f32 - y + CELL_3D_Y[lut_pos as usize] * self.cellular_jitter;
3613                            let vec_z =
3614                                zi as f32 - z + CELL_3D_Z[lut_pos as usize] * self.cellular_jitter;
3615
3616                            let new_distance =
3617                                fast_abs_f(vec_x) + fast_abs_f(vec_y) + fast_abs_f(vec_z);
3618
3619                            if new_distance < distance {
3620                                distance = new_distance;
3621                                xc = xi;
3622                                yc = yi;
3623                                zc = zi;
3624                            }
3625                        }
3626                    }
3627                }
3628            }
3629            CellularDistanceFunction::Natural => {
3630                for xi in xr - 1..xr + 2 {
3631                    for yi in yr - 1..yr + 2 {
3632                        for zi in zr - 1..zr + 2 {
3633                            let lut_pos: u8 = self.index3d_256(0, xi, yi, zi);
3634
3635                            let vec_x =
3636                                xi as f32 - x + CELL_3D_X[lut_pos as usize] * self.cellular_jitter;
3637                            let vec_y =
3638                                yi as f32 - y + CELL_3D_Y[lut_pos as usize] * self.cellular_jitter;
3639                            let vec_z =
3640                                zi as f32 - z + CELL_3D_Z[lut_pos as usize] * self.cellular_jitter;
3641
3642                            let new_distance =
3643                                (fast_abs_f(vec_x) + fast_abs_f(vec_y) + fast_abs_f(vec_z))
3644                                    + (vec_x * vec_x + vec_y * vec_y + vec_z * vec_z);
3645
3646                            if new_distance < distance {
3647                                distance = new_distance;
3648                                xc = xi;
3649                                yc = yi;
3650                                zc = zi;
3651                            }
3652                        }
3653                    }
3654                }
3655            }
3656        }
3657
3658        //let lut_pos : u8;
3659        match self.cellular_return_type {
3660            CellularReturnType::CellValue => self.val_coord_3d(self.seed as i32, xc, yc, zc),
3661            CellularReturnType::Distance => distance,
3662            _ => 0.0,
3663        }
3664    }
3665
3666    fn single_cellular_2edge3d(&self, x: f32, y: f32, z: f32) -> f32 {
3667        let xr = fast_round(x);
3668        let yr = fast_round(y);
3669        let zr = fast_round(z);
3670
3671        let mut distance: Vec<f32> = vec![999999.0; FN_CELLULAR_INDEX_MAX + 1];
3672        //FN_DECIMAL distance[FN_CELLULAR_INDEX_MAX+1] = { 999999,999999,999999,999999 };
3673
3674        match self.cellular_distance_function {
3675            CellularDistanceFunction::Euclidean => {
3676                for xi in xr - 1..xr + 2 {
3677                    for yi in yr - 1..yr + 2 {
3678                        for zi in zr - 1..zr + 2 {
3679                            let lut_pos: u8 = self.index3d_256(0, xi, yi, zi);
3680
3681                            let vec_x =
3682                                xi as f32 - x + CELL_3D_X[lut_pos as usize] * self.cellular_jitter;
3683                            let vec_y =
3684                                yi as f32 - y + CELL_3D_Y[lut_pos as usize] * self.cellular_jitter;
3685                            let vec_z =
3686                                zi as f32 - z + CELL_3D_Z[lut_pos as usize] * self.cellular_jitter;
3687
3688                            let new_distance = vec_x * vec_x + vec_y * vec_y + vec_z * vec_z;
3689
3690                            for i in (0..self.cellular_distance_index.1).rev() {
3691                                distance[i as usize] = f32::max(
3692                                    f32::min(distance[i as usize], new_distance),
3693                                    distance[i as usize - 1],
3694                                );
3695                            }
3696                            distance[0] = f32::min(distance[0], new_distance);
3697                        }
3698                    }
3699                }
3700            }
3701            CellularDistanceFunction::Manhattan => {
3702                for xi in xr - 1..xr + 2 {
3703                    for yi in yr - 1..yr + 2 {
3704                        for zi in zr - 1..zr + 2 {
3705                            let lut_pos = self.index3d_256(0, xi, yi, zi);
3706
3707                            let vec_x =
3708                                xi as f32 - x + CELL_3D_X[lut_pos as usize] * self.cellular_jitter;
3709                            let vec_y =
3710                                yi as f32 - y + CELL_3D_Y[lut_pos as usize] * self.cellular_jitter;
3711                            let vec_z =
3712                                zi as f32 - z + CELL_3D_Z[lut_pos as usize] * self.cellular_jitter;
3713
3714                            let new_distance =
3715                                fast_abs_f(vec_x) + fast_abs_f(vec_y) + fast_abs_f(vec_z);
3716
3717                            for i in (0..=self.cellular_distance_index.1).rev() {
3718                                distance[i as usize] = f32::max(
3719                                    f32::min(distance[i as usize], new_distance),
3720                                    distance[i as usize - 1],
3721                                );
3722                            }
3723                            distance[0] = f32::min(distance[0], new_distance);
3724                        }
3725                    }
3726                }
3727            }
3728            CellularDistanceFunction::Natural => {
3729                for xi in xr - 1..xr + 2 {
3730                    for yi in yr - 1..yr + 2 {
3731                        for zi in zr - 1..zr + 2 {
3732                            let lut_pos = self.index3d_256(0, xi, yi, zi);
3733
3734                            let vec_x =
3735                                xi as f32 - x + CELL_3D_X[lut_pos as usize] * self.cellular_jitter;
3736                            let vec_y =
3737                                yi as f32 - y + CELL_3D_Y[lut_pos as usize] * self.cellular_jitter;
3738                            let vec_z =
3739                                zi as f32 - z + CELL_3D_Z[lut_pos as usize] * self.cellular_jitter;
3740
3741                            let new_distance =
3742                                (fast_abs_f(vec_x) + fast_abs_f(vec_y) + fast_abs_f(vec_z))
3743                                    + (vec_x * vec_x + vec_y * vec_y + vec_z * vec_z);
3744
3745                            for i in (0..=self.cellular_distance_index.1).rev() {
3746                                distance[i as usize] = f32::max(
3747                                    f32::min(distance[i as usize], new_distance),
3748                                    distance[i as usize - 1],
3749                                );
3750                            }
3751                            distance[0] = f32::min(distance[0], new_distance);
3752                        }
3753                    }
3754                }
3755            }
3756        }
3757
3758        match self.cellular_return_type {
3759            CellularReturnType::Distance2 => distance[self.cellular_distance_index.1 as usize],
3760            CellularReturnType::Distance2Add => {
3761                distance[self.cellular_distance_index.1 as usize]
3762                    + distance[self.cellular_distance_index.0 as usize]
3763            }
3764            CellularReturnType::Distance2Sub => {
3765                distance[self.cellular_distance_index.1 as usize]
3766                    - distance[self.cellular_distance_index.0 as usize]
3767            }
3768            CellularReturnType::Distance2Mul => {
3769                distance[self.cellular_distance_index.1 as usize]
3770                    * distance[self.cellular_distance_index.0 as usize]
3771            }
3772            CellularReturnType::Distance2Div => {
3773                distance[self.cellular_distance_index.0 as usize]
3774                    / distance[self.cellular_distance_index.1 as usize]
3775            }
3776            _ => 0.0,
3777        }
3778    }
3779
3780    #[allow(dead_code)]
3781    fn get_cellular(&self, mut x: f32, mut y: f32) -> f32 {
3782        x *= self.frequency;
3783        y *= self.frequency;
3784
3785        match self.cellular_return_type {
3786            CellularReturnType::CellValue => self.single_cellular(x, y),
3787            CellularReturnType::Distance => self.single_cellular(x, y),
3788            _ => self.single_cellular_2edge(x, y),
3789        }
3790    }
3791
3792    fn single_cellular(&self, x: f32, y: f32) -> f32 {
3793        let xr = fast_round(x);
3794        let yr = fast_round(y);
3795
3796        let mut distance: f32 = 999999.0;
3797
3798        match self.cellular_distance_function {
3799            CellularDistanceFunction::Euclidean => {
3800                for xi in xr - 1..xr + 2 {
3801                    for yi in yr - 1..yr + 2 {
3802                        let lut_pos: u8 = self.index2d_256(0, xi, yi);
3803
3804                        let vec_x =
3805                            xi as f32 - x + CELL_2D_X[lut_pos as usize] * self.cellular_jitter;
3806                        let vec_y =
3807                            yi as f32 - y + CELL_2D_Y[lut_pos as usize] * self.cellular_jitter;
3808
3809                        let new_distance = vec_x * vec_x + vec_y * vec_y;
3810
3811                        if new_distance < distance {
3812                            distance = new_distance;
3813                        }
3814                    }
3815                }
3816            }
3817            CellularDistanceFunction::Manhattan => {
3818                for xi in xr - 1..xr + 2 {
3819                    for yi in yr - 1..yr + 2 {
3820                        let lut_pos: u8 = self.index2d_256(0, xi, yi);
3821
3822                        let vec_x =
3823                            xi as f32 - x + CELL_2D_X[lut_pos as usize] * self.cellular_jitter;
3824                        let vec_y =
3825                            yi as f32 - y + CELL_2D_Y[lut_pos as usize] * self.cellular_jitter;
3826
3827                        let new_distance = fast_abs_f(vec_x) + fast_abs_f(vec_y);
3828
3829                        if new_distance < distance {
3830                            distance = new_distance;
3831                        }
3832                    }
3833                }
3834            }
3835            CellularDistanceFunction::Natural => {
3836                for xi in xr - 1..xr + 2 {
3837                    for yi in yr - 1..yr + 2 {
3838                        let lut_pos: u8 = self.index2d_256(0, xi, yi);
3839
3840                        let vec_x =
3841                            xi as f32 - x + CELL_2D_X[lut_pos as usize] * self.cellular_jitter;
3842                        let vec_y =
3843                            yi as f32 - y + CELL_2D_Y[lut_pos as usize] * self.cellular_jitter;
3844
3845                        let new_distance = (fast_abs_f(vec_x) + fast_abs_f(vec_y))
3846                            + (vec_x * vec_x + vec_y * vec_y);
3847
3848                        if new_distance < distance {
3849                            distance = new_distance;
3850                        }
3851                    }
3852                }
3853            }
3854        }
3855
3856        //let lut_pos : u8;
3857        match self.cellular_return_type {
3858            CellularReturnType::CellValue => {
3859                self.val_coord_2d(self.seed as i32, x as i32, y as i32)
3860            }
3861            _ => 0.0,
3862        }
3863    }
3864
3865    fn single_cellular_2edge(&self, x: f32, y: f32) -> f32 {
3866        let xr = fast_round(x);
3867        let yr = fast_round(y);
3868
3869        let mut distance: Vec<f32> = vec![999999.0; FN_CELLULAR_INDEX_MAX + 1];
3870
3871        match self.cellular_distance_function {
3872            CellularDistanceFunction::Euclidean => {
3873                for xi in xr - 1..xr + 2 {
3874                    for yi in yr - 1..yr + 2 {
3875                        let lut_pos = self.index2d_256(0, xi, yi);
3876
3877                        let vec_x =
3878                            xi as f32 - x + CELL_2D_X[lut_pos as usize] * self.cellular_jitter;
3879                        let vec_y =
3880                            yi as f32 - y + CELL_2D_Y[lut_pos as usize] * self.cellular_jitter;
3881
3882                        let new_distance = vec_x * vec_x + vec_y * vec_y;
3883
3884                        for i in (0..=self.cellular_distance_index.1).rev() {
3885                            distance[i as usize] = f32::max(
3886                                f32::min(distance[i as usize], new_distance),
3887                                distance[i as usize - 1],
3888                            );
3889                        }
3890                        distance[0] = f32::min(distance[0], new_distance);
3891                    }
3892                }
3893            }
3894            CellularDistanceFunction::Manhattan => {
3895                for xi in xr - 1..xr + 2 {
3896                    for yi in yr - 1..yr + 2 {
3897                        let lut_pos = self.index2d_256(0, xi, yi);
3898
3899                        let vec_x =
3900                            xi as f32 - x + CELL_2D_X[lut_pos as usize] * self.cellular_jitter;
3901                        let vec_y =
3902                            yi as f32 - y + CELL_2D_Y[lut_pos as usize] * self.cellular_jitter;
3903
3904                        let new_distance = fast_abs_f(vec_x) + fast_abs_f(vec_y);
3905
3906                        for i in (0..=self.cellular_distance_index.1).rev() {
3907                            distance[i as usize] = f32::max(
3908                                f32::min(distance[i as usize], new_distance),
3909                                distance[i as usize - 1],
3910                            );
3911                        }
3912                        distance[0] = f32::min(distance[0], new_distance);
3913                    }
3914                }
3915            }
3916            CellularDistanceFunction::Natural => {
3917                for xi in xr - 1..xr + 2 {
3918                    for yi in yr - 1..yr + 2 {
3919                        let lut_pos = self.index2d_256(0, xi, yi);
3920
3921                        let vec_x =
3922                            xi as f32 - x + CELL_2D_X[lut_pos as usize] * self.cellular_jitter;
3923                        let vec_y =
3924                            yi as f32 - y + CELL_2D_Y[lut_pos as usize] * self.cellular_jitter;
3925
3926                        let new_distance = (fast_abs_f(vec_x) + fast_abs_f(vec_y))
3927                            + (vec_x * vec_x + vec_y * vec_y);
3928
3929                        for i in (0..=self.cellular_distance_index.1).rev() {
3930                            distance[i as usize] = f32::max(
3931                                f32::min(distance[i as usize], new_distance),
3932                                distance[i as usize - 1],
3933                            );
3934                        }
3935                        distance[0] = f32::min(distance[0], new_distance);
3936                    }
3937                }
3938            }
3939        }
3940
3941        match self.cellular_return_type {
3942            CellularReturnType::Distance2 => distance[self.cellular_distance_index.0 as usize],
3943            CellularReturnType::Distance2Add => {
3944                distance[self.cellular_distance_index.1 as usize]
3945                    + distance[self.cellular_distance_index.0 as usize]
3946            }
3947            CellularReturnType::Distance2Sub => {
3948                distance[self.cellular_distance_index.1 as usize]
3949                    - distance[self.cellular_distance_index.0 as usize]
3950            }
3951            CellularReturnType::Distance2Mul => {
3952                distance[self.cellular_distance_index.1 as usize]
3953                    * distance[self.cellular_distance_index.0 as usize]
3954            }
3955            CellularReturnType::Distance2Div => {
3956                distance[self.cellular_distance_index.0 as usize]
3957                    / distance[self.cellular_distance_index.1 as usize]
3958            }
3959            _ => 0.0,
3960        }
3961    }
3962
3963    #[allow(dead_code)]
3964    fn gradient_perturb3d(&self, x: &mut f32, y: &mut f32, z: &mut f32) {
3965        self.single_gradient_perturb3d(0, self.gradient_perturb_amp, self.frequency, x, y, z);
3966    }
3967
3968    #[allow(dead_code)]
3969    fn gradient_perturb_fractal3d(&self, x: &mut f32, y: &mut f32, z: &mut f32) {
3970        let mut amp = self.gradient_perturb_amp * self.fractal_bounding;
3971        let mut freq = self.frequency;
3972        let mut i = 1;
3973
3974        self.single_gradient_perturb3d(self.perm[0], amp, self.frequency, x, y, z);
3975
3976        while i < self.octaves {
3977            freq *= self.lacunarity;
3978            amp *= self.gain;
3979            self.single_gradient_perturb3d(self.perm[i as usize], amp, freq, x, y, z);
3980
3981            i += 1;
3982        }
3983    }
3984
3985    #[allow(dead_code)]
3986    fn single_gradient_perturb3d(
3987        &self,
3988        offset: u8,
3989        warp_amp: f32,
3990        frequency: f32,
3991        x: &mut f32,
3992        y: &mut f32,
3993        z: &mut f32,
3994    ) {
3995        let xf = *x * frequency;
3996        let yf = *y * frequency;
3997        let zf = *z * frequency;
3998
3999        let x0 = fast_floor(xf);
4000        let y0 = fast_floor(yf);
4001        let z0 = fast_floor(zf);
4002        let x1 = x0 + 1;
4003        let y1 = y0 + 1;
4004        let z1 = z0 + 1;
4005
4006        let xs: f32;
4007        let ys: f32;
4008        let zs: f32;
4009        match self.interp {
4010            Interp::Linear => {
4011                xs = xf - x0 as f32;
4012                ys = yf - y0 as f32;
4013                zs = zf - z0 as f32;
4014            }
4015            Interp::Hermite => {
4016                xs = interp_hermite_func(xf - x0 as f32);
4017                ys = interp_hermite_func(yf - y0 as f32);
4018                zs = interp_hermite_func(zf - z0 as f32);
4019            }
4020            Interp::Quintic => {
4021                xs = interp_quintic_func(xf - x0 as f32);
4022                ys = interp_quintic_func(yf - y0 as f32);
4023                zs = interp_quintic_func(zf - z0 as f32);
4024            }
4025        }
4026
4027        let mut lut_pos0 = self.index3d_256(offset, x0, y0, z0);
4028        let mut lut_pos1 = self.index3d_256(offset, x1, y0, z0);
4029
4030        let mut lx0x = lerp(
4031            CELL_3D_X[lut_pos0 as usize],
4032            CELL_3D_X[lut_pos1 as usize],
4033            xs,
4034        );
4035        let mut ly0x = lerp(
4036            CELL_3D_Y[lut_pos0 as usize],
4037            CELL_3D_Y[lut_pos1 as usize],
4038            xs,
4039        );
4040        let mut lz0x = lerp(
4041            CELL_3D_Z[lut_pos0 as usize],
4042            CELL_3D_Z[lut_pos1 as usize],
4043            xs,
4044        );
4045
4046        lut_pos0 = self.index3d_256(offset, x0, y1, z0);
4047        lut_pos1 = self.index3d_256(offset, x1, y1, z0);
4048
4049        let mut lx1x = lerp(
4050            CELL_3D_X[lut_pos0 as usize],
4051            CELL_3D_X[lut_pos1 as usize],
4052            xs,
4053        );
4054        let mut ly1x = lerp(
4055            CELL_3D_Y[lut_pos0 as usize],
4056            CELL_3D_Y[lut_pos1 as usize],
4057            xs,
4058        );
4059        let mut lz1x = lerp(
4060            CELL_3D_Z[lut_pos0 as usize],
4061            CELL_3D_Z[lut_pos1 as usize],
4062            xs,
4063        );
4064
4065        let lx0y = lerp(lx0x, lx1x, ys);
4066        let ly0y = lerp(ly0x, ly1x, ys);
4067        let lz0y = lerp(lz0x, lz1x, ys);
4068
4069        lut_pos0 = self.index3d_256(offset, x0, y0, z1);
4070        lut_pos1 = self.index3d_256(offset, x1, y0, z1);
4071
4072        lx0x = lerp(
4073            CELL_3D_X[lut_pos0 as usize],
4074            CELL_3D_X[lut_pos1 as usize],
4075            xs,
4076        );
4077        ly0x = lerp(
4078            CELL_3D_Y[lut_pos0 as usize],
4079            CELL_3D_Y[lut_pos1 as usize],
4080            xs,
4081        );
4082        lz0x = lerp(
4083            CELL_3D_Z[lut_pos0 as usize],
4084            CELL_3D_Z[lut_pos1 as usize],
4085            xs,
4086        );
4087
4088        lut_pos0 = self.index3d_256(offset, x0, y1, z1);
4089        lut_pos1 = self.index3d_256(offset, x1, y1, z1);
4090
4091        lx1x = lerp(
4092            CELL_3D_X[lut_pos0 as usize],
4093            CELL_3D_X[lut_pos1 as usize],
4094            xs,
4095        );
4096        ly1x = lerp(
4097            CELL_3D_Y[lut_pos0 as usize],
4098            CELL_3D_Y[lut_pos1 as usize],
4099            xs,
4100        );
4101        lz1x = lerp(
4102            CELL_3D_Z[lut_pos0 as usize],
4103            CELL_3D_Z[lut_pos1 as usize],
4104            xs,
4105        );
4106
4107        *x += lerp(lx0y, lerp(lx0x, lx1x, ys), zs) * warp_amp;
4108        *y += lerp(ly0y, lerp(ly0x, ly1x, ys), zs) * warp_amp;
4109        *z += lerp(lz0y, lerp(lz0x, lz1x, ys), zs) * warp_amp;
4110    }
4111
4112    #[allow(dead_code)]
4113    fn gradient_perturb(&self, x: &mut f32, y: &mut f32) {
4114        self.single_gradient_perturb(0, self.gradient_perturb_amp, self.frequency, x, y);
4115    }
4116
4117    #[allow(dead_code)]
4118    fn gradient_perturb_fractal(&self, x: &mut f32, y: &mut f32) {
4119        let mut amp = self.gradient_perturb_amp * self.fractal_bounding;
4120        let mut freq = self.frequency;
4121        let mut i = 1;
4122
4123        self.single_gradient_perturb(self.perm[0], amp, self.frequency, x, y);
4124
4125        while i < self.octaves {
4126            freq *= self.lacunarity;
4127            amp *= self.gain;
4128            self.single_gradient_perturb(self.perm[i as usize], amp, freq, x, y);
4129            i += 1;
4130        }
4131    }
4132
4133    #[allow(dead_code)]
4134    fn single_gradient_perturb(
4135        &self,
4136        offset: u8,
4137        warp_amp: f32,
4138        frequency: f32,
4139        x: &mut f32,
4140        y: &mut f32,
4141    ) {
4142        let xf = *x * frequency;
4143        let yf = *y * frequency;
4144
4145        let x0 = fast_floor(xf);
4146        let y0 = fast_floor(yf);
4147        let x1 = x0 + 1;
4148        let y1 = y0 + 1;
4149
4150        let xs: f32;
4151        let ys: f32;
4152        match self.interp {
4153            Interp::Linear => {
4154                xs = xf - x0 as f32;
4155                ys = yf - y0 as f32;
4156            }
4157            Interp::Hermite => {
4158                xs = interp_hermite_func(xf - x0 as f32);
4159                ys = interp_hermite_func(yf - y0 as f32);
4160            }
4161            Interp::Quintic => {
4162                xs = interp_quintic_func(xf - x0 as f32);
4163                ys = interp_quintic_func(yf - y0 as f32);
4164            }
4165        }
4166
4167        let mut lut_pos0 = self.index2d_256(offset, x0, y0);
4168        let mut lut_pos1 = self.index2d_256(offset, x1, y0);
4169
4170        let lx0x = lerp(
4171            CELL_2D_X[lut_pos0 as usize],
4172            CELL_2D_X[lut_pos1 as usize],
4173            xs,
4174        );
4175        let ly0x = lerp(
4176            CELL_2D_Y[lut_pos0 as usize],
4177            CELL_2D_Y[lut_pos1 as usize],
4178            xs,
4179        );
4180
4181        lut_pos0 = self.index2d_256(offset, x0, y1);
4182        lut_pos1 = self.index2d_256(offset, x1, y1);
4183
4184        let lx1x = lerp(
4185            CELL_2D_X[lut_pos0 as usize],
4186            CELL_2D_X[lut_pos1 as usize],
4187            xs,
4188        );
4189        let ly1x = lerp(
4190            CELL_2D_Y[lut_pos0 as usize],
4191            CELL_2D_Y[lut_pos1 as usize],
4192            xs,
4193        );
4194
4195        *x += lerp(lx0x, lx1x, ys) * warp_amp;
4196        *y += lerp(ly0x, ly1x, ys) * warp_amp;
4197    }
4198}
4199
4200#[cfg(test)]
4201mod tests {
4202    use super::{CellularDistanceFunction, FastNoise, NoiseType};
4203
4204    #[test]
4205    // Tests that we make an RGB triplet at defaults and it is black.
4206    fn test_cellular_noise_overflow() {
4207        let mut noise = FastNoise::seeded(6000);
4208        noise.set_noise_type(NoiseType::Cellular);
4209        noise.set_frequency(0.08);
4210        noise.set_cellular_distance_function(CellularDistanceFunction::Manhattan);
4211        for y in 0..1024 {
4212            for x in 0..1024 {
4213                let frac_x = x as f32 / 1024.0;
4214                let frac_y = y as f32 / 1024.0;
4215
4216                let cell_value_f = noise.get_noise(frac_x, frac_y);
4217                assert!(cell_value_f != 0.0);
4218            }
4219        }
4220    }
4221}