1use crate::{ray::Ray, volumes::scaled::Scaled};
2use std::fmt::Debug;
3use vek::*;
4
5pub trait VolSize: Clone {
8 const SIZE: Vec3<u32>;
9}
10
11pub trait RectVolSize: Clone {
12 const RECT_SIZE: Vec2<u32>;
13}
14
15pub trait FilledVox: Sized + Clone + PartialEq {
17 fn default_non_filled() -> Self;
18 fn is_filled(&self) -> bool;
19
20 #[must_use]
21 fn or(self, other: Self) -> Self { if self.is_filled() { self } else { other } }
22}
23
24pub trait BaseVol {
26 type Vox;
27 type Error: Debug;
28
29 fn scaled_by(self, scale: Vec3<f32>) -> Scaled<Self>
30 where
31 Self: Sized,
32 {
33 Scaled { inner: self, scale }
34 }
35}
36
37impl<T: BaseVol> BaseVol for &T {
40 type Error = T::Error;
41 type Vox = T::Vox;
42}
43
44pub trait SizedVol: BaseVol {
48 fn lower_bound(&self) -> Vec3<i32>;
50
51 fn upper_bound(&self) -> Vec3<i32>;
53
54 fn size(&self) -> Vec3<u32> { (self.upper_bound() - self.lower_bound()).map(|e| e as u32) }
56}
57
58pub trait RasterableVol: BaseVol {
62 const SIZE: Vec3<u32>;
63}
64
65impl<V: RasterableVol> SizedVol for V {
66 fn lower_bound(&self) -> Vec3<i32> { Vec3::zero() }
67
68 fn upper_bound(&self) -> Vec3<i32> { V::SIZE.map(|e| e as i32) }
69}
70
71pub trait RectSizedVol: BaseVol {
73 fn lower_bound_xy(&self) -> Vec2<i32>;
74
75 fn upper_bound_xy(&self) -> Vec2<i32>;
76
77 fn size_xy(&self) -> Vec2<u32> {
78 (self.upper_bound_xy() - self.lower_bound_xy()).map(|e| e as u32)
79 }
80}
81
82pub trait RectRasterableVol: BaseVol {
87 const RECT_SIZE: Vec2<u32>;
88}
89
90impl<V: RectRasterableVol> RectSizedVol for V {
91 fn lower_bound_xy(&self) -> Vec2<i32> { Vec2::zero() }
92
93 fn upper_bound_xy(&self) -> Vec2<i32> { V::RECT_SIZE.map(|e| e as i32) }
94}
95
96pub trait ReadVol: BaseVol {
98 fn get(&self, pos: Vec3<i32>) -> Result<&Self::Vox, Self::Error>;
100
101 fn get_unchecked(&self, pos: Vec3<i32>) -> &Self::Vox { self.get(pos).unwrap() }
105
106 fn ray(
110 &self,
111 from: Vec3<f32>,
112 to: Vec3<f32>,
113 ) -> Ray<Self, fn(&Self::Vox) -> bool, fn(&Self::Vox, Vec3<i32>)>
114 where
115 Self: Sized,
116 {
117 Ray::new(self, from, to, |_| false)
118 }
119
120 fn for_each_in(&self, aabb: Aabb<i32>, mut f: impl FnMut(Vec3<i32>, Self::Vox))
123 where
124 Self::Vox: Copy,
125 {
126 for z in aabb.min.z..aabb.max.z + 1 {
127 for y in aabb.min.y..aabb.max.y + 1 {
128 for x in aabb.min.x..aabb.max.x + 1 {
129 if let Ok(block) = self.get(Vec3::new(x, y, z)) {
130 f(Vec3::new(x, y, z), *block);
131 }
132 }
133 }
134 }
135 }
136}
137
138pub trait SampleVol<I>: BaseVol {
143 type Sample: BaseVol + ReadVol;
144 fn sample(&self, range: I) -> Result<Self::Sample, Self::Error>;
152}
153
154pub trait WriteVol: BaseVol {
156 fn set(&mut self, pos: Vec3<i32>, vox: Self::Vox) -> Result<Self::Vox, Self::Error>;
159
160 fn map<F: FnOnce(Self::Vox) -> Self::Vox>(
163 &mut self,
164 pos: Vec3<i32>,
165 f: F,
166 ) -> Result<Self::Vox, Self::Error>
167 where
168 Self: ReadVol,
169 Self::Vox: Clone,
170 {
171 self.set(pos, f(self.get(pos)?.clone()))
174 }
175}
176
177pub trait IntoVolIterator<'a>: BaseVol
180where
181 Self::Vox: 'a,
182{
183 type IntoIter: Iterator<Item = (Vec3<i32>, &'a Self::Vox)>;
184
185 fn vol_iter(self, lower_bound: Vec3<i32>, upper_bound: Vec3<i32>) -> Self::IntoIter;
186}
187
188pub trait IntoPosIterator: BaseVol {
189 type IntoIter: Iterator<Item = Vec3<i32>>;
190
191 fn pos_iter(self, lower_bound: Vec3<i32>, upper_bound: Vec3<i32>) -> Self::IntoIter;
192}
193
194pub trait IntoFullVolIterator<'a>: BaseVol
199where
200 Self::Vox: 'a,
201{
202 type IntoIter: Iterator<Item = (Vec3<i32>, &'a Self::Vox)>;
203
204 fn full_vol_iter(self) -> Self::IntoIter;
205}
206
207impl<'a, T: 'a + SizedVol> IntoFullVolIterator<'a> for &'a T
213where
214 Self: IntoVolIterator<'a>,
215{
216 type IntoIter = <Self as IntoVolIterator<'a>>::IntoIter;
217
218 fn full_vol_iter(self) -> Self::IntoIter {
219 self.vol_iter(self.lower_bound(), self.upper_bound())
220 }
221}
222
223pub trait IntoFullPosIterator: BaseVol {
224 type IntoIter: Iterator<Item = Vec3<i32>>;
225
226 fn full_pos_iter(self) -> Self::IntoIter;
227}
228
229impl<'a, T: 'a + SizedVol> IntoFullPosIterator for &'a T
230where
231 Self: IntoPosIterator,
232{
233 type IntoIter = <Self as IntoPosIterator>::IntoIter;
234
235 fn full_pos_iter(self) -> Self::IntoIter {
236 self.pos_iter(self.lower_bound(), self.upper_bound())
237 }
238}
239
240#[derive(Clone)]
245pub struct DefaultPosIterator {
246 current: Vec3<i32>,
247 begin: Vec2<i32>,
248 end: Vec3<i32>,
249}
250
251impl DefaultPosIterator {
252 pub fn new(lower_bound: Vec3<i32>, upper_bound: Vec3<i32>) -> Self {
253 debug_assert!(lower_bound.map2(upper_bound, |l, u| l <= u).reduce_and());
254 let end = if lower_bound.map2(upper_bound, |l, u| l < u).reduce_and() {
255 upper_bound
256 } else {
257 lower_bound
260 };
261 Self {
262 current: lower_bound,
263 begin: From::from(lower_bound),
264 end,
265 }
266 }
267}
268
269impl Iterator for DefaultPosIterator {
270 type Item = Vec3<i32>;
271
272 fn next(&mut self) -> Option<Vec3<i32>> {
273 if self.current.z == self.end.z {
274 return None;
275 }
276 let ret = self.current;
277 self.current.x += 1;
278 if self.current.x == self.end.x {
279 self.current.x = self.begin.x;
280 self.current.y += 1;
281 if self.current.y == self.end.y {
282 self.current.y = self.begin.y;
283 self.current.z += 1;
284 }
285 }
286 Some(ret)
287 }
288}
289
290#[derive(Clone)]
293pub struct DefaultVolIterator<'a, T: ReadVol> {
294 vol: &'a T,
295 pos_iter: DefaultPosIterator,
296}
297
298impl<'a, T: ReadVol> DefaultVolIterator<'a, T> {
299 pub fn new(vol: &'a T, lower_bound: Vec3<i32>, upper_bound: Vec3<i32>) -> Self {
300 Self {
301 vol,
302 pos_iter: DefaultPosIterator::new(lower_bound, upper_bound),
303 }
304 }
305}
306
307impl<'a, T: ReadVol> Iterator for DefaultVolIterator<'a, T> {
308 type Item = (Vec3<i32>, &'a T::Vox);
309
310 fn next(&mut self) -> Option<(Vec3<i32>, &'a T::Vox)> {
311 for pos in &mut self.pos_iter {
312 if let Ok(vox) = self.vol.get(pos) {
313 return Some((pos, vox));
314 }
315 }
316 None
317 }
318}
319
320impl<T: ReadVol> ReadVol for &T {
321 #[inline(always)]
322 fn get(&self, pos: Vec3<i32>) -> Result<&'_ Self::Vox, Self::Error> { (*self).get(pos) }
323}