diff --git a/engine/src/engine/engine_event_handling.rs b/engine/src/engine/engine_event_handling.rs index 2a77c21..1cbdf92 100644 --- a/engine/src/engine/engine_event_handling.rs +++ b/engine/src/engine/engine_event_handling.rs @@ -20,7 +20,7 @@ pub enum EngineEvent<'a> { JoystickButtonDown(&'a Joystick), JoystickButtonUp(&'a Joystick), - JoystickAxis(&'a Joystick), + JoystickAxis(&'a Joystick, u8, i16), JoystickAdded(&'a Joystick), JoystickRemoved(&'a Joystick), @@ -91,9 +91,10 @@ impl Engine { Self::controller_removed(world, consumer, controller)? } - Event::JoystickAxis(joystick) => { - consumer.event(world, EngineEvent::JoystickAxis(joystick))? - } + Event::JoystickAxis(joystick, axis_index, value) => consumer.event( + world, + EngineEvent::JoystickAxis(joystick, axis_index, value), + )?, Event::JoystickButtonDown(joystick) => { consumer.event(world, EngineEvent::JoystickButtonDown(joystick))? } diff --git a/engine/src/scene/content/components/free_space_control.rs b/engine/src/scene/content/components/free_space_control.rs index 8a8a13d..5d01027 100644 --- a/engine/src/scene/content/components/free_space_control.rs +++ b/engine/src/scene/content/components/free_space_control.rs @@ -44,6 +44,10 @@ pub struct FreeSpaceControl { rotation: Vector3>, position: Vector3, + current_translation: Matrix4, + current_rotation: Matrix3, + current_transform: Matrix4, + /// (yaw, pitch, roll) input_rotation: Vector3, /// (forward, sideward, upward) @@ -60,6 +64,10 @@ impl FreeSpaceControl { rotation: vec3(Deg(0.0), Deg(0.0), Deg(0.0)), position: Vector3::zero(), + current_translation: Matrix4::one(), + current_rotation: Matrix3::one(), + current_transform: Matrix4::one(), + input_rotation: Vector3::zero(), input_position: Vector3::zero(), @@ -125,12 +133,12 @@ impl FreeSpaceControl { * Matrix3::from_angle_x(self.rotation.z) } - pub fn update(&mut self, now: Duration) -> Option> { + pub fn update(&mut self, now: Duration) { let diff = match self.last_update { Some(last_update) => now - last_update, None => { self.last_update = Some(now); - return None; + return; } }; @@ -140,7 +148,21 @@ impl FreeSpaceControl { self.add_rotation(rotation_changes); self.position += rotated_position_changes; - Some(Matrix4::from_translation(self.position) * Matrix4::from(self.rotation_matrix())) + self.current_translation = Matrix4::from_translation(self.position); + self.current_rotation = self.rotation_matrix(); + self.current_transform = self.current_translation * Matrix4::from(self.current_rotation); + } + + pub fn translation(&self) -> Matrix4 { + self.current_translation + } + + pub fn rotation(&self) -> Matrix3 { + self.current_rotation + } + + pub fn transform(&self) -> Matrix4 { + self.current_transform } #[rustfmt::skip] diff --git a/engine/src/scene/rendering/shaders/raytracing/hardware/default/raygen.rgen b/engine/src/scene/rendering/shaders/raytracing/hardware/default/raygen.rgen index 82165a6..d0022b6 100644 --- a/engine/src/scene/rendering/shaders/raytracing/hardware/default/raygen.rgen +++ b/engine/src/scene/rendering/shaders/raytracing/hardware/default/raygen.rgen @@ -65,7 +65,7 @@ void main() if (pay_load.distance == -1.0) { position = vec3(INFINITY); - } else { + } else if (pay_load.color.w > 0.0) { position = origin.xyz + pay_load.distance * direction.xyz; imageStore(output_image, ivec2(gl_LaunchIDEXT.xy), vec4(pay_load.color.xyz, 1.0)); } diff --git a/examples/free_space/src/game.rs b/examples/free_space/src/game.rs index 25f7159..4689a70 100644 --- a/examples/free_space/src/game.rs +++ b/examples/free_space/src/game.rs @@ -3,7 +3,10 @@ use std::collections::HashMap; use anyhow::Result; use ecs::*; -use engine::prelude::*; +use engine::prelude::{ + cgmath::{Vector3, Vector4}, + *, +}; #[derive(Clone, Copy, Debug)] struct PlayerEntity(Entity); @@ -33,35 +36,35 @@ enum Control { } #[derive(Clone, Debug)] -struct ControllerSettings { +struct InputSettings { mappings: HashMap<(String, Input), Control>, } -impl Default for ControllerSettings { +impl Default for InputSettings { fn default() -> Self { Self { mappings: [ ( - ("Controller 1".to_string(), Input::Axis(0)), + ("Joystick 1".to_string(), Input::Axis(0)), Control::Throttle, ), ( - ("Controller 1".to_string(), Input::Axis(1)), + ("Joystick 1".to_string(), Input::Axis(1)), Control::StrafeHorizontal, ), ( - ("Controller 1".to_string(), Input::Axis(2)), + ("Joystick 1".to_string(), Input::Axis(2)), Control::StrafeVertical, ), - (("Controller 1".to_string(), Input::Axis(3)), Control::Pitch), + (("Joystick 1".to_string(), Input::Axis(3)), Control::Pitch), ( - ("Controller 1".to_string(), Input::Button(Button::One)), + ("Joystick 1".to_string(), Input::Button(Button::One)), Control::PrimaryWeapon, ), - (("Controller 2".to_string(), Input::Axis(1)), Control::Yaw), - (("Controller 2".to_string(), Input::Axis(0)), Control::Roll), + (("Joystick 2".to_string(), Input::Axis(1)), Control::Yaw), + (("Joystick 2".to_string(), Input::Axis(0)), Control::Roll), ( - ("Controller 2".to_string(), Input::Button(Button::One)), + ("Joystick 2".to_string(), Input::Button(Button::One)), Control::SecondaryWeapon, ), ] @@ -71,14 +74,10 @@ impl Default for ControllerSettings { } } -impl ControllerSettings { - pub fn map_axis( - &self, - controller_name: impl ToString, - axes: ControllerAxis, - ) -> Vec<(Control, f32)> { +impl InputSettings { + pub fn map_axis(&self, device_name: impl ToString, axis: u8) -> Option { self.mappings - .get(&controller_name.to_string()) + .get(&(device_name.to_string(), Input::Axis(axis))) .map(|control| *control) } } @@ -92,26 +91,30 @@ impl Game { pub fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()> { let player = world.resources.get::(); - let fighter_object = world.entity_mut(player.0)?; + let (fighter_object, resources) = world.entity_resources(player.0)?; match event { - EngineEvent::MouseButtonDown(MouseButton::Left) => { - let camera_control = world.resources.get_mut::(); - camera_control.mouse_down(); - } - EngineEvent::MouseButtonUp(MouseButton::Left) => { - let camera_control = world.resources.get_mut::(); - camera_control.mouse_release(); - } - EngineEvent::MouseMotion(x, y) => { - let mut resources = world.resources.multi_mut(); - let scene = resources.get::(); - let camera_control = resources.get::(); + EngineEvent::JoystickAxis(joystick, axis_index, value) => { + let normalized = value as f32 * (i16::MAX as f32).recip(); + let input_settings = resources.get::(); + let player_control = fighter_object.get_component_mut::()?; - camera_control.mouse_move(x, y, scene.view_mut())?; - } + if let Some(control) = input_settings.map_axis(joystick.name(), axis_index) { + match control { + Control::Throttle => player_control.set_throttle(normalized), + Control::StrafeHorizontal => { + player_control.set_left_right_strafe(normalized) + } + Control::StrafeVertical => player_control.set_up_down_strafe(normalized), + Control::Yaw => player_control.set_yaw(normalized), + Control::Pitch => player_control.set_pitch(normalized), + Control::Roll => player_control.set_roll(normalized), - EngineEvent::ControllerAxis(controller, axis) => {} + Control::PrimaryWeapon => (), + Control::SecondaryWeapon => (), + } + } + } _ => (), } @@ -129,6 +132,8 @@ impl Game { EmptyFilter, )?; + world_builder.add_update("camera_position", 1_000, Self::camera_update, EmptyFilter)?; + Ok(()) } @@ -138,6 +143,7 @@ impl Game { let player = PlayerEntity(world.add_entity(fighter)?); world.resources.insert(player); + world.resources.insert(InputSettings::default()); world.commit_entity_changes() } @@ -151,10 +157,23 @@ impl Game { draw: &mut Draw, control: &mut FreeSpaceControl, ) -> Result<()> { - if let Some(transform) = control.update(world.now()) { - draw.set_transform(transform)?; - } + control.update(world.now()); + draw.set_transform(control.transform()) + } - Ok(()) + fn camera_update( + world: &mut World, + _entity: Entity, + control: &mut FreeSpaceControl, + ) -> Result<()> { + let scene = world.resources.get_mut::(); + let view = scene.view_mut(); + + view.camera_mut() + .set_center((control.translation() * Vector4::unit_w()).truncate()); + view.camera_mut() + .set_eye_dir(control.rotation() * Vector3::unit_y()); + + view.update_buffer() } } diff --git a/presentation/src/input/eventsystem.rs b/presentation/src/input/eventsystem.rs index 9ab2187..4eef87b 100644 --- a/presentation/src/input/eventsystem.rs +++ b/presentation/src/input/eventsystem.rs @@ -74,7 +74,7 @@ pub enum Event<'a> { ControllerRemoved(&'a Controller), // joystick events - JoystickAxis(&'a Joystick), + JoystickAxis(&'a Joystick, u8, i16), JoystickButtonDown(&'a Joystick), JoystickButtonUp(&'a Joystick), JoystickAdded(&'a Joystick), @@ -349,6 +349,21 @@ impl EventSystem { event_callback(Event::JoystickAdded(&joystick))?; self.connected_joysticks.insert(joystick.id(), joystick); } + SdlEvent::JoyDeviceRemoved { which, .. } => { + if let Some(joysticks) = self.connected_joysticks.remove(&which) { + event_callback(Event::JoystickRemoved(&joysticks))?; + } + } + SdlEvent::JoyAxisMotion { + which, + axis_idx, + value, + .. + } => { + if let Some(joysticks) = self.connected_joysticks.get(&which) { + event_callback(Event::JoystickAxis(&joysticks, axis_idx, value))?; + } + } SdlEvent::DropFile { filename, .. } => { event_callback(Event::FileDrop(filename))?; }