1use bracket_random::prelude::RandomNumberGenerator;
7
8#[derive(Debug, PartialEq, Copy, Clone)]
9pub 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)]
24pub enum Interp {
26 Linear,
27 Hermite,
28 Quintic,
29}
30
31#[derive(Debug, PartialEq, Copy, Clone)]
32pub enum FractalType {
34 FBM,
35 Billow,
36 RigidMulti,
37}
38
39#[derive(Debug, PartialEq, Copy, Clone)]
40pub enum CellularDistanceFunction {
42 Euclidean,
43 Manhattan,
44 Natural,
45}
46
47#[derive(Debug, PartialEq, Copy, Clone)]
48pub 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
79const 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
1686fn 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 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 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 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 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 #[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 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 {
2768 i1 = 0.;
2769 j1 = 0.;
2770 k1 = 1.;
2771 i2 = 1.;
2772 j2 = 0.;
2773 k2 = 1.;
2774 }
2775 } else
2776 {
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 {
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 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 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 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 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 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 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}