use sophus_autodiff::linalg::VecF64;
use sophus_lie::Isometry3F64;
use crate::{
prelude::*,
renderables::{
color::Color,
LineSegment3,
},
};
pub struct Axes3Builder {
world_from_local_axes: Vec<Isometry3F64>,
scale: f64,
line_width: f32,
}
impl Axes3Builder {
fn new(world_from_local: &[Isometry3F64]) -> Self {
Self {
world_from_local_axes: world_from_local.to_vec(),
scale: 1.0,
line_width: 5.0,
}
}
pub fn scale(&mut self, scale: f64) -> &mut Self {
self.scale = scale;
self
}
pub fn line_width(&mut self, line_width: f32) -> &mut Self {
self.line_width = line_width;
self
}
pub fn build(&self) -> Vec<LineSegment3> {
let zero_in_local = VecF64::<3>::zeros();
let x_axis_local = VecF64::<3>::new(self.scale, 0.0, 0.0);
let y_axis_local = VecF64::<3>::new(0.0, self.scale, 0.0);
let z_axis_local = VecF64::<3>::new(0.0, 0.0, self.scale);
let mut lines = vec![];
for world_from_local in self.world_from_local_axes.iter() {
let zero_in_world = world_from_local.transform(zero_in_local);
let axis_x_in_world = world_from_local.transform(x_axis_local);
let axis_y_in_world = world_from_local.transform(y_axis_local);
let axis_z_in_world = world_from_local.transform(z_axis_local);
lines.push(LineSegment3 {
p0: zero_in_world.cast(),
p1: axis_x_in_world.cast(),
color: Color {
r: 1.0,
g: 0.0,
b: 0.0,
a: 1.0,
},
line_width: self.line_width,
});
lines.push(LineSegment3 {
p0: zero_in_world.cast(),
p1: axis_y_in_world.cast(),
color: Color {
r: 0.0,
g: 1.0,
b: 0.0,
a: 1.0,
},
line_width: self.line_width,
});
lines.push(LineSegment3 {
p0: zero_in_world.cast(),
p1: axis_z_in_world.cast(),
color: Color {
r: 0.0,
g: 0.0,
b: 1.0,
a: 1.0,
},
line_width: self.line_width,
});
}
lines
}
}
pub fn make_axes3(world_from_local_axes: &[Isometry3F64]) -> Vec<LineSegment3> {
Axes3Builder::new(world_from_local_axes).build()
}
pub fn axes3(world_from_local_axes: &[Isometry3F64]) -> Axes3Builder {
Axes3Builder::new(world_from_local_axes)
}
pub fn make_axis3(world_from_local: Isometry3F64) -> Vec<LineSegment3> {
make_axes3(&[world_from_local])
}
pub fn axis3(world_from_local: Isometry3F64) -> Axes3Builder {
Axes3Builder::new(&[world_from_local])
}