layer_proc_gen/generic_layers/
reduced_points.rs1use std::{ops::Range, sync::Arc};
2
3use arrayvec::ArrayVec;
4
5use crate::{
6 Chunk, Layer,
7 debug::{Debug, DebugContent},
8 rolling_grid::GridPoint,
9 vec2::{Bounds, Point2d},
10};
11
12use super::UniformPoint;
13
14pub trait Reducible: From<Point2d> + PartialEq + Clone + Sized + 'static {
18 const RADIUS_RANGE: Range<i64>;
20
21 fn radius(&self) -> i64;
23 fn position(&self) -> Point2d;
25 fn debug(&self) -> Vec<DebugContent> {
28 vec![DebugContent::Circle {
29 center: self.position(),
30 radius: self.radius() as f32,
31 }]
32 }
33}
34
35#[derive(PartialEq, Debug, Clone)]
36pub struct ReducedUniformPoint<P, const SIZE: u8, const SALT: u64> {
38 pub points: ArrayVec<P, 7>,
40}
41
42impl<P, const SIZE: u8, const SALT: u64> Default for ReducedUniformPoint<P, SIZE, SALT> {
43 fn default() -> Self {
44 Self {
45 points: Default::default(),
46 }
47 }
48}
49
50impl<P: Reducible, const SIZE: u8, const SALT: u64> Chunk for ReducedUniformPoint<P, SIZE, SALT> {
51 type LayerStore<T> = Arc<T>;
52 type Dependencies = Layer<UniformPoint<P, SIZE, SALT>>;
53 const SIZE: Point2d<u8> = Point2d::splat(SIZE);
54
55 fn compute(raw_points: &Self::Dependencies, index: GridPoint<Self>) -> Self {
56 let mut points = ArrayVec::new();
57 'points: for p in raw_points
58 .get_or_compute(index.into_same_chunk_size())
59 .points
60 {
61 for other in raw_points.get_range(
62 Bounds::point(p.position()).pad(Point2d::splat(p.radius() + P::RADIUS_RANGE.end)),
63 ) {
64 for other in other.points {
65 if other == p {
66 continue;
67 }
68
69 let lower_priority = p
71 .radius()
72 .cmp(&other.radius())
73 .then_with(|| p.position().cmp(&other.position()))
74 .is_lt();
75
76 if other.position().manhattan_dist(p.position()) < p.radius() + other.radius()
78 && lower_priority
79 {
80 continue 'points;
81 }
82 }
83 }
84 points.push(p);
85 }
86 ReducedUniformPoint { points }
87 }
88
89 fn clear(raw_points: &Self::Dependencies, index: GridPoint<Self>) {
90 raw_points.clear(Self::bounds(index));
91 }
92}
93
94impl<P: Reducible, const SIZE: u8, const SALT: u64> Debug for ReducedUniformPoint<P, SIZE, SALT> {
95 fn debug(&self) -> Vec<DebugContent> {
96 self.points
97 .iter()
98 .flat_map(|p| {
99 let mut debug = p.debug();
100 for debug in &mut debug {
101 match debug {
103 DebugContent::Line(..) => {}
104 DebugContent::Circle { radius, .. } => *radius = 1.,
105 DebugContent::Text { .. } => {}
106 }
107 }
108 debug
109 })
110 .collect()
111 }
112}