Corrects orientation for local up. Adds dbg ui for orientation.

Still using the model as the camera stand-in. Next up is enabling collision detection and gravity.
This commit is contained in:
Joe Ardent 2022-01-05 00:16:22 -08:00
parent 7da7f80b18
commit 9a7b3b511a

View file

@ -8,10 +8,6 @@ use bevy::{
utils::tracing::info, utils::tracing::info,
}; };
// stolen with neither shame nor pity from
// git@github.com:sburris0/bevy_flycam.git, b90f6fc, which is copyright 2020
// Spencer Burris
pub const PLANET_RADIUS: f32 = 75.0; pub const PLANET_RADIUS: f32 = 75.0;
const PLAYER_DIST: f32 = PLANET_RADIUS + 300.0; const PLAYER_DIST: f32 = PLANET_RADIUS + 300.0;
@ -21,6 +17,12 @@ struct PlayerState {
velocity: Vec3, velocity: Vec3,
} }
#[derive(Default)]
struct UpState {
player_up: Vec3,
cam_up: Vec3,
}
impl Default for PlayerState { impl Default for PlayerState {
fn default() -> Self { fn default() -> Self {
PlayerState { PlayerState {
@ -63,6 +65,9 @@ pub struct FlyCam;
#[derive(Component, Debug)] #[derive(Component, Debug)]
pub struct CyberBike; pub struct CyberBike;
#[derive(Component)]
struct UpText;
/// Spawns the `Camera3dBundle` to be controlled /// Spawns the `Camera3dBundle` to be controlled
fn setup_player(mut commands: Commands, asset_server: Res<AssetServer>) { fn setup_player(mut commands: Commands, asset_server: Res<AssetServer>) {
commands commands
@ -88,9 +93,49 @@ fn setup_player(mut commands: Commands, asset_server: Res<AssetServer>) {
.insert(CyberBike); .insert(CyberBike);
} }
fn setup_dbg_ui(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn_bundle(UiCameraBundle::default());
commands
.spawn_bundle(TextBundle {
style: Style {
align_self: AlignSelf::FlexEnd,
..Default::default()
},
// Use `Text` directly
text: Text {
// Construct a `Vec` of `TextSection`s
sections: vec![TextSection {
value: "".to_string(),
style: TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: 40.0,
color: Color::GOLD,
},
}],
..Default::default()
},
..Default::default()
})
.insert(UpText);
}
fn dbg_ui_system(state: Res<UpState>, mut query: Query<&mut Text, With<UpText>>) {
let cos = state.player_up.dot(state.cam_up);
let mut text = query.single_mut();
text.sections[0].value = format!(
"up: {:?}\ncam_up: {:?}\ntheta: {:.2}",
state.player_up,
state.cam_up,
cos.acos().to_degrees()
);
}
fn player_move( fn player_move(
time: Res<Time>, time: Res<Time>,
_settings: Res<MovementSettings>, _settings: Res<MovementSettings>,
mut up_state: ResMut<UpState>,
mut state: ResMut<PlayerState>, mut state: ResMut<PlayerState>,
mut bike_query: Query<&mut Transform, (With<CyberBike>, Without<FlyCam>)>, mut bike_query: Query<&mut Transform, (With<CyberBike>, Without<FlyCam>)>,
mut cam_query: Query<&mut Transform, (With<FlyCam>, Without<CyberBike>)>, mut cam_query: Query<&mut Transform, (With<FlyCam>, Without<CyberBike>)>,
@ -100,16 +145,25 @@ fn player_move(
let mut bike_xform = bike_query.single_mut(); let mut bike_xform = bike_query.single_mut();
let up = bike_xform.translation.normalize(); let up = bike_xform.translation.normalize();
let cam_up = bike_xform.up(); let cam_up = bike_xform.up();
let hlevel = up.cross(cam_up).normalize(); let cos = up.dot(cam_up);
let roll = bike_xform.left().dot(hlevel).acos() * 0.5 * dt;
let roll = Quat::from_axis_angle(bike_xform.forward(), roll);
let vlevel = up.cross(hlevel).normalize(); let theta = cos.acos();
let pitch = bike_xform.forward().dot(vlevel).acos() * 0.5 * dt; let rate = if !theta.is_normal() {
let pitch = Quat::from_axis_angle(bike_xform.right(), pitch); 0.0
} else if theta.is_sign_negative() {
-0.4
} else {
0.4
} * dt;
let angle = if rate.is_sign_negative() {
rate.max(theta)
} else {
rate.min(theta)
};
let rot = pitch; // * roll; let rot = Quat::from_axis_angle(cam_up.cross(up).normalize(), angle);
if rot.is_finite() {
if rot.is_finite() && theta.abs() > 0.0085 {
bike_xform.rotate(rot); bike_xform.rotate(rot);
} }
@ -120,6 +174,9 @@ fn player_move(
//state.velocity = -up * settings.gravity * dt; //state.velocity = -up * settings.gravity * dt;
} }
up_state.cam_up = cam_up;
up_state.player_up = up;
let mut cam_xform = cam_query.single_mut(); let mut cam_xform = cam_query.single_mut();
cam_xform.translation = bike_xform.translation + (up * CAM_DIST); cam_xform.translation = bike_xform.translation + (up * CAM_DIST);
cam_xform.look_at(bike_xform.translation, Vec3::Y); cam_xform.look_at(bike_xform.translation, Vec3::Y);
@ -149,6 +206,11 @@ fn player_look(
GamepadEventType::ButtonChanged(GamepadButtonType::LeftTrigger2, val) => { GamepadEventType::ButtonChanged(GamepadButtonType::LeftTrigger2, val) => {
istate.throttle = -val; istate.throttle = -val;
} }
GamepadEventType::ButtonChanged(GamepadButtonType::East, val) => {
if val > 0.5 {
vel = Vec3::ZERO;
}
}
GamepadEventType::AxisChanged(GamepadAxisType::LeftStickX, val) => { GamepadEventType::AxisChanged(GamepadAxisType::LeftStickX, val) => {
istate.yaw = -val; istate.yaw = -val;
} }
@ -214,7 +276,10 @@ impl Plugin for PlayerPlugin {
app.init_resource::<PlayerState>() app.init_resource::<PlayerState>()
.init_resource::<MovementSettings>() .init_resource::<MovementSettings>()
.init_resource::<InputState>() .init_resource::<InputState>()
.init_resource::<UpState>()
.add_startup_system(setup_player) .add_startup_system(setup_player)
.add_startup_system(setup_dbg_ui)
.add_system(dbg_ui_system)
.add_system(player_move.label("move")) .add_system(player_move.label("move"))
.add_system(player_look.after("move")) .add_system(player_look.after("move"))
.add_system(cursor_grab); .add_system(cursor_grab);