Add the bike model to the scene; shows rotation is messed up.

This commit is contained in:
Joe Ardent 2022-01-02 23:35:59 -08:00
parent 98bac257fe
commit 81c1a0e685
2 changed files with 80 additions and 52 deletions

View file

@ -5,12 +5,18 @@ use bevy::{
Input,
},
prelude::*,
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;
const PLAYER_DIST: f32 = PLANET_RADIUS + 300.0;
const CAM_DIST: f32 = 25.0;
struct PlayerState {
velocity: Vec3,
}
@ -54,33 +60,71 @@ impl Default for MovementSettings {
#[derive(Component, Debug)]
pub struct FlyCam;
#[derive(Component, Debug)]
pub struct CyberBike;
/// Spawns the `Camera3dBundle` to be controlled
fn setup_player(mut commands: Commands) {
fn setup_player(mut commands: Commands, asset_server: Res<AssetServer>) {
commands
.spawn_bundle(PerspectiveCameraBundle {
transform: Transform::from_xyz(0.0, 100.0, -500.0).looking_at(Vec3::ZERO, Vec3::Y),
transform: Transform::from_xyz(PLAYER_DIST + CAM_DIST, 0.0, 0.0)
.looking_at(Vec3::ZERO, Vec3::Y),
..Default::default()
})
.insert(FlyCam);
commands
.spawn_bundle((
Transform {
translation: Vec3::new(PLAYER_DIST, 0.0, 0.0),
..Default::default()
}
.looking_at(Vec3::ZERO, Vec3::Y),
GlobalTransform::identity(),
))
.with_children(|rider| {
rider.spawn_scene(asset_server.load("cyber-bike_no_y_up.glb#Scene0"));
})
.insert(CyberBike);
}
/// Handles keyboard input and movement
fn player_move(
time: Res<Time>,
state: Res<PlayerState>,
mut query: Query<&mut Transform, With<FlyCam>>,
_settings: Res<MovementSettings>,
mut state: ResMut<PlayerState>,
mut bike_query: Query<&mut Transform, (With<CyberBike>, Without<FlyCam>)>,
mut cam_query: Query<&mut Transform, (With<FlyCam>, Without<CyberBike>)>,
) {
let mut transform = query.single_mut();
let dt = time.delta_seconds();
//let down =
if !state.velocity.is_nan() {
transform.translation += state.velocity * dt;
let mut bike_xform = bike_query.single_mut();
let up = bike_xform.translation.normalize();
let cam_up = bike_xform.up();
let hlevel = up.cross(cam_up).normalize();
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 pitch = bike_xform.forward().dot(vlevel).acos() * 0.5 * dt;
let pitch = Quat::from_axis_angle(bike_xform.right(), pitch);
let rot = pitch; // * roll;
if rot.is_finite() {
bike_xform.rotate(rot);
}
if state.velocity.is_finite() {
//state.velocity += -up * settings.gravity * dt;
bike_xform.translation += state.velocity * dt;
} else {
//state.velocity = -up * settings.gravity * dt;
}
let mut cam_xform = cam_query.single_mut();
cam_xform.translation = bike_xform.translation + (up * CAM_DIST);
cam_xform.look_at(bike_xform.translation, Vec3::Y);
}
/// Handles looking around if cursor is locked
fn player_look(
settings: Res<MovementSettings>,
windows: Res<Windows>,
@ -88,7 +132,7 @@ fn player_look(
time: Res<Time>,
mut istate: ResMut<InputState>,
mut pstate: ResMut<PlayerState>,
mut query: Query<&mut Transform, With<FlyCam>>,
mut query: Query<&mut Transform, With<CyberBike>>,
) {
let window = windows.get_primary().unwrap();
let window_scale = window.height().min(window.width());
@ -96,35 +140,14 @@ fn player_look(
let mut transform = query.single_mut();
let mut vel = pstate.velocity;
let accel = settings.accel * dt * istate.throttle;
//dbg!(istate.throttle);
if !pstate.velocity.is_nan() {
if pstate.velocity.is_finite() {
for GamepadEvent(_, ev) in istate.event_reader.iter(&events) {
dbg!(&istate.throttle, &ev);
// Using smallest of height or width ensures equal vertical and horizontal
// sensitivity
// state.pitch -= (settings.sensitivity * ev.delta.y *
// window_scale).to_radians();
// state.yaw -=
// (settings.sensitivity * ev.delta.x * window_scale).to_radians();
// state.pitch = state.pitch.clamp(-1.54, 1.54);
// // Order is important to prevent unintended roll
// transform.rotation = Quat::from_axis_angle(Vec3::Y, state.yaw)
// * Quat::from_axis_angle(Vec3::X, state.pitch);
dbg!(ev);
match *ev {
GamepadEventType::ButtonChanged(GamepadButtonType::RightTrigger2, val) => {
istate.throttle = -val;
istate.throttle = val;
}
GamepadEventType::ButtonChanged(GamepadButtonType::LeftTrigger2, val) => {
istate.throttle = val;
istate.throttle = -val;
}
GamepadEventType::AxisChanged(GamepadAxisType::LeftStickX, val) => {
istate.yaw = -val;
@ -132,18 +155,22 @@ fn player_look(
GamepadEventType::AxisChanged(GamepadAxisType::LeftStickY, val) => {
istate.pitch = -val;
}
_ => {}
_ => {
info!("unhandled gamepad event: {:?}", ev);
}
}
}
vel += transform.local_z() * accel;
let accel = settings.accel * dt * istate.throttle;
vel += transform.forward() * accel;
// drag
let v2 = vel.length_squared().min(20_000.0);
let v2 = vel.length_squared().min(100_000.0);
if v2 < 0.05 {
vel = Vec3::ZERO;
} else {
let drag = vel * settings.drag * v2 * time.delta_seconds();
let drag = vel * settings.drag * v2.sqrt() * time.delta_seconds();
vel -= drag;
}
} else {
@ -152,7 +179,8 @@ fn player_look(
let d_alt = (settings.sensitivity * dt * window_scale * istate.pitch).to_radians();
let d_az = (settings.sensitivity * dt * window_scale * istate.yaw).to_radians();
let rotation = Quat::from_rotation_y(d_az) * Quat::from_rotation_x(d_alt);
let rotation = Quat::from_axis_angle(transform.local_y(), d_az)
* Quat::from_axis_angle(transform.local_x(), d_alt);
transform.rotate(rotation);

View file

@ -1,5 +1,5 @@
use bevy::prelude::*;
use cyber_rider::flycam::{MovementSettings, PlayerPlugin};
use cyber_rider::flycam::{MovementSettings, PlayerPlugin, PLANET_RADIUS};
/*
stolen with neither shame nor pity from
@ -7,9 +7,8 @@ git@github.com:sburris0/bevy_flycam.git, b90f6fc, which is copyright 2020
Spencer Burris
*/
const BIG_RADIUS: f32 = 150.0;
const LIGHT_RANGE: f32 = BIG_RADIUS * 3.0;
const LIGHT_DIST: f32 = BIG_RADIUS * 1.2;
const LIGHT_RANGE: f32 = PLANET_RADIUS * 2.2;
const LIGHT_DIST: f32 = PLANET_RADIUS * 1.2;
fn main() {
App::new()
@ -17,7 +16,7 @@ fn main() {
.add_plugins(DefaultPlugins)
.add_plugin(PlayerPlugin)
.insert_resource(MovementSettings {
sensitivity: 1.0, // default: 1.0
sensitivity: 0.3, // default: 1.0
accel: 20.0, // default: 40.0
drag: 0.1, // default: 0.05
gravity: 10.0, // default: 10.0
@ -44,35 +43,35 @@ fn setup(
mut materials: ResMut<Assets<StandardMaterial>>,
) {
let red_light = PointLight {
intensity: 10_000.0,
intensity: 5_000.0,
range: LIGHT_RANGE,
color: Color::RED,
..Default::default()
};
let blue_light = PointLight {
intensity: 10_000.0,
intensity: 5_000.0,
range: LIGHT_RANGE,
color: Color::BLUE,
..Default::default()
};
let purple_light = PointLight {
intensity: 10_000.0,
intensity: 5_000.0,
range: LIGHT_RANGE,
color: Color::PURPLE,
..Default::default()
};
commands.insert_resource(AmbientLight {
color: Color::PINK,
brightness: 0.08,
color: Color::WHITE,
brightness: 0.12,
});
// world
commands.spawn_bundle(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere {
radius: BIG_RADIUS,
radius: PLANET_RADIUS,
subdivisions: 6,
})),
material: materials.add(StandardMaterial {
@ -84,6 +83,7 @@ fn setup(
..Default::default()
});
// east light
commands
.spawn_bundle(PointLightBundle {