Skip to content

Commit

Permalink
Rotate camera around an arbitrary "up" axis
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Dec 3, 2023
1 parent 2ce0ead commit e858926
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 12 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ fn main() {
.insert_resource(MovementSettings {
sensitivity: 0.00015, // default: 0.00012
speed: 12.0, // default: 12.0
up: Vec3::Y,
})
.insert_resource(KeyBindings {
move_ascend: KeyCode::E,
Expand Down
1 change: 1 addition & 0 deletions examples/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ fn main() {
.insert_resource(MovementSettings {
sensitivity: 0.00015, // default: 0.00012
speed: 12.0, // default: 12.0
up: Vec3::Y,
})
.add_systems(Startup, setup)
.run();
Expand Down
1 change: 1 addition & 0 deletions examples/key_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ fn main() {
.insert_resource(MovementSettings {
sensitivity: 0.00015, // default: 0.00012
speed: 12.0, // default: 12.0
up: Vec3::Y,
})
// Unreal movement layout
.insert_resource(KeyBindings {
Expand Down
36 changes: 24 additions & 12 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ struct InputState {
pub struct MovementSettings {
pub sensitivity: f32,
pub speed: f32,
pub up: Vec3,
}

impl Default for MovementSettings {
fn default() -> Self {
Self {
sensitivity: 0.00012,
speed: 12.,
up: Vec3::Y,
}
}
}
Expand Down Expand Up @@ -84,10 +86,10 @@ fn initial_grab_cursor(mut primary_window: Query<&mut Window, With<PrimaryWindow
}

/// Spawns the `Camera3dBundle` to be controlled
fn setup_player(mut commands: Commands) {
fn setup_player(mut commands: Commands, settings: Res<MovementSettings>) {
commands.spawn((
Camera3dBundle {
transform: Transform::from_xyz(-2.0, 5.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
transform: Transform::from_xyz(-2.0, 5.0, 5.0).looking_at(Vec3::ZERO, settings.up),
..Default::default()
},
FlyCam,
Expand All @@ -106,9 +108,8 @@ fn player_move(
if let Ok(window) = primary_window.get_single() {
for (_camera, mut transform) in query.iter_mut() {
let mut velocity = Vec3::ZERO;
let local_z = transform.local_z();
let forward = -Vec3::new(local_z.x, 0., local_z.z);
let right = Vec3::new(local_z.z, 0., -local_z.x);
let forward = transform.forward();
let right = transform.right();

for key in keys.get_pressed() {
match window.cursor.grab_mode {
Expand All @@ -124,9 +125,9 @@ fn player_move(
} else if key == key_bindings.move_right {
velocity += right;
} else if key == key_bindings.move_ascend {
velocity += Vec3::Y;
velocity += settings.up;
} else if key == key_bindings.move_descend {
velocity -= Vec3::Y;
velocity -= settings.up;
}
}
}
Expand All @@ -152,7 +153,8 @@ fn player_look(
if let Ok(window) = primary_window.get_single() {
for mut transform in query.iter_mut() {
for ev in state.reader_motion.read(&motion) {
let (mut yaw, mut pitch, _) = transform.rotation.to_euler(EulerRot::YXZ);
let mut yaw = 0.0;
let mut pitch = 0.0;
match window.cursor.grab_mode {
CursorGrabMode::None => (),
_ => {
Expand All @@ -163,11 +165,21 @@ fn player_look(
}
}

pitch = pitch.clamp(-1.54, 1.54);

// Order is important to prevent unintended roll
transform.rotation =
Quat::from_axis_angle(Vec3::Y, yaw) * Quat::from_axis_angle(Vec3::X, pitch);
transform.rotation = Quat::from_axis_angle(settings.up, yaw)
* transform.rotation
* Quat::from_axis_angle(Vec3::X, pitch);

let up = transform.up();
let right = transform.right();
let pitch = settings.up.cross(up).dot(right).atan2(settings.up.dot(up));
let restricted_pitch = pitch.clamp(-1.54, 1.54);
let diff = restricted_pitch - pitch;
transform.rotate_axis(right, diff);

// Eliminate accumulated roll and ensure we don't flip onto our heads.
let forward = transform.forward();
transform.look_to(forward, settings.up);
}
}
} else {
Expand Down

0 comments on commit e858926

Please sign in to comment.