fixed global time problem

This commit is contained in:
skyeshroom 2021-08-09 17:15:08 -07:00
parent b1464a48a8
commit ab1657a758

View File

@ -1,22 +1,32 @@
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
// loop constants
const UPDATE_INTERVAL: u32 = 40; const UPDATE_INTERVAL: u32 = 40;
const DEBUG_LOOP: bool = false; const DEBUG_LOOP: bool = false;
// physics constants
const GRAVITY: f32 = -9.8;
// a struct made for physics objects // a struct made for physics objects
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
struct PhysicsObject { struct PhysicsObject {
location: [f32; 3], location: [f32; 3],
velocity: [f32; 3] velocity: [f32; 3],
gravity_enabled: bool
} }
fn main() { fn main() {
// global time
let mut time = Duration::new(0,0);
// track the delta time (the duration of the previous loop in milliseconds) // track the delta time (the duration of the previous loop in milliseconds)
let mut delta_time = Duration::new(0, 0); let mut delta_time = Duration::new(0, 0);
// create a test physics object // create a test physics object
let mut test_object = PhysicsObject { let mut test_object = PhysicsObject {
location: [0.0, 0.0, 0.0], location: [0.0, 0.0, 100.0],
velocity: [0.0, 0.0, 0.0] velocity: [0.0, 0.0, 0.0],
gravity_enabled: true
}; };
loop { loop {
@ -25,51 +35,62 @@ fn main() {
// update // update
if delta_time.as_millis() as u32 >= UPDATE_INTERVAL { if delta_time.as_millis() as u32 >= UPDATE_INTERVAL {
if DEBUG_LOOP {
println!("Updating");
}
update(delta_time, &mut test_object); update(delta_time, &mut test_object);
// DEBUG
println!("Time: {}ms | test_object | Location: {:?} | Velocity: {:?}", time.as_millis(), test_object.location, test_object.velocity);
// keep track of time
time += delta_time;
// reset the delta time // reset the delta time
delta_time = Instant::now().duration_since(start_time); delta_time = Duration::new(0,0);
} }
// support interpolation via fractional "relative time"
let relative_time: f32 = delta_time.as_millis() as f32 / UPDATE_INTERVAL as f32;
if DEBUG_LOOP {
println!("Displaying | Delta Time: {}ms | Relative Time: {}", delta_time.as_millis(), relative_time);
}
display(relative_time, &test_object);
// update the time // update the time
delta_time += Instant::now().duration_since(start_time); delta_time += Instant::now().duration_since(start_time);
display(delta_time, &test_object);
} }
} }
// update function // update function
// TODO - I think I'm resetting delta time in the wrong place or just using it incorrectly; frameskips aren't happening at all // TODO - I think I'm resetting delta time in the wrong place or just using it incorrectly; frameskips aren't happening at all
fn update(delta_time: Duration, object: &mut PhysicsObject) { fn update(delta_time: Duration, object: &mut PhysicsObject) {
// calculate the exact timestep (fractional time in seconds) from delta time if DEBUG_LOOP {
let timestep: f32 = delta_time.as_millis() as f32 / 1000.0; println!("Updating");
println!("Timestep: {}", timestep);
// gravity
let acceleration: [f32; 3] = [0.0, 0.0, -9.8];
// update velocity based on acceleration (specifically gravity)
for i in 0..3 {
object.velocity[i] += acceleration[i] * timestep;
} }
// calculate the exact timestep (fractional time in seconds) from delta time
let timestep: f32 = delta_time.as_millis() as f32 / 1000.0;
// update location based on velocity // update location based on velocity
for i in 0..3 { for i in 0..3 {
object.location[i] += object.velocity[i]; object.location[i] += timestep * object.velocity[i];
}
// gravity
if object.gravity_enabled {
object.velocity[2] += GRAVITY * timestep;
}
// prevent the object from going below the ground plane, and kill downward velocity upon "hitting" the ground plane
if object.location[2] <= 0.0 {
object.location[2] = 0.0;
object.velocity[2] = object.velocity[2].max(0.0);
} }
} }
// render function // render function
fn display(interpolation: f32, object: &PhysicsObject) { fn display(delta_time: Duration, object: &PhysicsObject) {
// calculate interpolation via delta time
let interpolation: f32 = delta_time.as_millis() as f32 / UPDATE_INTERVAL as f32;
// DEBUG
if DEBUG_LOOP {
println!("Displaying | Delta Time: {}ms | Relative Time: {}", delta_time.as_millis(), interpolation);
}
// create a "render object", which we can apply interpolation to // create a "render object", which we can apply interpolation to
let mut render_object = *object; let mut render_object = *object;
@ -78,7 +99,8 @@ fn display(interpolation: f32, object: &PhysicsObject) {
render_object.location[i] += render_object.velocity[i] * interpolation; render_object.location[i] += render_object.velocity[i] * interpolation;
} }
println!("Object location: {:?}", render_object.location); // DEBUG
// println!("test_object | Location: {:?} | Velocity: {:?}", render_object.location, render_object.velocity);
} }
// 1D linear interpolation // 1D linear interpolation