veloren_world/util/
fast_noise.rs

1use super::{RandomField, Sampler};
2use std::{f32, ops::Add};
3use vek::*;
4
5pub struct FastNoise {
6    noise: RandomField,
7}
8
9impl FastNoise {
10    pub const fn new(seed: u32) -> Self {
11        Self {
12            noise: RandomField::new(seed),
13        }
14    }
15
16    #[expect(clippy::excessive_precision)] // TODO: Pending review in #587
17    fn noise_at(&self, pos: Vec3<i32>) -> f32 {
18        (self.noise.get(pos) & 4095) as f32 * 0.000244140625
19    }
20}
21
22impl Sampler<'static> for FastNoise {
23    type Index = Vec3<f64>;
24    type Sample = f32;
25
26    fn get(&self, pos: Self::Index) -> Self::Sample {
27        // let align_pos = pos.map(|e| e.floor());
28        // let near_pos = align_pos.map(|e| e as i32);
29
30        // let v000 = self.noise_at(near_pos + Vec3::new(0, 0, 0));
31        // let v100 = self.noise_at(near_pos + Vec3::new(1, 0, 0));
32        // let v010 = self.noise_at(near_pos + Vec3::new(0, 1, 0));
33        // let v110 = self.noise_at(near_pos + Vec3::new(1, 1, 0));
34        // let v001 = self.noise_at(near_pos + Vec3::new(0, 0, 1));
35        // let v101 = self.noise_at(near_pos + Vec3::new(1, 0, 1));
36        // let v011 = self.noise_at(near_pos + Vec3::new(0, 1, 1));
37        // let v111 = self.noise_at(near_pos + Vec3::new(1, 1, 1));
38
39        // let factor = (pos - align_pos).map(|e| e as f32);
40
41        // let v00 = v000 + factor.z * (v001 - v000);
42        // let v10 = v010 + factor.z * (v011 - v010);
43        // let v01 = v100 + factor.z * (v101 - v100);
44        // let v11 = v110 + factor.z * (v111 - v110);
45
46        // let v0 = v00 + factor.y * (v01 - v00);
47        // let v1 = v10 + factor.y * (v11 - v10);
48
49        // (v0 + factor.x * (v1 - v0)) * 2.0 - 1.0
50
51        let near_pos = pos.map(|e| e.floor() as i32);
52
53        let v000 = self.noise_at(near_pos + Vec3::new(0, 0, 0));
54        let v100 = self.noise_at(near_pos + Vec3::new(1, 0, 0));
55        let v010 = self.noise_at(near_pos + Vec3::new(0, 1, 0));
56        let v110 = self.noise_at(near_pos + Vec3::new(1, 1, 0));
57        let v001 = self.noise_at(near_pos + Vec3::new(0, 0, 1));
58        let v101 = self.noise_at(near_pos + Vec3::new(1, 0, 1));
59        let v011 = self.noise_at(near_pos + Vec3::new(0, 1, 1));
60        let v111 = self.noise_at(near_pos + Vec3::new(1, 1, 1));
61
62        let factor = pos.map(|e| {
63            let f = e.fract().add(1.0).fract() as f32;
64            f.powi(2) * (3.0 - 2.0 * f)
65        });
66
67        let x00 = v000 + factor.x * (v100 - v000);
68        let x10 = v010 + factor.x * (v110 - v010);
69        let x01 = v001 + factor.x * (v101 - v001);
70        let x11 = v011 + factor.x * (v111 - v011);
71
72        let y0 = x00 + factor.y * (x10 - x00);
73        let y1 = x01 + factor.y * (x11 - x01);
74
75        (y0 + factor.z * (y1 - y0)) * 2.0 - 1.0
76    }
77}
78
79pub struct FastNoise2d {
80    noise: RandomField,
81}
82
83impl FastNoise2d {
84    pub const fn new(seed: u32) -> Self {
85        Self {
86            noise: RandomField::new(seed),
87        }
88    }
89
90    #[expect(clippy::excessive_precision)] // TODO: Pending review in #587
91    fn noise_at(&self, pos: Vec2<i32>) -> f32 {
92        (self.noise.get(Vec3::new(pos.x, pos.y, 0)) & 4095) as f32 * 0.000244140625
93    }
94}
95
96impl Sampler<'static> for FastNoise2d {
97    type Index = Vec2<f64>;
98    type Sample = f32;
99
100    fn get(&self, pos: Self::Index) -> Self::Sample {
101        let near_pos = pos.map(|e| e.floor() as i32);
102
103        let v00 = self.noise_at(near_pos + Vec2::new(0, 0));
104        let v10 = self.noise_at(near_pos + Vec2::new(1, 0));
105        let v01 = self.noise_at(near_pos + Vec2::new(0, 1));
106        let v11 = self.noise_at(near_pos + Vec2::new(1, 1));
107
108        let factor = pos.map(|e| {
109            let f = e.fract().add(1.0).fract() as f32;
110            f.powi(2) * (3.0 - 2.0 * f)
111        });
112
113        let v0 = v00 + factor.x * (v10 - v00);
114        let v1 = v01 + factor.x * (v11 - v01);
115
116        (v0 + factor.y * (v1 - v0)) * 2.0 - 1.0
117    }
118}