Dummy scene with mostly-working camera
This commit is contained in:
parent
7e77e51b14
commit
78f6d3d0ff
|
|
@ -0,0 +1,17 @@
|
|||
[package]
|
||||
name = "terroir"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
bevy = { version = "0.14.1", features = ["dynamic_linking"] }
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 1
|
||||
|
||||
[profile.dev.package."*"]
|
||||
opt-level = 3
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
lto = "thin"
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
use {
|
||||
bevy::{input::mouse::MouseMotion, prelude::*, window::CursorGrabMode},
|
||||
std::f32::consts::{FRAC_PI_2, FRAC_PI_4, PI, TAU},
|
||||
};
|
||||
|
||||
#[derive(Bundle, Default)]
|
||||
pub struct PanOrbitCameraBundle {
|
||||
pub camera: Camera3dBundle,
|
||||
pub state: PanOrbitState,
|
||||
pub settings: PanOrbitSettings,
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct PanOrbitState {
|
||||
pub center: Vec3,
|
||||
pub radius: f32,
|
||||
pub pitch: f32,
|
||||
pub yaw: f32,
|
||||
}
|
||||
|
||||
impl Default for PanOrbitState {
|
||||
fn default() -> Self {
|
||||
PanOrbitState {
|
||||
center: Vec3::ZERO,
|
||||
radius: 2.0,
|
||||
pitch: -FRAC_PI_4,
|
||||
yaw: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The configuration of the pan-orbit controller
|
||||
#[derive(Component)]
|
||||
pub struct PanOrbitSettings {
|
||||
/// World units per pixel of mouse motion
|
||||
pub pan_sensitivity: f32,
|
||||
/// Radians per pixel of mouse motion
|
||||
pub orbit_sensitivity: f32,
|
||||
/// Exponent per pixel of mouse motion
|
||||
pub zoom_sensitivity: f32,
|
||||
}
|
||||
|
||||
impl Default for PanOrbitSettings {
|
||||
fn default() -> Self {
|
||||
PanOrbitSettings {
|
||||
pan_sensitivity: 0.001, // 1000 pixels per world unit
|
||||
orbit_sensitivity: 0.1f32.to_radians(), // 0.1 degree per pixel
|
||||
zoom_sensitivity: 0.01,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(
|
||||
mut evr_motion: EventReader<MouseMotion>,
|
||||
mouse: Res<ButtonInput<MouseButton>>,
|
||||
mut q_camera: Query<(&PanOrbitSettings, &mut PanOrbitState, &mut Transform)>,
|
||||
mut q_window: Query<&mut Window>,
|
||||
) {
|
||||
let mouse_motion: Vec2 = evr_motion.read().map(|ev| ev.delta).sum();
|
||||
|
||||
for (settings, mut state, mut transform) in &mut q_camera {
|
||||
if mouse.any_pressed([MouseButton::Left, MouseButton::Right]) {
|
||||
q_window.single_mut().cursor.grab_mode = CursorGrabMode::Locked;
|
||||
} else {
|
||||
q_window.single_mut().cursor.grab_mode = CursorGrabMode::None;
|
||||
}
|
||||
|
||||
if mouse.pressed(MouseButton::Right) {
|
||||
state.pitch = (state.pitch - settings.orbit_sensitivity * mouse_motion.y)
|
||||
.clamp(-FRAC_PI_2, FRAC_PI_2);
|
||||
state.yaw += settings.orbit_sensitivity * mouse_motion.x;
|
||||
if state.yaw > PI {
|
||||
state.yaw -= TAU;
|
||||
}
|
||||
if state.yaw < -PI {
|
||||
state.yaw += TAU;
|
||||
}
|
||||
}
|
||||
|
||||
if mouse.pressed(MouseButton::Left) {
|
||||
// TODO this needs to take the current rotation into account
|
||||
state.center += (settings.pan_sensitivity * mouse_motion * -1.0)
|
||||
.extend(0.0)
|
||||
.xzy();
|
||||
}
|
||||
|
||||
if mouse.pressed(MouseButton::Middle) {
|
||||
state.radius = (state.radius + settings.zoom_sensitivity * mouse_motion.y).max(0.0);
|
||||
}
|
||||
|
||||
transform.rotation = Quat::from_euler(EulerRot::YXZ, state.yaw, state.pitch, 0.0);
|
||||
transform.translation = state.center + transform.back() * state.radius;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
mod camera;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_systems(Startup, setup)
|
||||
.add_systems(Update, camera::update)
|
||||
.run();
|
||||
}
|
||||
|
||||
/// set up a simple 3D scene
|
||||
fn setup(
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::new(1.0, 0.2, 1.0)),
|
||||
material: materials.add(Color::srgb_u8(124, 144, 255)),
|
||||
transform: Transform::from_xyz(0.0, -0.2, 0.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(PointLightBundle {
|
||||
point_light: PointLight {
|
||||
shadows_enabled: true,
|
||||
..default()
|
||||
},
|
||||
transform: Transform::from_xyz(4.0, 8.0, 4.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(camera::PanOrbitCameraBundle::default());
|
||||
}
|
||||
Loading…
Reference in New Issue