freenectrs 0.1.0

A rust wrapper for libfreenect
Documentation
extern crate freenectrs;
#[macro_use]
extern crate glium;
extern crate obj;
extern crate genmesh;
extern crate image;

mod glwinhelp;

use glwinhelp::{imgwin, VirtualKeyCode};
use std::time::Duration;

use freenectrs::freenect;


macro_rules! ptry {
    ($x: expr) => (
        match $x{
            Ok(x) => x,
            Err(r) => {println!("Error: {}", r); return }
        }
        )
}

#[inline]
fn depth_to_img(data: &[u16]) -> image::RgbaImage {
    image::RgbaImage::from_fn(640, 480, |x, y| {
        let idx = y * 640 + x;
        let val = data[idx as usize];
        // let val = val / 2048;
        // let val = val / 10;
        let val = if val > 600 { val - 600 } else { 0 };
        let val = val / 2;
        let val = if val > 255 { 255 } else { val };
        let val = val as u8;
        image::Rgba([val, val, val, 255])
    })
}

pub fn main() {
    let ctx = ptry!(freenect::FreenectContext::init_with_video_motor());
    let dev_count = ptry!(ctx.num_devices());
    if dev_count == 0 {
        println!("No device connected - abort");
        return;
    } else {
        println!("Found {} devices, use first", dev_count);
    }
    let device = ptry!(ctx.open_device(0));
    ptry!(device.set_depth_mode(freenect::FreenectResolution::Medium,
                                freenect::FreenectDepthFormat::MM));
    ptry!(device.set_video_mode(freenect::FreenectResolution::Medium,
                                freenect::FreenectVideoFormat::Rgb));

    let mut dwin = imgwin::ImgWindow::new("Live Depth");
    let mut vwin = imgwin::ImgWindow::new("Live RGB");

    let dstream = ptry!(device.depth_stream());
    let vstream = ptry!(device.video_stream());
    let mut dimg = image::RgbaImage::new(640, 480);
    let mut vimg = image::RgbaImage::new(640, 480);
    ctx.spawn_process_thread().unwrap();
    let mut inphandler = InputHandler {
        device: &device,
        is_closed: false,
    };
    loop {
        let _ = imgwin::FixWaitTimer::new(Duration::from_millis(1000 / 25));
        if let Ok((data, _ /* timestamp */)) = dstream.receiver.try_recv() {
            dimg = depth_to_img(&*data);
        }
        if let Ok((data, _ /* timestamp */)) = vstream.receiver.try_recv() {
            vimg = image::RgbaImage::from_fn(640, 480, |x, y| {
                let idx = 3 * (y * 640 + x) as usize;
                let (r, g, b) = (data[idx], data[idx + 1], data[idx + 2]);
                image::Rgba([r, g, b, 255])
            });
        }
        dwin.set_img(dimg.clone());
        vwin.set_img(vimg.clone());
        dwin.redraw();
        vwin.redraw();
        dwin.check_for_event(&mut inphandler);
        vwin.check_for_event(&mut inphandler);
        if inphandler.is_closed {
            break;
        }
    }
    ctx.stop_process_thread().unwrap();
}

struct InputHandler<'a, 'b: 'a> {
    device: &'a freenect::FreenectDevice<'a, 'b>,
    is_closed: bool,
}

impl<'a, 'b> imgwin::EventHandler for InputHandler<'a, 'b> {
    fn close_event(&mut self) {
        self.is_closed = true;
    }
    fn key_event(&mut self, inp: Option<VirtualKeyCode>) {
        if let Some(code) = inp {
            match code {
                VirtualKeyCode::Up => {
                    ptry!(self.device.set_tilt_degree(ptry!(self.device.get_tilt_degree()) + 10.0))
                }
                VirtualKeyCode::Down => {
                    ptry!(self.device.set_tilt_degree(ptry!(self.device.get_tilt_degree()) - 10.0))
                }

                VirtualKeyCode::Q => self.is_closed = true,
                _ => (),
            }
        }
    }
}