This commit is contained in:
Quaternions 2024-02-20 22:27:31 -08:00
parent efdb4c97be
commit c895a66ad6

View File

@ -397,11 +397,9 @@ impl HitboxMesh{
trait StyleHelper{ trait StyleHelper{
fn get_control(&self,control:Controls,controls:Controls)->bool; fn get_control(&self,control:Controls,controls:Controls)->bool;
fn allow_strafe(&self,controls:Controls)->bool;
fn get_control_dir(&self,controls:Controls)->Planar64Vec3; fn get_control_dir(&self,controls:Controls)->Planar64Vec3;
fn get_walk_target_velocity(&self,camera:&PhysicsCamera,input_state:&InputState,normal:&Planar64Vec3)->Planar64Vec3; fn get_y_control_dir(&self,camera:&PhysicsCamera,controls:Controls)->Planar64Vec3;
fn get_ladder_target_velocity(&self,camera:&PhysicsCamera,input_state:&InputState,normal:&Planar64Vec3)->Planar64Vec3; fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,controls:Controls)->Planar64Vec3;
fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,input_state:&InputState)->Planar64Vec3;
fn calculate_mesh(&self)->HitboxMesh; fn calculate_mesh(&self)->HitboxMesh;
} }
impl StyleHelper for StyleModifiers{ impl StyleHelper for StyleModifiers{
@ -409,11 +407,6 @@ impl StyleHelper for StyleModifiers{
controls.intersection(self.controls_mask).contains(control) controls.intersection(self.controls_mask).contains(control)
} }
fn allow_strafe(&self,controls:Controls)->bool{
//disable strafing according to strafe settings
self.strafe.as_ref().is_some_and(|s|s.allow_strafe(controls))
}
fn get_control_dir(&self,controls:Controls)->Planar64Vec3{ fn get_control_dir(&self,controls:Controls)->Planar64Vec3{
//don't get fancy just do it //don't get fancy just do it
let mut control_dir:Planar64Vec3 = Planar64Vec3::ZERO; let mut control_dir:Planar64Vec3 = Planar64Vec3::ZERO;
@ -440,62 +433,13 @@ impl StyleHelper for StyleModifiers{
return control_dir return control_dir
} }
fn get_walk_target_velocity(&self,camera:&PhysicsCamera,input_state:&InputState,normal:&Planar64Vec3)->Planar64Vec3{ fn get_y_control_dir(&self,camera:&PhysicsCamera,controls:Controls)->Planar64Vec3{
let mut control_dir=self.get_control_dir(input_state.controls); camera.rotation_y()*self.get_control_dir(controls)
if control_dir==Planar64Vec3::ZERO{
return control_dir;
} }
let camera_mat=camera.rotation_y();
control_dir=camera_mat*control_dir; fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,controls:Controls)->Planar64Vec3{
let n=normal.length();
let m=control_dir.length();
let d=normal.dot(control_dir)/m;
if d<n{
let cr=normal.cross(control_dir);
if cr==Planar64Vec3::ZERO{
Planar64Vec3::ZERO
}else{
cr.cross(*normal)*(self.walk_speed/(n*(n*n-d*d).sqrt()*m))
}
}else{
Planar64Vec3::ZERO
}
}
fn get_ladder_target_velocity(&self,camera:&PhysicsCamera,input_state:&InputState,normal:&Planar64Vec3)->Planar64Vec3{
let mut control_dir=self.get_control_dir(input_state.controls);
if control_dir==Planar64Vec3::ZERO{
return control_dir;
}
let camera_mat=camera.rotation();
control_dir=camera_mat*control_dir;
let n=normal.length();
let m=control_dir.length();
let mut d=normal.dot(control_dir)/m;
if d< -self.ladder_dot*n{
control_dir=Planar64Vec3::Y*m;
d=normal.y();
}else if self.ladder_dot*n<d{
control_dir=Planar64Vec3::NEG_Y*m;
d=-normal.y();
}
//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
if d.get().unsigned_abs()<n.get().unsigned_abs(){
let cr=normal.cross(control_dir);
if cr==Planar64Vec3::ZERO{
Planar64Vec3::ZERO
}else{
cr.cross(*normal)*(self.ladder_speed/(n*(n*n-d*d).sqrt()))
}
}else{
Planar64Vec3::ZERO
}
}
fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,input_state:&InputState)->Planar64Vec3{
//don't interpolate this! discrete mouse movement, constant acceleration //don't interpolate this! discrete mouse movement, constant acceleration
camera.rotation()*self.get_control_dir(input_state.controls) camera.rotation()*self.get_control_dir(controls)
} }
fn calculate_mesh(&self)->HitboxMesh{ fn calculate_mesh(&self)->HitboxMesh{
let mesh=match self.hitbox.mesh{ let mesh=match self.hitbox.mesh{
@ -738,23 +682,27 @@ impl TouchingState{
PhysicsCollisionAttributes::Contact{contacting,general}=>{ PhysicsCollisionAttributes::Contact{contacting,general}=>{
let normal=contact_normal(models,hitbox_mesh,contact); let normal=contact_normal(models,hitbox_mesh,contact);
match &contacting.contact_behaviour{ match &contacting.contact_behaviour{
Some(gameplay_attributes::ContactingBehaviour::Ladder(_))=>{ Some(gameplay_attributes::ContactingBehaviour::Ladder(_))=>if let Some(ladder_settings)=style.ladder{
//ladder walkstate //ladder walkstate
let mut target_velocity=style.get_ladder_target_velocity(camera,input_state,&normal); let control_dir=style.get_propulsion_control_dir(camera,input_state.controls);
let mut target_velocity=ladder_settings.get_ladder_target_velocity(control_dir,normal);
self.constrain_velocity(models,hitbox_mesh,&mut target_velocity); self.constrain_velocity(models,hitbox_mesh,&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);
self.constrain_acceleration(models,hitbox_mesh,&mut acceleration); self.constrain_acceleration(models,hitbox_mesh,&mut acceleration);
a=acceleration; a=acceleration;
}, },
None=>if style.surf_slope.map_or(true,|s|normal.walkable(s,Planar64Vec3::Y)){ None=>if let Some(walk_settings)=style.walk{
//check ground //check ground
let mut target_velocity=style.get_walk_target_velocity(camera,input_state,&normal); if walk_settings.is_slope_walkable(normal,Planar64Vec3::Y){
let control_dir=style.get_y_control_dir(camera,input_state.controls);
let mut target_velocity=walk_settings.get_walk_target_velocity(control_dir,normal);
self.constrain_velocity(models,hitbox_mesh,&mut target_velocity); self.constrain_velocity(models,hitbox_mesh,&mut target_velocity);
let (walk_state,mut acceleration)=WalkState::ground(body,style,gravity,target_velocity,contact.clone(),&normal); let (walk_state,mut acceleration)=WalkState::ground(body,style,gravity,target_velocity,contact.clone(),&normal);
move_state=MoveState::Walk(walk_state); move_state=MoveState::Walk(walk_state);
self.constrain_acceleration(models,hitbox_mesh,&mut acceleration); self.constrain_acceleration(models,hitbox_mesh,&mut acceleration);
a=acceleration; a=acceleration;
}
}, },
_=>(), _=>(),
} }
@ -1453,13 +1401,15 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,models
} }
}, },
PhysicsInstruction::StrafeTick=>{ PhysicsInstruction::StrafeTick=>{
//TODO make this less huge
if let Some(strafe_settings)=state.style.strafe{ if let Some(strafe_settings)=state.style.strafe{
let control_dir=state.style.get_control_dir(state.input_state.controls); let controls=state.input_state.controls;
if strafe_settings.activates(controls){
let masked_controls=strafe_settings.mask(controls);
let control_dir=state.style.get_control_dir(masked_controls);
if control_dir!=Planar64Vec3::ZERO{ if control_dir!=Planar64Vec3::ZERO{
let camera_mat=state.camera.simulate_move_rotation_y(state.input_state.lerp_delta(state.time).x); let camera_mat=state.camera.simulate_move_rotation_y(state.input_state.lerp_delta(state.time).x);
//TODO: normalize control_dir but careful for zero if let Some(v)=strafe_settings.tick_velocity(state.body.velocity,(camera_mat*control_dir).with_length(Planar64::ONE)){
//(it's fun for cheating for now)
if let Some(v)=strafe_settings.tick_velocity(state.body.velocity,camera_mat*control_dir){
//this is wrong but will work ig //this is wrong but will work ig
//need to note which push planes activate in push solve and keep those //need to note which push planes activate in push solve and keep those
if set_velocity_cull(&mut state.body,&mut state.touching,&data.models,&data.hitbox_mesh,v){ if set_velocity_cull(&mut state.body,&mut state.touching,&data.models,&data.hitbox_mesh,v){
@ -1469,6 +1419,7 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,models
} }
} }
} }
}
PhysicsInstruction::ReachWalkTargetVelocity=>{ PhysicsInstruction::ReachWalkTargetVelocity=>{
match &mut state.move_state{ match &mut state.move_state{
MoveState::Air MoveState::Air