From 91d19e94a03a4bb98e4731cafb2dfef816be3678 Mon Sep 17 00:00:00 2001 From: yuni Date: Thu, 23 May 2024 00:31:31 +0200 Subject: [PATCH] implement preferred looking direction for NPCs --- src/actor.rs | 19 +++++++++++++++++++ src/cmd.rs | 9 +++++++++ src/common.rs | 10 ++++++++++ src/data/defs.txt | 5 +++++ 4 files changed, 43 insertions(+) diff --git a/src/actor.rs b/src/actor.rs index f5281d2..1ca5657 100644 --- a/src/actor.rs +++ b/src/actor.rs @@ -32,6 +32,7 @@ impl Plugin for ActorPlugin { update_power, handle_wants_maxrotation, handle_wants_maxvelocity, + handle_wants_lookat, ), ); app.add_systems( @@ -153,6 +154,8 @@ pub struct WantsMaxRotation(pub f64); #[derive(Component)] pub struct WantsMaxVelocity(pub f64); #[derive(Component)] +pub struct WantsToLookAt(pub String); +#[derive(Component)] pub struct Identifier(pub String); #[derive(Component)] @@ -556,6 +559,22 @@ fn handle_wants_maxvelocity( } } +fn handle_wants_lookat( + mut query: Query<( + &Position, + &mut Rotation, + &mut ExternalTorque, + &WantsToLookAt, + )>, + id2pos: Res, +) { + for (pos, mut rot, mut _torque, target_id) in &mut query { + if let Some(target_pos) = id2pos.0.get(&target_id.0) { + rot.0 = look_at_quat(**pos, *target_pos, DVec3::Y); + } + } +} + fn handle_damage( mut ew_playerdies: EventWriter, mut q_hp: Query<(&mut HitPoints, Option<&Player>), Changed>, diff --git a/src/cmd.rs b/src/cmd.rs index 873b05d..c8546c8 100644 --- a/src/cmd.rs +++ b/src/cmd.rs @@ -84,6 +84,7 @@ struct ParserState { has_ring: bool, wants_maxrotation: Option, wants_maxvelocity: Option, + wants_tolookat_id: Option, collider_is_mesh: bool, collider_is_one_mesh_of_scene: bool, thrust_forward: f32, @@ -140,6 +141,7 @@ impl Default for ParserState { has_ring: false, wants_maxrotation: None, wants_maxvelocity: None, + wants_tolookat_id: None, collider_is_mesh: false, collider_is_one_mesh_of_scene: false, thrust_forward: default_engine.thrust_forward, @@ -503,6 +505,10 @@ pub fn load_defs(mut ew_spawn: EventWriter) { continue; } } + ["wants", "lookat", id] => { + // NOTE: Will not work if the actor has no engine + state.wants_tolookat_id = Some(id.to_string()); + } ["armodel", asset_name] => { state.ar_model = Some(asset_name.to_string()); } @@ -714,6 +720,9 @@ fn spawn_entities( if let Some(value) = state.wants_maxvelocity { actor.insert(actor::WantsMaxVelocity(value)); } + if let Some(value) = &state.wants_tolookat_id { + actor.insert(actor::WantsToLookAt(value.clone())); + } if let Some(color) = state.light_color { actor.insert(( PointLight { diff --git a/src/common.rs b/src/common.rs index a9490b0..85b3f12 100644 --- a/src/common.rs +++ b/src/common.rs @@ -107,3 +107,13 @@ pub fn in_shadow( return closest_vector.length() < max_distance; } + +pub fn look_at_quat(from: DVec3, to: DVec3, up: DVec3) -> DQuat { + let direction = (to - from).normalize(); + let right = up.cross(direction).normalize(); + let corrected_up = direction.cross(right); + + let mat3 = bevy::math::DMat3::from_cols(right, corrected_up, direction); + + DQuat::from_mat3(&mat3) +} diff --git a/src/data/defs.txt b/src/data/defs.txt index 1b6f41f..fc8e102 100644 --- a/src/data/defs.txt +++ b/src/data/defs.txt @@ -459,6 +459,7 @@ actor -3300 10 0 pizzeria angularmomentum 0 0 0 wants maxrotation 0 wants maxvelocity 0 + wants lookat player thrust 15 6 3 400 0.5 rotationy -126 scale 3 @@ -475,6 +476,7 @@ actor -3300 10 0 pizzeria thrust 1.2 1 1 20 1.5 wants maxrotation 0 wants maxvelocity 0 + wants lookat player rotationy -90 angularmomentum 0 0 0 pronoun he @@ -533,6 +535,7 @@ actor 100 -18000 2000 clippy angularmomentum 0 0 0 wants maxrotation 0 wants maxvelocity 0 + wants lookat player thrust 15 6 3 400 0.5 pointofinterest yes rotationy -90 @@ -684,6 +687,7 @@ actor -184971e3 149410e3 -134273e3 clippy angularmomentum 0 0 0 wants maxrotation 0 wants maxvelocity 0 + wants lookat player thrust 15 6 3 400 0.5 pointofinterest yes rotationy -90 @@ -828,6 +832,7 @@ actor 0 -44e3 0 clippy angularmomentum 0 0 0 wants maxrotation 0 wants maxvelocity 0 + wants lookat player thrust 15 6 3 400 0.5 pointofinterest yes rotationy -90