batch operations

This commit is contained in:
Skye Terran 2021-08-09 23:01:29 -07:00
parent 0dc33e54ab
commit 568e0cb835
3 changed files with 121 additions and 35 deletions

76
Cargo.lock generated
View File

@ -8,6 +8,12 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "futures" name = "futures"
version = "0.3.16" version = "0.3.16"
@ -102,13 +108,31 @@ dependencies = [
"slab", "slab",
] ]
[[package]]
name = "getrandom"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]] [[package]]
name = "hypoloop" name = "hypoloop"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"futures", "futures",
"rand",
] ]
[[package]]
name = "libc"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.4.0" version = "2.4.0"
@ -127,6 +151,12 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "ppv-lite86"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]] [[package]]
name = "proc-macro-hack" name = "proc-macro-hack"
version = "0.5.19" version = "0.5.19"
@ -157,6 +187,46 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "rand"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
dependencies = [
"rand_core",
]
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.3" version = "0.4.3"
@ -179,3 +249,9 @@ name = "unicode-xid"
version = "0.2.2" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"

View File

@ -7,3 +7,4 @@ edition = "2018"
[dependencies] [dependencies]
futures = "0.3.16" futures = "0.3.16"
rand = "0.8.4"

View File

@ -1,4 +1,5 @@
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use rand::Rng;
// loop constants // loop constants
const UPDATE_INTERVAL: u32 = 40; const UPDATE_INTERVAL: u32 = 40;
@ -8,8 +9,9 @@ const DEBUG_LOOP: bool = false;
const GRAVITY: f32 = -9.8; const GRAVITY: f32 = -9.8;
// a struct made for physics objects // a struct made for physics objects
#[derive(Copy, Clone)] #[derive(Clone)]
struct PhysicsObject { struct PhysicsObject {
name: String,
location: [f32; 3], location: [f32; 3],
velocity: [f32; 3], velocity: [f32; 3],
gravity_enabled: bool gravity_enabled: bool
@ -24,27 +26,36 @@ fn main() {
// 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 // a vector of objects to calculate physics for
let mut test_object = PhysicsObject { let mut objects: Vec<PhysicsObject> = vec![];
location: [0.0, 0.0, 10.0], let mut rng = rand::thread_rng();
velocity: [0.0, 5.0, 0.0], for i in 0..6 {
let new_object = PhysicsObject {
name: i.to_string(),
location: [0.0, 0.0, 0.0],
velocity: [rng.gen::<f32>() * 10.0, rng.gen::<f32>() * 10.0, rng.gen::<f32>() * 10.0],
gravity_enabled: true gravity_enabled: true
}; };
objects.push(new_object)
}
while simulate { while simulate {
// start timing the loop // start timing the loop
let start_time = Instant::now(); let start_time = Instant::now();
// update // update
if delta_time.as_millis() as u32 >= UPDATE_INTERVAL { if delta_time.as_millis() as u32 >= UPDATE_INTERVAL {
update(delta_time, &mut test_object); update(delta_time, &mut objects);
// reset the delta time // reset the delta time
delta_time = Duration::new(0,0); delta_time = Duration::new(0,0);
} }
// DEBUG // DEBUG
println!("Time: {}s | test_object | Location: {:?} | Velocity: {:?}", time.as_millis() as f32 / 1000.0, test_object.location, test_object.velocity); for object in objects.iter() {
println!("Time: {}s | {} | Location: {:?} | Velocity: {:?}", time.as_millis() as f32 / 1000.0, object.name, object.location, object.velocity);
}
//display(delta_time, &test_object); //display(delta_time, &test_object);
@ -57,7 +68,7 @@ fn main() {
// 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, objects: &mut Vec<PhysicsObject>) {
if DEBUG_LOOP { if DEBUG_LOOP {
println!("Updating"); println!("Updating");
} }
@ -65,14 +76,19 @@ fn update(delta_time: Duration, object: &mut PhysicsObject) {
// calculate the exact timestep (fractional time in seconds) from delta time // calculate the exact timestep (fractional time in seconds) from delta time
let timestep: f32 = delta_time.as_millis() as f32 / 1000.0; let timestep: f32 = delta_time.as_millis() as f32 / 1000.0;
for object in objects.iter_mut() {
// update location based on velocity // update location based on velocity
for i in 0..3 { for i in 0..3 {
object.location[i] += timestep * object.velocity[i]; // location += timestep * velocity
// use an FMA here to halve the rounding error
object.location[i] = timestep.mul_add(object.velocity[i], object.location[i]);
} }
// gravity // gravity
if object.gravity_enabled { if object.gravity_enabled {
object.velocity[2] += GRAVITY * timestep; // velocity += timestep * gravity
// use an FMA here to halve the rounding error
object.velocity[2] = timestep.mul_add(GRAVITY, object.velocity[2]);
} }
// prevent the object from going below the ground plane, and kill downward velocity upon "hitting" the ground plane // prevent the object from going below the ground plane, and kill downward velocity upon "hitting" the ground plane
@ -80,6 +96,7 @@ fn update(delta_time: Duration, object: &mut PhysicsObject) {
object.location[2] = 0.0; object.location[2] = 0.0;
object.velocity[2] = object.velocity[2].max(0.0); object.velocity[2] = object.velocity[2].max(0.0);
} }
}
} }
// render function // render function
@ -92,14 +109,6 @@ fn display(delta_time: Duration, object: &PhysicsObject) {
println!("Displaying | Delta Time: {}ms | Relative Time: {}", delta_time.as_millis(), interpolation); println!("Displaying | Delta Time: {}ms | Relative Time: {}", delta_time.as_millis(), interpolation);
} }
// create a "render object", which we can apply interpolation to
let mut render_object = *object;
// interpolate physics values for smooth rendering
for i in 0..3 {
render_object.location[i] += render_object.velocity[i] * interpolation;
}
// DEBUG // DEBUG
// println!("test_object | Location: {:?} | Velocity: {:?}", render_object.location, render_object.velocity); // println!("test_object | Location: {:?} | Velocity: {:?}", render_object.location, render_object.velocity);
} }