Add the bike model to the scene; shows rotation is messed up.
This commit is contained in:
parent
98bac257fe
commit
81c1a0e685
2 changed files with 80 additions and 52 deletions
112
src/flycam.rs
112
src/flycam.rs
|
@ -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);
|
||||
|
||||
|
|
22
src/main.rs
22
src/main.rs
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue