Merge branch 'neura/update-noise' into 'master'

Update noise

See merge request veloren/veloren!4512
This commit is contained in:
Marcel 2024-06-26 12:12:15 +00:00
commit 6a4fcbe412
10 changed files with 348 additions and 281 deletions

143
Cargo.lock generated
View File

@ -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"

View File

@ -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" }

View File

@ -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 = [

View File

@ -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<Turbulence<SuperSimplex, Perlin>, 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() {

View File

@ -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 }

View File

@ -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<Turbulence<SuperSimplex, Perlin>, 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;

View File

@ -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<Perlin>,
}
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),
}
}
}

View File

@ -550,7 +550,7 @@ pub fn get_rivers<F: fmt::Debug + Float + Into<f64>, G: Float + Into<f64>>(
fn get_max_slope(
map_size_lg: MapSizeLg,
h: &[Alt],
rock_strength_nz: &(impl NoiseFn<[f64; 3]> + Sync),
rock_strength_nz: &(impl NoiseFn<f64, 3> + 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<f64, 3> + 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<f64, 3> + Sync),
oldh: impl Fn(usize) -> f32 + Sync,
oldb: impl Fn(usize) -> f32 + Sync,
is_ocean: impl Fn(usize) -> bool + Sync,

View File

@ -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<Perlin>,
pub alt_nz: util::HybridMulti<Perlin>,
pub hill_nz: SuperSimplex,
pub temp_nz: Fbm,
pub temp_nz: Fbm<Perlin>,
// Humidity noise
pub humid_nz: Billow,
pub humid_nz: Billow<Perlin>,
// Small amounts of noise for simulating rough terrain.
pub small_nz: BasicMulti,
pub rock_nz: HybridMulti,
pub tree_nz: BasicMulti,
pub small_nz: BasicMulti<Perlin>,
pub rock_nz: HybridMulti<Perlin>,
pub tree_nz: BasicMulti<Perlin>,
// 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<Perlin>,
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::<Perlin>::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::<Perlin>::DEFAULT_LACUNARITY)
.set_persistence(util::HybridMulti::<Perlin>::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;

View File

@ -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<F: Float + Sync, A: Send, H: Send>(
Ok([west, east])
}
/// A 2-dimensional vector, for internal use.
type Vector2<T> = [T; 2];
/// A 3-dimensional vector, for internal use.
type Vector3<T> = [T; 3];
/// A 4-dimensional vector, for internal use.
type Vector4<T> = [T; 4];
#[inline]
fn zip_with2<T, U, V, F>(a: Vector2<T>, b: Vector2<U>, f: F) -> Vector2<V>
fn build_sources<Source>(seed: u32, octaves: usize) -> Vec<Source>
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<T, U, V, F>(a: Vector3<T>, b: Vector3<U>, f: F) -> Vector3<V>
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<T, U, V, F>(a: Vector4<T>, b: Vector4<U>, f: F) -> Vector4<V>
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<T>(a: Vector2<T>, b: T) -> Vector2<T>
where
T: Copy + Mul<T, Output = T>,
{
zip_with2(a, const2(b), Mul::mul)
}
#[inline]
fn mul3<T>(a: Vector3<T>, b: T) -> Vector3<T>
where
T: Copy + Mul<T, Output = T>,
{
zip_with3(a, const3(b), Mul::mul)
}
#[inline]
fn mul4<T>(a: Vector4<T>, b: T) -> Vector4<T>
where
T: Copy + Mul<T, Output = T>,
{
zip_with4(a, const4(b), Mul::mul)
}
#[inline]
fn const2<T: Copy>(x: T) -> Vector2<T> { [x, x] }
#[inline]
fn const3<T: Copy>(x: T) -> Vector3<T> { [x, x, x] }
#[inline]
fn const4<T: Copy>(x: T) -> Vector4<T> { [x, x, x, x] }
fn build_sources(seed: u32, octaves: usize) -> Vec<Perlin> {
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<Perlin> {
///
/// 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<T> {
/// 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<Perlin>,
sources: Vec<T>,
//scale_factor: f64,
}
impl HybridMulti {
impl<T> HybridMulti<T>
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<T>) -> 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<T> Default for HybridMulti<T>
where
T: Default + Seedable,
{
fn default() -> Self { Self::new(Self::DEFAULT_SEED) }
}
impl MultiFractal for HybridMulti {
impl<T> MultiFractal for HybridMulti<T>
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<T> Seedable for HybridMulti<T>
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<T> NoiseFn<f64, 2> for HybridMulti<T>
where
T: NoiseFn<f64, 2>,
{
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<T> NoiseFn<f64, 3> for HybridMulti<T>
where
T: NoiseFn<f64, 3>,
{
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<T> NoiseFn<f64, 4> for HybridMulti<T>
where
T: NoiseFn<f64, 4>,
{
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<T> + 'a, T> NoiseFn<T> 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<DistanceFunction>,
/// 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<F>(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<f64, 2> 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<f64, 3> 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<f64, 4> 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,
)
}
}