veloren/common/src/volumes/scaled.rs

48 lines
1.5 KiB
Rust
Raw Normal View History

2020-04-24 14:20:16 +00:00
use crate::vol::{BaseVol, ReadVol, SizedVol, Vox};
use vek::*;
pub struct Scaled<'a, V> {
pub inner: &'a V,
pub scale: Vec3<f32>,
}
impl<'a, V: BaseVol> BaseVol for Scaled<'a, V> {
type Error = V::Error;
type Vox = V::Vox;
}
impl<'a, V: ReadVol> ReadVol for Scaled<'a, V> {
#[inline(always)]
fn get(&self, pos: Vec3<i32>) -> Result<&Self::Vox, Self::Error> {
let pos = pos.map2(self.scale, |e, scale| (e as f32 / scale).trunc() as i32);
let search_size = (Vec3::one() / self.scale).map(|e: f32| e.ceil() as i32);
(-search_size.x / 2..search_size.x / 2)
.map(|i| {
(-search_size.y / 2..search_size.y / 2).map(move |j| {
(-search_size.z / 2..search_size.z / 2).map(move |k| Vec3::new(i, j, k))
})
})
.flatten()
.flatten()
.map(|offs| self.inner.get(pos + offs))
.find(|vox| vox.as_ref().map(|v| !v.is_empty()).unwrap_or(false))
.unwrap_or_else(|| self.inner.get(pos))
}
}
impl<'a, V: SizedVol> SizedVol for Scaled<'a, V> {
#[inline(always)]
fn lower_bound(&self) -> Vec3<i32> {
self.inner
.lower_bound()
.map2(self.scale, |e, scale| (e as f32 * scale).floor() as i32)
2020-04-24 14:20:16 +00:00
}
#[inline(always)]
fn upper_bound(&self) -> Vec3<i32> {
self.inner
.upper_bound()
.map2(self.scale, |e, scale| ((e as f32 - 1.0) * scale).floor() as i32 + 1)
2020-04-24 14:20:16 +00:00
}
}