From e8e81e8e522afee9cc18fdf9c4722e21330772c0 Mon Sep 17 00:00:00 2001 From: yuni Date: Sat, 16 Nov 2024 19:55:42 +0100 Subject: [PATCH] WIP crisper camera controls (apply rotation) --- src/actor.rs | 11 +++++++++ src/camera.rs | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/cmd.rs | 1 + 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/actor.rs b/src/actor.rs index f476bf3..cf1a9b0 100644 --- a/src/actor.rs +++ b/src/actor.rs @@ -38,6 +38,7 @@ impl Plugin for ActorPlugin { update_physics_lifeforms.run_if(game_running), update_power.run_if(game_running), handle_gravity.run_if(game_running), + handle_wants_rotation.run_if(game_running), handle_wants_maxrotation.run_if(game_running), handle_wants_maxvelocity .run_if(game_running) @@ -176,6 +177,8 @@ pub struct WantsMaxVelocity(pub f64); #[derive(Component)] pub struct WantsToLookAt(pub String); #[derive(Component)] +pub struct WantsRotation(pub DQuat); +#[derive(Component)] pub struct WantsMatchVelocityWith(pub String); #[derive(Component)] pub struct Identifier(pub String); @@ -703,6 +706,14 @@ fn handle_wants_maxvelocity( } } +fn handle_wants_rotation( + mut q_actor: Query<(&mut Rotation, &WantsRotation)>, +) { + for (mut rot, setrot) in &mut q_actor { + **rot = setrot.0; + } +} + fn handle_wants_lookat( mut query: Query< ( diff --git a/src/camera.rs b/src/camera.rs index 5390569..788dd71 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -443,8 +443,73 @@ fn manage_player_actor( } } -#[allow(clippy::too_many_arguments)] pub fn apply_input_to_player( + settings: Res, + mut commands: Commands, + mut q_player: Query< + (Entity, &Rotation, Option<&mut actor::WantsRotation>), + With, + >, + mut mouse_events: EventReader, + key_input: Res>, + q_windows: Query<&Window, With>, +) { + let player = q_player.get_single_mut(); + if player.is_err() { + return; + } + let (entity, rot, setrot) = player.unwrap(); + + let (win_res_x, win_res_y): (f32, f32); + if let Ok(window) = &q_windows.get_single() { + win_res_x = window.resolution.width(); + win_res_y = window.resolution.height(); + } else { + win_res_x = 1920.0; + win_res_y = 1050.0; + } + + // Determine rotation delta + let mut pitch_yaw_rot = Vec3::ZERO; + let mut mouse_delta = Vec2::ZERO; + for mouse_event in mouse_events.read() { + mouse_delta += mouse_event.delta; + } + if mouse_delta != Vec2::ZERO { + if key_input.pressed(settings.key_rotate) { + pitch_yaw_rot[2] += 2.0 * mouse_delta.x / win_res_x; + } else { + pitch_yaw_rot[0] += 2.0 * mouse_delta.y / win_res_y; + pitch_yaw_rot[1] -= 2.0 * mouse_delta.x / win_res_x; + } + } + + // Apply rotation to player + if pitch_yaw_rot != Vec3::ZERO { + let rot_offset = DQuat::from_euler( + EulerRot::XYZ, + pitch_yaw_rot[0] as f64, + pitch_yaw_rot[1] as f64, + pitch_yaw_rot[2] as f64, + ); + let rot_current = if let Some(setrot) = &setrot { + setrot.0 + } else { + **rot + }; + let rot_target = rot_current * rot_offset; + if let Some(mut setrot) = setrot { + setrot.0 = rot_target; + } else { + commands + .entity(entity) + .try_insert(actor::WantsRotation(rot_target)); + } + } +} + +#[allow(clippy::too_many_arguments)] +pub fn apply_input_to_player_old( time: Res