diff --git a/gloom-rs/src/camera.rs b/gloom-rs/src/camera.rs new file mode 100644 index 0000000..3801cf8 --- /dev/null +++ b/gloom-rs/src/camera.rs @@ -0,0 +1,37 @@ +pub struct ChaseCamera { + pub position: glm::Vec3, + pub target: glm::Vec3, + pub radius: f32, + pub perspective: glm::Mat4, +} + +impl ChaseCamera { + pub fn new(radius: f32, perspective: glm::Mat4) -> Self { + ChaseCamera { + position: glm::vec3(100.0, 35.0, 0.0), + target: glm::vec3(0.0, 0.0, 0.0), + radius, + perspective, + } + } + + pub(crate) fn view_matrix(&self) -> glm::Mat4 { + glm::look_at( + &self.position, + &self.target, + &self.up() + ) + } + + pub fn forward(&self) -> glm::Vec3 { + glm::normalize(&(&self.target - self.position)) + } + + pub fn up(&self) -> glm::Vec3 { + glm::vec3(0.0, 1.0, 0.0) + } + + pub fn right(&self) -> glm::Vec3 { + glm::normalize(&glm::cross(&self.forward(), &self.up())) + } +} diff --git a/gloom-rs/src/draw.rs b/gloom-rs/src/draw.rs index c794319..639eb27 100644 --- a/gloom-rs/src/draw.rs +++ b/gloom-rs/src/draw.rs @@ -8,6 +8,7 @@ use std::pin::Pin; use crate::mesh::{ Mesh, Terrain, Helicopter }; use crate::toolbox::{self, AnimCTX}; +use crate::camera::{ ChaseCamera }; unsafe fn draw_scene(node: &SceneNode, @@ -57,33 +58,10 @@ pub enum Nodes { SceneRoot, } -pub struct ChaseCamera { - pub position: glm::Vec3, - pub target: glm::Vec3, - pub radius: f32, // set to big number to get normal camera - pub perspective: glm::Mat4, - pitch: f32, - yaw: f32 -} - -impl ChaseCamera { - pub fn new(radius: f32, perspective: glm::Mat4) -> Self { - ChaseCamera { - position: glm::vec3(100.0, 35.0, 0.0), - target: glm::vec3(0.0, 0.0, 0.0), - radius, - perspective, - pitch: 0.0, - yaw: 0.0 - } - } -} - pub struct World { pub nodes: HashMap>>>>, pub anim_ctxs: Vec, pub camera: ChaseCamera, - pub model_transformation: glm::Mat4 } impl World { @@ -92,7 +70,7 @@ impl World { let nodes = Self::setup_scene_graph(&meshes); let anim_ctxs:Vec = Vec::new(); let camera = ChaseCamera::new(radius, perspective); - World { nodes, anim_ctxs, camera, model_transformation: glm::identity() } + World { nodes, anim_ctxs, camera } } fn load_models() -> HashMap { @@ -171,14 +149,6 @@ impl World { return nodes; } - fn view_matrix(&self) -> glm::Mat4 { - glm::look_at( - &self.camera.position, - &self.camera.target, - &glm::vec3(0.0, 1.0, 0.0) - ) - } - pub fn update(&mut self, elapsed: f32, shader: &Shader) { let rotor_speed = 60.0; @@ -206,13 +176,7 @@ impl World { self.camera.position += direction * (distance - self.camera.radius); } - // update camera angles - self.camera.yaw = direction.z.atan2(direction.x) + glm::half_pi::(); - let horizontal_distance = (direction.x * direction.x + direction.z * direction.z).sqrt(); - self.camera.pitch = direction.y.atan2(horizontal_distance); - - - let transform_thus_far = self.camera.perspective * self.view_matrix(); + let transform_thus_far = self.camera.perspective * self.camera.view_matrix(); // Build scene graph on the fly or store scene_root separately unsafe { diff --git a/gloom-rs/src/main.rs b/gloom-rs/src/main.rs index cd1d8ed..a2d140d 100644 --- a/gloom-rs/src/main.rs +++ b/gloom-rs/src/main.rs @@ -18,13 +18,12 @@ mod mesh; mod scene_graph; mod toolbox; mod draw; +mod camera; use glutin::event::{Event, WindowEvent, DeviceEvent, KeyboardInput, ElementState::{Pressed, Released}, VirtualKeyCode::{self, *}}; use glutin::event_loop::ControlFlow; - use crate::draw::Nodes; -use crate::scene_graph::SceneNode; use crate::toolbox::AnimCTX; // initial window size @@ -136,6 +135,8 @@ fn main() { } } + let translation_speed = 1.0; + // Handle keyboard input if let Ok(keys) = pressed_keys.lock() { for key in keys.iter() { @@ -159,6 +160,18 @@ fn main() { } } + VirtualKeyCode::Right => { + world.camera.position -= world.camera.right() * translation_speed; + } + VirtualKeyCode::Left => { + world.camera.position += world.camera.right() * translation_speed; + } + VirtualKeyCode::Down => { + world.camera.position.y -= translation_speed; + } + VirtualKeyCode::Up => { + world.camera.position.y += translation_speed; + } _ => { } } }