From 7f841427dd5b28feaa71e37170b2fceb3a8fabe9 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 8 Sep 2023 20:14:18 -0700 Subject: [PATCH] wip: tickless physics --- src/body.rs | 118 +++++++++++++++++++++++++++++++++------------------- src/main.rs | 16 +++---- 2 files changed, 83 insertions(+), 51 deletions(-) diff --git a/src/body.rs b/src/body.rs index b60c221..14272e5 100644 --- a/src/body.rs +++ b/src/body.rs @@ -5,6 +5,8 @@ pub enum PhysicsInstruction { CollisionEnd(RelativeCollision), StrafeTick, Jump, + SetWalkTargetVelocity(glam::Vec3), + ReachWalkTargetVelocity, // Water, // Spawn( // Option, @@ -14,15 +16,25 @@ pub enum PhysicsInstruction { } pub struct Body { - pub position: glam::Vec3,//I64 where 2^32 = 1 u - pub velocity: glam::Vec3,//I64 where 2^32 = 1 u/s - pub time: TIME,//nanoseconds x xxxxD! + position: glam::Vec3,//I64 where 2^32 = 1 u + velocity: glam::Vec3,//I64 where 2^32 = 1 u/s + acceleration: glam::Vec3,//I64 where 2^32 = 1 u/s/s + time: TIME,//nanoseconds x xxxxD! +} + +pub enum MoveRestriction { + Air, + Water, + Ground, + Ladder,//multiple ladders how } pub struct PhysicsState { pub body: Body, pub contacts: Vec, + //temp pub models_cringe_clone: Vec, + pub temp_control_dir: glam::Vec3, pub time: TIME, pub strafe_tick_num: TIME, pub strafe_tick_den: TIME, @@ -30,6 +42,7 @@ pub struct PhysicsState { pub mv: f32, pub walkspeed: f32, pub friction: f32, + pub walk_target_velocity: glam::Vec3, pub gravity: glam::Vec3, pub grounded: bool, pub jump_trying: bool, @@ -173,50 +186,45 @@ impl RelativeCollision { pub type TIME = i64; +impl Body { + pub fn with_position(position:glam::Vec3) -> Self { + Self{ + position: position, + velocity: glam::Vec3::ZERO, + acceleration: glam::Vec3::ZERO, + time: 0, + } + } + pub fn extrapolated_position(&self,time: TIME)->glam::Vec3{ + let dt=(time-self.time) as f64/1_000_000_000f64; + self.position+self.velocity*(dt as f32)+self.acceleration*((0.5*dt*dt) as f32) + } + pub fn advance_time(&mut self, time: TIME){ + self.position=self.extrapolated_position(time); + self.time=time; + } +} + const CONTROL_JUMP:u32 = 0b01000000;//temp DATA NORMALIZATION!@#$ impl PhysicsState { - //delete this, we are tickless gamers - pub fn run(&mut self, time: TIME, control_dir: glam::Vec3, controls: u32){ - let target_tick = (time*self.strafe_tick_num/self.strafe_tick_den) as u32; - //the game code can run for 1 month before running out of ticks - while self.tick glam::Vec3 { - let dt=(time-self.body.time) as f64/1_000_000_000f64; - self.body.position+self.body.velocity*(dt as f32)+self.gravity*((0.5*dt*dt) as f32) + pub fn advance_time(&mut self, time: TIME){ + self.body.advance_time(time); + self.time=time; } fn next_strafe_instruction(&self) -> Option> { @@ -304,7 +312,31 @@ impl crate::instruction::InstructionEmitter for PhysicsState } impl crate::instruction::InstructionConsumer for PhysicsState { - fn process_instruction(&mut self, instruction:TimedInstruction) { - // + fn process_instruction(&mut self, ins:TimedInstruction) { + //mutate position and velocity and time + self.advance_time(ins.time);//should this be in run? + match ins.instruction { + PhysicsInstruction::CollisionStart(_) => todo!(), + PhysicsInstruction::CollisionEnd(_) => todo!(), + PhysicsInstruction::StrafeTick => { + //let control_dir=self.get_control_dir();//this should respect your mouse interpolation settings + let d=self.body.velocity.dot(self.temp_control_dir); + if d { + self.grounded=false;//do I need this? + self.body.velocity+=glam::Vec3::new(0.0,0.715588/2.0*100.0,0.0); + } + PhysicsInstruction::ReachWalkTargetVelocity => { + //precisely set velocity + self.body.velocity=self.walk_target_velocity; + } + PhysicsInstruction::SetWalkTargetVelocity(v) => { + self.walk_target_velocity=v; + //calculate acceleration yada yada + }, + } } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index d1c9d65..c6e526e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -292,11 +292,7 @@ impl strafe_client::framework::Example for Skybox { controls:0, }; let physics = strafe_client::body::PhysicsState { - body: strafe_client::body::Body { - position: glam::Vec3::new(5.0,0.0,5.0), - velocity: glam::Vec3::new(0.0,0.0,0.0), - time: 0, - }, + body: strafe_client::body::Body::with_position(glam::Vec3::new(5.0,5.0,5.0)), time: 0, tick: 0, strafe_tick_num: 100,//100t @@ -306,12 +302,14 @@ impl strafe_client::framework::Example for Skybox { mv: 2.7, grounded: true, jump_trying: false, + temp_control_dir: glam::Vec3::ZERO, walkspeed: 18.0, contacts: Vec::::new(), models_cringe_clone: modeldatas.iter().map(|m|strafe_client::body::Model::new(m.transform)).collect(), + walk_target_velocity: glam::Vec3::ZERO, }; - let camera_uniforms = camera.to_uniform_data(physics.extrapolate_position(0)); + let camera_uniforms = camera.to_uniform_data(physics.body.extrapolated_position(0)); let camera_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: Some("Camera"), contents: bytemuck::cast_slice(&camera_uniforms), @@ -638,13 +636,15 @@ impl strafe_client::framework::Example for Skybox { let time=self.start_time.elapsed().as_nanos() as i64; - self.physics.run(time,control_dir,self.camera.controls); + self.physics.temp_control_dir=control_dir; + self.physics.jump_trying=self.camera.controls&CONTROL_JUMP!=0; + self.physics.run(time); let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); // update rotation - let camera_uniforms = self.camera.to_uniform_data(self.physics.extrapolate_position(time)); + let camera_uniforms = self.camera.to_uniform_data(self.physics.body.extrapolated_position(time)); self.staging_belt .write_buffer( &mut encoder,