basic moving camera
This commit is contained in:
parent
d5bcbb5339
commit
2ce1d6e809
5 changed files with 4050 additions and 1 deletions
3845
Cargo.lock
generated
3845
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -4,3 +4,4 @@ version = "0.1.0"
|
|||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
bevy = "0.4"
|
||||
|
|
152
src/camera.rs
Normal file
152
src/camera.rs
Normal file
|
@ -0,0 +1,152 @@
|
|||
use bevy::{input::mouse::MouseMotion, math::clamp, prelude::*};
|
||||
|
||||
pub struct FlyCamera {
|
||||
/// The speed the FlyCamera moves at. Defaults to `1.0`
|
||||
pub speed: f32,
|
||||
/// The sensitivity of the FlyCamera's motion based on mouse movement. Defaults to `3.0`
|
||||
pub sensitivity: f32,
|
||||
/// The amount of deceleration to apply to the camera's motion. Defaults to `1.0`
|
||||
pub friction: f32,
|
||||
/// The current pitch of the FlyCamera in degrees. This value is always up-to-date, enforced by [FlyCameraPlugin](struct.FlyCameraPlugin.html)
|
||||
pub pitch: f32,
|
||||
/// The current pitch of the FlyCamera in degrees. This value is always up-to-date, enforced by [FlyCameraPlugin](struct.FlyCameraPlugin.html)
|
||||
pub yaw: f32,
|
||||
/// The current velocity of the FlyCamera. This value is always up-to-date, enforced by [FlyCameraPlugin](struct.FlyCameraPlugin.html)
|
||||
pub velocity: Vec3,
|
||||
}
|
||||
impl Default for FlyCamera {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
speed: 1.5,
|
||||
sensitivity: 3.0,
|
||||
friction: 1.0,
|
||||
pitch: 0.0,
|
||||
yaw: 0.0,
|
||||
velocity: Vec3::zero(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn forward_vector(rotation: &Quat) -> Vec3 {
|
||||
rotation.mul_vec3(Vec3::unit_z()).normalize()
|
||||
}
|
||||
|
||||
fn forward_walk_vector(rotation: &Quat) -> Vec3 {
|
||||
let f = forward_vector(rotation);
|
||||
let f_flattened = Vec3::new(f.x, 0.0, f.z).normalize();
|
||||
f_flattened
|
||||
}
|
||||
|
||||
fn strafe_vector(rotation: &Quat) -> Vec3 {
|
||||
// Rotate it 90 degrees to get the strafe direction
|
||||
Quat::from_rotation_y(90.0f32.to_radians())
|
||||
.mul_vec3(forward_walk_vector(rotation))
|
||||
.normalize()
|
||||
}
|
||||
|
||||
fn movement_axis(
|
||||
input: &Res<Input<KeyCode>>,
|
||||
plus: KeyCode,
|
||||
minus: KeyCode,
|
||||
) -> f32 {
|
||||
let mut axis = 0.0;
|
||||
if input.pressed(plus) {
|
||||
axis += 1.0;
|
||||
}
|
||||
if input.pressed(minus) {
|
||||
axis -= 1.0;
|
||||
}
|
||||
axis
|
||||
}
|
||||
|
||||
fn camera_movement_system(
|
||||
time: Res<Time>,
|
||||
keyboard_input: Res<Input<KeyCode>>,
|
||||
mut query: Query<(&mut FlyCamera, &mut Transform)>,
|
||||
) {
|
||||
for (mut options, mut transform) in query.iter_mut() {
|
||||
let (axis_h, axis_v, axis_float) = (movement_axis(&keyboard_input, KeyCode::D, KeyCode::A),
|
||||
movement_axis(
|
||||
&keyboard_input,
|
||||
KeyCode::S,
|
||||
KeyCode::W,
|
||||
),
|
||||
movement_axis(&keyboard_input, KeyCode::Space, KeyCode::LControl),
|
||||
);
|
||||
|
||||
let rotation = transform.rotation;
|
||||
let accel: Vec3 = (strafe_vector(&rotation) * axis_h)
|
||||
+ (forward_walk_vector(&rotation) * axis_v)
|
||||
+ (Vec3::unit_y() * axis_float);
|
||||
let accel: Vec3 = if accel.length() != 0.0 {
|
||||
accel.normalize() * options.speed
|
||||
} else {
|
||||
Vec3::zero()
|
||||
};
|
||||
|
||||
let friction: Vec3 = if options.velocity.length() != 0.0 {
|
||||
options.velocity.normalize() * -1.0 * options.friction
|
||||
} else {
|
||||
Vec3::zero()
|
||||
};
|
||||
|
||||
options.velocity += accel * time.delta_seconds();
|
||||
|
||||
let delta_friction = friction * time.delta_seconds();
|
||||
|
||||
options.velocity = if (options.velocity + delta_friction).signum()
|
||||
!= options.velocity.signum()
|
||||
{
|
||||
Vec3::zero()
|
||||
} else {
|
||||
options.velocity + delta_friction
|
||||
};
|
||||
|
||||
transform.translation += options.velocity;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct State {
|
||||
mouse_motion_event_reader: EventReader<MouseMotion>,
|
||||
}
|
||||
|
||||
fn mouse_motion_system(
|
||||
time: Res<Time>,
|
||||
mut state: ResMut<State>,
|
||||
mouse_motion_events: Res<Events<MouseMotion>>,
|
||||
mut query: Query<(&mut FlyCamera, &mut Transform)>,
|
||||
) {
|
||||
let mut delta: Vec2 = Vec2::zero();
|
||||
for event in state.mouse_motion_event_reader.iter(&mouse_motion_events) {
|
||||
delta += event.delta;
|
||||
}
|
||||
if delta.is_nan() {
|
||||
return;
|
||||
}
|
||||
|
||||
for (mut options, mut transform) in query.iter_mut() {
|
||||
options.yaw -= delta.x * options.sensitivity * time.delta_seconds();
|
||||
options.pitch += delta.y * options.sensitivity * time.delta_seconds();
|
||||
|
||||
options.pitch = clamp(options.pitch, -89.9, 89.9);
|
||||
// println!("pitch: {}, yaw: {}", options.pitch, options.yaw);
|
||||
|
||||
let yaw_radians = options.yaw.to_radians();
|
||||
let pitch_radians = options.pitch.to_radians();
|
||||
|
||||
transform.rotation = Quat::from_axis_angle(Vec3::unit_y(), yaw_radians)
|
||||
* Quat::from_axis_angle(-Vec3::unit_x(), pitch_radians);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FlyCameraPlugin;
|
||||
|
||||
impl Plugin for FlyCameraPlugin {
|
||||
fn build(&self, app: &mut AppBuilder) {
|
||||
app
|
||||
.init_resource::<State>()
|
||||
.add_system(camera_movement_system.system())
|
||||
.add_system(mouse_motion_system.system());
|
||||
}
|
||||
}
|
1
src/lib.rs
Normal file
1
src/lib.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod camera;
|
52
src/main.rs
52
src/main.rs
|
@ -1,3 +1,53 @@
|
|||
use bevy::prelude::*;
|
||||
use rake::camera::FlyCamera;
|
||||
use rake::camera::FlyCameraPlugin;
|
||||
use std::process::exit;
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
App::build()
|
||||
.add_resource(Msaa { samples: 4 })
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_startup_system(init.system())
|
||||
.add_plugin(FlyCameraPlugin)
|
||||
.add_system(exit_game_system.system())
|
||||
.run();
|
||||
}
|
||||
|
||||
fn init(
|
||||
commands: &mut Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
commands
|
||||
.spawn(LightBundle {
|
||||
transform: Transform::from_translation(Vec3::new(4.0, 8.0, 4.0)),
|
||||
..Default::default()
|
||||
})
|
||||
.spawn(Camera3dBundle::default())
|
||||
.with(FlyCamera::default());
|
||||
|
||||
let box_mesh = meshes.add(Mesh::from(shape::Cube { size: 0.25 }));
|
||||
let box_material = materials.add(Color::rgb(1.0, 0.2, 0.3).into());
|
||||
|
||||
const AMOUNT: i32 = 6;
|
||||
for x in -(AMOUNT / 2)..(AMOUNT / 2) {
|
||||
for y in -(AMOUNT / 2)..(AMOUNT / 2) {
|
||||
for z in -(AMOUNT / 2)..(AMOUNT / 2) {
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: box_mesh.clone(),
|
||||
material: box_material.clone(),
|
||||
transform: Transform::from_translation(Vec3::new(
|
||||
x as f32, y as f32, z as f32,
|
||||
)),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn exit_game_system(keyboard_input: Res<Input<KeyCode>>) {
|
||||
if keyboard_input.pressed(KeyCode::Escape) {
|
||||
exit(0);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue