Flycam physics: make it linear (remove drag), use meaningful parameters
This commit is contained in:
parent
24bcc55e74
commit
a056c6f934
|
@ -2,6 +2,8 @@ use glam::{Mat4, Quat, Vec2, Vec3};
|
|||
use std::time::Instant;
|
||||
use winit::event::{ElementState, VirtualKeyCode};
|
||||
|
||||
const LN2: f32 = 0.6931472; // TODO figure out how to use lazy_static! or something
|
||||
|
||||
pub trait Camera {
|
||||
fn get_eye(&self) -> [f32; 4];
|
||||
fn get_vp(&self) -> [[f32; 4]; 4];
|
||||
|
@ -28,8 +30,7 @@ pub struct Flycam {
|
|||
// constants
|
||||
turn_sensitivity: f32,
|
||||
thrust_mag: f32,
|
||||
friction_coeff: f32,
|
||||
drag_coeff: f32,
|
||||
damping_coeff: f32,
|
||||
aspect: f32,
|
||||
fovy: f32,
|
||||
znear: f32,
|
||||
|
@ -37,7 +38,9 @@ pub struct Flycam {
|
|||
}
|
||||
|
||||
impl Flycam {
|
||||
pub fn new(turn_sensitivity: f32, thrust_mag: f32, friction_coeff: f32, drag_coeff: f32) -> Self {
|
||||
/// thrust_speed: top speed when using a single thruster, in units/second
|
||||
/// duration to halve difference between current and target velocity, in seconds
|
||||
pub fn new(turn_sensitivity: f32, thrust_speed: f32, damper_half_life: f32) -> Self {
|
||||
Self {
|
||||
is_world_up_pressed: false,
|
||||
is_world_down_pressed: false,
|
||||
|
@ -55,9 +58,8 @@ impl Flycam {
|
|||
velocity: Vec3::new(0.0, 0.0, 0.0),
|
||||
position: Vec3::new(0.0, 0.5, 1.0),
|
||||
turn_sensitivity,
|
||||
thrust_mag,
|
||||
friction_coeff,
|
||||
drag_coeff,
|
||||
thrust_mag: thrust_speed / damper_half_life * LN2,
|
||||
damping_coeff: LN2 / damper_half_life,
|
||||
aspect: 1.0, // TODO compute from size
|
||||
fovy: std::f32::consts::FRAC_PI_2,
|
||||
znear: 0.01,
|
||||
|
@ -135,7 +137,8 @@ impl Flycam {
|
|||
}
|
||||
|
||||
fn update_kinematic(&mut self, dt: f32) {
|
||||
let net_acc = self.get_thrust_acc() + self.get_friction_acc() + self.get_drag_acc();
|
||||
/// update velocity and position from acceleration using forward differences
|
||||
let net_acc = self.get_thrust_acc() + self.get_damping_acc();
|
||||
|
||||
let delta_vel = net_acc * dt;
|
||||
self.velocity += delta_vel;
|
||||
|
@ -161,12 +164,8 @@ impl Flycam {
|
|||
self.thrust_mag * thrusters_total
|
||||
}
|
||||
|
||||
fn get_friction_acc(&self) -> glam::Vec3 {
|
||||
self.friction_coeff * -self.velocity
|
||||
}
|
||||
|
||||
fn get_drag_acc(&self) -> glam::Vec3 {
|
||||
0.5 * self.drag_coeff * -self.velocity * self.velocity.length()
|
||||
fn get_damping_acc(&self) -> glam::Vec3 {
|
||||
self.damping_coeff * -self.velocity
|
||||
}
|
||||
|
||||
fn key_axis(negative: bool, positive: bool) -> f32 {
|
||||
|
|
|
@ -149,7 +149,7 @@ async fn make_window_renderer(window: &winit::window::Window) -> Renderer {
|
|||
fn main() {
|
||||
let event_loop = EventLoop::new();
|
||||
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
||||
let mut camera = Flycam::new(0.002, 50.0, 5.0, 5.0);
|
||||
let mut camera = Flycam::new(0.002, 10.0, 0.25);
|
||||
let mut is_grabbed = false;
|
||||
let mut ren = pollster::block_on(make_window_renderer(&window));
|
||||
// let mut state: Box<dyn WorldState> = Box::new(Planets::new(&mut ren));
|
||||
|
|
Loading…
Reference in New Issue