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:
parent
7da7f80b18
commit
9a7b3b511a
1 changed files with 77 additions and 12 deletions
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue