diff --git a/engine/src/assets/asset_manager.rs b/engine/src/assets/asset_manager.rs index 789cb5f..8009d39 100644 --- a/engine/src/assets/asset_manager.rs +++ b/engine/src/assets/asset_manager.rs @@ -41,10 +41,9 @@ impl AssetManager { #[inline] fn find_gltf_file(&self, name: &str) -> Option<&AssetPath> { - match self.gltf_file_map.get(name) { - Some(file) => Some(file), - None => self.glb_file_map.get(name), - } + self.gltf_file_map + .get(name) + .or_else(|| self.glb_file_map.get(name)) } pub fn insert_cached_assets(&self, cache: &AssetCache) -> Result<()> { diff --git a/engine/src/scene/content/components/free_space_control.rs b/engine/src/scene/content/components/free_space_control.rs index 5d01027..c8cac95 100644 --- a/engine/src/scene/content/components/free_space_control.rs +++ b/engine/src/scene/content/components/free_space_control.rs @@ -134,8 +134,13 @@ impl FreeSpaceControl { } pub fn update(&mut self, now: Duration) { - let diff = match self.last_update { - Some(last_update) => now - last_update, + let diff = match &mut self.last_update { + Some(last_update) => { + let diff = now - *last_update; + *last_update = now; + + diff + } None => { self.last_update = Some(now); return; diff --git a/engine/src/scene/general/free_camera_control.rs b/engine/src/scene/general/free_camera_control.rs index a2c3313..084d12c 100644 --- a/engine/src/scene/general/free_camera_control.rs +++ b/engine/src/scene/general/free_camera_control.rs @@ -1,3 +1,5 @@ +use std::time::Duration; + use crate::prelude::{cgmath::*, *}; use anyhow::Result; use context::prelude::cgmath::num_traits::clamp; @@ -29,12 +31,16 @@ pub struct FreeCameraControl { mouse_position: (u32, u32), + velocity: Vector3, + hold_info: Option, + last_update: Option, } impl FreeCameraControl { const SCALE: f32 = 0.3; const DEFAULT_DIR: Vector3 = vec3(0.0, 1.0, 0.0); + const SPEED: f32 = 2.0; pub fn new(view: &mut View) -> Result { view.camera_mut().look_at(false); @@ -48,20 +54,50 @@ impl FreeCameraControl { mouse_position: (0, 0), + velocity: Vector3::zero(), + hold_info: None, + + last_update: None, }) } - pub fn roll(&mut self, _view: &mut View) -> Result<()> { - todo!() + pub fn forward_back(&mut self, factor: f32) { + self.velocity.y += factor; } - pub fn pitch(&mut self, _view: &mut View) -> Result<()> { - todo!() + pub fn left_right(&mut self, factor: f32) { + self.velocity.x += factor; } - pub fn yaw(&mut self, _view: &mut View) -> Result<()> { - todo!() + pub fn up_down(&mut self, factor: f32) { + self.velocity.z += factor; + } + + pub fn update(&mut self, now: Duration, view: &mut View) -> Result<()> { + let diff = match &mut self.last_update { + Some(last_update) => { + let diff = now - *last_update; + *last_update = now; + + diff + } + None => { + self.last_update = Some(now); + return Ok(()); + } + }; + + let current_center = view.camera().center(); + let new_center = current_center + + diff.as_secs_f32() + * Self::SPEED + * Matrix3::from_angle_z(self.yaw) + * Matrix3::from_angle_x(self.roll) + * self.velocity; + + view.camera_mut().set_center(new_center); + view.update_buffer() } pub fn mouse_down(&mut self) { @@ -88,18 +124,6 @@ impl FreeCameraControl { Ok(()) } - pub fn forward_back(&mut self, _view: &mut View) -> Result<()> { - todo!() - } - - pub fn left_right(&mut self, _view: &mut View) -> Result<()> { - todo!() - } - - pub fn up_down(&mut self, _view: &mut View) -> Result<()> { - todo!() - } - fn update_camera(&self, view: &mut View) -> Result<()> { view.camera_mut().set_eye_dir( Matrix3::from_angle_z(self.yaw) * Matrix3::from_angle_x(self.roll) * Self::DEFAULT_DIR, diff --git a/examples/free_space/src/game.rs b/examples/free_space/src/game.rs index 4689a70..e2f79e6 100644 --- a/examples/free_space/src/game.rs +++ b/examples/free_space/src/game.rs @@ -4,7 +4,7 @@ use anyhow::Result; use ecs::*; use engine::prelude::{ - cgmath::{Vector3, Vector4}, + cgmath::{Vector3, Vector4, vec4}, *, }; @@ -85,7 +85,14 @@ impl InputSettings { pub struct Game; impl Game { - pub fn update(&mut self, _world: &mut World) -> Result<()> { + pub fn update(&mut self, world: &mut World) -> Result<()> { + let now = world.now(); + let mut resources = world.resources.multi_mut(); + let scene = resources.get::(); + let camera_control = resources.get::(); + + camera_control.update(now, scene.view_mut())?; + Ok(()) } @@ -94,6 +101,46 @@ impl Game { let (fighter_object, resources) = world.entity_resources(player.0)?; match event { + EngineEvent::MouseButtonDown(MouseButton::Left) => { + let camera_control = resources.get_mut::(); + camera_control.mouse_down(); + } + EngineEvent::MouseButtonUp(MouseButton::Left) => { + let camera_control = resources.get_mut::(); + camera_control.mouse_release(); + } + EngineEvent::MouseMotion(x, y) => { + let mut resources = resources.multi_mut(); + let scene = resources.get::(); + let camera_control = resources.get::(); + + camera_control.mouse_move(x, y, scene.view_mut())?; + } + EngineEvent::KeyDown(key) => { + let camera_control = resources.get_mut::(); + + match key { + Keycode::W => camera_control.forward_back(1.0), + Keycode::A => camera_control.left_right(-1.0), + Keycode::S => camera_control.forward_back(-1.0), + Keycode::D => camera_control.left_right(1.0), + + _ => (), + } + } + EngineEvent::KeyUp(key) => { + let camera_control = resources.get_mut::(); + + match key { + Keycode::W => camera_control.forward_back(-1.0), + Keycode::A => camera_control.left_right(1.0), + Keycode::S => camera_control.forward_back(1.0), + Keycode::D => camera_control.left_right(-1.0), + + _ => (), + } + } + EngineEvent::JoystickAxis(joystick, axis_index, value) => { let normalized = value as f32 * (i16::MAX as f32).recip(); let input_settings = resources.get::(); @@ -132,13 +179,13 @@ impl Game { EmptyFilter, )?; - world_builder.add_update("camera_position", 1_000, Self::camera_update, EmptyFilter)?; + // world_builder.add_update("camera_position", 1_000, Self::camera_update, EmptyFilter)?; Ok(()) } pub fn setup_scene(world: &mut World) -> Result<()> { - let mut fighter = AssetHandler::create(world).create_entity("fighter")?; + let mut fighter = AssetHandler::create(world).create_entity("craft_cargoA")?; fighter.insert_component(FreeSpaceControl::new(FreeSpaceControlSettings::default())); let player = PlayerEntity(world.add_entity(fighter)?); @@ -166,13 +213,15 @@ impl Game { _entity: Entity, control: &mut FreeSpaceControl, ) -> Result<()> { + const DEFAULT_CENTER: Vector4 = vec4(0.0, 0.0, 0.0, 1.0); + let scene = world.resources.get_mut::(); let view = scene.view_mut(); view.camera_mut() - .set_center((control.translation() * Vector4::unit_w()).truncate()); + .set_center((control.translation() * DEFAULT_CENTER).truncate()); view.camera_mut() - .set_eye_dir(control.rotation() * Vector3::unit_y()); + .set_eye_dir(control.rotation() * Vector3::unit_x()); view.update_buffer() } diff --git a/examples/free_space/src/main.rs b/examples/free_space/src/main.rs index 76ee6a7..9cd8848 100644 --- a/examples/free_space/src/main.rs +++ b/examples/free_space/src/main.rs @@ -14,13 +14,17 @@ use skybox::SkyBox; fn main() -> Result<()> { let mut world_builder = World::builder(); - Engine::new::(EngineCreateInfo::default(), &mut world_builder)?; + let mut engine_ci = EngineCreateInfo::default(); + engine_ci.resource_base_path = "/home/michaelh/Sync/space_game/".to_string(); + engine_ci.asset_directories.gltf_file_directory = "objects".into(); + engine_ci.raytracing_info.recursion_depth = 30; + + Engine::new::(engine_ci, &mut world_builder)?; world_builder.add_system(GameState::update); world_builder.resources.insert(GameState::default()); - // let dir = Path::new("C:/Users/M.Huebner/Downloads/skybox"); - let dir = Path::new("/home/michaelh/Sync/skybox"); + let dir = Path::new("/home/michaelh/Sync/space_game/skybox"); SkyBox::new( &mut world_builder, [