use bracket_random::prelude::RandomNumberGenerator;
#[derive(PartialEq, Copy, Clone)]
pub enum NoiseType {
Value,
ValueFractal,
Perlin,
PerlinFractal,
Simplex,
SimplexFractal,
Cellular,
WhiteNoise,
Cubic,
CubicFractal,
}
#[derive(PartialEq, Copy, Clone)]
pub enum Interp {
Linear,
Hermite,
Quintic,
}
#[derive(PartialEq, Copy, Clone)]
pub enum FractalType {
FBM,
Billow,
RigidMulti,
}
#[derive(PartialEq, Copy, Clone)]
pub enum CellularDistanceFunction {
Euclidean,
Manhattan,
Natural,
}
#[derive(PartialEq, Copy, Clone)]
pub enum CellularReturnType {
CellValue,
Distance,
Distance2,
Distance2Add,
Distance2Sub,
Distance2Mul,
Distance2Div,
}
pub struct FastNoise {
rng: RandomNumberGenerator,
seed: u64,
frequency: f32,
interp: Interp,
noise_type: NoiseType,
octaves: i32,
lacunarity: f32,
gain: f32,
fractal_type: FractalType,
cellular_distance_function: CellularDistanceFunction,
cellular_return_type: CellularReturnType,
cellular_distance_index: (i32, i32),
cellular_jitter: f32,
gradient_perturb_amp: f32,
perm: Vec<u8>,
perm12: Vec<u8>,
fractal_bounding: f32,
}
const GRAD_X: [f32; 12] = [1.0, -1., 1., -1., 1., -1., 1., -1., 0., 0., 0., 0.];
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;
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
}
}
#[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 {
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
}
pub fn seeded(seed: u64) -> FastNoise {
let mut noise = FastNoise {
rng: RandomNumberGenerator::seeded(seed),
seed,
frequency: 0.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(seed);
noise.calculate_fractal_bounding();
noise
}
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;
}
}
pub fn get_seed(&self) -> u64 {
self.seed
}
pub fn set_frequency(&mut self, frequency: f32) {
self.frequency = frequency
}
pub fn get_frequency(&self) -> f32 {
self.frequency
}
pub fn set_interp(&mut 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
}
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();
}
pub fn get_fractal_octaves(&self) -> i32 {
self.octaves
}
pub fn set_fractal_lacunarity(&mut self, lacunarity: f32) {
self.lacunarity = lacunarity
}
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();
}
pub fn get_fractal_gain(&self) -> f32 {
self.gain
}
pub fn set_fractal_type(&mut self, fractal_type: FractalType) {
self.fractal_type = fractal_type
}
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
}
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
}
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_jitter(&mut self, jitter: f32) {
self.cellular_jitter = jitter
}
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
}
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;
}
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 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]
}
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]
}
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
}
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]
}
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]
}
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),
},
}
}
#[allow(dead_code)]
fn get_white_noise4d(&self, x: f32, y: f32, z: f32, w: f32) -> f32 {
unsafe {
let xc: i32 = std::mem::transmute_copy(&x);
let yc: i32 = std::mem::transmute_copy(&y);
let zc: i32 = std::mem::transmute_copy(&z);
let wc: i32 = std::mem::transmute_copy(&w);
self.val_coord_4d(
self.seed as i32,
xc ^ (xc as i32 >> 16),
yc ^ (yc >> 16),
zc ^ (zc >> 16),
wc ^ (wc >> 16),
)
}
}
fn get_white_noise3d(&self, x: f32, y: f32, z: f32) -> f32 {
unsafe {
let xc: i32 = std::mem::transmute_copy(&x);
let yc: i32 = std::mem::transmute_copy(&y);
let zc: i32 = std::mem::transmute_copy(&z);
self.val_coord_3d(
self.seed as i32,
xc ^ (xc >> 16),
yc ^ (yc >> 16),
zc ^ (zc >> 16),
)
}
}
fn get_white_noise(&self, x: f32, y: f32) -> f32 {
unsafe {
let xc: i32 = std::mem::transmute_copy(&x);
let yc: i32 = std::mem::transmute_copy(&y);
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)]
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)
}
#[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;
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)
}
#[allow(dead_code)]
fn get_perlin_fractal(&self, mut x: f32, mut y: f32) -> f32 {
x *= self.frequency;
y *= self.frequency;
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),
}
}
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;
amp *= self.gain;
sum += self.single_perlin(self.perm[i as usize], x, y) * amp;
i += 1;
}
sum * self.fractal_bounding
}
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;
while i < self.octaves {
x *= self.lacunarity;
y *= self.lacunarity;
amp *= self.gain;
sum += (fast_abs_f(self.single_perlin(self.perm[i as usize], x, y)) * 2.0 - 1.0) * amp;
i += 1;
}
sum * self.fractal_bounding
}
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
}
#[allow(dead_code)]
fn get_perlin(&self, x: f32, y: f32) -> f32 {
self.single_perlin(0, x * self.frequency, y * self.frequency)
}
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)
}
#[allow(dead_code)]
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 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;
while i < self.octaves {
x *= self.lacunarity;
y *= self.lacunarity;
z *= self.lacunarity;
amp *= self.gain;
sum += self.single_simplex3d(self.perm[i as usize], x, y, z) * amp;
i += 1;
}
sum * self.fractal_bounding
}
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;
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
{
i1 = 0.;
j1 = 0.;
k1 = 1.;
i2 = 1.;
j2 = 0.;
k2 = 1.;
}
} else
{
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
{
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;
let n0;
let n1;
let n2;
let n3;
t = 0.6 - x0 * x0 - y0 * y0 - z0 * z0;
if t < 0. {
n0 = 0.;
} else {
t *= t;
n0 = t * t * self.grad_coord_3d(offset, i, j, k, x0, y0, z0);
}
t = 0.6 - x1 * x1 - y1 * y1 - z1 * z1;
if t < 0. {
n1 = 0.
} else {
t *= t;
n1 = 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;
if t < 0. {
n2 = 0.
} else {
t *= t;
n2 = 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;
if t < 0. {
n3 = 0.
} else {
t *= t;
n3 = 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;
let n0;
let n1;
let n2;
t = 0.5 - x0 * x0 - y0 * y0;
if t < 0. {
n0 = 0.
} else {
t *= t;
n0 = t * t * self.grad_coord_2d(offset, i, j, x0, y0);
}
t = 0.5 - x1 * x1 - y1 * y1;
if t < 0. {
n1 = 0.
} else {
t *= t;
n1 = t * t * self.grad_coord_2d(offset, i + i1 as i32, j + j1 as i32, x1, y1);
}
t = 0.5 - x2 * x2 - y2 * y2;
if t < 0. {
n2 = 0.
} else {
t *= t;
n2 = 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 n0: f32;
let n1: f32;
let n2: f32;
let n3: f32;
let n4: 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;
if t < 0.0 {
n0 = 0.;
} else {
t *= t;
n0 = 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;
if t < 0.0 {
n1 = 0.;
} else {
t *= t;
n1 = 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;
if t < 0.0 {
n2 = 0.;
} else {
t *= t;
n2 = 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;
if t < 0.0 {
n3 = 0.;
} else {
t *= t;
n3 = 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;
if t < 0.0 {
n4 = 0.;
} else {
t *= t;
n4 = 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) as f32
}
#[allow(dead_code)]
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)]
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;
}
}
}
}
}
}
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<f32> = 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 {
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;
}
}
}
}
}
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<f32> = 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]
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);
}
}
}
}