diff --git a/src/physics.rs b/src/physics.rs index 9bb7b8c..c5d78bb 100644 --- a/src/physics.rs +++ b/src/physics.rs @@ -166,14 +166,14 @@ impl TransientAcceleration{ } } } - fn ground(walk_settings:&gameplay_style::WalkSettings,body:&Body,gravity:Planar64Vec3,velocity:Planar64Vec3,contact:ContactCollision,normal:Planar64Vec3)->Self{ - let target_diff=velocity-body.velocity; + fn ground(walk_settings:&gameplay_style::WalkSettings,body:&Body,gravity:Planar64Vec3,target_velocity:Planar64Vec3,normal:Planar64Vec3)->Self{ + let target_diff=target_velocity-body.velocity; //precalculate accel let accel=walk_settings.accel(target_diff,gravity); Self::with_target_diff(target_diff,accel,body.time) } - fn ladder(ladder_settings:&gameplay_style::LadderSettings,body:&Body,gravity:Planar64Vec3,velocity:Planar64Vec3,contact:ContactCollision,normal:Planar64Vec3)->Self{ - let target_diff=velocity-body.velocity; + fn ladder(ladder_settings:&gameplay_style::LadderSettings,body:&Body,gravity:Planar64Vec3,target_velocity:Planar64Vec3,normal:Planar64Vec3)->Self{ + let target_diff=target_velocity-body.velocity; let accel=ladder_settings.accel(target_diff,gravity); Self::with_target_diff(target_diff,accel,body.time) } @@ -186,21 +186,37 @@ impl TransientAcceleration{ } } impl ContactMoveState{ - fn ground(walk_settings:&gameplay_style::WalkSettings,body:&Body,gravity:Planar64Vec3,velocity:Planar64Vec3,contact:ContactCollision,normal:Planar64Vec3)->Self{ + fn ground(walk_settings:&gameplay_style::WalkSettings,body:&Body,gravity:Planar64Vec3,target_velocity:Planar64Vec3,contact:ContactCollision,normal:Planar64Vec3)->Self{ Self{ - target:TransientAcceleration::ground(walk_settings,body,gravity,velocity,contact,normal), + target:TransientAcceleration::ground(walk_settings,body,gravity,target_velocity,normal), contact, jump_direction:JumpDirection::Exactly(Planar64Vec3::Y), } } - fn ladder(ladder_settings:&gameplay_style::LadderSettings,body:&Body,gravity:Planar64Vec3,velocity:Planar64Vec3,contact:ContactCollision,normal:Planar64Vec3)->Self{ + fn ladder(ladder_settings:&gameplay_style::LadderSettings,body:&Body,gravity:Planar64Vec3,target_velocity:Planar64Vec3,contact:ContactCollision,normal:Planar64Vec3)->Self{ Self{//,style,velocity,normal,style.ladder_speed,style.ladder_accel - target:TransientAcceleration::ladder(ladder_settings,body,gravity,velocity,contact,normal), + target:TransientAcceleration::ladder(ladder_settings,body,gravity,target_velocity,normal), contact, jump_direction:JumpDirection::FromContactNormal, } } } +fn ground_things(walk_settings:&gameplay_style::WalkSettings,contact:&ContactCollision,touching:&TouchingState,models:&PhysicsModels,hitbox_mesh:&HitboxMesh,style:&StyleModifiers,camera:&PhysicsCamera,input_state:&InputState)->(Planar64Vec3,Planar64Vec3,Planar64Vec3){ + let normal=contact_normal(models,hitbox_mesh,contact); + let gravity=touching.base_acceleration(models,style,camera,input_state); + 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); + touching.constrain_velocity(models,hitbox_mesh,&mut target_velocity); + (gravity,target_velocity,normal) +} +fn ladder_things(ladder_settings:&gameplay_style::LadderSettings,contact:&ContactCollision,touching:&TouchingState,models:&PhysicsModels,hitbox_mesh:&HitboxMesh,style:&StyleModifiers,camera:&PhysicsCamera,input_state:&InputState)->(Planar64Vec3,Planar64Vec3,Planar64Vec3){ + let normal=contact_normal(models,hitbox_mesh,contact); + let gravity=touching.base_acceleration(models,style,camera,input_state); + let control_dir=style.get_y_control_dir(camera,input_state.controls); + let mut target_velocity=ladder_settings.get_ladder_target_velocity(control_dir,normal); + touching.constrain_velocity(models,hitbox_mesh,&mut target_velocity); + (gravity,target_velocity,normal) +} #[derive(Default)] struct PhysicsModels{ @@ -496,14 +512,16 @@ impl MoveState{ MoveState::Air|MoveState::Water=>(), MoveState::Walk(ContactMoveState{target,contact,jump_direction:_})=>{ if let Some(walk_settings)=&style.walk{ - *target=TransientAcceleration::ground(); + let (gravity,target_velocity,normal)=ground_things(walk_settings,contact,touching,models,hitbox_mesh,style,camera,input_state); + *target=TransientAcceleration::ground(walk_settings,body,gravity,target_velocity,normal); }else{ panic!("ContactMoveState exists in style which does not allow walking!"); } }, MoveState::Ladder(ContactMoveState{target,contact,jump_direction:_})=>{ if let Some(ladder_settings)=&style.ladder{ - *target=TransientAcceleration::ladder(); + let (gravity,target_velocity,normal)=ladder_things(ladder_settings,contact,touching,models,hitbox_mesh,style,camera,input_state); + *target=TransientAcceleration::ladder(ladder_settings,body,gravity,target_velocity,normal); }else{ panic!("ContactMoveState exists in style which does not allow walking!"); } @@ -1252,12 +1270,12 @@ fn run_teleport_behaviour(wormhole:&Option,models match (data.models.attr(convex_mesh_id.model_id),&c){ (PhysicsCollisionAttributes::Contact{contacting,general},Collision::Contact(contact))=>{ let mut v=state.body.velocity; - let normal=contact_normal(&data.models,&data.hitbox_mesh,contact); match &contacting.contact_behaviour{ Some(gameplay_attributes::ContactingBehaviour::Surf)=>println!("I'm surfing!"), Some(gameplay_attributes::ContactingBehaviour::Cling)=>println!("Unimplemented!"), &Some(gameplay_attributes::ContactingBehaviour::Elastic(elasticity))=>{ //velocity and normal are facing opposite directions so this is inherently negative. + let normal=contact_normal(&data.models,&data.hitbox_mesh,contact); let d=normal.dot(v)*(Planar64::ONE+Planar64::raw(elasticity as i64+1)); v+=normal*(d/normal.dot(normal)); }, @@ -1269,10 +1287,7 @@ fn run_teleport_behaviour(wormhole:&Option,models v=Planar64Vec3::ZERO;//model.velocity } //ladder walkstate - let gravity=state.touching.base_acceleration(&data.models,&state.style,&state.camera,&state.input_state); - let control_dir=state.style.get_y_control_dir(&state.camera,state.input_state.controls); - let mut target_velocity=ladder_settings.get_ladder_target_velocity(control_dir,normal); - state.touching.constrain_velocity(&data.models,&data.hitbox_mesh,&mut target_velocity); + let (gravity,target_velocity,normal)=ladder_things(ladder_settings,contact,&state.touching,&data.models,&data.hitbox_mesh,&state.style,&state.camera,&state.input_state); let walk_state=ContactMoveState::ladder(ladder_settings,&state.body,gravity,target_velocity,contact.clone(),normal); state.move_state=MoveState::Ladder(walk_state); state.move_state.apply_to_body(&mut state.body,&state.touching,&data.models,&data.hitbox_mesh,&state.style,&state.camera,&state.input_state); @@ -1281,10 +1296,7 @@ fn run_teleport_behaviour(wormhole:&Option,models None=>if let Some(walk_settings)=&state.style.walk{ if walk_settings.is_slope_walkable(contact_normal(&data.models,&data.hitbox_mesh,contact),Planar64Vec3::Y){ //ground - let gravity=state.touching.base_acceleration(&data.models,&state.style,&state.camera,&state.input_state); - let control_dir=state.style.get_y_control_dir(&state.camera,state.input_state.controls); - let mut target_velocity=walk_settings.get_walk_target_velocity(control_dir,normal); - state.touching.constrain_velocity(&data.models,&data.hitbox_mesh,&mut target_velocity); + let (gravity,target_velocity,normal)=ground_things(walk_settings,contact,&state.touching,&data.models,&data.hitbox_mesh,&state.style,&state.camera,&state.input_state); let walk_state=ContactMoveState::ground(walk_settings,&state.body,gravity,target_velocity,contact.clone(),normal); state.move_state=MoveState::Walk(walk_state); state.move_state.apply_to_body(&mut state.body,&state.touching,&data.models,&data.hitbox_mesh,&state.style,&state.camera,&state.input_state); @@ -1310,15 +1322,13 @@ fn run_teleport_behaviour(wormhole:&Option,models }, None=>(), } - let calc_move=if state.style.get_control(Controls::Jump,state.input_state.controls){ - state.style.jump.is_some_and(|jump_settings|{ - state.move_state.get_walk_state().is_some_and(|walk_state|{ - let jump_dir=walk_state.jump_direction.direction(&data.models,&data.hitbox_mesh,&walk_state.contact); - v=jump_settings.jumped_velocity(&state.style,jump_dir,v); - set_velocity_cull(&mut state.body,&mut state.touching,&data.models,&data.hitbox_mesh,v) - }) - }) - }else{false}; + if state.style.get_control(Controls::Jump,state.input_state.controls){ + if let (Some(jump_settings),Some(walk_state))=(&state.style.jump,state.move_state.get_walk_state()){ + let jump_dir=walk_state.jump_direction.direction(&data.models,&data.hitbox_mesh,&walk_state.contact); + v=jump_settings.jumped_velocity(&state.style,jump_dir,v); + set_velocity_cull(&mut state.body,&mut state.touching,&data.models,&data.hitbox_mesh,v); + } + } match &general.trajectory{ Some(trajectory)=>{ match trajectory{ @@ -1333,10 +1343,6 @@ fn run_teleport_behaviour(wormhole:&Option,models None=>(), } set_velocity(&mut state.body,&state.touching,&data.models,&data.hitbox_mesh,v); - //not sure if or is correct here - if calc_move||Planar64::ZERO{ @@ -1354,7 +1360,7 @@ fn run_teleport_behaviour(wormhole:&Option,models PhysicsCollisionAttributes::Contact{contacting:_,general:_}=>{ state.touching.remove(&c);//remove contact before calling contact_constrain_acceleration //check ground - (state.move_state,state.body.acceleration)=state.touching.get_move_state(&state.body,&data.models,&state.style,&data.hitbox_mesh,&state.camera,&state.input_state,state.time); + //TODO lol }, PhysicsCollisionAttributes::Intersect{intersecting:_,general:_}=>{ state.touching.remove(&c); @@ -1374,7 +1380,7 @@ fn run_teleport_behaviour(wormhole:&Option,models //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){ - (state.move_state,state.body.acceleration)=state.touching.get_move_state(&state.body,&data.models,&state.style,&data.hitbox_mesh,&state.camera,&state.input_state,state.time); + //? } } } @@ -1423,17 +1429,19 @@ fn run_teleport_behaviour(wormhole:&Option,models PhysicsInputInstruction::SetMoveUp(s)=>state.input_state.set_control(Controls::MoveUp,s), PhysicsInputInstruction::SetMoveDown(s)=>state.input_state.set_control(Controls::MoveDown,s), PhysicsInputInstruction::SetJump(s)=>{ + b_refresh_walk_target=false; state.input_state.set_control(Controls::Jump,s); if let Some(walk_state)=state.move_state.get_walk_state(){ if let Some(jump_settings)=&state.style.jump{ let jump_dir=walk_state.jump_direction.direction(&data.models,&data.hitbox_mesh,&walk_state.contact); let jumped_velocity=jump_settings.jumped_velocity(&state.style,jump_dir,state.body.velocity); + //TODO: be more precise about contacts if set_velocity_cull(&mut state.body,&mut state.touching,&data.models,&data.hitbox_mesh,jumped_velocity){ - (state.move_state,state.body.acceleration)=state.touching.get_move_state(&state.body,&data.models,&state.style,&data.hitbox_mesh,&state.camera,&state.input_state,state.time); + state.move_state=MoveState::Air; + b_refresh_walk_target=true; } } } - b_refresh_walk_target=false; }, PhysicsInputInstruction::SetZoom(s)=>{ state.input_state.set_control(Controls::Zoom,s); @@ -1449,8 +1457,8 @@ fn run_teleport_behaviour(wormhole:&Option,models ).unwrap_or(Planar64Vec3::ZERO); set_position(&mut state.body,&mut state.touching,spawn_point); set_velocity(&mut state.body,&state.touching,&data.models,&data.hitbox_mesh,Planar64Vec3::ZERO); - (state.move_state,state.body.acceleration)=state.touching.get_move_state(&state.body,&data.models,&state.style,&data.hitbox_mesh,&state.camera,&state.input_state,state.time); - b_refresh_walk_target=false; + state.move_state=MoveState::Air; + //b_refresh_walk_target will figure out gravity and stuff }, PhysicsInputInstruction::Idle=>{b_refresh_walk_target=false;},//literally idle! }