use crate::rapier::pipeline::{DebugColor, DebugRenderBackend, DebugRenderObject};
use nexus::rbd::math::Vector;
#[derive(Copy, Clone, Debug)]
pub struct DebugLine {
pub a: Vector,
pub b: Vector,
pub color: [f32; 4],
}
#[derive(Copy, Clone, Debug)]
pub struct DebugPoint {
pub point: Vector,
pub color: [f32; 4],
}
#[derive(Default)]
pub struct LineCollector {
pub lines: Vec<DebugLine>,
}
impl LineCollector {
pub fn push_rgba(&mut self, a: Vector, b: Vector, color: [f32; 4]) {
self.lines.push(DebugLine { a, b, color });
}
}
impl DebugRenderBackend for LineCollector {
fn draw_line(&mut self, _: DebugRenderObject, a: Vector, b: Vector, color: DebugColor) {
self.lines.push(DebugLine {
a,
b,
color: hsla_to_rgba(color),
});
}
}
pub fn hsla_to_rgba([h, s, l, a]: DebugColor) -> [f32; 4] {
let c = (1.0 - (2.0 * l - 1.0).abs()) * s;
let h6 = (h / 60.0).rem_euclid(6.0);
let x = c * (1.0 - (h6 % 2.0 - 1.0).abs());
let (r, g, b) = match h6 as u32 {
0 => (c, x, 0.0),
1 => (x, c, 0.0),
2 => (0.0, c, x),
3 => (0.0, x, c),
4 => (x, 0.0, c),
_ => (c, 0.0, x),
};
let m = l - c / 2.0;
[r + m, g + m, b + m, a]
}
#[cfg(feature = "dim2")]
pub(super) fn push_box(mins: Vector, maxs: Vector, color: [f32; 4], lines: &mut Vec<DebugLine>) {
let corners = [
mins,
Vector::new(maxs.x, mins.y),
maxs,
Vector::new(mins.x, maxs.y),
];
for i in 0..4 {
lines.push(DebugLine {
a: corners[i],
b: corners[(i + 1) % 4],
color,
});
}
}
#[cfg(feature = "dim3")]
pub(super) fn push_box(mins: Vector, maxs: Vector, color: [f32; 4], lines: &mut Vec<DebugLine>) {
let corner = |i: usize| {
Vector::new(
if i & 1 != 0 { maxs.x } else { mins.x },
if i & 2 != 0 { maxs.y } else { mins.y },
if i & 4 != 0 { maxs.z } else { mins.z },
)
};
for i in 0..8usize {
for bit in [1, 2, 4] {
let j = i ^ bit;
if j > i {
lines.push(DebugLine {
a: corner(i),
b: corner(j),
color,
});
}
}
}
}