veloren_world/util/
random.rs

1use super::{Sampler, seed_expan};
2use rand::RngCore;
3use vek::*;
4
5#[derive(Clone, Copy)]
6pub struct RandomField {
7    seed: u32,
8}
9
10impl RandomField {
11    pub const fn new(seed: u32) -> Self { Self { seed } }
12
13    pub fn chance(&self, pos: Vec3<i32>, chance: f32) -> bool { self.get_f32(pos) < chance }
14
15    pub fn get_f32(&self, pos: Vec3<i32>) -> f32 {
16        (self.get(pos) % (1 << 16)) as f32 / ((1 << 16) as f32)
17    }
18
19    pub fn choose<'a, T>(&self, pos: Vec3<i32>, slice: &'a [T]) -> Option<&'a T> {
20        if slice.is_empty() {
21            return None;
22        }
23
24        let i = self.get(pos) as usize;
25        slice.get(i % slice.len())
26    }
27}
28
29impl Sampler<'static> for RandomField {
30    type Index = Vec3<i32>;
31    type Sample = u32;
32
33    fn get(&self, pos: Self::Index) -> Self::Sample {
34        let pos = pos.map(|e| u32::from_le_bytes(e.to_le_bytes()));
35
36        let mut a = self.seed;
37        a = (a ^ 61) ^ (a >> 16);
38        a = a.wrapping_add(a << 3);
39        a ^= pos.x;
40        a ^= a >> 4;
41        a = a.wrapping_mul(0x27d4eb2d);
42        a ^= a >> 15;
43        a ^= pos.y;
44        a = (a ^ 61) ^ (a >> 16);
45        a = a.wrapping_add(a << 3);
46        a ^= a >> 4;
47        a ^= pos.z;
48        a = a.wrapping_mul(0x27d4eb2d);
49        a ^= a >> 15;
50        a
51    }
52}
53
54pub struct RandomPerm {
55    seed: u32,
56}
57
58impl RandomPerm {
59    pub const fn new(seed: u32) -> Self { Self { seed } }
60
61    pub fn chance(&self, perm: u32, chance: f32) -> bool {
62        (self.get(perm) % (1 << 16)) as f32 / ((1 << 16) as f32) < chance
63    }
64}
65
66impl Sampler<'static> for RandomPerm {
67    type Index = u32;
68    type Sample = u32;
69
70    fn get(&self, perm: Self::Index) -> Self::Sample {
71        seed_expan::diffuse_mult(&[self.seed, perm])
72    }
73}
74
75// `RandomPerm` is not high-quality but it is at least fast and deterministic.
76impl RngCore for RandomPerm {
77    fn next_u32(&mut self) -> u32 {
78        self.seed = self.get(self.seed) ^ 0xA7535839;
79        self.seed
80    }
81
82    fn next_u64(&mut self) -> u64 {
83        let a = self.next_u32();
84        let b = self.next_u32();
85        ((a as u64) << 32) | b as u64
86    }
87
88    fn fill_bytes(&mut self, dest: &mut [u8]) {
89        dest.iter_mut()
90            .for_each(|b| *b = (self.next_u32() & 0xFF) as u8);
91    }
92
93    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
94        self.fill_bytes(dest);
95        Ok(())
96    }
97}