slam-viewer 0.1.2

Simple wgpu based SLAM map viewer.
Documentation
use super::super::builder::{WindowBuilder, WindowBuilderDefault};
use super::super::camera::{CameraControllerConfig, CameraFrustum};
use super::super::lines::{Line, LineSource, LinesBuilder, LinesRendener};
use super::super::points::{Point, PointSource, PointsBuilder, PointsRendener};
use crate::pipes::{PipelineBuilder, PipelineRenderer, VertexFormat};

use nalgebra::Point3;
use slam_cv::{feature::Landmark, vo::World, Colors, Number};

pub struct WorldRenderer<N, F, W>
where
    N: 'static + Number,
    Point3<N>: VertexFormat<N>,
    F: 'static + Landmark<Number = N>,
    W: 'static + World<Landmark = F>,
{
    points: PointsRendener<N, W>,
    lines: LinesRendener<N, W>,
}

impl<N, F, W> PipelineBuilder for W
where
    N: 'static + Number,
    Point3<N>: VertexFormat<N>,
    F: 'static + Landmark<Number = N>,
    W: 'static + World<Landmark = F> + Clone,
{
    fn build(
        self: Box<Self>,
        device: &wgpu::Device,
        texture_format: wgpu::TextureFormat,
        uniform_bind_group_layout: &wgpu::BindGroupLayout,
    ) -> Box<dyn PipelineRenderer> {
        let world = *self;
        Box::new(WorldRenderer {
            points: PointsBuilder::new(world.clone()).build(
                device,
                texture_format,
                uniform_bind_group_layout,
            ),
            lines: LinesBuilder::new(world).build(
                device,
                texture_format,
                uniform_bind_group_layout,
            ),
        })
    }
}

impl<N, F, W> PipelineRenderer for WorldRenderer<N, F, W>
where
    N: 'static + Number,
    Point3<N>: VertexFormat<N>,
    F: 'static + Landmark<Number = N>,
    W: 'static + World<Landmark = F>,
{
    fn render<'a>(&'a mut self, device: &wgpu::Device, render_pass: &mut wgpu::RenderPass<'a>) {
        self.points.render(device, render_pass);
        self.lines.render(device, render_pass);
    }
}

impl<N, F, W> PointSource<N> for W
where
    N: 'static + Number,
    Point3<N>: VertexFormat<N>,
    F: 'static + Landmark<Number = N>,
    W: 'static + World<Landmark = F>,
{
    fn collect_visual_points(&self) -> Vec<Point<N>> {
        self.collect_landmarks(|lm| Point {
            position: lm.point_world(),
            color: Colors::red(),
        })
    }
}

impl<N, F, W> LineSource<N> for W
where
    N: 'static + Number,
    Point3<N>: VertexFormat<N>,
    F: 'static + Landmark<Number = N>,
    W: 'static + World<Landmark = F>,
{
    fn collect_visual_lines(&self) -> Vec<Line<N>> {
        self.collect_landmarks(|lm| Line {
            start: Point {
                position: lm.point_world(),
                color: Colors::red(),
            },
            end: Point::default(),
        })
    }
}

impl<F, W> WindowBuilderDefault<f32> for W
where
    F: 'static + Landmark<Number = f32>,
    W: 'static + World<Landmark = F>,
{
    fn default_window() -> WindowBuilder<f32> {
        WindowBuilder {
            title: Some("Map Viewer".to_string()),
            framerate: Some(120),

            camera: CameraFrustum {
                eye: Point3::new(0., 2., 5.),
                at: Point3::new(0., 0., 0.),

                fovy: std::f32::consts::FRAC_PI_4,
                znear: 0.1,
                zfar: 100.0,
            },
            camera_controller: CameraControllerConfig {
                mouse_left_speed: 1.0,
                mouse_right_speed: 5.0,
                scroll_speed: 1.0,
                keyboard_speed: 0.1,
            },
        }
    }
}