use glam::{IVec2, Vec2}; // Amanatides and Woo's fast Voxel Traversal pub struct AwDda { next: IVec2, step_sign: IVec2, step_delta: Vec2, t_max: Vec2, } impl AwDda { pub fn new(from: Vec2, to: Vec2) -> Self { let first = from.round().as_ivec2(); // direction we step for each component on each iteration let from_to_delta = to - from; let step_sign = from_to_delta.signum().as_ivec2(); let step_delta = 1.0 / from_to_delta.abs(); let frac = Vec2::new( if step_sign.x > 0 { (first.x as f32 + 0.5) - from.x } else { from.x - (first.x as f32 - 0.5) }, if step_sign.y > 0 { (first.y as f32 + 0.5) - from.y } else { from.y - (first.y as f32 - 0.5) }, ); let t_max = frac * step_delta; AwDda { next: first, step_sign, step_delta, t_max, } } } impl Iterator for AwDda { type Item = IVec2; fn next(&mut self) -> Option { if self.t_max.min_element() >= 1.0 { return None; } let cur = self.next; if self.t_max.x < self.t_max.y { self.next.x += self.step_sign.x; self.t_max.x += self.step_delta.x; } else { self.next.y += self.step_sign.y; self.t_max.y += self.step_delta.y; } Some(cur) } }