diff --git a/Cargo.toml b/Cargo.toml index 8242a72..1c7550e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,9 @@ image = "0.19.0" byteorder = "1.2.3" clap = "2.31.2" nalgebra = "0.15.3" +serde = "1.0.82" +serde_json = "1.0.33" +serde_derive = "1.0.82" [[bin]] name = "3d-viewer" diff --git a/src/lib.rs b/src/lib.rs index 74f76b8..41f6454 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,11 @@ #![warn(missing_docs)] +extern crate serde; + +#[macro_use] +extern crate serde_derive; + #[macro_use] extern crate log; extern crate stderrlog; diff --git a/src/programs/viewer.rs b/src/programs/viewer.rs index 44a3659..fe75e97 100644 --- a/src/programs/viewer.rs +++ b/src/programs/viewer.rs @@ -1,3 +1,9 @@ +extern crate serde; +extern crate serde_json; + +#[macro_use] +extern crate serde_derive; + #[macro_use] extern crate log; extern crate stderrlog; @@ -5,6 +11,8 @@ extern crate clap; extern crate glium; extern crate model_converter; +use std::fs::File; +use std::io::Write; use std::process::exit; use std::time::{Instant, Duration}; use std::thread::sleep; @@ -34,6 +42,29 @@ fn as_millis(duration: Duration) -> u64 { duration.as_secs() * 1_000 + (duration.subsec_nanos() as u64) / 1_000_000 } +#[derive(Serialize, Deserialize)] +struct Vector { + x: f64, + y: f64, + z: f64, +} + +impl From> for Vector { + fn from(v: Vector3) -> Vector { + Vector { + x: v[0], + y: v[1], + z: v[2], + } + } +} + +#[derive(Serialize, Deserialize)] +struct CameraEvent { + position: Vector, + target: Vector, +} + fn main() { let matches = App::new("3D Viewer") @@ -65,6 +96,8 @@ fn main() { .expect("Couldn't initialize logger"); let mut capture_count = 0; + let mut path_count = 0; + let mut path = vec![]; use std::f64::{MIN, MAX}; let mut bbox = BoundingBox3::new( @@ -125,6 +158,11 @@ fn main() { info!("Finished"); } + let center = (bbox.min() + bbox.max()) / 2.0; + let size = (bbox.max() - bbox.min()).norm(); + let center_f64 = Vector3::new(center.x() as f64, center.y() as f64, center.z() as f64); + let size_f64 = size as f64; + let mut closed = false; let mut camera = Camera::new( @@ -149,6 +187,7 @@ fn main() { use model_converter::controls::Controls; + let mut recording = false; let mut before = Instant::now(); while !closed { @@ -175,6 +214,27 @@ fn main() { }, .. } => closed = true, + // R key + Event::WindowEvent { + event: WindowEvent::KeyboardInput { + input: glutin::KeyboardInput { + virtual_keycode: Some(VirtualKeyCode::R), + state: ElementState::Pressed, .. + }, .. + }, .. + } => { + if ! recording { + path.clear(); + recording = true; + } else { + recording = false; + let string = serde_json::to_string(&path).unwrap(); + let mut file = File::create(format!("path-{}.json", path_count)).unwrap(); + file.write_all(string.as_bytes()).unwrap(); + path_count += 1; + } + }, + // Enter key Event::WindowEvent { event: WindowEvent::KeyboardInput { @@ -202,13 +262,7 @@ fn main() { }, .. }, .. - } => { - - should_screenshot = true; - - - - }, + } => should_screenshot = true, _ => (), } @@ -217,6 +271,16 @@ fn main() { controls.update(&mut camera, &renderer); renderer.render(&scene, &camera); + if recording { + let position = camera.position * size_f64 + center_f64; + let target = camera.target * size_f64 + center_f64; + + path.push(CameraEvent { + position: position.into(), + target: target.into(), + }); + } + if should_screenshot { // Make a screenshot let cap = renderer.capture();