squirrel3_rs/
lib.rs

1pub mod sq3 {
2    use std::time::Instant;
3    use std::cell::Cell;
4    use std::collections::hash_map::DefaultHasher;
5    use std::hash::{Hash, Hasher};
6    use std::thread;
7
8    thread_local! {
9        static RNG: Rng = Rng::new({
10            let mut hasher = DefaultHasher::new();
11            Instant::now().hash(&mut hasher);
12            thread::current().id().hash(&mut hasher);
13            let hash = hasher.finish();
14            ((hash << 1) | 1) as u32
15        });
16    }
17
18    pub struct Rng {
19        position: Cell<u32>,
20        _seed: Cell<u32>
21    }
22
23    impl Rng {
24        pub fn new(seed: u32) -> Self {
25            Self{
26                position: Cell::new(0),
27                _seed: Cell::new(seed)
28            }
29        }
30
31        #[inline]
32        pub fn seed(&self, value: u32) {
33            self._seed.set(value);
34        }
35
36        #[inline]
37        pub fn rand(&self) -> f32 {
38            let new_pos = self.position.get() + 1;
39            self.position.set(new_pos);
40            normalized(new_pos, self._seed.get())
41        }
42
43        #[inline]
44        pub fn bool(&self) -> bool {
45            self.rand() < 0.5
46        }
47
48        #[inline]
49        pub fn range_i32(&self, min: i32, max: i32) -> i32 {
50            (self.rand() * (max as f32 - min as f32)) as i32 + min
51        }
52
53        #[inline]
54        pub fn range_f32(&self, min: f32, max: f32) -> f32 {
55            (self.rand() * (max - min)) + min
56        }
57
58        #[inline]
59        pub fn range_u8(&self, min: u8, max: u8) -> u8 {
60            (self.rand() * (max as f32 - min as f32)) as u8 + min
61        }
62
63        #[inline]
64        pub fn range_usize(&self, min: usize, max: usize) -> usize {
65            (self.rand() * (max as f32 - min as f32)) as usize + min
66        }
67
68        #[inline]
69        pub fn range_u32(&self, min: u32, max: u32) -> u32 {
70            (self.rand() * (max as f32 - min as f32)) as u32 + min
71        }
72
73        #[inline]
74        pub fn u8(&self, max: u8) -> u8 {
75            (self.rand() * max as f32) as u8
76        }
77
78        #[inline]
79        pub fn usize(&self, max: usize) -> usize {
80            (self.rand() * max as f32) as usize
81        }
82
83        #[inline]
84        pub fn u32(&self, max: u32) -> u32 {
85            (self.rand() * max as f32) as u32
86        }
87
88        #[inline]
89        pub fn shuffle<T>(&self, slice: &mut [T]) {
90            for n in 1..slice.len() {
91                slice.swap(n, self.usize(n + 1));
92            }
93        }
94    }
95
96    // HELPER FUNCTIONS
97    #[inline]
98    pub fn rand() -> f32 {
99        RNG.with(|rng| rng.rand())
100    }
101
102    #[inline]
103    pub fn bool() -> bool {
104        RNG.with(|rng| rng.bool())
105    }
106
107    #[inline]
108    pub fn range_i32(min: i32, max: i32) -> i32 {
109        RNG.with(|rng| rng.range_i32(min, max))
110    }
111
112    #[inline]
113    pub fn range_f32(min: f32, max: f32) -> f32 {
114        RNG.with(|rng| rng.range_f32(min, max))
115    }
116
117    #[inline]
118    pub fn range_u8(min: u8, max: u8) -> u8 {
119        RNG.with(|rng| rng.range_u8(min, max))
120    }
121
122    #[inline]
123    pub fn range_usize(min: usize, max: usize) -> usize {
124        RNG.with(|rng| rng.range_usize(min, max))
125    }
126
127    #[inline]
128    pub fn range_u32(min: u32, max: u32) -> u32 {
129        RNG.with(|rng| rng.range_u32(min, max))
130    }
131
132    #[inline]
133    pub fn u8(max: u8) -> u8 {
134        RNG.with(|rng| rng.u8(max))
135    }
136
137    #[inline]
138    pub fn usize(max: usize) -> usize {
139        RNG.with(|rng| rng.usize(max))
140    }
141
142    #[inline]
143    pub fn u32(max: u32) -> u32 {
144        RNG.with(|rng| rng.u32(max))
145    }
146
147    #[inline]
148    pub fn seed(seed: u32) {
149        RNG.with(|rng| rng.seed(seed))
150    }
151
152    #[inline]
153    pub fn shuffle<T>(slice: &mut [T]) {
154        RNG.with(|rng| rng.shuffle(slice))
155    }
156
157    // NO SIDE EFFECTS FUNCTIONS
158
159    // https://www.youtube.com/watch?v=LWFzPP8ZbdU
160    pub fn squirrel3(position: u32, seed: u32) -> u32 {
161        let mut mangled = position.wrapping_mul(0xB5297A4D);
162        mangled = mangled.wrapping_add(seed);
163        mangled = mangled ^ (mangled >> 8);
164        mangled = mangled.wrapping_add(0x68E31DA4);
165        mangled = mangled ^ (mangled << 8);
166        mangled = mangled.wrapping_mul(0x1B56C4E9);
167        mangled = mangled ^ (mangled >> 8);
168        mangled
169    }
170
171    #[inline]
172    pub fn normalized(position: u32, seed: u32) -> f32 {
173        squirrel3(position, seed) as f32 / u32::MAX as f32
174    }
175
176    #[inline]
177    pub fn noise1d(position: u32) -> f32 {
178        normalized(position, 0)
179    }
180
181    #[inline]
182    pub fn noise2d(x: u32, y: u32) -> f32 {
183        normalized(x.wrapping_add(y.wrapping_mul(198491317)), 0)
184    }
185
186    #[inline]
187    pub fn noise3d(x: u32, y: u32, z: u32) -> f32 {
188        normalized(x.wrapping_add(y.wrapping_mul(198491317)).wrapping_add(z.wrapping_mul(6542989)), 0)
189    }
190}