fix ladders

This commit is contained in:
Quaternions 2023-11-08 16:47:46 -08:00
parent f7072be5b4
commit 63cfbbfa9c

View File

@ -592,20 +592,28 @@ impl StyleModifiers{
let control_dir=camera_mat*self.get_control_dir(controls); let control_dir=camera_mat*self.get_control_dir(controls);
control_dir*self.walk_speed control_dir*self.walk_speed
} }
fn get_ladder_target_velocity(&self,camera:&PhysicsCamera,controls:u32,next_mouse:&MouseState,time:Time)->Planar64Vec3{ fn get_ladder_target_velocity(&self,camera:&PhysicsCamera,controls:u32,next_mouse:&MouseState,time:Time,normal:&Planar64Vec3)->Planar64Vec3{
let mut control_dir=self.get_control_dir(controls);
if control_dir==Planar64Vec3::ZERO{
return control_dir;
}
let camera_mat=camera.simulate_move_rotation(camera.mouse.lerp(&next_mouse,time)); let camera_mat=camera.simulate_move_rotation(camera.mouse.lerp(&next_mouse,time));
let control_dir=camera_mat*self.get_control_dir(controls); control_dir=camera_mat*control_dir;
// local m=sqrt(ControlDir.length_squared()) let n=normal.length();
// local d=dot(Normal,ControlDir)/m let m=control_dir.length();
// if d<-LadderDot then let mut d=normal.dot(control_dir)/m;
// ControlDir=Up*m if d< -self.ladder_dot*n{
// d=dot(Normal,Up) control_dir=Planar64Vec3::Y*m;
// elseif LadderDot<d then d=normal.y();
// ControlDir=Up*-m }else if self.ladder_dot*n<d{
// d=-dot(Normal,Up) control_dir=Planar64Vec3::NEG_Y*m;
// end d=-normal.y();
// return cross(cross(Normal,ControlDir),Normal)/sqrt(1-d*d) }
control_dir*self.walk_speed //n=d if you are standing on top of a ladder and press E.
//two fixes:
//- ladder movement is not allowed on walkable surfaces
//- fix the underlying issue
normal.cross(control_dir).cross(*normal)*(self.ladder_speed/(n*(n*n-d*d).sqrt()))
} }
fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,controls:u32,next_mouse:&MouseState,time:Time)->Planar64Vec3{ fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,controls:u32,next_mouse:&MouseState,time:Time)->Planar64Vec3{
let camera_mat=camera.simulate_move_rotation(camera.mouse.lerp(&next_mouse,time)); let camera_mat=camera.simulate_move_rotation(camera.mouse.lerp(&next_mouse,time));
@ -816,7 +824,7 @@ impl TouchingState{
match &contacting.contact_behaviour{ match &contacting.contact_behaviour{
Some(crate::model::ContactingBehaviour::Ladder(_))=>{ Some(crate::model::ContactingBehaviour::Ladder(_))=>{
//ladder walkstate //ladder walkstate
let mut target_velocity=style.get_ladder_target_velocity(camera,controls,next_mouse,time); let mut target_velocity=style.get_ladder_target_velocity(camera,controls,next_mouse,time,&normal);
self.constrain_velocity(models,&mut target_velocity); self.constrain_velocity(models,&mut target_velocity);
let (walk_state,mut acceleration)=WalkState::ladder(body,style,gravity,target_velocity,contact.clone(),&normal); let (walk_state,mut acceleration)=WalkState::ladder(body,style,gravity,target_velocity,contact.clone(),&normal);
move_state=MoveState::Ladder(walk_state); move_state=MoveState::Ladder(walk_state);
@ -1117,7 +1125,7 @@ impl PhysicsState {
let n=self.models.mesh(contact.model_id).face_nd(contact.face_id).0; let n=self.models.mesh(contact.model_id).face_nd(contact.face_id).0;
let gravity=self.touching.base_acceleration(&self.models,&self.style,&self.camera,self.controls,&self.next_mouse,self.time); let gravity=self.touching.base_acceleration(&self.models,&self.style,&self.camera,self.controls,&self.next_mouse,self.time);
let mut a; let mut a;
let mut v=self.style.get_ladder_target_velocity(&self.camera,self.controls,&self.next_mouse,self.time); let mut v=self.style.get_ladder_target_velocity(&self.camera,self.controls,&self.next_mouse,self.time,&n);
self.touching.constrain_velocity(&self.models,&mut v); self.touching.constrain_velocity(&self.models,&mut v);
(*state,a)=WalkEnum::with_target_velocity(&self.body,&self.style,v,&n,self.style.ladder_speed,self.style.ladder_accel); (*state,a)=WalkEnum::with_target_velocity(&self.body,&self.style,v,&n,self.style.ladder_speed,self.style.ladder_accel);
self.touching.constrain_acceleration(&self.models,&mut a); self.touching.constrain_acceleration(&self.models,&mut a);
@ -1343,7 +1351,7 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
} }
//ladder walkstate //ladder walkstate
let gravity=self.touching.base_acceleration(&self.models,&self.style,&self.camera,self.controls,&self.next_mouse,self.time); let gravity=self.touching.base_acceleration(&self.models,&self.style,&self.camera,self.controls,&self.next_mouse,self.time);
let mut target_velocity=self.style.get_ladder_target_velocity(&self.camera,self.controls,&self.next_mouse,self.time); let mut target_velocity=self.style.get_ladder_target_velocity(&self.camera,self.controls,&self.next_mouse,self.time,&normal);
self.touching.constrain_velocity(&self.models,&mut target_velocity); self.touching.constrain_velocity(&self.models,&mut target_velocity);
let (walk_state,a)=WalkState::ladder(&self.body,&self.style,gravity,target_velocity,contact.clone(),&normal); let (walk_state,a)=WalkState::ladder(&self.body,&self.style,gravity,target_velocity,contact.clone(),&normal);
self.move_state=MoveState::Ladder(walk_state); self.move_state=MoveState::Ladder(walk_state);
@ -1444,7 +1452,7 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
WalkEnum::Reached=>(), WalkEnum::Reached=>(),
WalkEnum::Transient(walk_target)=>{ WalkEnum::Transient(walk_target)=>{
//precisely set velocity //precisely set velocity
let a=self.style.gravity; let a=Planar64Vec3::ZERO;//ignore gravity for now.
set_acceleration(&mut self.body,&self.touching,&self.models,a); set_acceleration(&mut self.body,&self.touching,&self.models,a);
let v=walk_target.velocity; let v=walk_target.velocity;
set_velocity(&mut self.body,&self.touching,&self.models,v); set_velocity(&mut self.body,&self.touching,&self.models,v);