From 0632e322cfd68bec2148255e8f5d861161daf27d Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 18 Sep 2023 21:10:07 -0700 Subject: [PATCH] implement walk with hashing lole!! --- src/body.rs | 65 ++++++++++++++++++++++++++++++++++++++++++++++++----- src/main.rs | 15 +++++++++++-- 2 files changed, 73 insertions(+), 7 deletions(-) diff --git a/src/body.rs b/src/body.rs index 46952e5..6ec57d6 100644 --- a/src/body.rs +++ b/src/body.rs @@ -22,6 +22,25 @@ pub struct Body { acceleration: glam::Vec3,//I64 where 2^32 = 1 u/s/s time: TIME,//nanoseconds x xxxxD! } +trait MyHash{ + fn hash(&self) -> u64; +} +impl MyHash for Body { + fn hash(&self) -> u64 { + let mut hasher=std::collections::hash_map::DefaultHasher::new(); + for &el in self.position.as_ref().iter() { + std::hash::Hasher::write(&mut hasher, el.to_ne_bytes().as_slice()); + } + for &el in self.velocity.as_ref().iter() { + std::hash::Hasher::write(&mut hasher, el.to_ne_bytes().as_slice()); + } + for &el in self.acceleration.as_ref().iter() { + std::hash::Hasher::write(&mut hasher, el.to_ne_bytes().as_slice()); + } + std::hash::Hasher::write(&mut hasher, self.time.to_ne_bytes().as_slice()); + return std::hash::Hasher::finish(&hasher);//hash check to see if walk target is valid + } +} pub enum MoveRestriction { Air, @@ -89,6 +108,21 @@ impl MouseInterpolationState { } } +pub struct WalkState { + pub target_velocity: glam::Vec3, + pub target_time: TIME, + pub body_hash: u64, +} +impl WalkState { + pub fn new() -> Self { + Self{ + target_velocity:glam::Vec3::ZERO, + target_time:0, + body_hash:0,//oh no, hash collisions + } + } +} + pub struct PhysicsState { pub body: Body, pub hitbox_halfsize: glam::Vec3, @@ -105,9 +139,10 @@ pub struct PhysicsState { pub strafe_tick_den: TIME, pub tick: u32, pub mv: f32, + pub walk: WalkState, pub walkspeed: f32, pub friction: f32, - pub walk_target_velocity: glam::Vec3, + pub walk_accel: f32, pub gravity: glam::Vec3, pub grounded: bool, pub jump_trying: bool, @@ -364,8 +399,15 @@ impl PhysicsState { // } fn next_walk_instruction(&self) -> Option> { - //check if you are accelerating towards a walk target velocity and create an instruction - return None; + //check if you have a valid walk state and create an instruction + if self.walk.body_hash==self.body.hash(){ + Some(TimedInstruction{ + time:self.walk.target_time, + instruction:PhysicsInstruction::ReachWalkTargetVelocity + }) + }else{ + return None; + } } fn mesh(&self) -> TreyMesh { let mut aabb=Aabb::new(); @@ -705,11 +747,24 @@ impl crate::instruction::InstructionConsumer for PhysicsStat } PhysicsInstruction::ReachWalkTargetVelocity => { //precisely set velocity - self.body.velocity=self.walk_target_velocity; + self.body.acceleration=glam::Vec3::ZERO; + self.body.velocity=self.walk.target_velocity; + //what if it's exactly the same, and the time delta is 0? + //the hash will succeed and it will poll the same instruction infinitely... } PhysicsInstruction::SetWalkTargetVelocity(v) => { - self.walk_target_velocity=v; //calculate acceleration yada yada + let target_diff=v-self.body.velocity; + if target_diff==glam::Vec3::ZERO{ + self.body.acceleration=glam::Vec3::ZERO; + }else{ + let accel=self.walk_accel.min(self.gravity.length()*self.friction); + let time_delta=target_diff.length()/accel; + self.body.acceleration=target_diff/time_delta; + self.walk.target_velocity=v; + self.walk.target_time=self.body.time+((time_delta as f64)*1_000_000_000f64) as TIME; + self.walk.body_hash=self.body.hash();//hash check to see if walk target is valid + } }, } } diff --git a/src/main.rs b/src/main.rs index 8c6a3ce..63d8611 100644 --- a/src/main.rs +++ b/src/main.rs @@ -298,7 +298,8 @@ impl strafe_client::framework::Example for Skybox { strafe_tick_num: 100,//100t strafe_tick_den: 1_000_000_000, gravity: glam::vec3(0.0,-100.0,0.0), - friction: 90.0, + friction: 1.2, + walk_accel: 90.0, mv: 2.7, grounded: false, jump_trying: false, @@ -306,7 +307,7 @@ impl strafe_client::framework::Example for Skybox { walkspeed: 18.0, contacts: std::collections::HashSet::new(), models_cringe_clone: modeldatas.iter().map(|m|strafe_client::body::Model::new(m.transform)).collect(), - walk_target_velocity: glam::Vec3::ZERO, + walk: strafe_client::body::WalkState::new(), hitbox_halfsize: glam::vec3(1.0,2.5,1.0), }; @@ -637,6 +638,16 @@ impl strafe_client::framework::Example for Skybox { let time=self.start_time.elapsed().as_nanos() as i64; + let walk_target_velocity=self.physics.walkspeed*control_dir; + //autohop (already pressing spacebar; the signal to begin trying to jump is different) + if walk_target_velocity!=self.physics.walk.target_velocity { + //scroll will be implemented with InputInstruction::Jump(true) but it blocks setting self.jump_trying=true + strafe_client::instruction::InstructionConsumer::process_instruction(&mut self.physics, strafe_client::instruction::TimedInstruction{ + time,//this is in the past when there is no instructions! + instruction:strafe_client::body::PhysicsInstruction::SetWalkTargetVelocity(walk_target_velocity) + }); + } + self.physics.temp_control_dir=control_dir; self.physics.jump_trying=self.camera.controls&CONTROL_JUMP!=0; self.physics.run(time);