diff --git a/src/bin/flat/main.rs b/src/bin/flat/main.rs index c1788f8..c9835fa 100644 --- a/src/bin/flat/main.rs +++ b/src/bin/flat/main.rs @@ -193,18 +193,10 @@ impl Space { let cell = RectInside { rect: self.rect }; let ray = cell.ray_to_local(ray); let objs = self.list_objects_inner(); - let hits = Self::trace_to_objects(objs.as_slice(), ray); let dist = cell.to_boundary(ray).expect("Can't get outta here!"); FlatTraceResult { end: Some(cell.ray_to_global(ray.forward(dist))), - objects: hits.into_iter().filter_map(|HitInternal { object, distance }| - if distance < dist { - let pos = ray.forward(distance).pos; - let rel = object.loc.rot.inverse() * (pos - object.loc.pos); - let dir = object.loc.rot.inverse() * ray.dir; - Some(Hit { id: object.id, distance, pos: cell.pos_to_global(pos), rel: Ray { pos: rel, dir } }) - } else { None } - ).collect(), + objects: Self::hit_objects(objs.as_slice(), ray, dist, |pos| cell.pos_to_global(pos)), } } @@ -212,19 +204,11 @@ impl Space { assert_eq!(self.which_subspace(ray.pos), Outer); let cell = basic_shapes::Rect { size: vec2(self.rect.outer_radius, self.rect.external_halflength) }; let objs = self.list_objects_outer(); - let hits = Self::trace_to_objects(objs.as_slice(), ray); let lim = cell.trace_into(ray); let dist = lim.unwrap_or(f32::INFINITY); FlatTraceResult { end: lim.map(|dist| ray.forward(dist)), - objects: hits.into_iter().filter_map(|HitInternal { object, distance }| - if distance < dist { - let pos = ray.forward(distance).pos; - let rel = object.loc.rot.inverse() * (pos - object.loc.pos); - let dir = object.loc.rot.inverse() * ray.dir; - Some(Hit { id: object.id, distance, pos, rel: Ray { pos: rel, dir } }) - } else { None } - ).collect(), + objects: Self::hit_objects(objs.as_slice(), ray, dist, |pos| pos), } } @@ -287,7 +271,6 @@ impl Space { if diff > 0.0 { let t = (-rel.dot(ray.dir) - diff.sqrt()) / ray.dir.length_squared(); if t >= 0.0 { - let pos = ray.forward(t).pos; return Some(HitInternal { object: &obj, distance: t }); } } @@ -295,6 +278,18 @@ impl Space { }).collect() } + fn hit_objects(objs: &[Object], ray: Ray, dist: f32, globalize: impl Fn(Vec2) -> Vec2) -> Vec { + let hits = Self::trace_to_objects(objs, ray); + hits.into_iter().filter_map(|HitInternal { object, distance }| + if distance < dist { + let pos = ray.forward(distance).pos; + let rel = object.loc.rot.inverse() * (pos - object.loc.pos); + let dir = object.loc.rot.inverse() * ray.dir; + Some(Hit { id: object.id, distance, pos: globalize(pos), rel: Ray { pos: rel, dir } }) + } else { None } + ).collect() + } + fn line(&self, a: Vec2, b: Vec2, step: f32) -> Vec { match self.which_subspace(a) { Outer => vec![b],