#[cfg(feature = "visualization")]
use apex_manifolds::{se2::SE2, se3::SE3};
#[cfg(feature = "visualization")]
use rerun::{Arrows2D, Arrows3D, Points2D, Points3D, Transform3D, Vec2D, Vec3D};
#[cfg(feature = "visualization")]
pub trait ToRerunTransform3D {
fn to_rerun_transform(&self) -> Transform3D;
}
#[cfg(feature = "visualization")]
pub trait ToRerunVec3D {
fn to_rerun_vec3d(&self) -> Vec3D;
}
#[cfg(feature = "visualization")]
pub trait ToRerunPoints3D {
fn to_rerun_points3d(&self) -> Points3D;
}
#[cfg(feature = "visualization")]
pub trait ToRerunArrows3D {
fn to_rerun_arrows3d(&self) -> Arrows3D;
}
#[cfg(feature = "visualization")]
pub trait ToRerunVec2D {
fn to_rerun_vec2d(&self) -> Vec2D;
}
#[cfg(feature = "visualization")]
pub trait ToRerunPoints2D {
fn to_rerun_points2d(&self) -> Points2D;
}
#[cfg(feature = "visualization")]
pub trait ToRerunArrows2D {
fn to_rerun_arrows2d(&self) -> Arrows2D;
}
#[cfg(feature = "visualization")]
pub trait ToRerunTransform3DFrom2D {
fn to_rerun_transform_3d(&self) -> Transform3D;
}
#[cfg(feature = "visualization")]
pub trait CollectRerunPoints3D<'a> {
fn collect_points3d(self) -> Points3D;
}
#[cfg(feature = "visualization")]
pub trait CollectRerunArrows3D<'a> {
fn collect_arrows3d(self) -> Arrows3D;
}
#[cfg(feature = "visualization")]
pub trait CollectRerunPoints2D<'a> {
fn collect_points2d(self) -> Points2D;
}
#[cfg(feature = "visualization")]
pub trait CollectRerunArrows2D<'a> {
fn collect_arrows2d(self) -> Arrows2D;
}
#[cfg(feature = "visualization")]
impl ToRerunTransform3D for SE3 {
fn to_rerun_transform(&self) -> Transform3D {
let trans = self.translation();
let rot = self.rotation_quaternion();
let position =
rerun::external::glam::Vec3::new(trans.x as f32, trans.y as f32, trans.z as f32);
let rotation = rerun::external::glam::Quat::from_xyzw(
rot.as_ref().i as f32,
rot.as_ref().j as f32,
rot.as_ref().k as f32,
rot.as_ref().w as f32,
);
Transform3D::from_translation_rotation(position, rotation)
}
}
#[cfg(feature = "visualization")]
impl ToRerunVec3D for SE3 {
fn to_rerun_vec3d(&self) -> Vec3D {
let trans = self.translation();
Vec3D::new(trans.x as f32, trans.y as f32, trans.z as f32)
}
}
#[cfg(feature = "visualization")]
impl ToRerunPoints3D for SE3 {
fn to_rerun_points3d(&self) -> Points3D {
let vec = self.to_rerun_vec3d();
Points3D::new([vec])
}
}
#[cfg(feature = "visualization")]
impl ToRerunArrows3D for SE3 {
fn to_rerun_arrows3d(&self) -> Arrows3D {
let rot_quat = self.rotation_quaternion();
let rot_mat = rot_quat.to_rotation_matrix();
let trans = self.translation();
let x_axis = [
rot_mat[(0, 0)] as f32,
rot_mat[(1, 0)] as f32,
rot_mat[(2, 0)] as f32,
];
let y_axis = [
rot_mat[(0, 1)] as f32,
rot_mat[(1, 1)] as f32,
rot_mat[(2, 1)] as f32,
];
let z_axis = [
rot_mat[(0, 2)] as f32,
rot_mat[(1, 2)] as f32,
rot_mat[(2, 2)] as f32,
];
let origin = [trans.x as f32, trans.y as f32, trans.z as f32];
Arrows3D::from_vectors([x_axis, y_axis, z_axis])
.with_origins([origin, origin, origin])
.with_colors([[255, 0, 0], [0, 255, 0], [0, 0, 255]]) }
}
#[cfg(feature = "visualization")]
impl<'a, I> CollectRerunPoints3D<'a> for I
where
I: Iterator<Item = &'a SE3>,
{
fn collect_points3d(self) -> Points3D {
let points: Vec<Vec3D> = self.map(|se3| se3.to_rerun_vec3d()).collect();
Points3D::new(points)
}
}
#[cfg(feature = "visualization")]
impl<'a, I> CollectRerunArrows3D<'a> for I
where
I: Iterator<Item = &'a SE3>,
{
fn collect_arrows3d(self) -> Arrows3D {
let mut vectors = Vec::new();
let mut origins = Vec::new();
let mut colors = Vec::new();
for se3 in self {
let rot_quat = se3.rotation_quaternion();
let rot_mat = rot_quat.to_rotation_matrix();
let trans = se3.translation();
let x_axis = [
rot_mat[(0, 0)] as f32,
rot_mat[(1, 0)] as f32,
rot_mat[(2, 0)] as f32,
];
let y_axis = [
rot_mat[(0, 1)] as f32,
rot_mat[(1, 1)] as f32,
rot_mat[(2, 1)] as f32,
];
let z_axis = [
rot_mat[(0, 2)] as f32,
rot_mat[(1, 2)] as f32,
rot_mat[(2, 2)] as f32,
];
let origin = [trans.x as f32, trans.y as f32, trans.z as f32];
vectors.push(x_axis);
vectors.push(y_axis);
vectors.push(z_axis);
origins.push(origin);
origins.push(origin);
origins.push(origin);
colors.push([255, 0, 0]); colors.push([0, 255, 0]); colors.push([0, 0, 255]); }
Arrows3D::from_vectors(vectors)
.with_origins(origins)
.with_colors(colors)
}
}
#[cfg(feature = "visualization")]
impl ToRerunVec2D for SE2 {
fn to_rerun_vec2d(&self) -> Vec2D {
Vec2D::new(self.x() as f32, self.y() as f32)
}
}
#[cfg(feature = "visualization")]
impl ToRerunPoints2D for SE2 {
fn to_rerun_points2d(&self) -> Points2D {
let vec = self.to_rerun_vec2d();
Points2D::new([vec])
}
}
#[cfg(feature = "visualization")]
impl ToRerunArrows2D for SE2 {
fn to_rerun_arrows2d(&self) -> Arrows2D {
let rot_mat = self.rotation_matrix();
let x_axis = [rot_mat[(0, 0)] as f32, rot_mat[(1, 0)] as f32];
let y_axis = [rot_mat[(0, 1)] as f32, rot_mat[(1, 1)] as f32];
let origin = [self.x() as f32, self.y() as f32];
Arrows2D::from_vectors([x_axis, y_axis])
.with_origins([origin, origin])
.with_colors([[255, 0, 0], [0, 255, 0]]) }
}
#[cfg(feature = "visualization")]
impl ToRerunTransform3DFrom2D for SE2 {
fn to_rerun_transform_3d(&self) -> Transform3D {
let position = rerun::external::glam::Vec3::new(self.x() as f32, self.y() as f32, 0.0);
let angle = self.angle();
let half_angle = (angle / 2.0) as f32;
let rotation =
rerun::external::glam::Quat::from_xyzw(0.0, 0.0, half_angle.sin(), half_angle.cos());
Transform3D::from_translation_rotation(position, rotation)
}
}
#[cfg(feature = "visualization")]
impl<'a, I> CollectRerunPoints2D<'a> for I
where
I: Iterator<Item = &'a SE2>,
{
fn collect_points2d(self) -> Points2D {
let points: Vec<Vec2D> = self.map(|se2| se2.to_rerun_vec2d()).collect();
Points2D::new(points)
}
}
#[cfg(feature = "visualization")]
impl<'a, I> CollectRerunArrows2D<'a> for I
where
I: Iterator<Item = &'a SE2>,
{
fn collect_arrows2d(self) -> Arrows2D {
let mut vectors = Vec::new();
let mut origins = Vec::new();
let mut colors = Vec::new();
for se2 in self {
let rot_mat = se2.rotation_matrix();
let x_axis = [rot_mat[(0, 0)] as f32, rot_mat[(1, 0)] as f32];
let y_axis = [rot_mat[(0, 1)] as f32, rot_mat[(1, 1)] as f32];
let origin = [se2.x() as f32, se2.y() as f32];
vectors.push(x_axis);
vectors.push(y_axis);
origins.push(origin);
origins.push(origin);
colors.push([255, 0, 0]); colors.push([0, 255, 0]); }
Arrows2D::from_vectors(vectors)
.with_origins(origins)
.with_colors(colors)
}
}
#[cfg(test)]
#[cfg(feature = "visualization")]
mod tests {
use super::*;
#[test]
fn test_se3_to_vec3d() {
use apex_manifolds::se3::SE3;
let pose = SE3::identity();
let vec = pose.to_rerun_vec3d();
assert_eq!(vec.x(), 0.0);
assert_eq!(vec.y(), 0.0);
assert_eq!(vec.z(), 0.0);
}
#[test]
fn test_se2_to_vec2d() {
use apex_manifolds::se2::SE2;
let pose = SE2::identity();
let vec = pose.to_rerun_vec2d();
assert_eq!(vec.x(), 0.0);
assert_eq!(vec.y(), 0.0);
}
#[test]
fn test_se3_collection_to_points() {
use apex_manifolds::se3::SE3;
let poses = [SE3::identity(), SE3::identity(), SE3::identity()];
let points = poses.iter().collect_points3d();
let _ = points;
}
#[test]
fn test_se2_collection_to_arrows() {
use apex_manifolds::se2::SE2;
let poses = [SE2::identity(), SE2::identity()];
let arrows = poses.iter().collect_arrows2d();
let _ = arrows;
}
}