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{
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_walk_target_velocity(&self,camera:&PhysicsCamera,input_state:&InputState,normal:&Planar64Vec3)->Planar64Vec3;
fn get_ladder_target_velocity(&self,camera:&PhysicsCamera,input_state:&InputState,normal:&Planar64Vec3)->Planar64Vec3;
fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,input_state:&InputState)->Planar64Vec3;
fn get_y_control_dir(&self,camera:&PhysicsCamera,controls:Controls)->Planar64Vec3;
fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,controls:Controls)->Planar64Vec3;
fn calculate_mesh(&self)->HitboxMesh;
}
impl StyleHelper for StyleModifiers{
@ -409,11 +407,6 @@ impl StyleHelper for StyleModifiers{
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{
//don't get fancy just do it
let mut control_dir:Planar64Vec3 = Planar64Vec3::ZERO;
@ -440,62 +433,13 @@ impl StyleHelper for StyleModifiers{
return control_dir
}
fn get_walk_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;
fn get_y_control_dir(&self,camera:&PhysicsCamera,controls:Controls)->Planar64Vec3{
camera.rotation_y()*self.get_control_dir(controls)
}
let camera_mat=camera.rotation_y();
control_dir=camera_mat*control_dir;
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{
fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,controls:Controls)->Planar64Vec3{
//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{
let mesh=match self.hitbox.mesh{
@ -738,23 +682,27 @@ impl TouchingState{
PhysicsCollisionAttributes::Contact{contacting,general}=>{
let normal=contact_normal(models,hitbox_mesh,contact);
match &contacting.contact_behaviour{
Some(gameplay_attributes::ContactingBehaviour::Ladder(_))=>{
Some(gameplay_attributes::ContactingBehaviour::Ladder(_))=>if let Some(ladder_settings)=style.ladder{
//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);
let (walk_state,mut acceleration)=WalkState::ladder(body,style,gravity,target_velocity,contact.clone(),&normal);
move_state=MoveState::Ladder(walk_state);
self.constrain_acceleration(models,hitbox_mesh,&mut 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
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);
let (walk_state,mut acceleration)=WalkState::ground(body,style,gravity,target_velocity,contact.clone(),&normal);
move_state=MoveState::Walk(walk_state);
self.constrain_acceleration(models,hitbox_mesh,&mut acceleration);
a=acceleration;
}
},
_=>(),
}
@ -1453,13 +1401,15 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,models
}
},
PhysicsInstruction::StrafeTick=>{
//TODO make this less huge
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{
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
//(it's fun for cheating for now)
if let Some(v)=strafe_settings.tick_velocity(state.body.velocity,camera_mat*control_dir){
if let Some(v)=strafe_settings.tick_velocity(state.body.velocity,(camera_mat*control_dir).with_length(Planar64::ONE)){
//this is wrong but will work ig
//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){
@ -1469,6 +1419,7 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,models
}
}
}
}
PhysicsInstruction::ReachWalkTargetVelocity=>{
match &mut state.move_state{
MoveState::Air