First draft for FreeSpaceControl
This commit is contained in:
parent
3835354503
commit
75d98aad6b
3 changed files with 165 additions and 11 deletions
158
engine/src/scene/general/free_space_control.rs
Normal file
158
engine/src/scene/general/free_space_control.rs
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
use context::prelude::cgmath::*;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
pub struct FreeSpaceControlSettings {
|
||||||
|
/// m / s^2
|
||||||
|
pub max_forward_acceleration: f32,
|
||||||
|
/// m / s^2
|
||||||
|
pub max_forward_deceleration: f32,
|
||||||
|
|
||||||
|
/// m / s^2
|
||||||
|
/// up, down, left, right
|
||||||
|
pub max_strafe_acceleration: f32,
|
||||||
|
|
||||||
|
/// ° / s^2
|
||||||
|
pub max_yaw_acceleration: Deg<f32>,
|
||||||
|
/// ° / s^2
|
||||||
|
pub max_pitch_acceleration: Deg<f32>,
|
||||||
|
/// ° / s^2
|
||||||
|
pub max_roll_acceleration: Deg<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for FreeSpaceControlSettings {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
max_forward_acceleration: 50.0,
|
||||||
|
max_forward_deceleration: 10.0,
|
||||||
|
|
||||||
|
max_strafe_acceleration: 5.0,
|
||||||
|
|
||||||
|
max_yaw_acceleration: Deg(5.0),
|
||||||
|
max_pitch_acceleration: Deg(5.0),
|
||||||
|
max_roll_acceleration: Deg(5.0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FreeSpaceControl {
|
||||||
|
settings: FreeSpaceControlSettings,
|
||||||
|
|
||||||
|
/// (yaw, pitch, roll)
|
||||||
|
rotation: Vector3<Deg<f32>>,
|
||||||
|
position: Vector3<f32>,
|
||||||
|
|
||||||
|
/// (yaw, pitch, roll)
|
||||||
|
input_rotation: Vector3<f32>,
|
||||||
|
/// (forward, sideward, upward)
|
||||||
|
input_position: Vector3<f32>,
|
||||||
|
|
||||||
|
last_update: Option<Duration>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FreeSpaceControl {
|
||||||
|
pub fn new(settings: FreeSpaceControlSettings) -> Self {
|
||||||
|
Self {
|
||||||
|
settings,
|
||||||
|
|
||||||
|
rotation: vec3(Deg(0.0), Deg(0.0), Deg(0.0)),
|
||||||
|
position: Vector3::zero(),
|
||||||
|
|
||||||
|
input_rotation: Vector3::zero(),
|
||||||
|
input_position: Vector3::zero(),
|
||||||
|
|
||||||
|
last_update: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn replace_settings(&mut self, settings: FreeSpaceControlSettings) {
|
||||||
|
self.settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_throttle(&mut self, throttle: f32) {
|
||||||
|
debug_assert!(-1.0 <= throttle);
|
||||||
|
debug_assert!(throttle <= 1.0);
|
||||||
|
|
||||||
|
self.input_position.y = throttle;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_left_right_strafe(&mut self, strafe: f32) {
|
||||||
|
debug_assert!(-1.0 <= strafe);
|
||||||
|
debug_assert!(strafe <= 1.0);
|
||||||
|
|
||||||
|
self.input_position.x = strafe;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_up_down_strafe(&mut self, strafe: f32) {
|
||||||
|
debug_assert!(-1.0 <= strafe);
|
||||||
|
debug_assert!(strafe <= 1.0);
|
||||||
|
|
||||||
|
self.input_position.z = strafe;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_yaw(&mut self, yaw: f32) {
|
||||||
|
debug_assert!(-1.0 <= yaw);
|
||||||
|
debug_assert!(yaw <= 1.0);
|
||||||
|
|
||||||
|
self.input_rotation.x = yaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_pitch(&mut self, pitch: f32) {
|
||||||
|
debug_assert!(-1.0 <= pitch);
|
||||||
|
debug_assert!(pitch <= 1.0);
|
||||||
|
|
||||||
|
self.input_rotation.y = pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_roll(&mut self, roll: f32) {
|
||||||
|
debug_assert!(-1.0 <= roll);
|
||||||
|
debug_assert!(roll <= 1.0);
|
||||||
|
|
||||||
|
self.input_rotation.z = roll;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_rotation(&mut self, rotation: Vector3<Deg<f32>>) {
|
||||||
|
self.rotation.x += rotation.x;
|
||||||
|
self.rotation.y += rotation.y;
|
||||||
|
self.rotation.z += rotation.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rotation_matrix(&self) -> Matrix3<f32> {
|
||||||
|
Matrix3::from_angle_z(self.rotation.x)
|
||||||
|
* Matrix3::from_angle_y(self.rotation.y)
|
||||||
|
* Matrix3::from_angle_x(self.rotation.z)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(&mut self, now: Duration) -> Option<Matrix4<f32>> {
|
||||||
|
let diff = match self.last_update {
|
||||||
|
Some(last_update) => now - last_update,
|
||||||
|
None => {
|
||||||
|
self.last_update = Some(now);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let (rotation_changes, position_changes) = self.calculate_tick_changes(diff);
|
||||||
|
|
||||||
|
let rotated_position_changes = self.rotation_matrix() * position_changes;
|
||||||
|
self.add_rotation(rotation_changes);
|
||||||
|
self.position += rotated_position_changes;
|
||||||
|
|
||||||
|
Some(Matrix4::from(self.rotation_matrix()) * Matrix4::from_translation(self.position))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
fn calculate_tick_changes(&self, diff: Duration) -> (Vector3<Deg<f32>>, Vector3<f32>) {
|
||||||
|
(
|
||||||
|
vec3(
|
||||||
|
Deg(diff.as_secs_f32() * self.input_rotation.x * self.settings.max_yaw_acceleration.0),
|
||||||
|
Deg(diff.as_secs_f32() * self.input_rotation.y * self.settings.max_pitch_acceleration.0),
|
||||||
|
Deg(diff.as_secs_f32() * self.input_rotation.z * self.settings.max_roll_acceleration.0),
|
||||||
|
),
|
||||||
|
vec3(
|
||||||
|
diff.as_secs_f32() * self.input_position.x * self.settings.max_strafe_acceleration,
|
||||||
|
diff.as_secs_f32() * self.input_position.y * if self.input_position.y > 0.0 { self.settings.max_forward_acceleration } else { self.settings.max_forward_deceleration },
|
||||||
|
diff.as_secs_f32() * self.input_position.z * self.settings.max_strafe_acceleration,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,9 @@
|
||||||
pub mod camera;
|
pub mod camera;
|
||||||
|
|
||||||
pub mod light;
|
|
||||||
|
|
||||||
pub mod validcommandbuffer;
|
|
||||||
|
|
||||||
pub mod view;
|
|
||||||
|
|
||||||
pub mod top_down_camera_control;
|
|
||||||
|
|
||||||
pub mod view_frustum;
|
|
||||||
|
|
||||||
pub mod free_camera_control;
|
pub mod free_camera_control;
|
||||||
|
pub mod free_space_control;
|
||||||
|
pub mod light;
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
|
pub mod top_down_camera_control;
|
||||||
|
pub mod validcommandbuffer;
|
||||||
|
pub mod view;
|
||||||
|
pub mod view_frustum;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
pub use super::camera::*;
|
pub use super::camera::*;
|
||||||
pub use super::free_camera_control::*;
|
pub use super::free_camera_control::*;
|
||||||
|
pub use super::free_space_control::*;
|
||||||
pub use super::light::*;
|
pub use super::light::*;
|
||||||
pub use super::top_down_camera_control::*;
|
pub use super::top_down_camera_control::*;
|
||||||
pub use super::validcommandbuffer::*;
|
pub use super::validcommandbuffer::*;
|
||||||
|
|
Loading…
Reference in a new issue