implement walk with hashing lole!!

This commit is contained in:
Quaternions 2023-09-18 21:10:07 -07:00
parent 7544c6e6ef
commit 0632e322cf
2 changed files with 73 additions and 7 deletions

View File

@ -22,6 +22,25 @@ pub struct Body {
acceleration: glam::Vec3,//I64 where 2^32 = 1 u/s/s acceleration: glam::Vec3,//I64 where 2^32 = 1 u/s/s
time: TIME,//nanoseconds x xxxxD! 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 { pub enum MoveRestriction {
Air, 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 struct PhysicsState {
pub body: Body, pub body: Body,
pub hitbox_halfsize: glam::Vec3, pub hitbox_halfsize: glam::Vec3,
@ -105,9 +139,10 @@ pub struct PhysicsState {
pub strafe_tick_den: TIME, pub strafe_tick_den: TIME,
pub tick: u32, pub tick: u32,
pub mv: f32, pub mv: f32,
pub walk: WalkState,
pub walkspeed: f32, pub walkspeed: f32,
pub friction: f32, pub friction: f32,
pub walk_target_velocity: glam::Vec3, pub walk_accel: f32,
pub gravity: glam::Vec3, pub gravity: glam::Vec3,
pub grounded: bool, pub grounded: bool,
pub jump_trying: bool, pub jump_trying: bool,
@ -364,9 +399,16 @@ impl PhysicsState {
// } // }
fn next_walk_instruction(&self) -> Option<TimedInstruction<PhysicsInstruction>> { fn next_walk_instruction(&self) -> Option<TimedInstruction<PhysicsInstruction>> {
//check if you are accelerating towards a walk target velocity and create an instruction //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; return None;
} }
}
fn mesh(&self) -> TreyMesh { fn mesh(&self) -> TreyMesh {
let mut aabb=Aabb::new(); let mut aabb=Aabb::new();
for vertex in Aabb::unit_vertices(){ for vertex in Aabb::unit_vertices(){
@ -705,11 +747,24 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
} }
PhysicsInstruction::ReachWalkTargetVelocity => { PhysicsInstruction::ReachWalkTargetVelocity => {
//precisely set velocity //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) => { PhysicsInstruction::SetWalkTargetVelocity(v) => {
self.walk_target_velocity=v;
//calculate acceleration yada yada //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
}
}, },
} }
} }

View File

@ -298,7 +298,8 @@ impl strafe_client::framework::Example for Skybox {
strafe_tick_num: 100,//100t strafe_tick_num: 100,//100t
strafe_tick_den: 1_000_000_000, strafe_tick_den: 1_000_000_000,
gravity: glam::vec3(0.0,-100.0,0.0), gravity: glam::vec3(0.0,-100.0,0.0),
friction: 90.0, friction: 1.2,
walk_accel: 90.0,
mv: 2.7, mv: 2.7,
grounded: false, grounded: false,
jump_trying: false, jump_trying: false,
@ -306,7 +307,7 @@ impl strafe_client::framework::Example for Skybox {
walkspeed: 18.0, walkspeed: 18.0,
contacts: std::collections::HashSet::new(), contacts: std::collections::HashSet::new(),
models_cringe_clone: modeldatas.iter().map(|m|strafe_client::body::Model::new(m.transform)).collect(), 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), 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 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.temp_control_dir=control_dir;
self.physics.jump_trying=self.camera.controls&CONTROL_JUMP!=0; self.physics.jump_trying=self.camera.controls&CONTROL_JUMP!=0;
self.physics.run(time); self.physics.run(time);