use crate::{output::Data, parts::Landscape, util::Key};
use arctk::{
geom::{Ray, Trace},
ord::{X, Y, Z},
};
use rand::prelude::SliceRandom;
use rand::Rng;
#[inline]
pub fn sample<R: Rng>(land: &Landscape, data: &mut Data, index: [usize; 3], mut rng: &mut R) {
let bump_dist = land.sett.bump_dist();
let num_pos_samples = land.sett.super_sampling().num_samples();
let num_cast_samples = land.sett.caster().num_samples();
let weight = 1.0 / num_pos_samples as f64;
let voxel = land.grid.gen_voxel(&index);
let sampler = land.sett.super_sampling();
let caster = land.sett.caster();
for n in 0..num_pos_samples {
let pos = sampler.sample(&voxel, n, rng);
let mut found = false;
let mut order = (0..num_cast_samples).collect::<Vec<i32>>();
order.as_mut_slice().shuffle(&mut rng);
for m in order {
let ray = caster.gen_ray(pos, m);
if let Some(key) = scan(land, ray, bump_dist) {
*data
.maps
.mut_map()
.get_mut(key)
.unwrap()
.get_mut(index)
.unwrap() += weight;
found = true;
break;
}
}
if !found {
println!(
"WARNING! Could not determine key at index: {} : {} : {}",
index[X], index[Y], index[Z],
);
*data.undetermined.get_mut(index).unwrap() += weight;
}
}
}
#[allow(clippy::expect_used)]
#[inline]
#[must_use]
pub fn scan<'a>(land: &'a Landscape, ray: Ray, bump_dist: f64) -> Option<&'a Key> {
debug_assert!(bump_dist > 0.0);
let bound_dist = land
.grid
.boundary()
.dist(&ray)
.expect("Failed to determine distance to grid boundary.");
land.tree.observe(ray, bump_dist, bound_dist).map(|hit| {
let interface: &Key = hit.tag();
let &(ref inside, ref outside) = land
.inters
.map()
.get(interface)
.unwrap_or_else(|| panic!("Entry '{}' not found in interface map.", interface));
if hit.side().is_inside() {
inside
} else {
outside
}
})
}