WIP crisper camera controls (apply acceleration)
This commit is contained in:
parent
e8e81e8e52
commit
06c2d90228
90
src/actor.rs
90
src/actor.rs
|
@ -17,6 +17,7 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_xpbd_3d::prelude::*;
|
use bevy_xpbd_3d::prelude::*;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub const ENGINE_SPEED_FACTOR: f32 = 30.0;
|
pub const ENGINE_SPEED_FACTOR: f32 = 30.0;
|
||||||
const MAX_TRANSMISSION_DISTANCE: f32 = 100.0;
|
const MAX_TRANSMISSION_DISTANCE: f32 = 100.0;
|
||||||
|
@ -39,6 +40,7 @@ impl Plugin for ActorPlugin {
|
||||||
update_power.run_if(game_running),
|
update_power.run_if(game_running),
|
||||||
handle_gravity.run_if(game_running),
|
handle_gravity.run_if(game_running),
|
||||||
handle_wants_rotation.run_if(game_running),
|
handle_wants_rotation.run_if(game_running),
|
||||||
|
handle_wants_acceleration.run_if(game_running),
|
||||||
handle_wants_maxrotation.run_if(game_running),
|
handle_wants_maxrotation.run_if(game_running),
|
||||||
handle_wants_maxvelocity
|
handle_wants_maxvelocity
|
||||||
.run_if(game_running)
|
.run_if(game_running)
|
||||||
|
@ -150,6 +152,12 @@ impl Default for ExperiencesGForce {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Default)]
|
||||||
|
pub struct WantsAcceleration {
|
||||||
|
pub direction: DVec3,
|
||||||
|
pub brake: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Player; // Attached to the suit of the player
|
pub struct Player; // Attached to the suit of the player
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
|
@ -580,6 +588,7 @@ pub fn handle_vehicle_enter_exit(
|
||||||
commands.entity(driver).remove::<PlayerCamera>();
|
commands.entity(driver).remove::<PlayerCamera>();
|
||||||
commands.entity(driver).remove::<Collider>();
|
commands.entity(driver).remove::<Collider>();
|
||||||
commands.entity(driver).insert(JustNowEnteredVehicle);
|
commands.entity(driver).insert(JustNowEnteredVehicle);
|
||||||
|
commands.entity(vehicle).insert(WantsAcceleration::default());
|
||||||
commands.entity(vehicle).remove::<hud::IsTargeted>();
|
commands.entity(vehicle).remove::<hud::IsTargeted>();
|
||||||
commands.entity(vehicle).insert(PlayerCamera);
|
commands.entity(vehicle).insert(PlayerCamera);
|
||||||
commands.entity(vehicle).insert(PlayerDrivesThis);
|
commands.entity(vehicle).insert(PlayerDrivesThis);
|
||||||
|
@ -706,14 +715,89 @@ fn handle_wants_maxvelocity(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_wants_rotation(
|
fn handle_wants_rotation(mut q_actor: Query<(&mut Rotation, &WantsRotation)>) {
|
||||||
mut q_actor: Query<(&mut Rotation, &WantsRotation)>,
|
|
||||||
) {
|
|
||||||
for (mut rot, setrot) in &mut q_actor {
|
for (mut rot, setrot) in &mut q_actor {
|
||||||
**rot = setrot.0;
|
**rot = setrot.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_wants_acceleration(
|
||||||
|
jupiter_pos: Res<game::JupiterPos>,
|
||||||
|
mut q_actor: Query<(
|
||||||
|
Entity,
|
||||||
|
&Transform,
|
||||||
|
&Position,
|
||||||
|
&mut LinearVelocity,
|
||||||
|
Option<&WantsAcceleration>,
|
||||||
|
Option<&hud::IsTargeted>,
|
||||||
|
Option<&PlayerCamera>,
|
||||||
|
)>,
|
||||||
|
) {
|
||||||
|
// Vector elements: (Entity, is_player, pos)
|
||||||
|
let mut request_closest: Vec<(Entity, bool, DVec3)> = vec![];
|
||||||
|
let mut closest_map: HashMap<Entity, DVec3> = HashMap::new();
|
||||||
|
|
||||||
|
// First, determine whether any actor wants to brake (=match velocity)
|
||||||
|
for (entity, _, pos, _, accel, _, is_player) in &mut q_actor {
|
||||||
|
if accel.is_some() && accel.unwrap().brake {
|
||||||
|
request_closest.push((entity, is_player.is_some(), pos.0.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If an actor is braking, find out relative to what it wants to brake
|
||||||
|
for (entity, is_player, pos) in &request_closest {
|
||||||
|
let mut target_v: Option<DVec3> = None;
|
||||||
|
|
||||||
|
// First, if this is the player, check whether they targeted anything
|
||||||
|
// so we can match velocity to the target.
|
||||||
|
if *is_player {
|
||||||
|
for (_, _, _, v, _, is_target, _) in &q_actor {
|
||||||
|
if is_target.is_some() {
|
||||||
|
target_v = Some(v.0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not, simply look for the closest object and match velocity to that.
|
||||||
|
if target_v.is_none() {
|
||||||
|
let mut closest_distance = camera::MAX_DIST_FOR_MATCH_VELOCITY;
|
||||||
|
for (testentity, _, testpos, v, _, _, _) in &q_actor {
|
||||||
|
if *entity != testentity {
|
||||||
|
let distance = (*pos - testpos.0).length();
|
||||||
|
if distance < closest_distance {
|
||||||
|
target_v = Some(v.0);
|
||||||
|
closest_distance = distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last resort: Match velocity to the orbital velocity around Jupiter
|
||||||
|
if target_v.is_none() {
|
||||||
|
let relative_pos = *pos - jupiter_pos.0;
|
||||||
|
target_v = Some(nature::orbital_velocity(relative_pos, nature::JUPITER_MASS));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(target_v) = target_v {
|
||||||
|
closest_map.insert(*entity, target_v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (entity, trans, _, mut v, accel, _, _) in &mut q_actor {
|
||||||
|
if let Some(accel) = accel {
|
||||||
|
if accel.brake {
|
||||||
|
if let Some(target_v) = closest_map.get(&entity) {
|
||||||
|
**v = *target_v;
|
||||||
|
}
|
||||||
|
} else if accel.direction != DVec3::ZERO {
|
||||||
|
let delta_v = trans.rotation * accel.direction.as_vec3();
|
||||||
|
**v += delta_v.as_dvec3();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_wants_lookat(
|
fn handle_wants_lookat(
|
||||||
mut query: Query<
|
mut query: Query<
|
||||||
(
|
(
|
||||||
|
|
|
@ -444,10 +444,15 @@ fn manage_player_actor(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_input_to_player(
|
pub fn apply_input_to_player(
|
||||||
settings: Res<var::Settings>,
|
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
|
settings: Res<var::Settings>,
|
||||||
mut q_player: Query<
|
mut q_player: Query<
|
||||||
(Entity, &Rotation, Option<&mut actor::WantsRotation>),
|
(
|
||||||
|
Entity,
|
||||||
|
&mut actor::WantsAcceleration,
|
||||||
|
&Rotation,
|
||||||
|
Option<&mut actor::WantsRotation>,
|
||||||
|
),
|
||||||
With<actor::PlayerCamera>,
|
With<actor::PlayerCamera>,
|
||||||
>,
|
>,
|
||||||
mut mouse_events: EventReader<MouseMotion>,
|
mut mouse_events: EventReader<MouseMotion>,
|
||||||
|
@ -458,7 +463,7 @@ pub fn apply_input_to_player(
|
||||||
if player.is_err() {
|
if player.is_err() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let (entity, rot, setrot) = player.unwrap();
|
let (entity, mut accel, rot, setrot) = player.unwrap();
|
||||||
|
|
||||||
let (win_res_x, win_res_y): (f32, f32);
|
let (win_res_x, win_res_y): (f32, f32);
|
||||||
if let Ok(window) = &q_windows.get_single() {
|
if let Ok(window) = &q_windows.get_single() {
|
||||||
|
@ -506,6 +511,32 @@ pub fn apply_input_to_player(
|
||||||
.try_insert(actor::WantsRotation(rot_target));
|
.try_insert(actor::WantsRotation(rot_target));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine acceleration
|
||||||
|
let mut axis_input: DVec3 = DVec3::ZERO;
|
||||||
|
if key_input.pressed(settings.key_forward) || settings.cruise_control_active {
|
||||||
|
axis_input.z += 1.0;
|
||||||
|
}
|
||||||
|
if key_input.pressed(settings.key_back) {
|
||||||
|
axis_input.z -= 1.0;
|
||||||
|
}
|
||||||
|
if key_input.pressed(settings.key_right) {
|
||||||
|
axis_input.x -= 1.0;
|
||||||
|
}
|
||||||
|
if key_input.pressed(settings.key_left) {
|
||||||
|
axis_input.x += 1.0;
|
||||||
|
}
|
||||||
|
if key_input.pressed(settings.key_up) {
|
||||||
|
axis_input.y += 1.0;
|
||||||
|
}
|
||||||
|
if key_input.pressed(settings.key_down) {
|
||||||
|
axis_input.y -= 1.0;
|
||||||
|
}
|
||||||
|
//axis_input = axis_input.clamp(DVec3::splat(-1.0), DVec3::splat(1.0));
|
||||||
|
|
||||||
|
// Apply acceleration to player
|
||||||
|
accel.direction = axis_input;
|
||||||
|
accel.brake = key_input.pressed(settings.key_stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
|
|
@ -1134,6 +1134,7 @@ fn spawn_entities(
|
||||||
if state.is_player {
|
if state.is_player {
|
||||||
actor.insert(actor::Player);
|
actor.insert(actor::Player);
|
||||||
actor.insert(actor::PlayerCamera);
|
actor.insert(actor::PlayerCamera);
|
||||||
|
actor.insert(actor::WantsAcceleration::default());
|
||||||
actor.insert(hud::AugmentedRealityOverlayBroadcaster);
|
actor.insert(hud::AugmentedRealityOverlayBroadcaster);
|
||||||
//actor.insert(actor::WantsRotation(Quat::IDENTITY));
|
//actor.insert(actor::WantsRotation(Quat::IDENTITY));
|
||||||
ew_updateavatar.send(hud::UpdateAvatarEvent);
|
ew_updateavatar.send(hud::UpdateAvatarEvent);
|
||||||
|
|
Loading…
Reference in a new issue