use anyhow::Result;
use super::rays::Ray;
use crate::core::sequential_model::SequentialSubModelIter;
pub type TraceResults = Vec<Vec<Result<Ray>>>;
pub fn trace(
sequential_submodel: &mut SequentialSubModelIter,
mut rays: Vec<Ray>,
) -> Vec<Vec<Result<Ray>>> {
let mut results: Vec<Vec<Result<Ray>>> = Vec::with_capacity(sequential_submodel.len() + 1);
for _ in 0..sequential_submodel.len() + 1 {
results.push(Vec::with_capacity(rays.len()));
}
for ray in &rays {
results[0].push(Ok(ray.clone()));
}
for (ctr, step) in sequential_submodel.enumerate() {
let (_, surf, _) = step;
for ray in &mut rays {
if ray.is_terminated() {
results[ctr + 1].push(Err(anyhow::anyhow!("Ray terminated")));
continue;
}
ray.transform(surf);
let (pos, norm) = match ray.intersect(surf, 1000) {
Ok((pos, norm)) => (pos, norm),
Err(e) => {
ray.terminate();
results[ctr + 1].push(Err(e));
continue;
}
};
if surf.outside_clear_aperture(pos) {
ray.terminate();
}
ray.displace(pos);
ray.redirect(&step, norm);
ray.i_transform(surf);
results[ctr + 1].push(Ok(ray.clone()));
}
}
results
}