diff --git a/Cargo.lock b/Cargo.lock index af344b665a..b23b27d4b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,7 +52,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if 1.0.0", - "getrandom 0.2.15", + "getrandom", "once_cell", "version_check", "zerocopy", @@ -373,7 +373,7 @@ name = "auth-common" version = "0.1.0" source = "git+https://gitlab.com/veloren/auth.git?rev=ae0e16783a9f9041951296885f082308e155db79#ae0e16783a9f9041951296885f082308e155db79" dependencies = [ - "rand 0.8.5", + "rand", "serde", "uuid", ] @@ -740,7 +740,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "270f1d341a2afc62604f8f688bee4e444d052b7a74c1458dd3aa7efb47d4077f" dependencies = [ "ambient-authority", - "rand 0.8.5", + "rand", ] [[package]] @@ -2536,17 +2536,6 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - [[package]] name = "getrandom" version = "0.2.15" @@ -2556,7 +2545,7 @@ dependencies = [ "cfg-if 1.0.0", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] @@ -2893,7 +2882,7 @@ dependencies = [ "idna 0.4.0", "ipnet", "once_cell", - "rand 0.8.5", + "rand", "thiserror", "tinyvec", "tokio", @@ -2914,7 +2903,7 @@ dependencies = [ "lru-cache", "once_cell", "parking_lot", - "rand 0.8.5", + "rand", "resolv-conf", "smallvec", "thiserror", @@ -3954,7 +3943,7 @@ checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys 0.48.0", ] @@ -3996,7 +3985,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" dependencies = [ - "getrandom 0.2.15", + "getrandom", ] [[package]] @@ -4128,11 +4117,12 @@ checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" [[package]] name = "noise" -version = "0.7.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82051dd6745d5184c6efb7bc8be14892a7f6d4f3ad6dbf754d1c7d7d5fe24b43" +checksum = "6da45c8333f2e152fc665d78a380be060eb84fad8ca4c9f7ac8ca29216cff0cc" dependencies = [ - "rand 0.7.3", + "num-traits", + "rand", "rand_xorshift", ] @@ -4705,7 +4695,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ "phf_shared", - "rand 0.8.5", + "rand", ] [[package]] @@ -4821,7 +4811,7 @@ name = "portpicker" version = "0.1.0" source = "git+https://github.com/xMAC94x/portpicker-rs?rev=df6b37872f3586ac3b21d08b56c8ec7cd92fb172#df6b37872f3586ac3b21d08b56c8ec7cd92fb172" dependencies = [ - "rand 0.8.5", + "rand", ] [[package]] @@ -5029,7 +5019,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e974563a4b1c2206bbc61191ca4da9c22e4308b4c455e8906751cc7828393f08" dependencies = [ "bytes", - "rand 0.8.5", + "rand", "ring", "rustc-hash", "rustls", @@ -5087,19 +5077,6 @@ dependencies = [ "nibble_vec", ] -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", -] - [[package]] name = "rand" version = "0.8.5" @@ -5107,18 +5084,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", + "rand_chacha", + "rand_core", ] [[package]] @@ -5128,16 +5095,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", + "rand_core", ] [[package]] @@ -5146,25 +5104,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.15", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", + "getrandom", ] [[package]] name = "rand_xorshift" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" dependencies = [ - "rand_core 0.5.1", + "rand_core", ] [[package]] @@ -5271,7 +5220,7 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ - "getrandom 0.2.15", + "getrandom", "libredox 0.1.3", "thiserror", ] @@ -5401,7 +5350,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if 1.0.0", - "getrandom 0.2.15", + "getrandom", "libc", "spin", "untrusted", @@ -6363,7 +6312,7 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cfc24238213e42ffb35314aad7a7f5d46649c5fbba3ea95ef24f7debb95874e" dependencies = [ - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -6852,7 +6801,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ "cfg-if 1.0.0", - "rand 0.8.5", + "rand", "static_assertions", ] @@ -6978,7 +6927,7 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" dependencies = [ - "getrandom 0.2.15", + "getrandom", "serde", ] @@ -7102,8 +7051,8 @@ dependencies = [ "num-traits", "ordered-float 4.2.0", "petgraph 0.6.5", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand", + "rand_chacha", "rayon", "ron", "roots", @@ -7187,7 +7136,7 @@ name = "veloren-common-i18n" version = "0.1.0" dependencies = [ "hashbrown 0.14.5", - "rand 0.8.5", + "rand", "serde", ] @@ -7244,7 +7193,7 @@ version = "0.10.0" dependencies = [ "itertools 0.13.0", "ordered-float 4.2.0", - "rand 0.8.5", + "rand", "rayon", "specs", "tracing", @@ -7274,7 +7223,7 @@ dependencies = [ "prometheus", "prometheus-hyper", "quinn", - "rand 0.8.5", + "rand", "rcgen", "rustls", "serde", @@ -7298,7 +7247,7 @@ dependencies = [ "criterion", "hashbrown 0.14.5", "prometheus", - "rand 0.8.5", + "rand", "tokio", "tracing", ] @@ -7309,7 +7258,7 @@ version = "0.1.0" dependencies = [ "clap", "protocol", - "rand 0.8.5", + "rand", "tokio", "tracing", "tracing-subscriber", @@ -7325,8 +7274,8 @@ dependencies = [ "fxhash", "hashbrown 0.14.5", "itertools 0.13.0", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand", + "rand_chacha", "rayon", "rmp-serde", "serde", @@ -7361,7 +7310,7 @@ dependencies = [ "portpicker", "prometheus", "quinn", - "rand 0.8.5", + "rand", "rayon", "refinery", "ron", @@ -7395,7 +7344,7 @@ version = "0.1.0" dependencies = [ "itertools 0.13.0", "lazy_static", - "rand 0.8.5", + "rand", "specs", "tracing", "vek 0.17.0", @@ -7421,7 +7370,7 @@ dependencies = [ "mimalloc", "num_cpus", "prometheus", - "rand 0.8.5", + "rand", "ratatui", "ron", "serde", @@ -7482,8 +7431,8 @@ dependencies = [ "num 0.4.3", "num_cpus", "ordered-float 4.2.0", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand", + "rand_chacha", "rayon", "rodio", "ron", @@ -7581,8 +7530,8 @@ dependencies = [ "num 0.4.3", "num-traits", "ordered-float 4.2.0", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand", + "rand_chacha", "rayon", "ron", "rstar", @@ -7642,12 +7591,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index f9e196e052..29f4e0f5a7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -168,6 +168,8 @@ hex = "0.4.3" rustls = { version = "0.23", default-features = false, features = ["std"] } quinn = { version = "0.11" } +noise = { version = "0.9", default-features = false } + [patch.crates-io] # until next specs release specs = { git = "https://github.com/amethyst/specs.git", rev = "4e2da1df29ee840baa9b936593c45592b7c9ae27" } diff --git a/server/Cargo.toml b/server/Cargo.toml index 7129abbc2d..b7ee2d2374 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -68,7 +68,7 @@ prometheus = { workspace = true } portpicker = { git = "https://github.com/xMAC94x/portpicker-rs", rev = "df6b37872f3586ac3b21d08b56c8ec7cd92fb172" } authc = { git = "https://gitlab.com/veloren/auth.git", rev = "ae0e16783a9f9041951296885f082308e155db79" } # xMAC94x/current_master_till_refactored branch enum-map = { workspace = true } -noise = { version = "0.7", default-features = false } +noise = { workspace = true } censor = "0.3" rusqlite = { version = "0.31.0", features = [ diff --git a/server/src/weather/sim.rs b/server/src/weather/sim.rs index 5ff5ff2618..851385b52e 100644 --- a/server/src/weather/sim.rs +++ b/server/src/weather/sim.rs @@ -3,7 +3,7 @@ use common::{ resources::TimeOfDay, weather::{Weather, WeatherGrid, CELL_SIZE, CHUNKS_PER_CELL}, }; -use noise::{NoiseFn, SuperSimplex, Turbulence}; +use noise::{NoiseFn, Perlin, SuperSimplex, Turbulence}; use vek::*; use world::World; @@ -92,15 +92,15 @@ impl WeatherSim { pub fn tick(&mut self, time_of_day: TimeOfDay, out: &mut WeatherGrid) -> LightningCells { let time = time_of_day.0; - let base_nz = Turbulence::new( - Turbulence::new(SuperSimplex::new()) + let base_nz: Turbulence, Perlin> = Turbulence::new( + Turbulence::new(SuperSimplex::new(0)) .set_frequency(0.2) .set_power(1.5), ) .set_frequency(2.0) .set_power(0.2); - let rain_nz = SuperSimplex::new(); + let rain_nz = SuperSimplex::new(0); let mut lightning_cells = Vec::new(); for (point, cell) in out.iter_mut() { diff --git a/world/Cargo.toml b/world/Cargo.toml index 13db1ce949..1fa986a6a4 100644 --- a/world/Cargo.toml +++ b/world/Cargo.toml @@ -36,7 +36,7 @@ fxhash = { workspace = true } image = { workspace = true } itertools = { workspace = true } vek = { workspace = true } -noise = { version = "0.7", default-features = false } +noise = { workspace = true } num = { workspace = true } ordered-float = { workspace = true } hashbrown = { workspace = true } diff --git a/world/examples/turb.rs b/world/examples/turb.rs index 3cb847412d..5a27f49845 100644 --- a/world/examples/turb.rs +++ b/world/examples/turb.rs @@ -1,4 +1,4 @@ -use noise::{NoiseFn, Seedable, SuperSimplex, Turbulence}; +use noise::{NoiseFn, Perlin, SuperSimplex, Turbulence}; use vek::*; @@ -8,16 +8,16 @@ const H: usize = 640; fn main() { let mut win = minifb::Window::new("Turb", W, H, minifb::WindowOptions::default()).unwrap(); - let nz = Turbulence::new( - Turbulence::new(SuperSimplex::new()) + let nz: Turbulence, Perlin> = Turbulence::new( + Turbulence::new(SuperSimplex::new(0)) .set_frequency(0.2) .set_power(1.5), ) .set_frequency(2.0) .set_power(0.2); - let _nz_x = SuperSimplex::new().set_seed(0); - let _nz_y = SuperSimplex::new().set_seed(1); + let _nz_x = SuperSimplex::new(0); + let _nz_y = SuperSimplex::new(1); let mut _time = 0.0f64; diff --git a/world/src/index.rs b/world/src/index.rs index 8f50d9b87c..8d4ed29b36 100644 --- a/world/src/index.rs +++ b/world/src/index.rs @@ -9,7 +9,7 @@ use common::{ trade::{SiteId, SitePrices}, }; use core::ops::Deref; -use noise::{Fbm, MultiFractal, Seedable, SuperSimplex}; +use noise::{Fbm, MultiFractal, Perlin, SuperSimplex}; use std::sync::Arc; const WORLD_COLORS_MANIFEST: &str = "world.style.colors"; @@ -136,15 +136,15 @@ impl IndexOwned { pub struct Noise { pub cave_nz: SuperSimplex, pub scatter_nz: SuperSimplex, - pub cave_fbm_nz: Fbm, + pub cave_fbm_nz: Fbm, } impl Noise { fn new(seed: u32) -> Self { Self { - cave_nz: SuperSimplex::new().set_seed(seed + 0), - scatter_nz: SuperSimplex::new().set_seed(seed + 1), - cave_fbm_nz: Fbm::new().set_seed(seed + 2).set_octaves(5), + cave_nz: SuperSimplex::new(seed + 0), + scatter_nz: SuperSimplex::new(seed + 1), + cave_fbm_nz: Fbm::new(seed + 2).set_octaves(5), } } } diff --git a/world/src/sim/erosion.rs b/world/src/sim/erosion.rs index a968758db9..4844861e8a 100644 --- a/world/src/sim/erosion.rs +++ b/world/src/sim/erosion.rs @@ -550,7 +550,7 @@ pub fn get_rivers, G: Float + Into>( fn get_max_slope( map_size_lg: MapSizeLg, h: &[Alt], - rock_strength_nz: &(impl NoiseFn<[f64; 3]> + Sync), + rock_strength_nz: &(impl NoiseFn + Sync), height_scale: impl Fn(usize) -> Alt + Sync, ) -> Box<[f64]> { let min_max_angle = (15.0 / 360.0 * 2.0 * std::f64::consts::PI).tan(); @@ -709,7 +709,7 @@ fn erode( max_g: f32, kdsed: f64, _seed: &RandomField, - rock_strength_nz: &(impl NoiseFn<[f64; 3]> + Sync), + rock_strength_nz: &(impl NoiseFn + Sync), uplift: impl Fn(usize) -> f32 + Sync, n_f: impl Fn(usize) -> f32 + Sync, m_f: impl Fn(usize) -> f32 + Sync, @@ -2523,7 +2523,7 @@ pub fn do_erosion( _max_uplift: f32, n_steps: usize, seed: &RandomField, - rock_strength_nz: &(impl NoiseFn<[f64; 3]> + Sync), + rock_strength_nz: &(impl NoiseFn + Sync), oldh: impl Fn(usize) -> f32 + Sync, oldb: impl Fn(usize) -> f32 + Sync, is_ocean: impl Fn(usize) -> bool + Sync, diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index 33e222adc5..8afd8cdbbc 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -55,8 +55,8 @@ use common::{ use common_base::prof_span; use common_net::msg::WorldMapMsg; use noise::{ - BasicMulti, Billow, Fbm, HybridMulti, MultiFractal, NoiseFn, RangeFunction, RidgedMulti, - Seedable, SuperSimplex, Worley, + core::worley::distance_functions, BasicMulti, Billow, Fbm, HybridMulti, MultiFractal, NoiseFn, + Perlin, RidgedMulti, SuperSimplex, }; use num::{traits::FloatConst, Float, Signed}; use rand::{Rng, SeedableRng}; @@ -109,16 +109,16 @@ struct GenCdf { pub(crate) struct GenCtx { pub turb_x_nz: SuperSimplex, pub turb_y_nz: SuperSimplex, - pub chaos_nz: RidgedMulti, - pub alt_nz: util::HybridMulti, + pub chaos_nz: RidgedMulti, + pub alt_nz: util::HybridMulti, pub hill_nz: SuperSimplex, - pub temp_nz: Fbm, + pub temp_nz: Fbm, // Humidity noise - pub humid_nz: Billow, + pub humid_nz: Billow, // Small amounts of noise for simulating rough terrain. - pub small_nz: BasicMulti, - pub rock_nz: HybridMulti, - pub tree_nz: BasicMulti, + pub small_nz: BasicMulti, + pub rock_nz: HybridMulti, + pub tree_nz: BasicMulti, // TODO: unused, remove??? @zesterer pub _cave_0_nz: SuperSimplex, @@ -133,8 +133,8 @@ pub(crate) struct GenCtx { pub _town_gen: StructureGen2d, pub river_seed: RandomField, - pub rock_strength_nz: Fbm, - pub uplift_nz: Worley, + pub rock_strength_nz: Fbm, + pub uplift_nz: util::Worley, } #[derive(Clone, Debug, Deserialize, Serialize)] @@ -716,52 +716,47 @@ impl WorldSim { // NOTE: Changing order will significantly change WorldGen, so try not to! let gen_ctx = GenCtx { - turb_x_nz: SuperSimplex::new().set_seed(rng.gen()), - turb_y_nz: SuperSimplex::new().set_seed(rng.gen()), - chaos_nz: RidgedMulti::new() - .set_octaves(7) - .set_frequency(RidgedMulti::DEFAULT_FREQUENCY * (5_000.0 / continent_scale)) - .set_seed(rng.gen()), - hill_nz: SuperSimplex::new().set_seed(rng.gen()), - alt_nz: util::HybridMulti::new() + turb_x_nz: SuperSimplex::new(rng.gen()), + turb_y_nz: SuperSimplex::new(rng.gen()), + chaos_nz: RidgedMulti::new(rng.gen()).set_octaves(7).set_frequency( + RidgedMulti::::DEFAULT_FREQUENCY * (5_000.0 / continent_scale), + ), + hill_nz: SuperSimplex::new(rng.gen()), + alt_nz: util::HybridMulti::new(rng.gen()) .set_octaves(8) .set_frequency(10_000.0 / continent_scale) // persistence = lacunarity^(-(1.0 - fractal increment)) - .set_lacunarity(util::HybridMulti::DEFAULT_LACUNARITY) - .set_persistence(util::HybridMulti::DEFAULT_LACUNARITY.powi(-1)) - .set_offset(0.0) - .set_seed(rng.gen()), - temp_nz: Fbm::new() + .set_lacunarity(util::HybridMulti::::DEFAULT_LACUNARITY) + .set_persistence(util::HybridMulti::::DEFAULT_LACUNARITY.powi(-1)) + .set_offset(0.0), + temp_nz: Fbm::new(rng.gen()) .set_octaves(6) .set_persistence(0.5) .set_frequency(1.0 / (((1 << 6) * 64) as f64)) - .set_lacunarity(2.0) - .set_seed(rng.gen()), + .set_lacunarity(2.0), - small_nz: BasicMulti::new().set_octaves(2).set_seed(rng.gen()), - rock_nz: HybridMulti::new().set_persistence(0.3).set_seed(rng.gen()), - tree_nz: BasicMulti::new() + small_nz: BasicMulti::new(rng.gen()).set_octaves(2), + rock_nz: HybridMulti::new(rng.gen()).set_persistence(0.3), + tree_nz: BasicMulti::new(rng.gen()) .set_octaves(12) - .set_persistence(0.75) - .set_seed(rng.gen()), - _cave_0_nz: SuperSimplex::new().set_seed(rng.gen()), - _cave_1_nz: SuperSimplex::new().set_seed(rng.gen()), + .set_persistence(0.75), + _cave_0_nz: SuperSimplex::new(rng.gen()), + _cave_1_nz: SuperSimplex::new(rng.gen()), structure_gen: StructureGen2d::new(rng.gen(), 24, 10), _big_structure_gen: StructureGen2d::new(rng.gen(), 768, 512), _region_gen: StructureGen2d::new(rng.gen(), 400, 96), - humid_nz: Billow::new() + humid_nz: Billow::new(rng.gen()) .set_octaves(9) .set_persistence(0.4) - .set_frequency(0.2) - .set_seed(rng.gen()), + .set_frequency(0.2), _fast_turb_x_nz: FastNoise::new(rng.gen()), _fast_turb_y_nz: FastNoise::new(rng.gen()), _town_gen: StructureGen2d::new(rng.gen(), 2048, 1024), river_seed: RandomField::new(rng.gen()), - rock_strength_nz: Fbm::new() + rock_strength_nz: Fbm::new(rng.gen()) .set_octaves(10) .set_lacunarity(rock_lacunarity) // persistence = lacunarity^(-(1.0 - fractal increment)) @@ -770,13 +765,10 @@ impl WorldSim { .set_frequency( 1.0 * (5_000.0 / continent_scale) / (2.0 * TerrainChunkSize::RECT_SIZE.x as f64 * 2.0.powi(10 - 1)), - ) - .set_seed(rng.gen()), - uplift_nz: Worley::new() - .set_seed(rng.gen()) + ), + uplift_nz: util::Worley::new(rng.gen()) .set_frequency(1.0 / (TerrainChunkSize::RECT_SIZE.x as f64 * uplift_scale)) - .set_displacement(1.0) - .set_range_function(RangeFunction::Euclidean), + .set_distance_function(distance_functions::euclidean), }; let river_seed = &gen_ctx.river_seed; diff --git a/world/src/sim/util.rs b/world/src/sim/util.rs index e1367ce0a2..16eb14f2f3 100644 --- a/world/src/sim/util.rs +++ b/world/src/sim/util.rs @@ -4,10 +4,13 @@ use common::{ vol::RectVolSize, }; use common_base::prof_span; -use noise::{MultiFractal, NoiseFn, Perlin, Seedable}; +use noise::{ + core::worley::*, math::vectors::*, permutationtable::PermutationTable, MultiFractal, NoiseFn, + Seedable, +}; use num::Float; use rayon::prelude::*; -use std::ops::Mul; +use std::sync::Arc; use vek::*; /// Calculates the smallest distance along an axis (x, y) from an edge of @@ -445,86 +448,14 @@ pub fn get_horizon_map( Ok([west, east]) } -/// A 2-dimensional vector, for internal use. -type Vector2 = [T; 2]; -/// A 3-dimensional vector, for internal use. -type Vector3 = [T; 3]; -/// A 4-dimensional vector, for internal use. -type Vector4 = [T; 4]; - -#[inline] -fn zip_with2(a: Vector2, b: Vector2, f: F) -> Vector2 +fn build_sources(seed: u32, octaves: usize) -> Vec where - T: Copy, - U: Copy, - F: Fn(T, U) -> V, + Source: Default + Seedable, { - let (ax, ay) = (a[0], a[1]); - let (bx, by) = (b[0], b[1]); - [f(ax, bx), f(ay, by)] -} - -#[inline] -fn zip_with3(a: Vector3, b: Vector3, f: F) -> Vector3 -where - T: Copy, - U: Copy, - F: Fn(T, U) -> V, -{ - let (ax, ay, az) = (a[0], a[1], a[2]); - let (bx, by, bz) = (b[0], b[1], b[2]); - [f(ax, bx), f(ay, by), f(az, bz)] -} - -#[inline] -fn zip_with4(a: Vector4, b: Vector4, f: F) -> Vector4 -where - T: Copy, - U: Copy, - F: Fn(T, U) -> V, -{ - let (ax, ay, az, aw) = (a[0], a[1], a[2], a[3]); - let (bx, by, bz, bw) = (b[0], b[1], b[2], b[3]); - [f(ax, bx), f(ay, by), f(az, bz), f(aw, bw)] -} - -#[inline] -fn mul2(a: Vector2, b: T) -> Vector2 -where - T: Copy + Mul, -{ - zip_with2(a, const2(b), Mul::mul) -} - -#[inline] -fn mul3(a: Vector3, b: T) -> Vector3 -where - T: Copy + Mul, -{ - zip_with3(a, const3(b), Mul::mul) -} - -#[inline] -fn mul4(a: Vector4, b: T) -> Vector4 -where - T: Copy + Mul, -{ - zip_with4(a, const4(b), Mul::mul) -} - -#[inline] -fn const2(x: T) -> Vector2 { [x, x] } - -#[inline] -fn const3(x: T) -> Vector3 { [x, x, x] } - -#[inline] -fn const4(x: T) -> Vector4 { [x, x, x, x] } - -fn build_sources(seed: u32, octaves: usize) -> Vec { let mut sources = Vec::with_capacity(octaves); for x in 0..octaves { - sources.push(Perlin::new().set_seed(seed + x as u32)); + let source = Source::default(); + sources.push(source.set_seed(seed + x as u32)); } sources } @@ -533,8 +464,10 @@ fn build_sources(seed: u32, octaves: usize) -> Vec { /// /// The result of this multifractal noise is that valleys in the noise should /// have smooth bottoms at all altitudes. +/// +/// Copied from noise crate to add offset. #[derive(Clone, Debug)] -pub struct HybridMulti { +pub struct HybridMulti { /// Total number of frequency octaves to generate the noise with. /// /// The number of octaves control the _amount of detail_ in the noise @@ -575,10 +508,14 @@ pub struct HybridMulti { pub offset: f64, seed: u32, - sources: Vec, + sources: Vec, + //scale_factor: f64, } -impl HybridMulti { +impl HybridMulti +where + T: Default + Seedable, +{ pub const DEFAULT_FREQUENCY: f64 = 2.0; pub const DEFAULT_LACUNARITY: f64 = /* std::f64::consts::PI * 2.0 / 3.0 */ 2.0; pub const DEFAULT_OCTAVES: usize = 6; @@ -589,26 +526,60 @@ impl HybridMulti { pub const DEFAULT_SEED: u32 = 0; pub const MAX_OCTAVES: usize = 32; - pub fn new() -> Self { + pub fn new(seed: u32) -> Self { Self { - seed: Self::DEFAULT_SEED, + seed, octaves: Self::DEFAULT_OCTAVES, frequency: Self::DEFAULT_FREQUENCY, lacunarity: Self::DEFAULT_LACUNARITY, persistence: Self::DEFAULT_PERSISTENCE, offset: Self::DEFAULT_OFFSET, - sources: build_sources(Self::DEFAULT_SEED, Self::DEFAULT_OCTAVES), + sources: build_sources(seed, Self::DEFAULT_OCTAVES), + //scale_factor: Self::calc_scale_factor(Self::DEFAULT_PERSISTENCE, + // Self::DEFAULT_OCTAVES), } } pub fn set_offset(self, offset: f64) -> Self { Self { offset, ..self } } + + #[allow(dead_code)] + pub fn set_sources(self, sources: Vec) -> Self { Self { sources, ..self } } + /*fn calc_scale_factor(persistence: f64, octaves: usize) -> f64 { + let mut result = persistence; + + // Do octave 0 + let mut amplitude = persistence; + let mut weight = result; + let mut signal = amplitude; + weight *= signal; + + result += signal; + + if octaves >= 1 { + result += (1..=octaves).fold(0.0, |acc, _| { + amplitude *= persistence; + weight = weight.max(1.0); + signal = amplitude; + weight *= signal; + acc + signal + }); + } + + 2.0 / result + }*/ } -impl Default for HybridMulti { - fn default() -> Self { Self::new() } +impl Default for HybridMulti +where + T: Default + Seedable, +{ + fn default() -> Self { Self::new(Self::DEFAULT_SEED) } } -impl MultiFractal for HybridMulti { +impl MultiFractal for HybridMulti +where + T: Default + Seedable, +{ fn set_octaves(self, mut octaves: usize) -> Self { if self.octaves == octaves { return self; @@ -618,6 +589,7 @@ impl MultiFractal for HybridMulti { Self { octaves, sources: build_sources(self.seed, octaves), + //scale_factor: Self::calc_scale_factor(self.persistence, octaves), ..self } } @@ -629,12 +601,16 @@ impl MultiFractal for HybridMulti { fn set_persistence(self, persistence: f64) -> Self { Self { persistence, + //scale_factor: Self::calc_scale_factor(persistence, self.octaves), ..self } } } -impl Seedable for HybridMulti { +impl Seedable for HybridMulti +where + T: Default + Seedable, +{ fn set_seed(self, seed: u32) -> Self { if self.seed == seed { return self; @@ -651,14 +627,21 @@ impl Seedable for HybridMulti { } /// 2-dimensional `HybridMulti` noise -impl NoiseFn<[f64; 2]> for HybridMulti { - fn get(&self, mut point: [f64; 2]) -> f64 { +impl NoiseFn for HybridMulti +where + T: NoiseFn, +{ + fn get(&self, point: [f64; 2]) -> f64 { + let mut point = Vector2::from(point); + + let mut attenuation = self.persistence; + // First unscaled octave of function; later octaves are scaled. - point = mul2(point, self.frequency); + point *= self.frequency; // Offset and bias to scale into [offset - 1.0, 1.0 + offset] range. let bias = 1.0; - let mut result = (self.sources[0].get(point) + self.offset) * bias * self.persistence; - let mut exp_scale = 1.0; + let mut result = + (self.sources[0].get(point.into_array()) + self.offset) * bias * self.persistence; let mut scale = self.persistence; let mut weight = result; @@ -668,37 +651,49 @@ impl NoiseFn<[f64; 2]> for HybridMulti { weight = weight.min(1.0); // Raise the spatial frequency. - point = mul2(point, self.lacunarity); + point *= self.lacunarity; // Get noise value, and scale it to the [offset - 1.0, 1.0 + offset] range. - let mut signal = (self.sources[x].get(point) + self.offset) * bias; + let mut signal = (self.sources[x].get(point.into_array()) + self.offset) * bias; // Scale the amplitude appropriately for this frequency. - exp_scale *= self.persistence; - signal *= exp_scale; + signal *= attenuation; + + scale += attenuation; + + // Increase the attenuation for the next octave, to be equal to persistence ^ (x + // + 1) + attenuation *= self.persistence; // Add it in, weighted by previous octave's noise value. result += weight * signal; // Update the weighting value. weight *= signal; - scale += exp_scale; } // Scale the result to the [-1,1] range + //result * self.scale_factor (result / scale) / bias - self.offset } } /// 3-dimensional `HybridMulti` noise -impl NoiseFn<[f64; 3]> for HybridMulti { - fn get(&self, mut point: [f64; 3]) -> f64 { +impl NoiseFn for HybridMulti +where + T: NoiseFn, +{ + fn get(&self, point: [f64; 3]) -> f64 { + let mut point = Vector3::from(point); + + let mut attenuation = self.persistence; + // First unscaled octave of function; later octaves are scaled. - point = mul3(point, self.frequency); + point *= self.frequency; // Offset and bias to scale into [offset - 1.0, 1.0 + offset] range. let bias = 1.0; - let mut result = (self.sources[0].get(point) + self.offset) * bias * self.persistence; - let mut exp_scale = 1.0; + let mut result = + (self.sources[0].get(point.into_array()) + self.offset) * bias * self.persistence; let mut scale = self.persistence; let mut weight = result; @@ -708,37 +703,49 @@ impl NoiseFn<[f64; 3]> for HybridMulti { weight = weight.min(1.0); // Raise the spatial frequency. - point = mul3(point, self.lacunarity); + point *= self.lacunarity; // Get noise value, and scale it to the [0, 1.0] range. - let mut signal = (self.sources[x].get(point) + self.offset) * bias; + let mut signal = (self.sources[x].get(point.into_array()) + self.offset) * bias; // Scale the amplitude appropriately for this frequency. - exp_scale *= self.persistence; - signal *= exp_scale; + signal *= attenuation; + + scale += attenuation; + + // Increase the attenuation for the next octave, to be equal to persistence ^ (x + // + 1) + attenuation *= self.persistence; // Add it in, weighted by previous octave's noise value. result += weight * signal; // Update the weighting value. weight *= signal; - scale += exp_scale; } // Scale the result to the [-1,1] range + //result * self.scale_factor (result / scale) / bias - self.offset } } /// 4-dimensional `HybridMulti` noise -impl NoiseFn<[f64; 4]> for HybridMulti { - fn get(&self, mut point: [f64; 4]) -> f64 { +impl NoiseFn for HybridMulti +where + T: NoiseFn, +{ + fn get(&self, point: [f64; 4]) -> f64 { + let mut point = Vector4::from(point); + + let mut attenuation = self.persistence; + // First unscaled octave of function; later octaves are scaled. - point = mul4(point, self.frequency); + point *= self.frequency; // Offset and bias to scale into [offset - 1.0, 1.0 + offset] range. let bias = 1.0; - let mut result = (self.sources[0].get(point) + self.offset) * bias * self.persistence; - let mut exp_scale = 1.0; + let mut result = + (self.sources[0].get(point.into_array()) + self.offset) * bias * self.persistence; let mut scale = self.persistence; let mut weight = result; @@ -748,29 +755,34 @@ impl NoiseFn<[f64; 4]> for HybridMulti { weight = weight.min(1.0); // Raise the spatial frequency. - point = mul4(point, self.lacunarity); + point *= self.lacunarity; // Get noise value, and scale it to the [0, 1.0] range. - let mut signal = (self.sources[x].get(point) + self.offset) * bias; + let mut signal = (self.sources[x].get(point.into_array()) + self.offset) * bias; // Scale the amplitude appropriately for this frequency. - exp_scale *= self.persistence; - signal *= exp_scale; + signal *= attenuation; + + scale += attenuation; + + // Increase the attenuation for the next octave, to be equal to persistence ^ (x + // + 1) + attenuation *= self.persistence; // Add it in, weighted by previous octave's noise value. result += weight * signal; // Update the weighting value. weight *= signal; - scale += exp_scale; } // Scale the result to the [-1,1] range + //result * self.scale_factor (result / scale) / bias - self.offset } } -/* code used by sharp in future +/* code used by sharp in future – note: NoiseFn impl probably broken by noise crate upgrade from 0.7 to 0.9 /// Noise function that applies a scaling factor and a bias to the output value /// from the source function. /// @@ -811,3 +823,121 @@ impl<'a, F: NoiseFn + 'a, T> NoiseFn for ScaleBias<'a, F> { fn get(&self, point: T) -> f64 { (self.source.get(point) * self.scale) + self.bias } } */ + +/// Noise function that outputs Worley noise. +/// +/// Copied from noise crate to make thread-safe. +#[derive(Clone)] +pub struct Worley { + /// Specifies the distance function to use when calculating the boundaries + /// of the cell. + pub distance_function: Arc, + + /// Signifies whether the distance from the borders of the cell should be + /// returned, or the value for the cell. + pub return_type: ReturnType, + + /// Frequency of the seed points. + pub frequency: f64, + + seed: u32, + perm_table: PermutationTable, +} + +type DistanceFunction = dyn Fn(&[f64], &[f64]) -> f64 + Sync + Send; + +impl Worley { + //pub const DEFAULT_SEED: u32 = 0; + pub const DEFAULT_FREQUENCY: f64 = 1.0; + + pub fn new(seed: u32) -> Self { + Self { + perm_table: PermutationTable::new(seed), + seed, + distance_function: Arc::new(distance_functions::euclidean), + return_type: ReturnType::Value, + frequency: Self::DEFAULT_FREQUENCY, + } + } + + /// Sets the distance function used by the Worley cells. + pub fn set_distance_function(self, function: F) -> Self + where + F: Fn(&[f64], &[f64]) -> f64 + 'static + Sync + Send, + { + Self { + distance_function: Arc::new(function), + ..self + } + } + + /// Enables or disables applying the distance from the nearest seed point + /// to the output value. + #[allow(dead_code)] + pub fn set_return_type(self, return_type: ReturnType) -> Self { + Self { + return_type, + ..self + } + } + + /// Sets the frequency of the seed points. + pub fn set_frequency(self, frequency: f64) -> Self { Self { frequency, ..self } } +} + +impl Default for Worley { + fn default() -> Self { Self::new(0) } +} + +impl Seedable for Worley { + /// Sets the seed value used by the Worley cells. + fn set_seed(self, seed: u32) -> Self { + // If the new seed is the same as the current seed, just return self. + if self.seed == seed { + return self; + } + + // Otherwise, regenerate the permutation table based on the new seed. + Self { + perm_table: PermutationTable::new(seed), + seed, + ..self + } + } + + fn seed(&self) -> u32 { self.seed } +} + +impl NoiseFn for Worley { + fn get(&self, point: [f64; 2]) -> f64 { + worley_2d( + &self.perm_table, + &*self.distance_function, + self.return_type, + Vector2::from(point) * self.frequency, + ) + } +} + +impl NoiseFn for Worley { + fn get(&self, point: [f64; 3]) -> f64 { + worley_3d( + &self.perm_table, + &*self.distance_function, + self.return_type, + Vector3::from(point) * self.frequency, + ) + } +} + +#[allow(clippy::cognitive_complexity)] +impl NoiseFn for Worley { + fn get(&self, point: [f64; 4]) -> f64 { + worley_4d( + &self.perm_table, + &*self.distance_function, + self.return_type, + Vector4::from(point) * self.frequency, + ) + } +}