From c3b2e48a5013b2306c9711912fff705026da9abe Mon Sep 17 00:00:00 2001 From: Huon Imberger Date: Fri, 28 Apr 2023 20:37:16 +1000 Subject: [PATCH 1/6] Add smoothness config --- src/lib.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 5bf4388..f44a4ae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,7 +29,7 @@ pub struct PanOrbitCameraPlugin; impl Plugin for PanOrbitCameraPlugin { fn build(&self, app: &mut App) { - app.insert_resource(ActiveViewportData::default()) + app.insert_resource(ActiveCameraData::default()) .add_systems( (active_viewport_data, pan_orbit_camera) .chain() @@ -117,6 +117,10 @@ pub struct PanOrbitCamera { pub beta_lower_limit: Option, /// The sensitivity of the orbiting motion. Defaults to `1.0`. pub orbit_sensitivity: f32, + /// How much smoothing is applied to the orbit motion. A value of `0.0` disables smoothing, + /// so there's a 1:1 mapping of input to camera position. A value of `1.0` is infinite, + /// smoothing, which you probably don't want. Defaults to `0.8`. + pub orbit_smoothness: f32, /// The sensitivity of the panning motion. Defaults to `1.0`. pub pan_sensitivity: f32, /// The sensitivity of moving the camera closer or further way using the scroll wheel. Defaults to `1.0`. @@ -151,6 +155,7 @@ impl Default for PanOrbitCamera { is_upside_down: false, allow_upside_down: false, orbit_sensitivity: 1.0, + orbit_smoothness: 0.8, pan_sensitivity: 1.0, zoom_sensitivity: 1.0, button_orbit: MouseButton::Left, @@ -471,8 +476,9 @@ fn pan_orbit_camera( || pan_orbit.target_beta != pan_orbit.beta { // Otherwise, interpolate our way there - let mut target_alpha = pan_orbit.alpha.lerp(&pan_orbit.target_alpha, &0.2); - let mut target_beta = pan_orbit.beta.lerp(&pan_orbit.target_beta, &0.2); + let t = 1.0 - pan_orbit.orbit_smoothness; + let mut target_alpha = pan_orbit.alpha.lerp(&pan_orbit.target_alpha, &t); + let mut target_beta = pan_orbit.beta.lerp(&pan_orbit.target_beta, &t); // If we're super close, then just snap to target rotation to save cycles if (target_alpha - pan_orbit.target_alpha).abs() < 0.001 { From e0ee4b0937c7cc268f401b6a3a00f2ab675b1997 Mon Sep 17 00:00:00 2001 From: Huon Imberger Date: Fri, 28 Apr 2023 20:38:12 +1000 Subject: [PATCH 2/6] If cam not active, don't skip everything, just skip input (effectively disable) --- src/lib.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f44a4ae..ad8beda 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -335,12 +335,6 @@ fn pan_orbit_camera( continue; } - // Abort early if this camera not active. Do this after initializing so cameras are always - // initialized. - if active_viewport_data.entity != Some(entity) { - continue; - } - // 1 - Get Input let mut pan = Vec2::ZERO; @@ -348,7 +342,7 @@ fn pan_orbit_camera( let mut scroll = 0.0; let mut orbit_button_changed = false; - if pan_orbit.enabled { + if pan_orbit.enabled && active_viewport_data.entity == Some(entity) { if orbit_pressed(&pan_orbit, &mouse_input, &key_input) { rotation_move += mouse_delta * pan_orbit.orbit_sensitivity; } else if pan_pressed(&pan_orbit, &mouse_input, &key_input) { From 3408bde499bdd444fc27de67a23a31d36b42c2c5 Mon Sep 17 00:00:00 2001 From: Huon Imberger Date: Fri, 28 Apr 2023 20:38:39 +1000 Subject: [PATCH 3/6] Rename active viewport data to active cam data --- examples/animate.rs | 65 +++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 18 ++++++------- 2 files changed, 74 insertions(+), 9 deletions(-) create mode 100644 examples/animate.rs diff --git a/examples/animate.rs b/examples/animate.rs new file mode 100644 index 0000000..0282ff3 --- /dev/null +++ b/examples/animate.rs @@ -0,0 +1,65 @@ +//! Demonstrates how you can animate the movement of the camera + +use bevy::prelude::*; +use bevy_panorbit_camera::{PanOrbitCamera, PanOrbitCameraPlugin}; +use std::f32::consts::TAU; + +fn main() { + App::new() + .add_plugins(DefaultPlugins) + .add_plugin(PanOrbitCameraPlugin) + .add_startup_system(setup) + .add_system(animate) + .run(); +} + +fn setup( + mut commands: Commands, + mut meshes: ResMut>, + mut materials: ResMut>, +) { + // Ground + commands.spawn(PbrBundle { + mesh: meshes.add(shape::Plane::from_size(5.0).into()), + material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()), + ..default() + }); + // Cube + commands.spawn(PbrBundle { + mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })), + material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()), + transform: Transform::from_xyz(0.0, 0.5, 0.0), + ..default() + }); + // Light + commands.spawn(PointLightBundle { + point_light: PointLight { + intensity: 1500.0, + shadows_enabled: true, + ..default() + }, + transform: Transform::from_xyz(4.0, 8.0, 4.0), + ..default() + }); + // Camera + commands.spawn(( + Camera3dBundle::default(), + PanOrbitCamera { + // Optionally disable smoothing to have full control over the camera's position + // orbit_smoothness: 0.0, + // Might want to disable the controls + enabled: false, + ..default() + }, + )); +} + +// Animate the camera's position +fn animate(time: Res