diff --git a/bracket-noise/Cargo.toml b/bracket-noise/Cargo.toml index 5ec4647..9a34ee1 100755 --- a/bracket-noise/Cargo.toml +++ b/bracket-noise/Cargo.toml @@ -16,6 +16,7 @@ license = "MIT" [dependencies] bracket-random = { path = "../bracket-random", version = "~0.8" } +fastnoise-lite = "1.1" [dev-dependencies] crossterm = "~0.25" diff --git a/bracket-noise/src/fastnoise.rs b/bracket-noise/src/fastnoise.rs index 87c78a3..c7087bd 100755 --- a/bracket-noise/src/fastnoise.rs +++ b/bracket-noise/src/fastnoise.rs @@ -1,9 +1,9 @@ -// A port of Auburn's FastNoise to Rust. -// I really didn't like the noise libraries I could find, so I ported the one I like. -// Original code: https://github.com/Auburns/FastNoise -// The original is MIT licensed, so this is compatible. +// A compatibility wrapper for bracket-noise's FastNoise API. +// Coherent noise generation is delegated to FastNoiseLite where possible. -use bracket_random::prelude::RandomNumberGenerator; +use fastnoise_lite as fnl; +use fastnoise_lite::FastNoiseLite; +use std::num::Wrapping; #[derive(Debug, PartialEq, Copy, Clone)] /// Type of noise to generate @@ -57,7 +57,7 @@ pub enum CellularReturnType { } pub struct FastNoise { - rng: RandomNumberGenerator, + inner: FastNoiseLite, seed: u64, frequency: f32, interp: Interp, @@ -71,1691 +71,31 @@ pub struct FastNoise { cellular_distance_index: (i32, i32), cellular_jitter: f32, gradient_perturb_amp: f32, - perm: Vec, - perm12: Vec, - fractal_bounding: f32, } -// Constants that used to be at the top -const GRAD_X: [f32; 12] = [1.0, -1., 1., -1., 1., -1., 1., -1., 0., 0., 0., 0.]; +const FN_CELLULAR_INDEX_MAX: i32 = 3; -const GRAD_Y: [f32; 12] = [1., 1., -1., -1., 0., 0., 0., 0., 1., -1., 1., -1.]; - -const GRAD_Z: [f32; 12] = [0., 0., 0., 0., 1., 1., -1., -1., 1., 1., -1., -1.]; - -#[allow(dead_code)] -const GRAD_4D: [f32; 128] = [ - 0., 1., 1., 1., 0., 1., 1., -1., 0., 1., -1., 1., 0., 1., -1., -1., 0., -1., 1., 1., 0., -1., - 1., -1., 0., -1., -1., 1., 0., -1., -1., -1., 1., 0., 1., 1., 1., 0., 1., -1., 1., 0., -1., 1., - 1., 0., -1., -1., -1., 0., 1., 1., -1., 0., 1., -1., -1., 0., -1., 1., -1., 0., -1., -1., 1., - 1., 0., 1., 1., 1., 0., -1., 1., -1., 0., 1., 1., -1., 0., -1., -1., 1., 0., 1., -1., 1., 0., - -1., -1., -1., 0., 1., -1., -1., 0., -1., 1., 1., 1., 0., 1., 1., -1., 0., 1., -1., 1., 0., 1., - -1., -1., 0., -1., 1., 1., 0., -1., 1., -1., 0., -1., -1., 1., 0., -1., -1., -1., 0., -]; - -#[allow(clippy::unreadable_literal)] -#[allow(clippy::excessive_precision)] -const VAL_LUT: [f32; 256] = [ - 0.3490196078, - 0.4352941176, - -0.4509803922, - 0.6392156863, - 0.5843137255, - -0.1215686275, - 0.7176470588, - -0.1058823529, - 0.3960784314, - 0.0431372549, - -0.03529411765, - 0.3176470588, - 0.7254901961, - 0.137254902, - 0.8588235294, - -0.8196078431, - -0.7960784314, - -0.3333333333, - -0.6705882353, - -0.3882352941, - 0.262745098, - 0.3254901961, - -0.6470588235, - -0.9215686275, - -0.5294117647, - 0.5294117647, - -0.4666666667, - 0.8117647059, - 0.3803921569, - 0.662745098, - 0.03529411765, - -0.6156862745, - -0.01960784314, - -0.3568627451, - -0.09019607843, - 0.7490196078, - 0.8352941176, - -0.4039215686, - -0.7490196078, - 0.9529411765, - -0.0431372549, - -0.9294117647, - -0.6549019608, - 0.9215686275, - -0.06666666667, - -0.4431372549, - 0.4117647059, - -0.4196078431, - -0.7176470588, - -0.8117647059, - -0.2549019608, - 0.4901960784, - 0.9137254902, - 0.7882352941, - -1.0, - -0.4745098039, - 0.7960784314, - 0.8509803922, - -0.6784313725, - 0.4588235294, - 1.0, - -0.1843137255, - 0.4509803922, - 0.1450980392, - -0.231372549, - -0.968627451, - -0.8588235294, - 0.4274509804, - 0.003921568627, - -0.003921568627, - 0.2156862745, - 0.5058823529, - 0.7647058824, - 0.2078431373, - -0.5921568627, - 0.5764705882, - -0.1921568627, - -0.937254902, - 0.08235294118, - -0.08235294118, - 0.9058823529, - 0.8274509804, - 0.02745098039, - -0.168627451, - -0.7803921569, - 0.1137254902, - -0.9450980392, - 0.2, - 0.01960784314, - 0.5607843137, - 0.2705882353, - 0.4431372549, - -0.9607843137, - 0.6156862745, - 0.9294117647, - -0.07450980392, - 0.3098039216, - 0.9921568627, - -0.9137254902, - -0.2941176471, - -0.3411764706, - -0.6235294118, - -0.7647058824, - -0.8901960784, - 0.05882352941, - 0.2392156863, - 0.7333333333, - 0.6549019608, - 0.2470588235, - 0.231372549, - -0.3960784314, - -0.05098039216, - -0.2235294118, - -0.3725490196, - 0.6235294118, - 0.7019607843, - -0.8274509804, - 0.4196078431, - 0.07450980392, - 0.8666666667, - -0.537254902, - -0.5058823529, - -0.8039215686, - 0.09019607843, - -0.4823529412, - 0.6705882353, - -0.7882352941, - 0.09803921569, - -0.6078431373, - 0.8039215686, - -0.6, - -0.3254901961, - -0.4117647059, - -0.01176470588, - 0.4823529412, - 0.168627451, - 0.8745098039, - -0.3647058824, - -0.1607843137, - 0.568627451, - -0.9921568627, - 0.9450980392, - 0.5137254902, - 0.01176470588, - -0.1450980392, - -0.5529411765, - -0.5764705882, - -0.1137254902, - 0.5215686275, - 0.1607843137, - 0.3725490196, - -0.2, - -0.7254901961, - 0.631372549, - 0.7098039216, - -0.568627451, - 0.1294117647, - -0.3098039216, - 0.7411764706, - -0.8509803922, - 0.2549019608, - -0.6392156863, - -0.5607843137, - -0.3176470588, - 0.937254902, - 0.9843137255, - 0.5921568627, - 0.6941176471, - 0.2862745098, - -0.5215686275, - 0.1764705882, - 0.537254902, - -0.4901960784, - -0.4588235294, - -0.2078431373, - -0.2156862745, - 0.7725490196, - 0.3647058824, - -0.2392156863, - 0.2784313725, - -0.8823529412, - 0.8980392157, - 0.1215686275, - 0.1058823529, - -0.8745098039, - -0.9843137255, - -0.7019607843, - 0.9607843137, - 0.2941176471, - 0.3411764706, - 0.1529411765, - 0.06666666667, - -0.9764705882, - 0.3019607843, - 0.6470588235, - -0.5843137255, - 0.05098039216, - -0.5137254902, - -0.137254902, - 0.3882352941, - -0.262745098, - -0.3019607843, - -0.1764705882, - -0.7568627451, - 0.1843137255, - -0.5450980392, - -0.4980392157, - -0.2784313725, - -0.9529411765, - -0.09803921569, - 0.8901960784, - -0.2862745098, - -0.3803921569, - 0.5529411765, - 0.7803921569, - -0.8352941176, - 0.6862745098, - 0.7568627451, - 0.4980392157, - -0.6862745098, - -0.8980392157, - -0.7725490196, - -0.7098039216, - -0.2470588235, - -0.9058823529, - 0.9764705882, - 0.1921568627, - 0.8431372549, - -0.05882352941, - 0.3568627451, - 0.6078431373, - 0.5450980392, - 0.4039215686, - -0.7333333333, - -0.4274509804, - 0.6, - 0.6784313725, - -0.631372549, - -0.02745098039, - -0.1294117647, - 0.3333333333, - -0.8431372549, - 0.2235294118, - -0.3490196078, - -0.6941176471, - 0.8823529412, - 0.4745098039, - 0.4666666667, - -0.7411764706, - -0.2705882353, - 0.968627451, - 0.8196078431, - -0.662745098, - -0.4352941176, - -0.8666666667, - -0.1529411765, -]; - -#[allow(clippy::unreadable_literal)] -#[allow(clippy::excessive_precision)] -const CELL_2D_X: [f32; 256] = [ - -0.6440658039, - -0.08028078721, - 0.9983546168, - 0.9869492062, - 0.9284746418, - 0.6051097552, - -0.794167404, - -0.3488667991, - -0.943136526, - -0.9968171318, - 0.8740961579, - 0.1421139764, - 0.4282553608, - -0.9986665833, - 0.9996760121, - -0.06248383632, - 0.7120139305, - 0.8917660409, - 0.1094842955, - -0.8730880804, - 0.2594811489, - -0.6690063346, - -0.9996834972, - -0.8803608671, - -0.8166554937, - 0.8955599676, - -0.9398321388, - 0.07615451399, - -0.7147270565, - 0.8707354457, - -0.9580008579, - 0.4905965632, - 0.786775944, - 0.1079711577, - 0.2686638979, - 0.6113487322, - -0.530770584, - -0.7837268286, - -0.8558691039, - -0.5726093896, - -0.9830740914, - 0.7087766359, - 0.6807027153, - -0.08864708788, - 0.6704485923, - -0.1350735482, - -0.9381333003, - 0.9756655376, - 0.4231433671, - -0.4959787385, - 0.1005554325, - -0.7645857281, - -0.5859053796, - -0.9751154306, - -0.6972258572, - 0.7907012002, - -0.9109899213, - -0.9584307894, - -0.8269529333, - 0.2608264719, - -0.7773760119, - 0.7606456974, - -0.8961083758, - -0.9838134719, - 0.7338893576, - 0.2161226729, - 0.673509891, - -0.5512056873, - 0.6899744332, - 0.868004831, - 0.5897430311, - -0.8950444221, - -0.3595752773, - 0.8209486981, - -0.2912360132, - -0.9965011374, - 0.9766994634, - 0.738790822, - -0.4730947722, - 0.8946479441, - -0.6943628971, - -0.6620468182, - -0.0887255502, - -0.7512250855, - -0.5322986898, - 0.5226295385, - 0.2296318375, - 0.7915307344, - -0.2756485999, - -0.6900234522, - 0.07090588086, - 0.5981278485, - 0.3033429312, - -0.7253142797, - -0.9855874307, - -0.1761843396, - -0.6438468325, - -0.9956136595, - 0.8541580762, - -0.9999807666, - -0.02152416253, - -0.8705983095, - -0.1197138014, - -0.992107781, - -0.9091181546, - 0.788610536, - -0.994636402, - 0.4211256853, - 0.3110430857, - -0.4031127839, - 0.7610684239, - 0.7685674467, - 0.152271555, - -0.9364648723, - 0.1681333739, - -0.3567427907, - -0.418445483, - -0.98774778, - 0.8705250765, - -0.8911701067, - -0.7315350966, - 0.6030885658, - -0.4149130821, - 0.7585339481, - 0.6963196535, - 0.8332685012, - -0.8086815232, - 0.7518116724, - -0.3490535894, - 0.6972110903, - -0.8795676928, - -0.6442331882, - 0.6610236811, - -0.9853565782, - -0.590338458, - 0.09843602117, - 0.5646534882, - -0.6023259233, - -0.3539248861, - 0.5132728656, - 0.9380385118, - -0.7599270056, - -0.7425936564, - -0.6679610562, - -0.3018497816, - 0.814478266, - 0.03777430269, - -0.7514235086, - 0.9662556939, - -0.4720194901, - -0.435054126, - 0.7091901235, - 0.929379209, - 0.9997434357, - 0.8306320299, - -0.9434019629, - -0.133133759, - 0.5048413216, - 0.3711995273, - 0.98552091, - 0.7401857005, - -0.9999981398, - -0.2144033253, - 0.4808624681, - -0.413835885, - 0.644229305, - 0.9626648696, - 0.1833665934, - 0.5794129, - 0.01404446873, - 0.4388494993, - 0.5213612322, - -0.5281609948, - -0.9745306846, - -0.9904373013, - 0.9100232252, - -0.9914057719, - 0.7892627765, - 0.3364421659, - -0.9416099764, - 0.7802732656, - 0.886302871, - 0.6524471291, - 0.5762186726, - -0.08987644664, - -0.2177026782, - -0.9720345052, - -0.05722538858, - 0.8105983127, - 0.3410261032, - 0.6452309645, - -0.7810612152, - 0.9989395718, - -0.808247815, - 0.6370177929, - 0.5844658772, - 0.2054070861, - 0.055960522, - -0.995827561, - 0.893409165, - -0.931516824, - 0.328969469, - -0.3193837488, - 0.7314755657, - -0.7913517714, - -0.2204109786, - 0.9955900414, - -0.7112353139, - -0.7935008741, - -0.9961918204, - -0.9714163995, - -0.9566188669, - 0.2748495632, - -0.4681743221, - -0.9614449642, - 0.585194072, - 0.4532946061, - -0.9916113176, - 0.942479587, - -0.9813704753, - -0.6538429571, - 0.2923335053, - -0.2246660704, - -0.1800781949, - -0.9581216256, - 0.552215082, - -0.9296791922, - 0.643183699, - 0.9997325981, - -0.4606920354, - -0.2148721265, - 0.3482070809, - 0.3075517813, - 0.6274756393, - 0.8910881765, - -0.6397771309, - -0.4479080125, - -0.5247665011, - -0.8386507094, - 0.3901291416, - 0.1458336921, - 0.01624613149, - -0.8273199879, - 0.5611100679, - -0.8380219841, - -0.9856122234, - -0.861398618, - 0.6398413916, - 0.2694510795, - 0.4327334514, - -0.9960265354, - -0.939570655, - -0.8846996446, - 0.7642113189, - -0.7002080528, - 0.664508256, -]; - -#[allow(clippy::unreadable_literal)] -#[allow(clippy::excessive_precision)] -const CELL_2D_Y: [f32; 256] = [ - 0.7649700911, - 0.9967722885, - 0.05734160033, - -0.1610318741, - 0.371395799, - -0.7961420628, - 0.6076990492, - -0.9371723195, - 0.3324056156, - 0.07972205329, - -0.4857529277, - -0.9898503007, - 0.9036577593, - 0.05162417479, - -0.02545330525, - -0.998045976, - -0.7021653386, - -0.4524967717, - -0.9939885256, - -0.4875625128, - -0.9657481729, - -0.7432567015, - 0.02515761212, - 0.4743044842, - 0.5771254669, - 0.4449408324, - 0.3416365773, - 0.9970960285, - 0.6994034849, - 0.4917517499, - 0.286765333, - 0.8713868327, - 0.6172387009, - 0.9941540269, - 0.9632339851, - -0.7913613129, - 0.847515538, - 0.6211056739, - 0.5171924952, - -0.8198283277, - -0.1832084353, - 0.7054329737, - 0.7325597678, - 0.9960630973, - 0.7419559859, - 0.9908355749, - -0.346274329, - 0.2192641299, - -0.9060627411, - -0.8683346653, - 0.9949314574, - -0.6445220433, - -0.8103794704, - -0.2216977607, - 0.7168515217, - 0.612202264, - -0.412428616, - 0.285325116, - 0.56227115, - -0.9653857009, - -0.6290361962, - 0.6491672535, - 0.443835306, - -0.1791955706, - -0.6792690269, - -0.9763662173, - 0.7391782104, - 0.8343693968, - 0.7238337389, - 0.4965557504, - 0.8075909592, - -0.4459769977, - -0.9331160806, - -0.5710019572, - 0.9566512346, - -0.08357920318, - 0.2146116448, - -0.6739348049, - 0.8810115417, - 0.4467718167, - -0.7196250184, - -0.749462481, - 0.9960561112, - 0.6600461127, - -0.8465566164, - -0.8525598897, - -0.9732775654, - 0.6111293616, - -0.9612584717, - -0.7237870097, - -0.9974830104, - -0.8014006968, - 0.9528814544, - -0.6884178931, - -0.1691668301, - 0.9843571905, - 0.7651544003, - -0.09355982605, - -0.5200134429, - -0.006202125807, - -0.9997683284, - 0.4919944954, - -0.9928084436, - -0.1253880012, - -0.4165383308, - -0.6148930171, - -0.1034332049, - -0.9070022917, - -0.9503958117, - 0.9151503065, - -0.6486716073, - 0.6397687707, - -0.9883386937, - 0.3507613761, - 0.9857642561, - -0.9342026446, - -0.9082419159, - 0.1560587169, - 0.4921240607, - -0.453669308, - 0.6818037859, - 0.7976742329, - 0.9098610522, - 0.651633524, - 0.7177318024, - -0.5528685241, - 0.5882467118, - 0.6593778956, - 0.9371027648, - -0.7168658839, - -0.4757737632, - 0.7648291307, - 0.7503650398, - 0.1705063456, - -0.8071558121, - -0.9951433815, - -0.8253280792, - -0.7982502628, - 0.9352738503, - 0.8582254747, - -0.3465310238, - 0.65000842, - -0.6697422351, - 0.7441962291, - -0.9533555, - 0.5801940659, - -0.9992862963, - -0.659820211, - 0.2575848092, - 0.881588113, - -0.9004043022, - -0.7050172826, - 0.369126382, - -0.02265088836, - 0.5568217228, - -0.3316515286, - 0.991098079, - -0.863212164, - -0.9285531277, - 0.1695539323, - -0.672402505, - -0.001928841934, - 0.9767452145, - -0.8767960349, - 0.9103515037, - -0.7648324016, - 0.2706960452, - -0.9830446035, - 0.8150341657, - -0.9999013716, - -0.8985605806, - 0.8533360801, - 0.8491442537, - -0.2242541966, - -0.1379635899, - -0.4145572694, - 0.1308227633, - 0.6140555916, - 0.9417041303, - -0.336705587, - -0.6254387508, - 0.4631060578, - -0.7578342456, - -0.8172955655, - -0.9959529228, - -0.9760151351, - 0.2348380732, - -0.9983612848, - 0.5856025746, - -0.9400538266, - -0.7639875669, - 0.6244544645, - 0.04604054566, - 0.5888424828, - 0.7708490978, - -0.8114182882, - 0.9786766212, - -0.9984329822, - 0.09125496582, - -0.4492438803, - -0.3636982357, - 0.9443405575, - -0.9476254645, - -0.6818676535, - -0.6113610831, - 0.9754070948, - -0.0938108173, - -0.7029540015, - -0.6085691109, - -0.08718862881, - -0.237381926, - 0.2913423132, - 0.9614872426, - 0.8836361266, - -0.2749974196, - -0.8108932717, - -0.8913607575, - 0.129255541, - -0.3342637104, - -0.1921249337, - -0.7566302845, - -0.9563164339, - -0.9744358146, - 0.9836522982, - -0.2863615732, - 0.8337016872, - 0.3683701937, - 0.7657119102, - -0.02312427772, - 0.8875600535, - 0.976642191, - 0.9374176384, - 0.9515313457, - -0.7786361937, - -0.4538302125, - -0.7685604874, - -0.8940796454, - -0.8512462154, - 0.5446696133, - 0.9207601495, - -0.9893091197, - -0.9998680229, - 0.5617309299, - -0.8277411985, - 0.545636467, - 0.1690223212, - -0.5079295433, - 0.7685069899, - -0.9630140787, - 0.9015219132, - 0.08905695279, - -0.3423550559, - -0.4661614943, - -0.6449659371, - 0.7139388509, - 0.7472809229, -]; - -#[allow(clippy::unreadable_literal)] -#[allow(clippy::excessive_precision)] -const CELL_3D_X: [f32; 256] = [ - 0.3752498686, - 0.687188096, - 0.2248135212, - 0.6692006647, - -0.4376476931, - 0.6139972552, - 0.9494563929, - 0.8065108882, - -0.2218812853, - 0.8484661167, - 0.5551817596, - 0.2133903499, - 0.5195126593, - -0.6440141975, - -0.5192897331, - -0.3697654077, - -0.07927779647, - 0.4187757321, - -0.750078731, - 0.6579554632, - -0.6859803838, - -0.6878407087, - 0.9490848347, - 0.5795829433, - -0.5325976529, - -0.1363699466, - 0.417665879, - -0.9108236468, - 0.4438605427, - 0.819294887, - -0.4033873915, - -0.2817317705, - 0.3969665622, - 0.5323450134, - -0.6833017297, - 0.3881436661, - -0.7119144767, - -0.2306979838, - -0.9398873022, - 0.1701906676, - -0.4261839496, - -0.003712295499, - -0.734675004, - -0.3195046015, - 0.7345307424, - 0.9766246496, - -0.02003735175, - -0.4824156342, - 0.4245892007, - 0.9072427669, - 0.593346808, - -0.8911762541, - -0.7657571834, - -0.5268198896, - -0.8801903279, - -0.6296409617, - -0.09492481344, - -0.4920470525, - 0.7307666154, - -0.2514540636, - -0.3356210347, - -0.3522787894, - 0.87847885, - -0.7424096346, - 0.5757585274, - 0.4519299338, - 0.6420368628, - -0.1128478447, - 0.499874883, - 0.5291681739, - -0.5098837195, - 0.5639583502, - -0.8456386526, - -0.9657134875, - -0.576437342, - -0.5666013014, - 0.5667702405, - -0.481316582, - 0.7313389916, - -0.3805628566, - -0.6512675909, - -0.2787156951, - 0.8648059114, - -0.9730216276, - -0.8335820906, - 0.2673159641, - 0.231150148, - 0.01286214638, - 0.6774953261, - 0.6542885718, - -0.02545450161, - 0.2101238586, - -0.5572105885, - 0.813705672, - -0.7546026951, - -0.2502500006, - -0.9979289381, - 0.7024037039, - 0.08990874624, - 0.8170812432, - 0.4226980265, - -0.2442153475, - -0.9183326731, - 0.6068222411, - 0.818676691, - -0.7236735282, - -0.5383903295, - -0.6269337242, - -0.0939331121, - 0.9203878539, - -0.7256396824, - 0.6292431149, - 0.4234156978, - 0.006685688024, - -0.2598694113, - 0.6408036421, - 0.05899871622, - 0.7090281418, - -0.5905222072, - 0.3128214264, - -0.691925826, - 0.3634019349, - -0.6772511147, - -0.3204583896, - -0.3906740409, - -0.3342190395, - -0.517779592, - -0.6817711267, - 0.6422383105, - 0.4388482478, - 0.2968562611, - -0.2019778353, - 0.6014865048, - 0.9519280722, - 0.3398889569, - 0.8179709354, - 0.2365522154, - 0.3262175096, - -0.8060715954, - -0.2068642503, - 0.6208057279, - -0.5274282502, - -0.3722334928, - -0.8923412971, - 0.5341834201, - -0.3663701513, - -0.6114600319, - 0.5026307556, - 0.8396151729, - 0.9245042467, - -0.7994843957, - -0.5357200589, - -0.6283359739, - -0.61351886, - -0.875632008, - -0.5278879423, - 0.9087491985, - -0.03500215466, - -0.261365798, - -0.579523541, - -0.3765052689, - -0.74398252, - 0.4257318052, - -0.1214508921, - 0.8561809753, - 0.6802835104, - -0.5452131039, - -0.1997156478, - 0.4562348357, - -0.811704301, - 0.67793962, - -0.9237819106, - 0.6973511259, - -0.5189506, - 0.5517320032, - -0.396710831, - 0.5493762815, - -0.2507853002, - 0.4788634005, - 0.387333516, - -0.2176515694, - 0.6749832419, - 0.2148283022, - -0.7521815872, - 0.4697000159, - 0.7890593699, - -0.7606162952, - 0.01083397843, - 0.5254091908, - -0.6748025877, - 0.751091524, - 0.05259056135, - 0.01889481232, - -0.6037423727, - -0.6542965129, - 0.08873301081, - -0.6191345671, - 0.4331858488, - -0.3858351946, - -0.1429059747, - 0.4118221036, - -0.6247153214, - -0.611423014, - 0.5542939606, - -0.9432768808, - -0.4567870451, - -0.7349133547, - 0.399304489, - -0.7474927672, - 0.02589419753, - 0.783915821, - 0.6138668752, - 0.4276376047, - -0.4347886353, - 0.02947841302, - -0.833742746, - 0.3817221742, - -0.8743368359, - -0.3823443796, - -0.6829243811, - -0.3681903049, - -0.367626833, - -0.434583373, - 0.235891995, - -0.6874880269, - -0.5115661773, - -0.5534962601, - 0.5632777056, - 0.686191532, - -0.05095871588, - -0.06865785057, - -0.5975288531, - -0.6429790056, - -0.3729361548, - 0.2237917666, - 0.6046773225, - -0.5041542295, - -0.03972191174, - 0.7028828406, - -0.5560856498, - 0.5898328456, - -0.9308076766, - 0.4617069864, - 0.3190983137, - 0.9116567753, - -0.45029554, - 0.3346334459, - 0.8525005645, - 0.2528483381, - -0.8306630147, - -0.6880390622, - 0.7448684026, - -0.1963355843, - -0.5900257974, - 0.9097057294, - -0.2509196808, -]; - -#[allow(clippy::unreadable_literal)] -#[allow(clippy::excessive_precision)] -const CELL_3D_Y: [f32; 256] = [ - -0.6760585049, - -0.09136176499, - 0.1681325679, - -0.6688468686, - -0.4822753902, - -0.7891068824, - -0.1877509944, - 0.548470914, - -0.463339443, - -0.4050542082, - 0.3218158513, - 0.2546493823, - -0.3753271935, - 0.4745384887, - 0.481254652, - -0.8934416489, - -0.6737085076, - 0.7469917228, - 0.3826230411, - 0.6751013678, - -0.7248119515, - -0.3224276742, - -0.02076190936, - -0.6404268166, - -0.5292028444, - 0.7151414636, - -0.6144655059, - -0.369912124, - 0.6942067212, - -0.4481558248, - -0.6366894559, - 0.5956568471, - 0.564274539, - 0.7145584688, - 0.6871918316, - 0.5657918509, - -0.6275978114, - 0.4146983062, - 0.2638993789, - -0.792633138, - 0.5706133514, - 0.8606546462, - 0.6490900316, - -0.8242699196, - 0.6765819124, - 0.1959534069, - -0.8426769757, - -0.5917672797, - 0.7517364266, - 0.03252559226, - 0.0883617105, - 0.4475064813, - -0.1418643552, - 0.7343428473, - 0.3870192548, - -0.7716703522, - 0.4839898327, - 0.7437439055, - -0.5989573348, - -0.8357068955, - 0.6086049038, - 0.9194627258, - 0.4718297238, - -0.2650335884, - -0.6470352599, - -0.5555181303, - 0.1222351235, - 0.7802044684, - -0.8636947022, - -0.2341352163, - 0.683030874, - -0.5005858287, - 0.2334616211, - 0.2576877608, - 0.6666816727, - -0.7663996863, - 0.794201982, - 0.6189308788, - 0.6071033261, - -0.4206058253, - -0.3957336915, - -0.8170257484, - -0.1043240417, - 0.0002167596213, - 0.1816339018, - -0.6838094939, - -0.2495341969, - -0.7116756954, - -0.03361673621, - -0.3350836431, - 0.2137186039, - 0.2557996786, - 0.7490117093, - 0.4942936549, - -0.352686853, - -0.3952445435, - -0.0459964767, - -0.7115787471, - 0.08022899756, - 0.5362268157, - -0.8258613686, - 0.1114171723, - 0.3882823051, - -0.7915404457, - 0.3250957662, - 0.6401346464, - -0.2662724517, - -0.6727907114, - -0.994730818, - -0.3596358977, - 0.2344610069, - -0.6645215546, - -0.7107590611, - -0.4646617327, - 0.6717191355, - 0.5101893498, - 0.1185768238, - 0.236005093, - -0.7811024061, - 0.5089325193, - 0.6073187658, - -0.7930732557, - -0.6822767155, - 0.3201532885, - 0.7545302807, - 0.1072664448, - 0.6784033173, - -0.6595924967, - 0.7276509498, - 0.5586689436, - -0.6498636788, - 0.6789333174, - 0.7105966551, - -0.2872214155, - 0.496746217, - -0.3880337977, - 0.7324070604, - -0.9326634749, - -0.5867839255, - 0.8003043651, - -0.1631882481, - -0.6796374681, - -0.8066678503, - 0.4238177418, - 0.7715863549, - 0.5455367347, - -0.03205115397, - -0.6005545066, - -0.5423640002, - 0.3569205906, - -0.582071752, - 0.6407354361, - 0.7777142984, - -0.09956428618, - 0.1100002681, - 0.8136349123, - 0.2923431904, - 0.9735794425, - 0.8324974864, - -0.6179617717, - -0.9248386523, - -0.6448780771, - -0.5274402761, - -0.7862170565, - 0.2682099744, - -0.5848777694, - -0.6364561467, - -0.7167402514, - -0.8677012494, - 0.4205286707, - -0.7007832749, - 0.243272451, - -0.1899846085, - -0.6146124977, - -0.8093357692, - -0.03545096987, - -0.7191590868, - 0.7478645848, - 0.3623517328, - 0.8436992512, - -0.2445711729, - 0.6897356637, - -0.1708070787, - 0.4639272368, - -0.7917186656, - 0.02980025428, - 0.6334156172, - -0.9815544807, - -0.2307217304, - 0.1080823318, - 0.5167601798, - -0.845120016, - 0.441572562, - 0.5876789172, - -0.6365908737, - 0.68350166, - 0.5849723959, - 0.1164114357, - -0.7379813884, - -0.9613237178, - -0.9071943084, - -0.7682111105, - 0.639074459, - -0.619358298, - 0.2807257131, - -0.01800868791, - 0.3776607289, - 0.7207567823, - 0.5536661486, - -0.9974053117, - -0.02047200006, - -0.6739453804, - -0.5607471297, - 0.8815553192, - 0.8275977415, - 0.3928902456, - 0.550991396, - 0.4247623676, - -0.3436948871, - -0.3653537677, - 0.3181702902, - -0.6067173171, - -0.8984128477, - 0.4220839766, - 0.7238407199, - -0.7766913695, - 0.6460037842, - 0.2544775664, - 0.6488840578, - 0.805016833, - -0.9183807036, - 0.4144046357, - 0.270587208, - -0.8813684494, - 0.6985971877, - -0.7795603017, - -0.8624480731, - 0.5532697017, - 0.711179521, - -0.7798160574, - 0.5225859041, - 0.1261859368, - 0.3398033582, - -0.7472173667, - -0.4032647119, - -0.4246578154, - 0.8481212377, - -0.2144838537, - 0.3431714491, - 0.5310188231, - 0.6682978632, - 0.3110433206, - 0.9263293599, - -0.6155600569, - 0.07169784399, - 0.8985888773, -]; - -#[allow(clippy::unreadable_literal)] -#[allow(clippy::excessive_precision)] -const CELL_3D_Z: [f32; 256] = [ - -0.6341391283, - -0.7207118346, - 0.9597866014, - 0.3237504235, - -0.7588642466, - -0.01782410481, - 0.2515593809, - 0.2207257205, - -0.8579541106, - 0.3406410681, - 0.7669470462, - -0.9431957648, - 0.7676171537, - -0.6000491115, - -0.7062096948, - 0.2550207115, - 0.7347325213, - 0.5163625202, - -0.5394270162, - 0.3336656285, - -0.0638635111, - -0.6503195787, - 0.3143356798, - -0.5039217245, - 0.6605180464, - -0.6855479011, - -0.6693185756, - 0.1832083647, - -0.5666258437, - 0.3576482138, - -0.6571949095, - -0.7522101635, - -0.7238865886, - 0.4538887323, - 0.2467106257, - 0.7274778869, - 0.3151170655, - -0.8802293764, - -0.2167232729, - 0.5854637865, - 0.7019741052, - 0.5091756071, - 0.1973189533, - 0.46743546, - 0.05197599597, - 0.088354718, - 0.5380464843, - -0.6458224544, - -0.5045952393, - 0.419347884, - 0.8000823542, - -0.07445020656, - -0.6272881641, - -0.428020311, - -0.2747382083, - -0.08987283726, - 0.8699098354, - 0.4524761885, - -0.3274603257, - 0.4882262167, - -0.7189983256, - 0.1746079907, - 0.0751772698, - -0.6152927202, - 0.4998474673, - -0.6979677227, - 0.7568667263, - -0.6152612058, - 0.06447140991, - -0.8155744872, - -0.5229602449, - 0.6567836838, - -0.4799905631, - 0.03153534591, - 0.4724992466, - -0.3026458097, - -0.2191225827, - -0.620692287, - 0.3107552588, - 0.8235670294, - 0.6474915988, - -0.5047637941, - 0.4911488878, - -0.2307138167, - -0.5216800015, - 0.6789305939, - 0.9403734863, - 0.702390397, - 0.7347584625, - 0.6779567958, - 0.9765635805, - -0.9436177661, - -0.358465925, - -0.3058706624, - 0.5533414464, - -0.8838306897, - 0.04496841812, - 0.01687374963, - -0.9927133148, - -0.211752318, - 0.3732015249, - 0.9632990593, - -0.07682417004, - -0.07232213047, - 0.4733721775, - 0.2579229713, - 0.7995216286, - 0.3928189967, - 0.04107517667, - 0.1534542912, - 0.6468965045, - 0.4030684878, - -0.5617300988, - -0.885463029, - 0.693729985, - -0.5736527866, - -0.9911905409, - -0.66451538, - 0.2028855685, - 0.8019541421, - -0.3903877149, - -0.4888495114, - -0.2753714057, - -0.8915202143, - 0.5273119089, - 0.9363714773, - -0.5212228249, - -0.31642672, - 0.2409440761, - -0.703776404, - -0.6996810411, - -0.7058714505, - -0.3650566783, - 0.1064744278, - 0.7985729102, - 0.424680257, - -0.6384535592, - 0.1540161646, - -0.07702731943, - -0.5627789132, - -0.7667919169, - -0.509815999, - 0.4590525092, - 0.1552595611, - 0.345402042, - 0.7537656024, - 0.7906259247, - -0.6218493452, - 0.02979350071, - -0.1337893489, - -0.1483818606, - 0.549965562, - 0.01882482408, - -0.7833783002, - 0.4702855809, - 0.2435827372, - 0.2978428332, - 0.2256499906, - 0.4885036897, - 0.5312962584, - 0.05401156992, - 0.1749922158, - -0.7352273018, - 0.6058980284, - 0.4416079111, - 0.4417378638, - 0.5455879807, - -0.6681295324, - 0.1973431441, - 0.4053292055, - 0.2220375492, - 0.2957118467, - 0.6910913512, - 0.5940890106, - -0.2014135283, - -0.9172588213, - -0.4254361401, - -0.6146586825, - -0.7996193253, - -0.3716777111, - -0.9448876842, - -0.2620349924, - 0.9615995749, - -0.4679683524, - 0.3905937144, - 0.613593722, - 0.1422937358, - 0.1908754211, - 0.8189704912, - -0.7300408736, - -0.4108776451, - -0.5319834504, - -0.8970265651, - -0.5386359045, - 0.4082255906, - 0.7245356676, - 0.5239080873, - -0.8937552226, - -0.553637673, - 0.2354455182, - -0.0860293075, - -0.1399373318, - -0.4666323327, - 0.5560157407, - 0.1772619533, - -0.8893937725, - -0.5632714576, - -0.5666264959, - -0.3670263736, - -0.06717242579, - 0.6205295181, - -0.4110536264, - 0.7090054553, - 0.183899597, - -0.5605470555, - 0.3879565548, - 0.7420893903, - -0.2347595118, - -0.8577217497, - 0.6325590203, - -0.8736152276, - 0.7048011129, - -0.06317948268, - 0.8753285574, - -0.05843650473, - -0.3674922622, - -0.5256624401, - 0.7861039337, - 0.3287714416, - 0.5910593099, - -0.3896960134, - 0.6864605361, - 0.7164918431, - -0.290014277, - -0.6796169617, - 0.1632515592, - 0.04485347486, - 0.8320545697, - 0.01339408056, - -0.2874989857, - 0.615630723, - 0.3430367014, - 0.8193658136, - -0.5829600957, - 0.07911697781, - 0.7854296063, - -0.4107442306, - 0.4766964066, - -0.9045999527, - -0.1673856787, - 0.2828077348, - -0.5902737632, - -0.321506229, - -0.5224513133, - -0.4090169985, - -0.3599685311, -]; - -const FN_CELLULAR_INDEX_MAX: usize = 3; const X_PRIME: i32 = 1619; const Y_PRIME: i32 = 31337; const Z_PRIME: i32 = 6971; -#[allow(dead_code)] const W_PRIME: i32 = 1013; -const F3: f32 = 1.0 / 3.0; -const G3: f32 = 1.0 / 6.0; -#[allow(clippy::excessive_precision)] -#[allow(clippy::unreadable_literal)] -const SQRT3: f32 = 1.7320508075688772935274463415059; -const F2: f32 = 0.5 * (SQRT3 - 1.0); -const G2: f32 = (3.0 - SQRT3) / 6.0; -#[allow(dead_code)] -#[allow(clippy::excessive_precision)] -#[allow(clippy::unreadable_literal)] -const F4: f32 = (2.23606797749979 - 1.0) / 4.0; -#[allow(dead_code)] -#[allow(clippy::excessive_precision)] -#[allow(clippy::unreadable_literal)] -const G4: f32 = (5.0 - 2.23606797749979) / 20.0; -const CUBIC_3D_BOUNDING: f32 = 1.0 / (1.5 * 1.5 * 1.5); -const CUBIC_2D_BOUNDING: f32 = 1.0 / 1.5 * 1.5; - -// Utility functions -fn fast_floor(f: f32) -> i32 { - if f >= 0.0 { f as i32 } else { f as i32 - 1 } -} -fn fast_round(f: f32) -> i32 { - if f >= 0.0 { - (f + 0.5) as i32 - } else { - (f - 0.5) as i32 +impl Default for FastNoise { + fn default() -> Self { + Self::new() } } -#[allow(dead_code)] -fn fast_abs(i: i32) -> i32 { - i32::abs(i) -} - -fn fast_abs_f(i: f32) -> f32 { - f32::abs(i) -} - -fn lerp(a: f32, b: f32, t: f32) -> f32 { - a + t * (b - a) -} - -fn interp_hermite_func(t: f32) -> f32 { - t * t * (3. - 2. * t) -} - -fn interp_quintic_func(t: f32) -> f32 { - t * t * t * (t * (t * 6. - 15.) + 10.) -} - -#[allow(clippy::many_single_char_names)] -fn cubic_lerp(a: f32, b: f32, c: f32, d: f32, t: f32) -> f32 { - let p = (d - c) - (a - b); - t * t * t * p + t * t * ((a - b) - p) + t * (c - a) + b -} - -#[allow(clippy::unreadable_literal)] -#[allow(clippy::new_without_default)] impl FastNoise { /// Creates a new noise instance, using simplex noise defaults. pub fn new() -> FastNoise { - let mut noise = FastNoise { - rng: RandomNumberGenerator::seeded(1337), - seed: 1337, - frequency: 1.0, - interp: Interp::Quintic, - noise_type: NoiseType::Simplex, - octaves: 3, - lacunarity: 2.0, - gain: 0.5, - fractal_type: FractalType::FBM, - cellular_distance_function: CellularDistanceFunction::Euclidean, - cellular_return_type: CellularReturnType::CellValue, - cellular_distance_index: (0, 1), - cellular_jitter: 0.45, - gradient_perturb_amp: 1.0, - perm: vec![0; 512], - perm12: vec![0; 512], - fractal_bounding: 0.0, - }; - noise.set_seed(1337); - noise.calculate_fractal_bounding(); - noise + Self::seeded(1337) } /// Creates a new noise instance, using simplex noise defaults and specifying a random seed. pub fn seeded(seed: u64) -> FastNoise { let mut noise = FastNoise { - rng: RandomNumberGenerator::seeded(seed), + inner: FastNoiseLite::with_seed(to_fnl_seed(seed)), seed, frequency: 0.0, interp: Interp::Quintic, @@ -1769,2423 +109,321 @@ impl FastNoise { cellular_distance_index: (0, 1), cellular_jitter: 0.45, gradient_perturb_amp: 1.0, - perm: vec![0; 512], - perm12: vec![0; 512], - fractal_bounding: 0.0, }; - noise.set_seed(seed); - noise.calculate_fractal_bounding(); + + noise.sync_inner_settings(); noise } + fn sync_inner_settings(&mut self) { + self.inner.set_seed(Some(to_fnl_seed(self.seed))); + self.inner.set_frequency(Some(self.frequency)); + self.inner + .set_noise_type(Some(map_noise_type(self.noise_type))); + + let fractal_type = if is_fractal_noise_type(self.noise_type) { + map_fractal_type(self.fractal_type) + } else { + fnl::FractalType::None + }; + + self.inner.set_fractal_type(Some(fractal_type)); + self.inner.set_fractal_octaves(Some(self.octaves.max(1))); + self.inner.set_fractal_lacunarity(Some(self.lacunarity)); + self.inner.set_fractal_gain(Some(self.gain)); + + self.inner + .set_cellular_distance_function(Some(map_cellular_distance_function( + self.cellular_distance_function, + ))); + self.inner + .set_cellular_return_type(Some(map_cellular_return_type(self.cellular_return_type))); + self.inner.set_cellular_jitter(Some(self.cellular_jitter)); + } + /// Re-seeds the noise system with a new seed. pub fn set_seed(&mut self, seed: u64) { self.seed = seed; - self.rng = RandomNumberGenerator::seeded(seed); - - for i in 0..=255 { - self.perm[i as usize] = i; - } - - for j in 0..256 { - let rng = self.rng.next_u64() % (256 - j); - let k = rng + j; - let l = self.perm[j as usize]; - self.perm[j as usize] = self.perm[k as usize]; - self.perm[j as usize + 256] = self.perm[k as usize]; - self.perm[k as usize] = l; - self.perm12[j as usize] = self.perm[j as usize] % 12; - self.perm12[j as usize + 256] = self.perm[j as usize] % 12; - } + self.sync_inner_settings(); } pub fn get_seed(&self) -> u64 { self.seed } + pub fn set_frequency(&mut self, frequency: f32) { - self.frequency = frequency + self.frequency = frequency; + self.sync_inner_settings(); } + pub fn get_frequency(&self) -> f32 { self.frequency } + pub fn set_interp(&mut self, interp: Interp) { - self.interp = interp + self.interp = interp; } + pub fn get_interp(&self) -> Interp { self.interp } + pub fn set_noise_type(&mut self, nt: NoiseType) { - self.noise_type = nt + self.noise_type = nt; + self.sync_inner_settings(); } + pub fn get_noise_type(&self) -> NoiseType { self.noise_type } + pub fn set_fractal_octaves(&mut self, octaves: i32) { self.octaves = octaves; - self.calculate_fractal_bounding(); + self.sync_inner_settings(); } + pub fn get_fractal_octaves(&self) -> i32 { self.octaves } + pub fn set_fractal_lacunarity(&mut self, lacunarity: f32) { - self.lacunarity = lacunarity + self.lacunarity = lacunarity; + self.sync_inner_settings(); } + pub fn get_fractal_lacunarity(&self) -> f32 { self.lacunarity } + pub fn set_fractal_gain(&mut self, gain: f32) { self.gain = gain; - self.calculate_fractal_bounding(); + self.sync_inner_settings(); } + pub fn get_fractal_gain(&self) -> f32 { self.gain } + pub fn set_fractal_type(&mut self, fractal_type: FractalType) { - self.fractal_type = fractal_type + self.fractal_type = fractal_type; + self.sync_inner_settings(); } + pub fn get_fractal_type(&self) -> FractalType { self.fractal_type } + pub fn set_cellular_distance_function( &mut self, cellular_distance_function: CellularDistanceFunction, ) { - self.cellular_distance_function = cellular_distance_function + self.cellular_distance_function = cellular_distance_function; + self.sync_inner_settings(); } + pub fn get_cellular_distance_function(&self) -> CellularDistanceFunction { self.cellular_distance_function } + pub fn set_cellular_return_type(&mut self, cellular_return_type: CellularReturnType) { - self.cellular_return_type = cellular_return_type + self.cellular_return_type = cellular_return_type; + self.sync_inner_settings(); } + pub fn get_cellular_return_type(&self) -> CellularReturnType { self.cellular_return_type } + pub fn get_cellular_distance_indices(&self) -> (i32, i32) { self.cellular_distance_index } + + pub fn set_cellular_distance_indices(&mut self, i1: i32, i2: i32) { + let min = i32::min(i1, i2).clamp(0, FN_CELLULAR_INDEX_MAX); + let max = i32::max(i1, i2).clamp(0, FN_CELLULAR_INDEX_MAX); + + self.cellular_distance_index = (min, max); + } + pub fn set_cellular_jitter(&mut self, jitter: f32) { - self.cellular_jitter = jitter + self.cellular_jitter = jitter; + self.sync_inner_settings(); } + pub fn get_cellular_jitter(&self) -> f32 { self.cellular_jitter } + pub fn set_gradient_perterb_amp(&mut self, gradient_perturb_amp: f32) { - self.gradient_perturb_amp = gradient_perturb_amp + self.gradient_perturb_amp = gradient_perturb_amp; } + pub fn get_gradient_perterb_amp(&self) -> f32 { self.gradient_perturb_amp } - fn calculate_fractal_bounding(&mut self) { - let mut amp: f32 = self.gain; - let mut amp_fractal: f32 = 1.0; - for _ in 0..self.octaves { - amp_fractal += amp; - amp *= self.gain; + pub fn get_noise(&self, x: f32, y: f32) -> f32 { + match self.noise_type { + NoiseType::WhiteNoise => self.get_white_noise(x, y), + _ => self.inner.get_noise_2d(x, y), } - self.fractal_bounding = 1.0 / amp_fractal; } - pub fn set_cellular_distance_indices(&mut self, i1: i32, i2: i32) { - self.cellular_distance_index.0 = i32::min(i1, i2); - self.cellular_distance_index.1 = i32::max(i1, i2); - - self.cellular_distance_index.0 = i32::min( - i32::max(self.cellular_distance_index.0, 0), - FN_CELLULAR_INDEX_MAX as i32, - ); - self.cellular_distance_index.1 = i32::min( - i32::max(self.cellular_distance_index.1, 0), - FN_CELLULAR_INDEX_MAX as i32, - ); + pub fn get_noise3d(&self, x: f32, y: f32, z: f32) -> f32 { + match self.noise_type { + NoiseType::WhiteNoise => self.get_white_noise3d(x, y, z), + _ => self.inner.get_noise_3d(x, y, z), + } } pub fn index2d_12(&self, offset: u8, x: i32, y: i32) -> u8 { - self.perm12[(x & 0xff) as usize + self.perm[(y & 0xff) as usize + offset as usize] as usize] + self.hash_2d(offset, x, y) % 12 } pub fn index3d_12(&self, offset: u8, x: i32, y: i32, z: i32) -> u8 { - self.perm12[(x as usize & 0xff) - + self.perm - [(y as usize & 0xff) + self.perm[(z as usize & 0xff) + offset as usize] as usize] - as usize] + self.hash_3d(offset, x, y, z) % 12 } pub fn index4d_32(&self, offset: u8, x: i32, y: i32, z: i32, w: i32) -> u8 { - self.perm[(x as usize & 0xff) - + self.perm[(y as usize & 0xff) - + self.perm[(z as usize & 0xff) - + self.perm[(w as usize & 0xff) + offset as usize] as usize] - as usize] as usize] - & 31 + self.hash_4d(offset, x, y, z, w) & 31 } pub fn index2d_256(&self, offset: u8, x: i32, y: i32) -> u8 { - self.perm[(x as usize & 0xff) + self.perm[(y as usize & 0xff) + offset as usize] as usize] + self.hash_2d(offset, x, y) } pub fn index3d_256(&self, offset: u8, x: i32, y: i32, z: i32) -> u8 { - self.perm[(x as usize & 0xff) - + self.perm - [(y as usize & 0xff) + self.perm[(z as usize & 0xff) + offset as usize] as usize] - as usize] + self.hash_3d(offset, x, y, z) } pub fn index4d_256(&self, offset: u8, x: i32, y: i32, z: i32, w: i32) -> u8 { - self.perm[(x as usize & 0xff) - + self.perm[(y as usize & 0xff) - + self.perm[(z as usize & 0xff) - + self.perm[(w as usize & 0xff) + offset as usize] as usize] - as usize] as usize] - } - - fn val_coord_2d(&self, seed: i32, x: i32, y: i32) -> f32 { - use std::num::Wrapping; - - let mut n = Wrapping(seed); - n ^= Wrapping(X_PRIME) * Wrapping(x); - n ^= Wrapping(Y_PRIME) * Wrapping(y); - (n * n * n * Wrapping(60493i32)).0 as f32 / 2147483648.0 - } - - fn val_coord_3d(&self, seed: i32, x: i32, y: i32, z: i32) -> f32 { - use std::num::Wrapping; - - let mut n = Wrapping(seed); - n ^= Wrapping(X_PRIME) * Wrapping(x); - n ^= Wrapping(Y_PRIME) * Wrapping(y); - n ^= Wrapping(Z_PRIME) * Wrapping(z); - - (n * n * n * Wrapping(60493i32)).0 as f32 / 2147483648.0 - } - - #[allow(dead_code)] - #[allow(clippy::many_single_char_names)] - fn val_coord_4d(&self, seed: i32, x: i32, y: i32, z: i32, w: i32) -> f32 { - use std::num::Wrapping; - - let mut n = Wrapping(seed); - n ^= Wrapping(X_PRIME) * Wrapping(x); - n ^= Wrapping(Y_PRIME) * Wrapping(y); - n ^= Wrapping(Z_PRIME) * Wrapping(z); - n ^= Wrapping(W_PRIME) * Wrapping(w); - - (n * n * n * Wrapping(60493i32)).0 as f32 / 2147483648.0 - } - - fn val_coord_2d_fast(&self, offset: u8, x: i32, y: i32) -> f32 { - VAL_LUT[self.index2d_256(offset, x, y) as usize] - } - fn val_coord_3d_fast(&self, offset: u8, x: i32, y: i32, z: i32) -> f32 { - VAL_LUT[self.index3d_256(offset, x, y, z) as usize] - } - - fn grad_coord_2d(&self, offset: u8, x: i32, y: i32, xd: f32, yd: f32) -> f32 { - let lut_pos = self.index2d_12(offset, x, y) as usize; - xd * GRAD_X[lut_pos] + yd * GRAD_Y[lut_pos] - } - - #[allow(clippy::too_many_arguments)] - fn grad_coord_3d(&self, offset: u8, x: i32, y: i32, z: i32, xd: f32, yd: f32, zd: f32) -> f32 { - let lut_pos = self.index3d_12(offset, x, y, z) as usize; - xd * GRAD_X[lut_pos] + yd * GRAD_Y[lut_pos] + zd * GRAD_Z[lut_pos] - } - - #[allow(dead_code)] - #[allow(clippy::too_many_arguments)] - fn grad_coord_4d( - &self, - offset: u8, - x: i32, - y: i32, - z: i32, - w: i32, - xd: f32, - yd: f32, - zd: f32, - wd: f32, - ) -> f32 { - let lut_pos = self.index4d_32(offset, x, y, z, w) as usize; - xd * GRAD_4D[lut_pos] - + yd * GRAD_4D[lut_pos + 1] - + zd * GRAD_4D[lut_pos + 2] - + wd * GRAD_4D[lut_pos + 3] - } - - pub fn get_noise3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 { - x *= self.frequency; - y *= self.frequency; - z *= self.frequency; - - match self.noise_type { - NoiseType::Value => self.single_value3d(0, x, y, z), - NoiseType::ValueFractal => match self.fractal_type { - FractalType::FBM => self.single_value_fractal_fbm3d(x, y, z), - FractalType::Billow => self.single_value_fractal_billow3d(x, y, z), - FractalType::RigidMulti => self.single_value_fractal_rigid_multi3d(x, y, z), - }, - NoiseType::Perlin => self.single_perlin3d(0, x, y, z), - NoiseType::PerlinFractal => match self.fractal_type { - FractalType::FBM => self.single_perlin_fractal_fbm3d(x, y, z), - FractalType::Billow => self.single_perlin_fractal_billow3d(x, y, z), - FractalType::RigidMulti => self.single_perlin_fractal_rigid_multi3d(x, y, z), - }, - NoiseType::Simplex => self.single_simplex3d(0, x, y, z), - NoiseType::SimplexFractal => match self.fractal_type { - FractalType::FBM => self.single_simplex_fractal_fbm3d(x, y, z), - FractalType::Billow => self.single_simplex_fractal_billow3d(x, y, z), - FractalType::RigidMulti => self.single_simplex_fractal_rigid_multi3d(x, y, z), - }, - NoiseType::Cellular => match self.cellular_return_type { - CellularReturnType::CellValue => self.single_cellular3d(x, y, z), - CellularReturnType::Distance => self.single_cellular3d(x, y, z), - _ => self.single_cellular_2edge3d(x, y, z), - }, - NoiseType::WhiteNoise => self.get_white_noise3d(x, y, z), - NoiseType::Cubic => self.single_cubic3d(0, x, y, z), - NoiseType::CubicFractal => match self.fractal_type { - FractalType::FBM => self.single_cubic_fractal_fbm3d(x, y, z), - FractalType::Billow => self.single_cubic_fractal_billow3d(x, y, z), - FractalType::RigidMulti => self.single_cubic_fractal_rigid_multi3d(x, y, z), - }, - } - } - - pub fn get_noise(&self, mut x: f32, mut y: f32) -> f32 { - x *= self.frequency; - y *= self.frequency; - - match self.noise_type { - NoiseType::Value => self.single_value(0, x, y), - NoiseType::ValueFractal => match self.fractal_type { - FractalType::FBM => self.single_value_fractal_fbm(x, y), - FractalType::Billow => self.single_value_fractal_billow(x, y), - FractalType::RigidMulti => self.single_value_fractal_rigid_multi(x, y), - }, - NoiseType::Perlin => self.single_perlin(0, x, y), - NoiseType::PerlinFractal => match self.fractal_type { - FractalType::FBM => self.single_perlin_fractal_fbm(x, y), - FractalType::Billow => self.single_perlin_fractal_billow(x, y), - FractalType::RigidMulti => self.single_perlin_fractal_rigid_multi(x, y), - }, - NoiseType::Simplex => self.single_simplex(0, x, y), - NoiseType::SimplexFractal => match self.fractal_type { - FractalType::FBM => self.single_simplex_fractal_fbm(x, y), - FractalType::Billow => self.single_simplex_fractal_billow(x, y), - FractalType::RigidMulti => self.single_simplex_fractal_rigid_multi(x, y), - }, - NoiseType::Cellular => match self.cellular_return_type { - CellularReturnType::CellValue => self.single_cellular(x, y), - CellularReturnType::Distance => self.single_cellular(x, y), - _ => self.single_cellular_2edge(x, y), - }, - NoiseType::WhiteNoise => self.get_white_noise(x, y), - NoiseType::Cubic => self.single_cubic(0, x, y), - NoiseType::CubicFractal => match self.fractal_type { - FractalType::FBM => self.single_cubic_fractal_fbm(x, y), - FractalType::Billow => self.single_cubic_fractal_billow(x, y), - FractalType::RigidMulti => self.single_cubic_fractal_rigid_multi(x, y), - }, - } + self.hash_4d(offset, x, y, z, w) } - #[allow(dead_code)] - fn get_white_noise4d(&self, x: f32, y: f32, z: f32, w: f32) -> f32 { - let xc: i32 = x.to_bits() as i32; - let yc: i32 = y.to_bits() as i32; - let zc: i32 = z.to_bits() as i32; - let wc: i32 = w.to_bits() as i32; + fn get_white_noise(&self, x: f32, y: f32) -> f32 { + let xc = x.to_bits() as i32; + let yc = y.to_bits() as i32; - self.val_coord_4d( - self.seed as i32, - xc ^ (xc >> 16), - yc ^ (yc >> 16), - zc ^ (zc >> 16), - wc ^ (wc >> 16), - ) + val_coord_2d(to_fnl_seed(self.seed), xc ^ (xc >> 16), yc ^ (yc >> 16)) } fn get_white_noise3d(&self, x: f32, y: f32, z: f32) -> f32 { - let xc: i32 = x.to_bits() as i32; - let yc: i32 = y.to_bits() as i32; - let zc: i32 = z.to_bits() as i32; + let xc = x.to_bits() as i32; + let yc = y.to_bits() as i32; + let zc = z.to_bits() as i32; - self.val_coord_3d( - self.seed as i32, + val_coord_3d( + to_fnl_seed(self.seed), xc ^ (xc >> 16), yc ^ (yc >> 16), zc ^ (zc >> 16), ) } - fn get_white_noise(&self, x: f32, y: f32) -> f32 { - let xc: i32 = x.to_bits() as i32; - let yc: i32 = y.to_bits() as i32; - - self.val_coord_2d(self.seed as i32, xc ^ (xc >> 16), yc ^ (yc >> 16)) - } - - #[allow(dead_code)] - fn get_white_noise_int4d(&self, x: i32, y: i32, z: i32, w: i32) -> f32 { - self.val_coord_4d(self.seed as i32, x, y, z, w) - } - - #[allow(dead_code)] - fn get_white_noise_int3d(&self, x: i32, y: i32, z: i32) -> f32 { - self.val_coord_3d(self.seed as i32, x, y, z) - } - - #[allow(dead_code)] - fn get_white_noise_int(&self, x: i32, y: i32) -> f32 { - self.val_coord_2d(self.seed as i32, x, y) - } - - #[allow(dead_code)] - // Value noise - fn get_value_fractal3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 { - x *= self.frequency; - y *= self.frequency; - z *= self.frequency; - - match self.fractal_type { - FractalType::FBM => self.single_value_fractal_fbm3d(x, y, z), - FractalType::Billow => self.single_value_fractal_billow3d(x, y, z), - FractalType::RigidMulti => self.single_value_fractal_rigid_multi3d(x, y, z), - } - } - - #[allow(dead_code)] - fn get_value_fractal(&self, mut x: f32, mut y: f32) -> f32 { - x *= self.frequency; - y *= self.frequency; - - match self.fractal_type { - FractalType::FBM => self.single_value_fractal_fbm(x, y), - FractalType::Billow => self.single_value_fractal_billow(x, y), - FractalType::RigidMulti => self.single_value_fractal_rigid_multi(x, y), - } - } - - fn single_value_fractal_fbm3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 { - let mut sum: f32 = self.single_value3d(self.perm[0], x, y, z); - let mut amp = 1.0; - let mut i = 1; - - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - z *= self.lacunarity; - - amp *= self.gain; - sum += self.single_value3d(self.perm[i as usize], x, y, z) * amp; - - i += 1; - } - - sum * self.fractal_bounding - } - - fn single_value_fractal_billow3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 { - let mut sum: f32 = fast_abs_f(self.single_value3d(self.perm[0], x, y, z)) * 2.0 - 1.0; - let mut amp: f32 = 1.0; - let mut i: i32 = 1; - - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - z *= self.lacunarity; - - amp *= self.gain; - sum += - (fast_abs_f(self.single_value3d(self.perm[i as usize], x, y, z)) * 2.0 - 1.0) * amp; - - i += 1; - } - - sum * self.fractal_bounding - } - - fn single_value_fractal_rigid_multi3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 { - let mut sum: f32 = 1.0 - fast_abs_f(self.single_value3d(self.perm[0], x, y, z)); - let mut amp: f32 = 1.0; - let mut i = 1; - - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - z *= self.lacunarity; - - amp *= self.gain; - sum -= (1.0 - fast_abs_f(self.single_value3d(self.perm[i as usize], x, y, z))) * amp; - - i += 1; - } - sum - } - - #[allow(dead_code)] - fn get_value3d(&self, x: f32, y: f32, z: f32) -> f32 { - self.single_value3d( - 0, - x * self.frequency, - y * self.frequency, - z * self.frequency, - ) - } - - fn single_value3d(&self, offset: u8, x: f32, y: f32, z: f32) -> f32 { - let x0 = fast_floor(x); - let y0 = fast_floor(y); - let z0 = fast_floor(z); - let x1 = x0 + 1; - let y1 = y0 + 1; - let z1 = z0 + 1; - - let xs: f32; - let ys: f32; - let zs: f32; - match self.interp { - Interp::Linear => { - xs = x - x0 as f32; - ys = y - y0 as f32; - zs = z - z0 as f32; - } - Interp::Hermite => { - xs = interp_hermite_func(x - x0 as f32); - ys = interp_hermite_func(y - y0 as f32); - zs = interp_hermite_func(z - z0 as f32); - } - Interp::Quintic => { - xs = interp_quintic_func(x - x0 as f32); - ys = interp_quintic_func(y - y0 as f32); - zs = interp_quintic_func(z - z0 as f32); - } - } - - let xf00: f32 = lerp( - self.val_coord_3d_fast(offset, x0, y0, z0), - self.val_coord_3d_fast(offset, x1, y0, z0), - xs, - ); - let xf10: f32 = lerp( - self.val_coord_3d_fast(offset, x0, y1, z0), - self.val_coord_3d_fast(offset, x1, y1, z0), - xs, - ); - let xf01: f32 = lerp( - self.val_coord_3d_fast(offset, x0, y0, z1), - self.val_coord_3d_fast(offset, x1, y0, z1), - xs, - ); - let xf11: f32 = lerp( - self.val_coord_3d_fast(offset, x0, y1, z1), - self.val_coord_3d_fast(offset, x1, y1, z1), - xs, - ); - - let yf0: f32 = lerp(xf00, xf10, ys); - let yf1: f32 = lerp(xf01, xf11, ys); - - lerp(yf0, yf1, zs) - } - - fn single_value_fractal_fbm(&self, mut x: f32, mut y: f32) -> f32 { - let mut sum: f32 = self.single_value(self.perm[0], x, y); - let mut amp: f32 = 1.0; - let mut i = 1; - - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - - amp *= self.gain; - sum += self.single_value(self.perm[i as usize], x, y) * amp; - i += 1; - } - - sum * self.fractal_bounding - } - - fn single_value_fractal_billow(&self, mut x: f32, mut y: f32) -> f32 { - let mut sum: f32 = fast_abs_f(self.single_value(self.perm[0], x, y)) * 2.0 - 1.0; - let mut amp: f32 = 1.0; - let mut i = 1; - - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - amp *= self.gain; - sum += (fast_abs_f(self.single_value(self.perm[i as usize], x, y)) * 2.0 - 1.0) * amp; - i += 1; - } - - sum * self.fractal_bounding - } - - fn single_value_fractal_rigid_multi(&self, mut x: f32, mut y: f32) -> f32 { - let mut sum: f32 = 1.0 - fast_abs_f(self.single_value(self.perm[0], x, y)); - let mut amp: f32 = 1.0; - let mut i = 1; - - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - - amp *= self.gain; - sum -= (1.0 - fast_abs_f(self.single_value(self.perm[i as usize], x, y))) * amp; - i += 1; - } - - sum - } - - #[allow(dead_code)] - fn get_value(&self, x: f32, y: f32) -> f32 { - self.single_value(0, x * self.frequency, y * self.frequency) - } - - fn single_value(&self, offset: u8, x: f32, y: f32) -> f32 { - let x0 = fast_floor(x); - let y0 = fast_floor(y); - let x1 = x0 + 1; - let y1 = y0 + 1; - - let xs: f32; - let ys: f32; - match self.interp { - Interp::Linear => { - xs = x - x0 as f32; - ys = y - y0 as f32; - } - Interp::Hermite => { - xs = interp_hermite_func(x - x0 as f32); - ys = interp_hermite_func(y - y0 as f32); - } - Interp::Quintic => { - xs = interp_quintic_func(x - x0 as f32); - ys = interp_quintic_func(y - y0 as f32); - } - } - - let xf0 = lerp( - self.val_coord_2d_fast(offset, x0, y0), - self.val_coord_2d_fast(offset, x1, y0), - xs, - ); - let xf1 = lerp( - self.val_coord_2d_fast(offset, x0, y1), - self.val_coord_2d_fast(offset, x1, y1), - xs, - ); - - lerp(xf0, xf1, ys) - } - - // Perlin noise - - #[allow(dead_code)] - fn get_perlin_fractal3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 { - x *= self.frequency; - y *= self.frequency; - z *= self.frequency; - - match self.fractal_type { - FractalType::FBM => self.single_perlin_fractal_fbm3d(x, y, z), - FractalType::Billow => self.single_perlin_fractal_billow3d(x, y, z), - FractalType::RigidMulti => self.single_perlin_fractal_rigid_multi3d(x, y, z), - } - } - - fn single_perlin_fractal_fbm3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 { - let mut sum: f32 = self.single_perlin3d(self.perm[0], x, y, z); - let mut amp: f32 = 1.0; - let mut i = 1; - - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - z *= self.lacunarity; - - amp *= self.gain; - sum += self.single_perlin3d(self.perm[i as usize], x, y, z) * amp; - i += 1; - } - - sum * self.fractal_bounding - } - - fn single_perlin_fractal_billow3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 { - let mut sum: f32 = fast_abs_f(self.single_perlin3d(self.perm[0], x, y, z)) * 2.0 - 1.0; - let mut amp: f32 = 1.0; - let mut i = 1; - - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - z *= self.lacunarity; - - amp *= self.gain; - sum += (fast_abs_f(self.single_perlin3d(self.perm[i as usize], x, y, z)) * 2.0 - 1.0) - * amp; - i += 1; - } - - sum * self.fractal_bounding - } - - fn single_perlin_fractal_rigid_multi3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 { - let mut sum: f32 = 1.0 - fast_abs_f(self.single_perlin3d(self.perm[0], x, y, z)); - let mut amp: f32 = 1.0; - let mut i = 1; - - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - z *= self.lacunarity; - - amp *= self.gain; - sum -= (1.0 - fast_abs_f(self.single_perlin3d(self.perm[i as usize], x, y, z))) * amp; - - i += 1; - } - - sum - } - - #[allow(dead_code)] - fn get_perlin3d(&self, x: f32, y: f32, z: f32) -> f32 { - self.single_perlin3d( - 0, - x * self.frequency, - y * self.frequency, - z * self.frequency, - ) - } - - fn single_perlin3d(&self, offset: u8, x: f32, y: f32, z: f32) -> f32 { - let x0 = fast_floor(x); - let y0 = fast_floor(y); - let z0 = fast_floor(z); - let x1 = x0 + 1; - let y1 = y0 + 1; - let z1 = z0 + 1; - - let xs: f32; - let ys: f32; - let zs: f32; - - match self.interp { - Interp::Linear => { - xs = x - x0 as f32; - ys = y - y0 as f32; - zs = z - z0 as f32; - } - Interp::Hermite => { - xs = interp_hermite_func(x - x0 as f32); - ys = interp_hermite_func(y - y0 as f32); - zs = interp_hermite_func(z - z0 as f32); - } - Interp::Quintic => { - xs = interp_quintic_func(x - x0 as f32); - ys = interp_quintic_func(y - y0 as f32); - zs = interp_quintic_func(z - z0 as f32); - } - } - - let xd0 = x - x0 as f32; - let yd0 = y - y0 as f32; - let zd0 = z - z0 as f32; - let xd1 = xd0 - 1.0; - let yd1 = yd0 - 1.0; - let zd1 = zd0 - 1.0; + fn hash_2d(&self, offset: u8, x: i32, y: i32) -> u8 { + let seed = to_fnl_seed(self.seed).wrapping_add(offset as i32); + let value = val_coord_2d(seed, x, y); - let xf00 = lerp( - self.grad_coord_3d(offset, x0, y0, z0, xd0, yd0, zd0), - self.grad_coord_3d(offset, x1, y0, z0, xd1, yd0, zd0), - xs, - ); - let xf10 = lerp( - self.grad_coord_3d(offset, x0, y1, z0, xd0, yd1, zd0), - self.grad_coord_3d(offset, x1, y1, z0, xd1, yd1, zd0), - xs, - ); - let xf01 = lerp( - self.grad_coord_3d(offset, x0, y0, z1, xd0, yd0, zd1), - self.grad_coord_3d(offset, x1, y0, z1, xd1, yd0, zd1), - xs, - ); - let xf11 = lerp( - self.grad_coord_3d(offset, x0, y1, z1, xd0, yd1, zd1), - self.grad_coord_3d(offset, x1, y1, z1, xd1, yd1, zd1), - xs, - ); - - let yf0 = lerp(xf00, xf10, ys); - let yf1 = lerp(xf01, xf11, ys); - - lerp(yf0, yf1, zs) + ((value.abs() * 255.0) as u8).wrapping_add(offset) } - #[allow(dead_code)] - fn get_perlin_fractal(&self, mut x: f32, mut y: f32) -> f32 { - x *= self.frequency; - y *= self.frequency; + fn hash_3d(&self, offset: u8, x: i32, y: i32, z: i32) -> u8 { + let seed = to_fnl_seed(self.seed).wrapping_add(offset as i32); + let value = val_coord_3d(seed, x, y, z); - match self.fractal_type { - FractalType::FBM => self.single_perlin_fractal_fbm(x, y), - FractalType::Billow => self.single_perlin_fractal_billow(x, y), - FractalType::RigidMulti => self.single_perlin_fractal_rigid_multi(x, y), - } + ((value.abs() * 255.0) as u8).wrapping_add(offset) } - fn single_perlin_fractal_fbm(&self, mut x: f32, mut y: f32) -> f32 { - let mut sum = self.single_perlin(self.perm[0], x, y); - let mut amp = 1.0; - let mut i = 1; - - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; + fn hash_4d(&self, offset: u8, x: i32, y: i32, z: i32, w: i32) -> u8 { + let seed = to_fnl_seed(self.seed).wrapping_add(offset as i32); + let value = val_coord_4d(seed, x, y, z, w); - amp *= self.gain; - sum += self.single_perlin(self.perm[i as usize], x, y) * amp; - - i += 1; - } - - sum * self.fractal_bounding + ((value.abs() * 255.0) as u8).wrapping_add(offset) } +} - fn single_perlin_fractal_billow(&self, mut x: f32, mut y: f32) -> f32 { - let mut sum = fast_abs_f(self.single_perlin(self.perm[0], x, y)) * 2.0 - 1.0; - let mut amp = 1.0; - let mut i = 1; +fn to_fnl_seed(seed: u64) -> i32 { + seed as i32 +} - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; +fn map_noise_type(noise_type: NoiseType) -> fnl::NoiseType { + match noise_type { + NoiseType::Value | NoiseType::ValueFractal => fnl::NoiseType::Value, + NoiseType::Perlin | NoiseType::PerlinFractal => fnl::NoiseType::Perlin, - amp *= self.gain; - sum += (fast_abs_f(self.single_perlin(self.perm[i as usize], x, y)) * 2.0 - 1.0) * amp; - i += 1; - } + // The legacy Simplex implementation is mapped to FastNoiseLite's closest equivalent. + NoiseType::Simplex | NoiseType::SimplexFractal => fnl::NoiseType::OpenSimplex2, - sum * self.fractal_bounding + NoiseType::Cellular => fnl::NoiseType::Cellular, + NoiseType::Cubic | NoiseType::CubicFractal => fnl::NoiseType::ValueCubic, + NoiseType::WhiteNoise => fnl::NoiseType::Value, } +} - fn single_perlin_fractal_rigid_multi(&self, mut x: f32, mut y: f32) -> f32 { - let mut sum = 1.0 - fast_abs_f(self.single_perlin(self.perm[0], x, y)); - let mut amp = 1.0; - let mut i = 1; - - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - - amp *= self.gain; - sum -= (1.0 - fast_abs_f(self.single_perlin(self.perm[i as usize], x, y))) * amp; - i += 1; - } - - sum - } +fn is_fractal_noise_type(noise_type: NoiseType) -> bool { + matches!( + noise_type, + NoiseType::ValueFractal + | NoiseType::PerlinFractal + | NoiseType::SimplexFractal + | NoiseType::CubicFractal + ) +} - #[allow(dead_code)] - fn get_perlin(&self, x: f32, y: f32) -> f32 { - self.single_perlin(0, x * self.frequency, y * self.frequency) +fn map_fractal_type(fractal_type: FractalType) -> fnl::FractalType { + match fractal_type { + FractalType::FBM => fnl::FractalType::FBm, + FractalType::Billow => fnl::FractalType::PingPong, + FractalType::RigidMulti => fnl::FractalType::Ridged, } +} - fn single_perlin(&self, offset: u8, x: f32, y: f32) -> f32 { - let x0 = fast_floor(x); - let y0 = fast_floor(y); - let x1 = x0 + 1; - let y1 = y0 + 1; - - let xs: f32; - let ys: f32; - - match self.interp { - Interp::Linear => { - xs = x - x0 as f32; - ys = y - y0 as f32; - } - Interp::Hermite => { - xs = interp_hermite_func(x - x0 as f32); - ys = interp_hermite_func(y - y0 as f32); - } - Interp::Quintic => { - xs = interp_quintic_func(x - x0 as f32); - ys = interp_quintic_func(y - y0 as f32); - } - } - - let xd0 = x - x0 as f32; - let yd0 = y - y0 as f32; - let xd1 = xd0 - 1.0; - let yd1 = yd0 - 1.0; - - let xf0 = lerp( - self.grad_coord_2d(offset, x0, y0, xd0, yd0), - self.grad_coord_2d(offset, x1, y0, xd1, yd0), - xs, - ); - let xf1 = lerp( - self.grad_coord_2d(offset, x0, y1, xd0, yd1), - self.grad_coord_2d(offset, x1, y1, xd1, yd1), - xs, - ); - - lerp(xf0, xf1, ys) +fn map_cellular_distance_function( + function: CellularDistanceFunction, +) -> fnl::CellularDistanceFunction { + match function { + // The legacy Euclidean path used squared-distance behavior. + CellularDistanceFunction::Euclidean => fnl::CellularDistanceFunction::EuclideanSq, + CellularDistanceFunction::Manhattan => fnl::CellularDistanceFunction::Manhattan, + CellularDistanceFunction::Natural => fnl::CellularDistanceFunction::Hybrid, } +} - #[allow(dead_code)] - // Simplex noise - fn get_simplex_fractal3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 { - x *= self.frequency; - y *= self.frequency; - z *= self.frequency; - - match self.fractal_type { - FractalType::FBM => self.single_simplex_fractal_fbm3d(x, y, z), - FractalType::Billow => self.single_simplex_fractal_billow3d(x, y, z), - FractalType::RigidMulti => self.single_simplex_fractal_rigid_multi3d(x, y, z), - } +fn map_cellular_return_type(return_type: CellularReturnType) -> fnl::CellularReturnType { + match return_type { + CellularReturnType::CellValue => fnl::CellularReturnType::CellValue, + CellularReturnType::Distance => fnl::CellularReturnType::Distance, + CellularReturnType::Distance2 => fnl::CellularReturnType::Distance2, + CellularReturnType::Distance2Add => fnl::CellularReturnType::Distance2Add, + CellularReturnType::Distance2Sub => fnl::CellularReturnType::Distance2Sub, + CellularReturnType::Distance2Mul => fnl::CellularReturnType::Distance2Mul, + CellularReturnType::Distance2Div => fnl::CellularReturnType::Distance2Div, } +} - fn single_simplex_fractal_fbm3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 { - let mut sum = self.single_simplex3d(self.perm[0], x, y, z); - let mut amp = 1.0; - let mut i = 1; +fn val_coord_2d(seed: i32, x: i32, y: i32) -> f32 { + let mut n = Wrapping(seed); + n ^= Wrapping(X_PRIME) * Wrapping(x); + n ^= Wrapping(Y_PRIME) * Wrapping(y); - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - z *= self.lacunarity; + (n * n * n * Wrapping(60493)).0 as f32 / 2_147_483_648.0 +} - amp *= self.gain; - sum += self.single_simplex3d(self.perm[i as usize], x, y, z) * amp; - i += 1; - } +fn val_coord_3d(seed: i32, x: i32, y: i32, z: i32) -> f32 { + let mut n = Wrapping(seed); + n ^= Wrapping(X_PRIME) * Wrapping(x); + n ^= Wrapping(Y_PRIME) * Wrapping(y); + n ^= Wrapping(Z_PRIME) * Wrapping(z); - sum * self.fractal_bounding - } + (n * n * n * Wrapping(60493)).0 as f32 / 2_147_483_648.0 +} - fn single_simplex_fractal_billow3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 { - let mut sum = fast_abs_f(self.single_simplex3d(self.perm[0], x, y, z)) * 2.0 - 1.0; - let mut amp = 1.0; - let mut i = 1; +fn val_coord_4d(seed: i32, x: i32, y: i32, z: i32, w: i32) -> f32 { + let mut n = Wrapping(seed); + n ^= Wrapping(X_PRIME) * Wrapping(x); + n ^= Wrapping(Y_PRIME) * Wrapping(y); + n ^= Wrapping(Z_PRIME) * Wrapping(z); + n ^= Wrapping(W_PRIME) * Wrapping(w); - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - z *= self.lacunarity; - - amp *= self.gain; - sum += (fast_abs_f(self.single_simplex3d(self.perm[i as usize], x, y, z)) * 2.0 - 1.0) - * amp; - i += 1; - } - - sum * self.fractal_bounding - } - - fn single_simplex_fractal_rigid_multi3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 { - let mut sum = 1.0 - fast_abs_f(self.single_simplex3d(self.perm[0], x, y, z)); - let mut amp = 1.0; - let mut i = 1; - - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - z *= self.lacunarity; - - amp *= self.gain; - sum -= (1.0 - fast_abs_f(self.single_simplex3d(self.perm[i as usize], x, y, z))) * amp; - i += 1; - } - - sum - } - - #[allow(dead_code)] - fn get_simplex3d(&self, x: f32, y: f32, z: f32) -> f32 { - self.single_simplex3d( - 0, - x * self.frequency, - y * self.frequency, - z * self.frequency, - ) - } - - #[allow(clippy::many_single_char_names)] - #[allow(clippy::collapsible_if)] - #[allow(clippy::suspicious_else_formatting)] - fn single_simplex3d(&self, offset: u8, x: f32, y: f32, z: f32) -> f32 { - let mut t: f32 = (x + y + z) * F3; - let i = fast_floor(x + t); - let j = fast_floor(y + t); - let k = fast_floor(z + t); - - t = (i + j + k) as f32 * G3; - let x0 = i as f32 - t; - let y0 = j as f32 - t; - let z0 = k as f32 - t; - - let x0 = x - x0; - let y0 = y - y0; - let z0 = z - z0; - - let i1: f32; - let j1: f32; - let k1: f32; - let i2: f32; - let j2: f32; - let k2: f32; - - if x0 >= y0 { - if y0 >= z0 { - i1 = 1.; - j1 = 0.; - k1 = 0.; - i2 = 1.; - j2 = 1.; - k2 = 0.; - } else if x0 >= z0 { - i1 = 1.; - j1 = 0.; - k1 = 0.; - i2 = 1.; - j2 = 0.; - k2 = 1.; - } else - // x0 < z0 - { - i1 = 0.; - j1 = 0.; - k1 = 1.; - i2 = 1.; - j2 = 0.; - k2 = 1.; - } - } else - // x0 < y0 - { - if y0 < z0 { - i1 = 0.; - j1 = 0.; - k1 = 1.; - i2 = 0.; - j2 = 1.; - k2 = 1.; - } else if x0 < z0 { - i1 = 0.; - j1 = 1.; - k1 = 0.; - i2 = 0.; - j2 = 1.; - k2 = 1.; - } else - // x0 >= z0 - { - i1 = 0.; - j1 = 1.; - k1 = 0.; - i2 = 1.; - j2 = 1.; - k2 = 0.; - } - } - - let x1 = x0 - i1 + G3; - let y1 = y0 - j1 + G3; - let z1 = z0 - k1 + G3; - let x2 = x0 - i2 + 2.0 * G3; - let y2 = y0 - j2 + 2.0 * G3; - let z2 = z0 - k2 + 2.0 * G3; - let x3 = x0 - 1. + 3.0 * G3; - let y3 = y0 - 1. + 3.0 * G3; - let z3 = z0 - 1. + 3.0 * G3; - - t = 0.6 - x0 * x0 - y0 * y0 - z0 * z0; - let n0 = if t < 0. { - 0. - } else { - t *= t; - t * t * self.grad_coord_3d(offset, i, j, k, x0, y0, z0) - }; - - t = 0.6 - x1 * x1 - y1 * y1 - z1 * z1; - let n1 = if t < 0. { - 0. - } else { - t *= t; - t * t - * self.grad_coord_3d( - offset, - i + i1 as i32, - j + j1 as i32, - k + k1 as i32, - x1, - y1, - z1, - ) - }; - - t = 0.6 - x2 * x2 - y2 * y2 - z2 * z2; - let n2 = if t < 0. { - 0. - } else { - t *= t; - t * t - * self.grad_coord_3d( - offset, - i + i2 as i32, - j + j2 as i32, - k + k2 as i32, - x2, - y2, - z2, - ) - }; - - t = 0.6 - x3 * x3 - y3 * y3 - z3 * z3; - let n3 = if t < 0. { - 0. - } else { - t *= t; - t * t * self.grad_coord_3d(offset, i + 1, j + 1, k + 1, x3, y3, z3) - }; - - 32.0 * (n0 + n1 + n2 + n3) - } - - #[allow(dead_code)] - fn get_simplex_fractal(&self, mut x: f32, mut y: f32) -> f32 { - x *= self.frequency; - y *= self.frequency; - - match self.fractal_type { - FractalType::FBM => self.single_simplex_fractal_fbm(x, y), - FractalType::Billow => self.single_simplex_fractal_billow(x, y), - FractalType::RigidMulti => self.single_simplex_fractal_rigid_multi(x, y), - } - } - - fn single_simplex_fractal_fbm(&self, mut x: f32, mut y: f32) -> f32 { - let mut sum = self.single_simplex(self.perm[0], x, y); - let mut amp = 1.0; - let mut i = 1; - - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - - amp *= self.gain; - sum += self.single_simplex(self.perm[i as usize], x, y) * amp; - i += 1; - } - - sum * self.fractal_bounding - } - - fn single_simplex_fractal_billow(&self, mut x: f32, mut y: f32) -> f32 { - let mut sum = fast_abs_f(self.single_simplex(self.perm[0], x, y)) * 2.0 - 1.0; - let mut amp = 1.0; - let mut i = 1; - - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - - amp *= self.gain; - sum += (fast_abs_f(self.single_simplex(self.perm[i as usize], x, y)) * 2.0 - 1.0) * amp; - i += 1; - } - - sum * self.fractal_bounding - } - - fn single_simplex_fractal_rigid_multi(&self, mut x: f32, mut y: f32) -> f32 { - let mut sum = 1.0 - fast_abs_f(self.single_simplex(self.perm[0], x, y)); - let mut amp = 1.0; - let mut i = 1; - - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - - amp *= self.gain; - sum -= (1.0 - self.single_simplex(self.perm[i as usize], x, y)) * amp; - i += 1; - } - - sum - } - - #[allow(dead_code)] - fn single_simplex_fractal_blend(&self, mut x: f32, mut y: f32) -> f32 { - let mut sum = self.single_simplex(self.perm[0], x, y); - let mut amp = 1.0; - let mut i = 1; - - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - - amp *= self.gain; - sum += self.single_simplex(self.perm[i as usize], x, y) * amp + 1.0; - i += 1; - } - - sum * self.fractal_bounding - } - - #[allow(dead_code)] - fn get_simplex(&self, x: f32, y: f32) -> f32 { - self.single_simplex(0, x * self.frequency, y * self.frequency) - } - - #[allow(clippy::many_single_char_names)] - fn single_simplex(&self, offset: u8, x: f32, y: f32) -> f32 { - let mut t: f32 = (x + y) * F2; - let i = fast_floor(x + t); - let j = fast_floor(y + t); - - t = (i + j) as f32 * G2; - let x0 = i as f32 - t; - let y0 = j as f32 - t; - - let x0 = x - x0; - let y0 = y - y0; - - let (i1, j1) = if x0 > y0 { (1, 0) } else { (0, 1) }; - - let x1 = x0 - i1 as f32 + G2; - let y1 = y0 - j1 as f32 + G2; - let x2 = x0 - 1.0 + 2.0 * G2; - let y2 = y0 - 1.0 + 2.0 * G2; - - t = 0.5 - x0 * x0 - y0 * y0; - let n0 = if t < 0. { - 0. - } else { - t *= t; - t * t * self.grad_coord_2d(offset, i, j, x0, y0) - }; - - t = 0.5 - x1 * x1 - y1 * y1; - let n1 = if t < 0. { - 0. - } else { - t *= t; - t * t * self.grad_coord_2d(offset, i + i1, j + j1, x1, y1) - }; - - t = 0.5 - x2 * x2 - y2 * y2; - let n2 = if t < 0. { - 0. - } else { - t *= t; - t * t * self.grad_coord_2d(offset, i + 1, j + 1, x2, y2) - }; - - 70.0 * (n0 + n1 + n2) - } - - #[allow(dead_code)] - fn get_simplex_4d(&self, x: f32, y: f32, z: f32, w: f32) -> f32 { - self.single_simplex4d( - 0, - x * self.frequency, - y * self.frequency, - z * self.frequency, - w * self.frequency, - ) - } - - #[allow(dead_code)] - fn greater_1_0(&self, n: i32, greater_than: i32) -> i32 { - if n >= greater_than { 1 } else { 0 } - } - - #[allow(dead_code)] - #[allow(clippy::many_single_char_names)] - fn single_simplex4d(&self, offset: u8, x: f32, y: f32, z: f32, w: f32) -> f32 { - let mut t = (x + y + z + w) * F4; - let i = fast_floor(x + t) as f32; - let j = fast_floor(y + t) as f32; - let k = fast_floor(z + t) as f32; - let l = fast_floor(w + t) as f32; - t = (i + j + k + l) * G4; - let x0 = i - t; - let y0 = j - t; - let z0 = k - t; - let w0 = l - t; - let x0 = x - x0; - let y0 = y - y0; - let z0 = z - z0; - let w0 = w - w0; - - let mut rankx = 0; - let mut ranky = 0; - let mut rankz = 0; - let mut rankw = 0; - - if x0 > y0 { - rankx += 1; - } else { - ranky += 1; - } - if x0 > z0 { - rankx += 1; - } else { - rankz += 1 - }; - if x0 > w0 { - rankx += 1; - } else { - rankw += 1 - }; - if y0 > z0 { - ranky += 1; - } else { - rankz += 1 - }; - if y0 > w0 { - ranky += 1; - } else { - rankw += 1 - }; - if z0 > w0 { - rankz += 1; - } else { - rankw += 1 - }; - - let i1 = self.greater_1_0(rankx, 3); - let j1 = self.greater_1_0(ranky, 3); - let k1 = self.greater_1_0(rankz, 3); - let l1 = self.greater_1_0(rankw, 3); - - let i2 = self.greater_1_0(rankx, 2); - let j2 = self.greater_1_0(ranky, 2); - let k2 = self.greater_1_0(rankz, 2); - let l2 = self.greater_1_0(rankw, 2); - - let i3 = self.greater_1_0(rankx, 1); - let j3 = self.greater_1_0(ranky, 1); - let k3 = self.greater_1_0(rankz, 1); - let l3 = self.greater_1_0(rankw, 1); - - let x1 = x0 - i1 as f32 + G4; - let y1 = y0 - j1 as f32 + G4; - let z1 = z0 - k1 as f32 + G4; - let w1 = w0 - l1 as f32 + G4; - let x2 = x0 - i2 as f32 + 2.0 * G4; - let y2 = y0 - j2 as f32 + 2.0 * G4; - let z2 = z0 - k2 as f32 + 2.0 * G4; - let w2 = w0 - l2 as f32 + 2.0 * G4; - let x3 = x0 - i3 as f32 + 3.0 * G4; - let y3 = y0 - j3 as f32 + 3.0 * G4; - let z3 = z0 - k3 as f32 + 3.0 * G4; - let w3 = w0 - l3 as f32 + 3.0 * G4; - let x4 = x0 - 1.0 + 4.0 * G4; - let y4 = y0 - 1.0 + 4.0 * G4; - let z4 = z0 - 1.0 + 4.0 * G4; - let w4 = w0 - 1.0 + 4.0 * G4; - - t = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0; - let n0 = if t < 0.0 { - 0. - } else { - t *= t; - t * t - * self.grad_coord_4d( - offset, i as i32, j as i32, k as i32, l as i32, x0, y0, z0, w0, - ) - }; - t = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1; - let n1 = if t < 0.0 { - 0. - } else { - t *= t; - t * t - * self.grad_coord_4d( - offset, - i as i32 + i1, - j as i32 + j1, - k as i32 + k1, - l as i32 + l1, - x1, - y1, - z1, - w1, - ) - }; - t = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2; - let n2 = if t < 0.0 { - 0. - } else { - t *= t; - t * t - * self.grad_coord_4d( - offset, - i as i32 + i2, - j as i32 + j2, - k as i32 + k2, - l as i32 + l2, - x2, - y2, - z2, - w2, - ) - }; - t = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3; - let n3 = if t < 0.0 { - 0. - } else { - t *= t; - t * t - * self.grad_coord_4d( - offset, - i as i32 + i3, - j as i32 + j3, - k as i32 + k3, - l as i32 + l3, - x3, - y3, - z3, - w3, - ) - }; - t = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4; - let n4 = if t < 0.0 { - 0. - } else { - t *= t; - t * t - * self.grad_coord_4d( - offset, - i as i32 + 1, - j as i32 + 1, - k as i32 + 1, - l as i32 + 1, - x4, - y4, - z4, - w4, - ) - }; - - 27.0 * (n0 + n1 + n2 + n3 + n4) - } - - #[allow(dead_code)] - // Cubic Noise - fn get_cubic_fractal3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 { - x *= self.frequency; - y *= self.frequency; - z *= self.frequency; - - match self.fractal_type { - FractalType::FBM => self.single_cubic_fractal_fbm3d(x, y, z), - FractalType::Billow => self.single_cubic_fractal_billow3d(x, y, z), - FractalType::RigidMulti => self.single_cubic_fractal_rigid_multi3d(x, y, z), - } - } - - fn single_cubic_fractal_fbm3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 { - let mut sum = self.single_cubic3d(self.perm[0], x, y, z); - let mut amp = 1.0; - let mut i = 1; - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - z *= self.lacunarity; - - amp *= self.gain; - sum += self.single_cubic3d(self.perm[i as usize], x, y, z) * amp; - i += 1; - } - - sum * self.fractal_bounding - } - - fn single_cubic_fractal_billow3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 { - let mut sum = fast_abs_f(self.single_cubic3d(self.perm[0], x, y, z)) * 2.0 - 1.0; - let mut amp = 1.0; - let mut i = 1; - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - z *= self.lacunarity; - - amp *= self.gain; - sum += - (fast_abs_f(self.single_cubic3d(self.perm[i as usize], x, y, z)) * 2.0 - 1.0) * amp; - i += 1; - } - - sum * self.fractal_bounding - } - - fn single_cubic_fractal_rigid_multi3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 { - let mut sum = 1.0 - fast_abs_f(self.single_cubic3d(self.perm[0], x, y, z)); - let mut amp = 1.0; - let mut i = 1; - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - z *= self.lacunarity; - - amp *= self.gain; - sum -= (1.0 - fast_abs_f(self.single_cubic3d(self.perm[i as usize], x, y, z))) * amp; - i += 1; - } - - sum - } - - #[allow(dead_code)] - fn get_cubic3d(&self, x: f32, y: f32, z: f32) -> f32 { - self.single_cubic3d( - 0, - x * self.frequency, - y * self.frequency, - z * self.frequency, - ) - } - - fn single_cubic3d(&self, offset: u8, x: f32, y: f32, z: f32) -> f32 { - let x1 = fast_floor(x); - let y1 = fast_floor(y); - let z1 = fast_floor(z); - - let x0 = x1 - 1; - let y0 = y1 - 1; - let z0 = z1 - 1; - let x2 = x1 + 1; - let y2 = y1 + 1; - let z2 = z1 + 1; - let x3 = x1 + 2; - let y3 = y1 + 2; - let z3 = z1 + 2; - - let xs = x - x1 as f32; - let ys = y - y1 as f32; - let zs = z - z1 as f32; - - cubic_lerp( - cubic_lerp( - cubic_lerp( - self.val_coord_3d_fast(offset, x0, y0, z0), - self.val_coord_3d_fast(offset, x1, y0, z0), - self.val_coord_3d_fast(offset, x2, y0, z0), - self.val_coord_3d_fast(offset, x3, y0, z0), - xs, - ), - cubic_lerp( - self.val_coord_3d_fast(offset, x0, y1, z0), - self.val_coord_3d_fast(offset, x1, y1, z0), - self.val_coord_3d_fast(offset, x2, y1, z0), - self.val_coord_3d_fast(offset, x3, y1, z0), - xs, - ), - cubic_lerp( - self.val_coord_3d_fast(offset, x0, y2, z0), - self.val_coord_3d_fast(offset, x1, y2, z0), - self.val_coord_3d_fast(offset, x2, y2, z0), - self.val_coord_3d_fast(offset, x3, y2, z0), - xs, - ), - cubic_lerp( - self.val_coord_3d_fast(offset, x0, y3, z0), - self.val_coord_3d_fast(offset, x1, y3, z0), - self.val_coord_3d_fast(offset, x2, y3, z0), - self.val_coord_3d_fast(offset, x3, y3, z0), - xs, - ), - ys, - ), - cubic_lerp( - cubic_lerp( - self.val_coord_3d_fast(offset, x0, y0, z1), - self.val_coord_3d_fast(offset, x1, y0, z1), - self.val_coord_3d_fast(offset, x2, y0, z1), - self.val_coord_3d_fast(offset, x3, y0, z1), - xs, - ), - cubic_lerp( - self.val_coord_3d_fast(offset, x0, y1, z1), - self.val_coord_3d_fast(offset, x1, y1, z1), - self.val_coord_3d_fast(offset, x2, y1, z1), - self.val_coord_3d_fast(offset, x3, y1, z1), - xs, - ), - cubic_lerp( - self.val_coord_3d_fast(offset, x0, y2, z1), - self.val_coord_3d_fast(offset, x1, y2, z1), - self.val_coord_3d_fast(offset, x2, y2, z1), - self.val_coord_3d_fast(offset, x3, y2, z1), - xs, - ), - cubic_lerp( - self.val_coord_3d_fast(offset, x0, y3, z1), - self.val_coord_3d_fast(offset, x1, y3, z1), - self.val_coord_3d_fast(offset, x2, y3, z1), - self.val_coord_3d_fast(offset, x3, y3, z1), - xs, - ), - ys, - ), - cubic_lerp( - cubic_lerp( - self.val_coord_3d_fast(offset, x0, y0, z2), - self.val_coord_3d_fast(offset, x1, y0, z2), - self.val_coord_3d_fast(offset, x2, y0, z2), - self.val_coord_3d_fast(offset, x3, y0, z2), - xs, - ), - cubic_lerp( - self.val_coord_3d_fast(offset, x0, y1, z2), - self.val_coord_3d_fast(offset, x1, y1, z2), - self.val_coord_3d_fast(offset, x2, y1, z2), - self.val_coord_3d_fast(offset, x3, y1, z2), - xs, - ), - cubic_lerp( - self.val_coord_3d_fast(offset, x0, y2, z2), - self.val_coord_3d_fast(offset, x1, y2, z2), - self.val_coord_3d_fast(offset, x2, y2, z2), - self.val_coord_3d_fast(offset, x3, y2, z2), - xs, - ), - cubic_lerp( - self.val_coord_3d_fast(offset, x0, y3, z2), - self.val_coord_3d_fast(offset, x1, y3, z2), - self.val_coord_3d_fast(offset, x2, y3, z2), - self.val_coord_3d_fast(offset, x3, y3, z2), - xs, - ), - ys, - ), - cubic_lerp( - cubic_lerp( - self.val_coord_3d_fast(offset, x0, y0, z3), - self.val_coord_3d_fast(offset, x1, y0, z3), - self.val_coord_3d_fast(offset, x2, y0, z3), - self.val_coord_3d_fast(offset, x3, y0, z3), - xs, - ), - cubic_lerp( - self.val_coord_3d_fast(offset, x0, y1, z3), - self.val_coord_3d_fast(offset, x1, y1, z3), - self.val_coord_3d_fast(offset, x2, y1, z3), - self.val_coord_3d_fast(offset, x3, y1, z3), - xs, - ), - cubic_lerp( - self.val_coord_3d_fast(offset, x0, y2, z3), - self.val_coord_3d_fast(offset, x1, y2, z3), - self.val_coord_3d_fast(offset, x2, y2, z3), - self.val_coord_3d_fast(offset, x3, y2, z3), - xs, - ), - cubic_lerp( - self.val_coord_3d_fast(offset, x0, y3, z3), - self.val_coord_3d_fast(offset, x1, y3, z3), - self.val_coord_3d_fast(offset, x2, y3, z3), - self.val_coord_3d_fast(offset, x3, y3, z3), - xs, - ), - ys, - ), - zs, - ) * CUBIC_3D_BOUNDING - } - - #[allow(dead_code)] - fn get_cubic_fractal(&self, mut x: f32, mut y: f32) -> f32 { - x *= self.frequency; - y *= self.frequency; - - match self.fractal_type { - FractalType::FBM => self.single_cubic_fractal_fbm(x, y), - FractalType::Billow => self.single_cubic_fractal_billow(x, y), - FractalType::RigidMulti => self.single_cubic_fractal_rigid_multi(x, y), - } - } - - fn single_cubic_fractal_fbm(&self, mut x: f32, mut y: f32) -> f32 { - let mut sum = self.single_cubic(self.perm[0], x, y); - let mut amp = 1.0; - let mut i = 1; - - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - - amp *= self.gain; - sum += self.single_cubic(self.perm[i as usize], x, y) * amp; - i += 1; - } - - sum * self.fractal_bounding - } - - fn single_cubic_fractal_billow(&self, mut x: f32, mut y: f32) -> f32 { - let mut sum = fast_abs_f(self.single_cubic(self.perm[0], x, y)) * 2.0 - 1.0; - let mut amp = 1.0; - let mut i = 1; - - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - - amp *= self.gain; - sum += (fast_abs_f(self.single_cubic(self.perm[i as usize], x, y)) * 2.0 - 1.0) * amp; - i += 1; - } - - sum * self.fractal_bounding - } - - fn single_cubic_fractal_rigid_multi(&self, mut x: f32, mut y: f32) -> f32 { - let mut sum = 1.0 - fast_abs_f(self.single_cubic(self.perm[0], x, y)); - let mut amp = 1.0; - let mut i = 1; - - while i < self.octaves { - x *= self.lacunarity; - y *= self.lacunarity; - - amp *= self.gain; - sum -= (1.0 - fast_abs_f(self.single_cubic(self.perm[i as usize], x, y))) * amp; - i += 1; - } - - sum - } - - #[allow(dead_code)] - fn get_cubic(&self, x: f32, y: f32) -> f32 { - self.single_cubic(0, x * self.frequency, y * self.frequency) - } - - fn single_cubic(&self, offset: u8, x: f32, y: f32) -> f32 { - let x1 = fast_floor(x); - let y1 = fast_floor(y); - - let x0 = x1 - 1; - let y0 = y1 - 1; - let x2 = x1 + 1; - let y2 = y1 + 1; - let x3 = x1 + 2; - let y3 = y1 + 2; - - let xs = x - x1 as f32; - let ys = y - y1 as f32; - - cubic_lerp( - cubic_lerp( - self.val_coord_2d_fast(offset, x0, y0), - self.val_coord_2d_fast(offset, x1, y0), - self.val_coord_2d_fast(offset, x2, y0), - self.val_coord_2d_fast(offset, x3, y0), - xs, - ), - cubic_lerp( - self.val_coord_2d_fast(offset, x0, y1), - self.val_coord_2d_fast(offset, x1, y1), - self.val_coord_2d_fast(offset, x2, y1), - self.val_coord_2d_fast(offset, x3, y1), - xs, - ), - cubic_lerp( - self.val_coord_2d_fast(offset, x0, y2), - self.val_coord_2d_fast(offset, x1, y2), - self.val_coord_2d_fast(offset, x2, y2), - self.val_coord_2d_fast(offset, x3, y2), - xs, - ), - cubic_lerp( - self.val_coord_2d_fast(offset, x0, y3), - self.val_coord_2d_fast(offset, x1, y3), - self.val_coord_2d_fast(offset, x2, y3), - self.val_coord_2d_fast(offset, x3, y3), - xs, - ), - ys, - ) * CUBIC_2D_BOUNDING - } - - #[allow(dead_code)] - // Cellular Noise - fn get_cellular3d(&self, mut x: f32, mut y: f32, mut z: f32) -> f32 { - x *= self.frequency; - y *= self.frequency; - z *= self.frequency; - - match self.cellular_return_type { - CellularReturnType::CellValue => self.single_cellular3d(x, y, z), - CellularReturnType::Distance => self.single_cellular3d(x, y, z), - _ => self.single_cellular_2edge3d(x, y, z), - } - } - - fn single_cellular3d(&self, x: f32, y: f32, z: f32) -> f32 { - let xr = fast_round(x); - let yr = fast_round(y); - let zr = fast_round(z); - - let mut distance: f32 = 999999.0; - let mut xc: i32 = 0; - let mut yc: i32 = 0; - let mut zc: i32 = 0; - - match self.cellular_distance_function { - CellularDistanceFunction::Euclidean => { - for xi in xr - 1..xr + 2 { - for yi in yr - 1..yr + 2 { - for zi in zr - 1..zr + 2 { - let lut_pos: u8 = self.index3d_256(0, xi, yi, zi); - - let vec_x = - xi as f32 - x + CELL_3D_X[lut_pos as usize] * self.cellular_jitter; - let vec_y = - yi as f32 - y + CELL_3D_Y[lut_pos as usize] * self.cellular_jitter; - let vec_z = - zi as f32 - z + CELL_3D_Z[lut_pos as usize] * self.cellular_jitter; - - let new_distance = vec_x * vec_x + vec_y * vec_y + vec_z * vec_z; - - if new_distance < distance { - distance = new_distance; - xc = xi; - yc = yi; - zc = zi; - } - } - } - } - } - CellularDistanceFunction::Manhattan => { - for xi in xr - 1..xr + 2 { - for yi in yr - 1..yr + 2 { - for zi in zr - 1..zr + 2 { - let lut_pos: u8 = self.index3d_256(0, xi, yi, zi); - - let vec_x = - xi as f32 - x + CELL_3D_X[lut_pos as usize] * self.cellular_jitter; - let vec_y = - yi as f32 - y + CELL_3D_Y[lut_pos as usize] * self.cellular_jitter; - let vec_z = - zi as f32 - z + CELL_3D_Z[lut_pos as usize] * self.cellular_jitter; - - let new_distance = - fast_abs_f(vec_x) + fast_abs_f(vec_y) + fast_abs_f(vec_z); - - if new_distance < distance { - distance = new_distance; - xc = xi; - yc = yi; - zc = zi; - } - } - } - } - } - CellularDistanceFunction::Natural => { - for xi in xr - 1..xr + 2 { - for yi in yr - 1..yr + 2 { - for zi in zr - 1..zr + 2 { - let lut_pos: u8 = self.index3d_256(0, xi, yi, zi); - - let vec_x = - xi as f32 - x + CELL_3D_X[lut_pos as usize] * self.cellular_jitter; - let vec_y = - yi as f32 - y + CELL_3D_Y[lut_pos as usize] * self.cellular_jitter; - let vec_z = - zi as f32 - z + CELL_3D_Z[lut_pos as usize] * self.cellular_jitter; - - let new_distance = - (fast_abs_f(vec_x) + fast_abs_f(vec_y) + fast_abs_f(vec_z)) - + (vec_x * vec_x + vec_y * vec_y + vec_z * vec_z); - - if new_distance < distance { - distance = new_distance; - xc = xi; - yc = yi; - zc = zi; - } - } - } - } - } - } - - //let lut_pos : u8; - match self.cellular_return_type { - CellularReturnType::CellValue => self.val_coord_3d(self.seed as i32, xc, yc, zc), - CellularReturnType::Distance => distance, - _ => 0.0, - } - } - - fn single_cellular_2edge3d(&self, x: f32, y: f32, z: f32) -> f32 { - let xr = fast_round(x); - let yr = fast_round(y); - let zr = fast_round(z); - - let mut distance: Vec = vec![999999.0; FN_CELLULAR_INDEX_MAX + 1]; - //FN_DECIMAL distance[FN_CELLULAR_INDEX_MAX+1] = { 999999,999999,999999,999999 }; - - match self.cellular_distance_function { - CellularDistanceFunction::Euclidean => { - for xi in xr - 1..xr + 2 { - for yi in yr - 1..yr + 2 { - for zi in zr - 1..zr + 2 { - let lut_pos: u8 = self.index3d_256(0, xi, yi, zi); - - let vec_x = - xi as f32 - x + CELL_3D_X[lut_pos as usize] * self.cellular_jitter; - let vec_y = - yi as f32 - y + CELL_3D_Y[lut_pos as usize] * self.cellular_jitter; - let vec_z = - zi as f32 - z + CELL_3D_Z[lut_pos as usize] * self.cellular_jitter; - - let new_distance = vec_x * vec_x + vec_y * vec_y + vec_z * vec_z; - - for i in (0..self.cellular_distance_index.1).rev() { - distance[i as usize] = f32::max( - f32::min(distance[i as usize], new_distance), - distance[i as usize - 1], - ); - } - distance[0] = f32::min(distance[0], new_distance); - } - } - } - } - CellularDistanceFunction::Manhattan => { - for xi in xr - 1..xr + 2 { - for yi in yr - 1..yr + 2 { - for zi in zr - 1..zr + 2 { - let lut_pos = self.index3d_256(0, xi, yi, zi); - - let vec_x = - xi as f32 - x + CELL_3D_X[lut_pos as usize] * self.cellular_jitter; - let vec_y = - yi as f32 - y + CELL_3D_Y[lut_pos as usize] * self.cellular_jitter; - let vec_z = - zi as f32 - z + CELL_3D_Z[lut_pos as usize] * self.cellular_jitter; - - let new_distance = - fast_abs_f(vec_x) + fast_abs_f(vec_y) + fast_abs_f(vec_z); - - for i in (0..=self.cellular_distance_index.1).rev() { - distance[i as usize] = f32::max( - f32::min(distance[i as usize], new_distance), - distance[i as usize - 1], - ); - } - distance[0] = f32::min(distance[0], new_distance); - } - } - } - } - CellularDistanceFunction::Natural => { - for xi in xr - 1..xr + 2 { - for yi in yr - 1..yr + 2 { - for zi in zr - 1..zr + 2 { - let lut_pos = self.index3d_256(0, xi, yi, zi); - - let vec_x = - xi as f32 - x + CELL_3D_X[lut_pos as usize] * self.cellular_jitter; - let vec_y = - yi as f32 - y + CELL_3D_Y[lut_pos as usize] * self.cellular_jitter; - let vec_z = - zi as f32 - z + CELL_3D_Z[lut_pos as usize] * self.cellular_jitter; - - let new_distance = - (fast_abs_f(vec_x) + fast_abs_f(vec_y) + fast_abs_f(vec_z)) - + (vec_x * vec_x + vec_y * vec_y + vec_z * vec_z); - - for i in (0..=self.cellular_distance_index.1).rev() { - distance[i as usize] = f32::max( - f32::min(distance[i as usize], new_distance), - distance[i as usize - 1], - ); - } - distance[0] = f32::min(distance[0], new_distance); - } - } - } - } - } - - match self.cellular_return_type { - CellularReturnType::Distance2 => distance[self.cellular_distance_index.1 as usize], - CellularReturnType::Distance2Add => { - distance[self.cellular_distance_index.1 as usize] - + distance[self.cellular_distance_index.0 as usize] - } - CellularReturnType::Distance2Sub => { - distance[self.cellular_distance_index.1 as usize] - - distance[self.cellular_distance_index.0 as usize] - } - CellularReturnType::Distance2Mul => { - distance[self.cellular_distance_index.1 as usize] - * distance[self.cellular_distance_index.0 as usize] - } - CellularReturnType::Distance2Div => { - distance[self.cellular_distance_index.0 as usize] - / distance[self.cellular_distance_index.1 as usize] - } - _ => 0.0, - } - } - - #[allow(dead_code)] - fn get_cellular(&self, mut x: f32, mut y: f32) -> f32 { - x *= self.frequency; - y *= self.frequency; - - match self.cellular_return_type { - CellularReturnType::CellValue => self.single_cellular(x, y), - CellularReturnType::Distance => self.single_cellular(x, y), - _ => self.single_cellular_2edge(x, y), - } - } - - fn single_cellular(&self, x: f32, y: f32) -> f32 { - let xr = fast_round(x); - let yr = fast_round(y); - - let mut distance: f32 = 999999.0; - - match self.cellular_distance_function { - CellularDistanceFunction::Euclidean => { - for xi in xr - 1..xr + 2 { - for yi in yr - 1..yr + 2 { - let lut_pos: u8 = self.index2d_256(0, xi, yi); - - let vec_x = - xi as f32 - x + CELL_2D_X[lut_pos as usize] * self.cellular_jitter; - let vec_y = - yi as f32 - y + CELL_2D_Y[lut_pos as usize] * self.cellular_jitter; - - let new_distance = vec_x * vec_x + vec_y * vec_y; - - if new_distance < distance { - distance = new_distance; - } - } - } - } - CellularDistanceFunction::Manhattan => { - for xi in xr - 1..xr + 2 { - for yi in yr - 1..yr + 2 { - let lut_pos: u8 = self.index2d_256(0, xi, yi); - - let vec_x = - xi as f32 - x + CELL_2D_X[lut_pos as usize] * self.cellular_jitter; - let vec_y = - yi as f32 - y + CELL_2D_Y[lut_pos as usize] * self.cellular_jitter; - - let new_distance = fast_abs_f(vec_x) + fast_abs_f(vec_y); - - if new_distance < distance { - distance = new_distance; - } - } - } - } - CellularDistanceFunction::Natural => { - for xi in xr - 1..xr + 2 { - for yi in yr - 1..yr + 2 { - let lut_pos: u8 = self.index2d_256(0, xi, yi); - - let vec_x = - xi as f32 - x + CELL_2D_X[lut_pos as usize] * self.cellular_jitter; - let vec_y = - yi as f32 - y + CELL_2D_Y[lut_pos as usize] * self.cellular_jitter; - - let new_distance = (fast_abs_f(vec_x) + fast_abs_f(vec_y)) - + (vec_x * vec_x + vec_y * vec_y); - - if new_distance < distance { - distance = new_distance; - } - } - } - } - } - - //let lut_pos : u8; - match self.cellular_return_type { - CellularReturnType::CellValue => { - self.val_coord_2d(self.seed as i32, x as i32, y as i32) - } - _ => 0.0, - } - } - - fn single_cellular_2edge(&self, x: f32, y: f32) -> f32 { - let xr = fast_round(x); - let yr = fast_round(y); - - let mut distance: Vec = vec![999999.0; FN_CELLULAR_INDEX_MAX + 1]; - - match self.cellular_distance_function { - CellularDistanceFunction::Euclidean => { - for xi in xr - 1..xr + 2 { - for yi in yr - 1..yr + 2 { - let lut_pos = self.index2d_256(0, xi, yi); - - let vec_x = - xi as f32 - x + CELL_2D_X[lut_pos as usize] * self.cellular_jitter; - let vec_y = - yi as f32 - y + CELL_2D_Y[lut_pos as usize] * self.cellular_jitter; - - let new_distance = vec_x * vec_x + vec_y * vec_y; - - for i in (0..=self.cellular_distance_index.1).rev() { - distance[i as usize] = f32::max( - f32::min(distance[i as usize], new_distance), - distance[i as usize - 1], - ); - } - distance[0] = f32::min(distance[0], new_distance); - } - } - } - CellularDistanceFunction::Manhattan => { - for xi in xr - 1..xr + 2 { - for yi in yr - 1..yr + 2 { - let lut_pos = self.index2d_256(0, xi, yi); - - let vec_x = - xi as f32 - x + CELL_2D_X[lut_pos as usize] * self.cellular_jitter; - let vec_y = - yi as f32 - y + CELL_2D_Y[lut_pos as usize] * self.cellular_jitter; - - let new_distance = fast_abs_f(vec_x) + fast_abs_f(vec_y); - - for i in (0..=self.cellular_distance_index.1).rev() { - distance[i as usize] = f32::max( - f32::min(distance[i as usize], new_distance), - distance[i as usize - 1], - ); - } - distance[0] = f32::min(distance[0], new_distance); - } - } - } - CellularDistanceFunction::Natural => { - for xi in xr - 1..xr + 2 { - for yi in yr - 1..yr + 2 { - let lut_pos = self.index2d_256(0, xi, yi); - - let vec_x = - xi as f32 - x + CELL_2D_X[lut_pos as usize] * self.cellular_jitter; - let vec_y = - yi as f32 - y + CELL_2D_Y[lut_pos as usize] * self.cellular_jitter; - - let new_distance = (fast_abs_f(vec_x) + fast_abs_f(vec_y)) - + (vec_x * vec_x + vec_y * vec_y); - - for i in (0..=self.cellular_distance_index.1).rev() { - distance[i as usize] = f32::max( - f32::min(distance[i as usize], new_distance), - distance[i as usize - 1], - ); - } - distance[0] = f32::min(distance[0], new_distance); - } - } - } - } - - match self.cellular_return_type { - CellularReturnType::Distance2 => distance[self.cellular_distance_index.0 as usize], - CellularReturnType::Distance2Add => { - distance[self.cellular_distance_index.1 as usize] - + distance[self.cellular_distance_index.0 as usize] - } - CellularReturnType::Distance2Sub => { - distance[self.cellular_distance_index.1 as usize] - - distance[self.cellular_distance_index.0 as usize] - } - CellularReturnType::Distance2Mul => { - distance[self.cellular_distance_index.1 as usize] - * distance[self.cellular_distance_index.0 as usize] - } - CellularReturnType::Distance2Div => { - distance[self.cellular_distance_index.0 as usize] - / distance[self.cellular_distance_index.1 as usize] - } - _ => 0.0, - } - } - - #[allow(dead_code)] - fn gradient_perturb3d(&self, x: &mut f32, y: &mut f32, z: &mut f32) { - self.single_gradient_perturb3d(0, self.gradient_perturb_amp, self.frequency, x, y, z); - } - - #[allow(dead_code)] - fn gradient_perturb_fractal3d(&self, x: &mut f32, y: &mut f32, z: &mut f32) { - let mut amp = self.gradient_perturb_amp * self.fractal_bounding; - let mut freq = self.frequency; - let mut i = 1; - - self.single_gradient_perturb3d(self.perm[0], amp, self.frequency, x, y, z); - - while i < self.octaves { - freq *= self.lacunarity; - amp *= self.gain; - self.single_gradient_perturb3d(self.perm[i as usize], amp, freq, x, y, z); - - i += 1; - } - } - - #[allow(dead_code)] - fn single_gradient_perturb3d( - &self, - offset: u8, - warp_amp: f32, - frequency: f32, - x: &mut f32, - y: &mut f32, - z: &mut f32, - ) { - let xf = *x * frequency; - let yf = *y * frequency; - let zf = *z * frequency; - - let x0 = fast_floor(xf); - let y0 = fast_floor(yf); - let z0 = fast_floor(zf); - let x1 = x0 + 1; - let y1 = y0 + 1; - let z1 = z0 + 1; - - let xs: f32; - let ys: f32; - let zs: f32; - match self.interp { - Interp::Linear => { - xs = xf - x0 as f32; - ys = yf - y0 as f32; - zs = zf - z0 as f32; - } - Interp::Hermite => { - xs = interp_hermite_func(xf - x0 as f32); - ys = interp_hermite_func(yf - y0 as f32); - zs = interp_hermite_func(zf - z0 as f32); - } - Interp::Quintic => { - xs = interp_quintic_func(xf - x0 as f32); - ys = interp_quintic_func(yf - y0 as f32); - zs = interp_quintic_func(zf - z0 as f32); - } - } - - let mut lut_pos0 = self.index3d_256(offset, x0, y0, z0); - let mut lut_pos1 = self.index3d_256(offset, x1, y0, z0); - - let mut lx0x = lerp( - CELL_3D_X[lut_pos0 as usize], - CELL_3D_X[lut_pos1 as usize], - xs, - ); - let mut ly0x = lerp( - CELL_3D_Y[lut_pos0 as usize], - CELL_3D_Y[lut_pos1 as usize], - xs, - ); - let mut lz0x = lerp( - CELL_3D_Z[lut_pos0 as usize], - CELL_3D_Z[lut_pos1 as usize], - xs, - ); - - lut_pos0 = self.index3d_256(offset, x0, y1, z0); - lut_pos1 = self.index3d_256(offset, x1, y1, z0); - - let mut lx1x = lerp( - CELL_3D_X[lut_pos0 as usize], - CELL_3D_X[lut_pos1 as usize], - xs, - ); - let mut ly1x = lerp( - CELL_3D_Y[lut_pos0 as usize], - CELL_3D_Y[lut_pos1 as usize], - xs, - ); - let mut lz1x = lerp( - CELL_3D_Z[lut_pos0 as usize], - CELL_3D_Z[lut_pos1 as usize], - xs, - ); - - let lx0y = lerp(lx0x, lx1x, ys); - let ly0y = lerp(ly0x, ly1x, ys); - let lz0y = lerp(lz0x, lz1x, ys); - - lut_pos0 = self.index3d_256(offset, x0, y0, z1); - lut_pos1 = self.index3d_256(offset, x1, y0, z1); - - lx0x = lerp( - CELL_3D_X[lut_pos0 as usize], - CELL_3D_X[lut_pos1 as usize], - xs, - ); - ly0x = lerp( - CELL_3D_Y[lut_pos0 as usize], - CELL_3D_Y[lut_pos1 as usize], - xs, - ); - lz0x = lerp( - CELL_3D_Z[lut_pos0 as usize], - CELL_3D_Z[lut_pos1 as usize], - xs, - ); - - lut_pos0 = self.index3d_256(offset, x0, y1, z1); - lut_pos1 = self.index3d_256(offset, x1, y1, z1); - - lx1x = lerp( - CELL_3D_X[lut_pos0 as usize], - CELL_3D_X[lut_pos1 as usize], - xs, - ); - ly1x = lerp( - CELL_3D_Y[lut_pos0 as usize], - CELL_3D_Y[lut_pos1 as usize], - xs, - ); - lz1x = lerp( - CELL_3D_Z[lut_pos0 as usize], - CELL_3D_Z[lut_pos1 as usize], - xs, - ); - - *x += lerp(lx0y, lerp(lx0x, lx1x, ys), zs) * warp_amp; - *y += lerp(ly0y, lerp(ly0x, ly1x, ys), zs) * warp_amp; - *z += lerp(lz0y, lerp(lz0x, lz1x, ys), zs) * warp_amp; - } - - #[allow(dead_code)] - fn gradient_perturb(&self, x: &mut f32, y: &mut f32) { - self.single_gradient_perturb(0, self.gradient_perturb_amp, self.frequency, x, y); - } - - #[allow(dead_code)] - fn gradient_perturb_fractal(&self, x: &mut f32, y: &mut f32) { - let mut amp = self.gradient_perturb_amp * self.fractal_bounding; - let mut freq = self.frequency; - let mut i = 1; - - self.single_gradient_perturb(self.perm[0], amp, self.frequency, x, y); - - while i < self.octaves { - freq *= self.lacunarity; - amp *= self.gain; - self.single_gradient_perturb(self.perm[i as usize], amp, freq, x, y); - i += 1; - } - } - - #[allow(dead_code)] - fn single_gradient_perturb( - &self, - offset: u8, - warp_amp: f32, - frequency: f32, - x: &mut f32, - y: &mut f32, - ) { - let xf = *x * frequency; - let yf = *y * frequency; - - let x0 = fast_floor(xf); - let y0 = fast_floor(yf); - let x1 = x0 + 1; - let y1 = y0 + 1; - - let xs: f32; - let ys: f32; - match self.interp { - Interp::Linear => { - xs = xf - x0 as f32; - ys = yf - y0 as f32; - } - Interp::Hermite => { - xs = interp_hermite_func(xf - x0 as f32); - ys = interp_hermite_func(yf - y0 as f32); - } - Interp::Quintic => { - xs = interp_quintic_func(xf - x0 as f32); - ys = interp_quintic_func(yf - y0 as f32); - } - } - - let mut lut_pos0 = self.index2d_256(offset, x0, y0); - let mut lut_pos1 = self.index2d_256(offset, x1, y0); - - let lx0x = lerp( - CELL_2D_X[lut_pos0 as usize], - CELL_2D_X[lut_pos1 as usize], - xs, - ); - let ly0x = lerp( - CELL_2D_Y[lut_pos0 as usize], - CELL_2D_Y[lut_pos1 as usize], - xs, - ); - - lut_pos0 = self.index2d_256(offset, x0, y1); - lut_pos1 = self.index2d_256(offset, x1, y1); - - let lx1x = lerp( - CELL_2D_X[lut_pos0 as usize], - CELL_2D_X[lut_pos1 as usize], - xs, - ); - let ly1x = lerp( - CELL_2D_Y[lut_pos0 as usize], - CELL_2D_Y[lut_pos1 as usize], - xs, - ); - - *x += lerp(lx0x, lx1x, ys) * warp_amp; - *y += lerp(ly0x, ly1x, ys) * warp_amp; - } -} - -#[cfg(test)] -mod tests { - use super::{CellularDistanceFunction, FastNoise, NoiseType}; - - #[test] - // Tests that we make an RGB triplet at defaults and it is black. - fn test_cellular_noise_overflow() { - let mut noise = FastNoise::seeded(6000); - noise.set_noise_type(NoiseType::Cellular); - noise.set_frequency(0.08); - noise.set_cellular_distance_function(CellularDistanceFunction::Manhattan); - for y in 0..1024 { - for x in 0..1024 { - let frac_x = x as f32 / 1024.0; - let frac_y = y as f32 / 1024.0; - - let cell_value_f = noise.get_noise(frac_x, frac_y); - assert!(cell_value_f != 0.0); - } - } - } + (n * n * n * Wrapping(60493)).0 as f32 / 2_147_483_648.0 }