layer_proc_gen/
generic_layers.rs1use arrayvec::ArrayVec;
4use rand::prelude::*;
5
6use crate::{
7 Chunk,
8 debug::{Debug, DebugContent},
9 rolling_grid::GridPoint,
10 vec2::{Num, Point2d},
11};
12
13fn poisson_1(val: f32) -> u8 {
17 match val {
18 0.0..0.3679 => 0,
19 0.3670..0.7358 => 1,
20 0.7358..0.9197 => 2,
21 0.9197..0.981 => 3,
22 0.981..0.9963 => 4,
23 0.9963..0.9994 => 5,
24 0.9994..0.9999 => 6,
25 0.9999..1.0 => 7,
26 _ => panic!("{val} is not in range 0..1"),
27 }
28}
29
30#[derive(PartialEq, Debug, Clone)]
31pub struct UniformPoint<P, const SIZE: u8, const SALT: u64> {
36 pub points: ArrayVec<P, 7>,
39}
40
41impl<P, const SIZE: u8, const SALT: u64> Default for UniformPoint<P, SIZE, SALT> {
42 fn default() -> Self {
43 Self {
44 points: Default::default(),
45 }
46 }
47}
48
49impl<P: Reducible, const SIZE: u8, const SALT: u64> Chunk for UniformPoint<P, SIZE, SALT> {
50 type LayerStore<T> = T;
51 type Dependencies = ();
52
53 const SIZE: Point2d<u8> = Point2d::splat(SIZE);
54
55 fn compute((): &Self::Dependencies, index: GridPoint<Self>) -> Self {
56 let points = generate_points::<SALT, Self>(index);
57 Self {
58 points: points.map(P::from).collect(),
59 }
60 }
61
62 fn clear((): &Self::Dependencies, _index: GridPoint<Self>) {
63 }
65}
66
67impl<P: Reducible, const SIZE: u8, const SALT: u64> Debug for UniformPoint<P, SIZE, SALT> {
68 fn debug(&self) -> Vec<DebugContent> {
69 self.points.iter().flat_map(Reducible::debug).collect()
70 }
71}
72
73fn generate_points<const SALT: u64, C: Chunk + 'static>(
74 index: GridPoint<C>,
75) -> impl Iterator<Item = Point2d> {
76 let chunk_bounds = C::bounds(index);
77 let mut rng = rng_for_point::<SALT, _>(index);
78 let n = poisson_1(rng.random_range(0.0..=1.0)).into();
79 std::iter::from_fn(move || Some(chunk_bounds.sample(&mut rng))).take(n)
80}
81
82pub fn rng_for_point<const SALT: u64, T: Num>(index: Point2d<T>) -> SmallRng {
84 let x = SmallRng::seed_from_u64(index.x.as_u64());
85 let y = SmallRng::seed_from_u64(index.y.as_u64());
86 let salt = SmallRng::seed_from_u64(SALT);
87 let mut seed = <SmallRng as SeedableRng>::Seed::default();
88 for mut rng in [x, y, salt] {
89 let mut tmp = <SmallRng as SeedableRng>::Seed::default();
90 rng.fill_bytes(&mut tmp);
91 for (seed, tmp) in seed.iter_mut().zip(tmp.iter()) {
92 *seed ^= *tmp;
93 }
94 }
95 SmallRng::from_seed(seed)
96}
97
98mod reduced_points;
99pub use reduced_points::*;