forked from StrafesNET/strafe-client
implement walk with hashing lole!!
This commit is contained in:
parent
7544c6e6ef
commit
0632e322cf
63
src/body.rs
63
src/body.rs
@ -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
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
src/main.rs
15
src/main.rs
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user