1use std::sync::atomic::{AtomicI64, Ordering};
4use std::time::{UNIX_EPOCH, SystemTime};
5use std::num::Wrapping;
6
7use glam::{Vec3, DVec3};
8
9
10const MULTIPLIER: Wrapping<i64> = Wrapping(0x5DEECE66D);
11const ADDEND: Wrapping<i64> = Wrapping(0xB);
12const MASK: Wrapping<i64> = Wrapping((1 << 48) - 1);
13
14const FLOAT_DIV: f32 = (1u32 << 24) as f32;
15const DOUBLE_DIV: f64 = (1u64 << 53) as f64;
16
17
18#[inline]
19fn initial_scramble(seed: i64) -> Wrapping<i64> {
20 (Wrapping(seed) ^ MULTIPLIER) & MASK
21}
22
23
24fn gen_seed() -> i64 {
26 static SEED: AtomicI64 = AtomicI64::new(8682522807148012);
27 let mut current = SEED.load(Ordering::Relaxed);
28 loop {
29 let next = current.wrapping_mul(181783497276652981);
30 match SEED.compare_exchange_weak(current, next, Ordering::Relaxed, Ordering::Relaxed) {
31 Ok(_) => {
32 return match SystemTime::now().duration_since(UNIX_EPOCH) {
37 Ok(d) => next ^ (d.as_nanos() as i64),
38 Err(_) => next
39 };
40 }
41 Err(old) => current = old
42 }
43 }
44}
45
46
47#[derive(Debug, Clone)]
50pub struct JavaRandom {
51 seed: Wrapping<i64>,
52 next_gaussian: Option<f64>,
53}
54
55impl Default for JavaRandom {
56 fn default() -> Self {
57 Self::new_seeded()
58 }
59}
60
61impl JavaRandom {
62
63 #[inline]
64 pub fn new(seed: i64) -> JavaRandom {
65 JavaRandom { seed: initial_scramble(seed), next_gaussian: None }
66 }
67
68 #[inline]
69 pub fn new_seeded() -> JavaRandom {
70 Self::new(gen_seed())
71 }
72
73 #[inline]
74 pub fn new_blank() -> JavaRandom {
75 JavaRandom { seed: Wrapping(0), next_gaussian: None }
76 }
77
78 #[inline]
79 pub fn set_seed(&mut self, seed: i64) {
80 self.seed = initial_scramble(seed);
81 }
82
83 #[inline]
84 pub fn get_seed(&self) -> i64 {
85 self.seed.0
86 }
87
88 pub fn next_blank(&mut self) {
89 self.seed = (self.seed * MULTIPLIER + ADDEND) & MASK;
90 }
91
92 #[inline]
93 fn next(&mut self, bits: u8) -> i32 {
94 self.next_blank();
95 (self.seed.0 as u64 >> (48 - bits)) as i32
96 }
97
98 #[inline]
99 pub fn next_int(&mut self) -> i32 {
100 self.next(32)
101 }
102
103 pub fn next_int_bounded(&mut self, bound: i32) -> i32 {
104
105 debug_assert!(bound >= 0, "bound is negative");
106
107 if (bound & -bound) == bound {
108 (((bound as i64).wrapping_mul(self.next(31) as i64)) >> 31) as i32
110 } else {
111
112 let mut bits;
113 let mut val;
114
115 loop {
116 bits = self.next(31);
117 val = bits.rem_euclid(bound);
118 if bits.wrapping_sub(val).wrapping_add(bound - 1) >= 0 {
119 break;
120 }
121 }
122
123 val
124
125 }
126
127 }
128
129 pub fn next_long(&mut self) -> i64 {
130 ((self.next(32) as i64) << 32).wrapping_add(self.next(32) as i64)
131 }
132
133 pub fn next_float(&mut self) -> f32 {
135 self.next(24) as f32 / FLOAT_DIV
136 }
137
138 pub fn next_double(&mut self) -> f64 {
140 let high = (self.next(26) as i64) << 27;
141 let low = self.next(27) as i64;
142 (high.wrapping_add(low) as f64) / DOUBLE_DIV
143 }
144
145 pub fn next_gaussian(&mut self) -> f64 {
147 if let Some(next_gaussian) = self.next_gaussian.take() {
148 next_gaussian
149 } else {
150 loop {
151 let v1 = self.next_double() * 2.0 - 1.0;
152 let v2 = self.next_double() * 2.0 - 1.0;
153 let s = v1 * v1 + v2 * v2;
154 if s < 1.0 && s != 0.0 {
155 let multiplier = (-2.0 * s.ln() / s).sqrt();
156 self.next_gaussian = Some(v2 * multiplier);
157 break v1 * multiplier;
158 }
159 }
160 }
161 }
162
163 pub fn next_float_vec(&mut self) -> Vec3 {
166 Vec3 {
167 x: self.next_float(),
168 y: self.next_float(),
169 z: self.next_float(),
170 }
171 }
172
173 pub fn next_double_vec(&mut self) -> DVec3 {
176 DVec3 {
177 x: self.next_double(),
178 y: self.next_double(),
179 z: self.next_double(),
180 }
181 }
182
183 pub fn next_gaussian_vec(&mut self) -> DVec3 {
187 DVec3 {
188 x: self.next_gaussian(),
189 y: self.next_gaussian(),
190 z: self.next_gaussian(),
191 }
192 }
193
194 #[inline]
197 pub fn next_choice<T: Copy>(&mut self, items: &[T]) -> T {
198 items[self.next_int_bounded(items.len() as i32) as usize]
199 }
200
201 #[inline]
204 pub fn next_choice_ref<'a, T>(&mut self, items: &'a [T]) -> &'a T {
205 &items[self.next_int_bounded(items.len() as i32) as usize]
206 }
207
208 #[inline]
211 pub fn next_choice_mut<'a, T>(&mut self, items: &'a mut [T]) -> &'a mut T {
212 &mut items[self.next_int_bounded(items.len() as i32) as usize]
213 }
214
215}