This commit is contained in:
Quaternions 2024-02-16 00:19:44 -08:00
parent 0ac1c1aa6b
commit c55156bb92

View File

@ -4,10 +4,11 @@ use crate::model_physics::{self,PhysicsMesh,PhysicsMeshTransform,TransformedMesh
use strafesnet_common::bvh; use strafesnet_common::bvh;
use strafesnet_common::map; use strafesnet_common::map;
use strafesnet_common::aabb; use strafesnet_common::aabb;
use strafesnet_common::gameplay_modes::{self,StageId};
use strafesnet_common::gameplay_attributes::{self,CollisionAttributesId};
use strafesnet_common::model::{MeshId,ModelId}; use strafesnet_common::model::{MeshId,ModelId};
use strafesnet_common::gameplay_attributes::{self,CollisionAttributesId};
use strafesnet_common::gameplay_modes::{self,StageId};
use strafesnet_common::gameplay_style::{self,StyleModifiers}; use strafesnet_common::gameplay_style::{self,StyleModifiers};
use strafesnet_common::controls_bitflag::Controls;
use strafesnet_common::instruction::{self,InstructionEmitter,InstructionConsumer,TimedInstruction}; use strafesnet_common::instruction::{self,InstructionEmitter,InstructionConsumer,TimedInstruction};
use strafesnet_common::integer::{self,Time,Planar64,Planar64Vec3,Planar64Mat3,Angle32,Ratio64Vec2}; use strafesnet_common::integer::{self,Time,Planar64,Planar64Vec3,Planar64Mat3,Angle32,Ratio64Vec2};
use gameplay::ModeState; use gameplay::ModeState;
@ -91,10 +92,46 @@ impl MouseState {
} }
} }
#[derive(Clone,Debug,Default)]
pub struct InputState{
mouse:MouseState,
next_mouse:MouseState,
controls:strafesnet_common::controls_bitflag::Controls,
}
impl InputState{
fn set_next_mouse(&mut self,next_mouse:MouseState){
(self.next_mouse,self.mouse)=(next_mouse,self.next_mouse);
}
fn replace_mouse(&mut self,mouse:MouseState,next_mouse:MouseState){
(self.next_mouse,self.mouse)=(next_mouse,mouse);
}
fn time_delta(&self)->Time{
self.next_mouse.time-self.mouse.time
}
fn mouse_delta(&self)->glam::IVec2{
self.next_mouse.pos-self.mouse.pos
}
fn lerp_delta(&self,time:Time)->glam::IVec2{
//these are deltas
let dm=self.mouse_delta().as_i64vec2();
let t=(time-self.mouse.time).nanos();
let dt=self.time_delta().nanos();
((dm*t)/dt).as_ivec2()
}
}
enum JumpDirection{ enum JumpDirection{
Exactly(Planar64Vec3), Exactly(Planar64Vec3),
FromContactNormal, FromContactNormal,
} }
impl JumpDirection{
fn direction(&self,models:&PhysicsModels,hitbox_mesh:&HitboxMesh,contact:&ContactCollision)->Planar64Vec3{
match self{
JumpDirection::FromContactNormal=>contact_normal(models,hitbox_mesh,contact),
&JumpDirection::Exactly(dir)=>dir,
}
}
}
enum WalkEnum{ enum WalkEnum{
Reached, Reached,
Transient(WalkTarget), Transient(WalkTarget),
@ -189,7 +226,6 @@ pub struct PhysicsCamera{
//punch: Planar64Vec3, //punch: Planar64Vec3,
//punch_velocity: Planar64Vec3, //punch_velocity: Planar64Vec3,
sensitivity:Ratio64Vec2,//dots to Angle32 ratios sensitivity:Ratio64Vec2,//dots to Angle32 ratios
mouse:MouseState,//last seen absolute mouse pos
clamped_mouse_pos:glam::IVec2,//angles are calculated from this cumulative value clamped_mouse_pos:glam::IVec2,//angles are calculated from this cumulative value
//angle limits could be an enum + struct that defines whether it's limited and selects clamp or wrap depending //angle limits could be an enum + struct that defines whether it's limited and selects clamp or wrap depending
// enum AngleLimit{ // enum AngleLimit{
@ -203,32 +239,32 @@ pub struct PhysicsCamera{
impl PhysicsCamera{ impl PhysicsCamera{
const ANGLE_PITCH_LOWER_LIMIT:Angle32=Angle32::NEG_FRAC_PI_2; const ANGLE_PITCH_LOWER_LIMIT:Angle32=Angle32::NEG_FRAC_PI_2;
const ANGLE_PITCH_UPPER_LIMIT:Angle32=Angle32::FRAC_PI_2; const ANGLE_PITCH_UPPER_LIMIT:Angle32=Angle32::FRAC_PI_2;
pub fn move_mouse(&mut self,mouse_pos:glam::IVec2){ pub fn move_mouse(&mut self,mouse_delta:glam::IVec2){
let mut unclamped_mouse_pos=mouse_pos-self.mouse.pos+self.clamped_mouse_pos; let mut unclamped_mouse_pos=self.clamped_mouse_pos+mouse_delta;
unclamped_mouse_pos.y=unclamped_mouse_pos.y.clamp( unclamped_mouse_pos.y=unclamped_mouse_pos.y.clamp(
self.sensitivity.y.rhs_div_int(Self::ANGLE_PITCH_LOWER_LIMIT.get() as i64) as i32, self.sensitivity.y.rhs_div_int(Self::ANGLE_PITCH_LOWER_LIMIT.get() as i64) as i32,
self.sensitivity.y.rhs_div_int(Self::ANGLE_PITCH_UPPER_LIMIT.get() as i64) as i32, self.sensitivity.y.rhs_div_int(Self::ANGLE_PITCH_UPPER_LIMIT.get() as i64) as i32,
); );
self.clamped_mouse_pos=unclamped_mouse_pos; self.clamped_mouse_pos=unclamped_mouse_pos;
} }
pub fn simulate_move_angles(&self,mouse_pos:glam::IVec2)->glam::Vec2 { pub fn simulate_move_angles(&self,mouse_delta:glam::IVec2)->glam::Vec2 {
let a=-self.sensitivity.mul_int((mouse_pos-self.mouse.pos+self.clamped_mouse_pos).as_i64vec2()); let a=-self.sensitivity.mul_int((self.clamped_mouse_pos+mouse_delta).as_i64vec2());
let ax=Angle32::wrap_from_i64(a.x); let ax=Angle32::wrap_from_i64(a.x);
let ay=Angle32::clamp_from_i64(a.y) let ay=Angle32::clamp_from_i64(a.y)
//clamp to actual vertical cam limit //clamp to actual vertical cam limit
.clamp(Self::ANGLE_PITCH_LOWER_LIMIT,Self::ANGLE_PITCH_UPPER_LIMIT); .clamp(Self::ANGLE_PITCH_LOWER_LIMIT,Self::ANGLE_PITCH_UPPER_LIMIT);
return glam::vec2(ax.into(),ay.into()); return glam::vec2(ax.into(),ay.into());
} }
fn simulate_move_rotation(&self,mouse_pos:glam::IVec2)->Planar64Mat3{ fn simulate_move_rotation(&self,mouse_delta:glam::IVec2)->Planar64Mat3{
let a=-self.sensitivity.mul_int((mouse_pos-self.mouse.pos+self.clamped_mouse_pos).as_i64vec2()); let a=-self.sensitivity.mul_int((self.clamped_mouse_pos+mouse_delta).as_i64vec2());
let ax=Angle32::wrap_from_i64(a.x); let ax=Angle32::wrap_from_i64(a.x);
let ay=Angle32::clamp_from_i64(a.y) let ay=Angle32::clamp_from_i64(a.y)
//clamp to actual vertical cam limit //clamp to actual vertical cam limit
.clamp(Self::ANGLE_PITCH_LOWER_LIMIT,Self::ANGLE_PITCH_UPPER_LIMIT); .clamp(Self::ANGLE_PITCH_LOWER_LIMIT,Self::ANGLE_PITCH_UPPER_LIMIT);
Planar64Mat3::from_rotation_yx(ax,ay) Planar64Mat3::from_rotation_yx(ax,ay)
} }
fn simulate_move_rotation_y(&self,mouse_pos_x:i32)->Planar64Mat3{ fn simulate_move_rotation_y(&self,mouse_delta_x:i32)->Planar64Mat3{
let ax=-self.sensitivity.x.mul_int((mouse_pos_x-self.mouse.pos.x+self.clamped_mouse_pos.x) as i64); let ax=-self.sensitivity.x.mul_int((self.clamped_mouse_pos.x+mouse_delta_x) as i64);
Planar64Mat3::from_rotation_y(Angle32::wrap_from_i64(ax)) Planar64Mat3::from_rotation_y(Angle32::wrap_from_i64(ax))
} }
} }
@ -237,7 +273,6 @@ impl std::default::Default for PhysicsCamera{
fn default()->Self{ fn default()->Self{
Self{ Self{
sensitivity:Ratio64Vec2::ONE*200_000, sensitivity:Ratio64Vec2::ONE*200_000,
mouse:MouseState::default(),//t=0 does not cause divide by zero because it's immediately replaced
clamped_mouse_pos:glam::IVec2::ZERO, clamped_mouse_pos:glam::IVec2::ZERO,
} }
} }
@ -342,72 +377,60 @@ impl HitboxMesh{
} }
trait StyleHelper{ trait StyleHelper{
fn get_control(&self,control:u32,controls:u32)->bool; fn get_control(&self,control:Controls,controls:Controls)->bool;
fn allow_strafe(&self,controls:u32)->bool; fn allow_strafe(&self,controls:Controls)->bool;
fn get_control_dir(&self,controls:u32)->Planar64Vec3; fn get_control_dir(&self,controls:Controls)->Planar64Vec3;
//fn get_jump_time(&self)->Planar64; //fn get_jump_time(&self)->Planar64;
//fn get_jump_height(&self)->Planar64; //fn get_jump_height(&self)->Planar64;
//fn get_jump_energy(&self)->Planar64; //fn get_jump_energy(&self)->Planar64;
fn get_jump_deltav(&self)->Planar64; fn get_jump_deltav(&self)->Planar64;
fn get_walk_target_velocity(&self,camera:&PhysicsCamera,controls:u32,next_mouse:&MouseState,time:Time,normal:&Planar64Vec3)->Planar64Vec3; fn get_walk_target_velocity(&self,camera:&PhysicsCamera,input_state:&InputState,time:Time,normal:&Planar64Vec3)->Planar64Vec3;
fn get_ladder_target_velocity(&self,camera:&PhysicsCamera,controls:u32,next_mouse:&MouseState,time:Time,normal:&Planar64Vec3)->Planar64Vec3; fn get_ladder_target_velocity(&self,camera:&PhysicsCamera,input_state:&InputState,time:Time,normal:&Planar64Vec3)->Planar64Vec3;
fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,controls:u32,next_mouse:&MouseState,time:Time)->Planar64Vec3; fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,input_state:&InputState,time:Time)->Planar64Vec3;
fn calculate_mesh(&self)->HitboxMesh; fn calculate_mesh(&self)->HitboxMesh;
} }
impl StyleHelper for StyleModifiers{ impl StyleHelper for StyleModifiers{
fn get_control(&self,control:u32,controls:u32)->bool{ fn get_control(&self,control:Controls,controls:Controls)->bool{
controls&self.controls_mask&control==control controls.intersection(self.controls_mask).contains(control)
} }
fn allow_strafe(&self,controls:u32)->bool{ fn allow_strafe(&self,controls:Controls)->bool{
//disable strafing according to strafe settings //disable strafing according to strafe settings
self.strafe.as_ref().is_some_and(|s|s.mask(controls)) self.strafe.as_ref().is_some_and(|s|s.allow_strafe(controls))
} }
fn get_control_dir(&self,controls:u32)->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;
//Apply mask after held check so you can require non-allowed keys to be held for some reason //Apply mask after held check so you can require non-allowed keys to be held for some reason
let controls=controls&self.controls_mask; let controls=controls.intersection(self.controls_mask);
if controls & Self::CONTROL_MOVEFORWARD == Self::CONTROL_MOVEFORWARD { if controls.contains(Controls::MoveForward){
control_dir+=Self::FORWARD_DIR; control_dir+=Self::FORWARD_DIR;
} }
if controls & Self::CONTROL_MOVEBACK == Self::CONTROL_MOVEBACK { if controls.contains(Controls::MoveBackward){
control_dir-=Self::FORWARD_DIR; control_dir-=Self::FORWARD_DIR;
} }
if controls & Self::CONTROL_MOVELEFT == Self::CONTROL_MOVELEFT { if controls.contains(Controls::MoveLeft){
control_dir-=Self::RIGHT_DIR; control_dir-=Self::RIGHT_DIR;
} }
if controls & Self::CONTROL_MOVERIGHT == Self::CONTROL_MOVERIGHT { if controls.contains(Controls::MoveRight){
control_dir+=Self::RIGHT_DIR; control_dir+=Self::RIGHT_DIR;
} }
if controls & Self::CONTROL_MOVEUP == Self::CONTROL_MOVEUP { if controls.contains(Controls::MoveUp){
control_dir+=Self::UP_DIR; control_dir+=Self::UP_DIR;
} }
if controls & Self::CONTROL_MOVEDOWN == Self::CONTROL_MOVEDOWN { if controls.contains(Controls::MoveDown){
control_dir-=Self::UP_DIR; control_dir-=Self::UP_DIR;
} }
return control_dir return control_dir
} }
//fn get_jump_time(&self)->Planar64 fn get_walk_target_velocity(&self,camera:&PhysicsCamera,input_state:&InputState,time:Time,normal:&Planar64Vec3)->Planar64Vec3{
//fn get_jump_height(&self)->Planar64 let mut control_dir=self.get_control_dir(input_state.controls);
//fn get_jump_energy(&self)->Planar64
fn get_jump_deltav(&self)->Planar64{
match &self.jump_impulse{
&gameplay_style::JumpImpulse::FromTime(time)=>self.gravity.length()*(time/2),
&gameplay_style::JumpImpulse::FromHeight(height)=>(self.gravity.length()*height*2).sqrt(),
&gameplay_style::JumpImpulse::FromDeltaV(deltav)=>deltav,
&gameplay_style::JumpImpulse::FromEnergy(energy)=>(energy*2/self.mass).sqrt(),
}
}
fn get_walk_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{ if control_dir==Planar64Vec3::ZERO{
return control_dir; return control_dir;
} }
let camera_mat=camera.simulate_move_rotation_y(camera.mouse.lerp(&next_mouse,time).x); let camera_mat=camera.simulate_move_rotation_y(input_state.lerp_delta(time).x);
control_dir=camera_mat*control_dir; control_dir=camera_mat*control_dir;
let n=normal.length(); let n=normal.length();
let m=control_dir.length(); let m=control_dir.length();
@ -423,12 +446,12 @@ impl StyleHelper for StyleModifiers{
Planar64Vec3::ZERO Planar64Vec3::ZERO
} }
} }
fn get_ladder_target_velocity(&self,camera:&PhysicsCamera,controls:u32,next_mouse:&MouseState,time:Time,normal:&Planar64Vec3)->Planar64Vec3{ fn get_ladder_target_velocity(&self,camera:&PhysicsCamera,input_state:&InputState,time:Time,normal:&Planar64Vec3)->Planar64Vec3{
let mut control_dir=self.get_control_dir(controls); let mut control_dir=self.get_control_dir(input_state.controls);
if control_dir==Planar64Vec3::ZERO{ if control_dir==Planar64Vec3::ZERO{
return control_dir; return control_dir;
} }
let camera_mat=camera.simulate_move_rotation(camera.mouse.lerp(&next_mouse,time)); let camera_mat=camera.simulate_move_rotation(input_state.lerp_delta(time));
control_dir=camera_mat*control_dir; control_dir=camera_mat*control_dir;
let n=normal.length(); let n=normal.length();
let m=control_dir.length(); let m=control_dir.length();
@ -455,9 +478,9 @@ impl StyleHelper for StyleModifiers{
Planar64Vec3::ZERO Planar64Vec3::ZERO
} }
} }
fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,controls:u32,next_mouse:&MouseState,time:Time)->Planar64Vec3{ fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,input_state:&InputState,time:Time)->Planar64Vec3{
let camera_mat=camera.simulate_move_rotation(camera.mouse.lerp(&next_mouse,time)); let camera_mat=camera.simulate_move_rotation(input_state.lerp_delta(time));
camera_mat*self.get_control_dir(controls) camera_mat*self.get_control_dir(input_state.controls)
} }
fn calculate_mesh(&self)->HitboxMesh{ fn calculate_mesh(&self)->HitboxMesh{
let mesh=match self.hitbox.mesh{ let mesh=match self.hitbox.mesh{
@ -474,6 +497,30 @@ enum MoveState{
Walk(WalkState), Walk(WalkState),
Water, Water,
Ladder(WalkState), Ladder(WalkState),
Fly,
}
impl MoveState{
fn apply_to_body(&self,body:&mut Body,touching:&TouchingState,models:&PhysicsModels,hitbox_mesh:&HitboxMesh){
match self{
MoveState::Air=>{
//calculate base acceleration
let mut a=touching.base_acceleration(models, style, camera, controls, next_mouse, time);
//clip according to contacts
touching.constrain_acceleration(models,hitbox_mesh,&mut a);
},
MoveState::Water=>(),
MoveState::Fly=>{
//set velocity according to current control state
//clip velocity according to current touching state
//apply to body
},
MoveState::Walk(walk_state)
|MoveState::Ladder(walk_state)
=>{
//accelerate towards walk target or do nothing
},
}
}
} }
#[derive(Clone,Default)] #[derive(Clone,Default)]
@ -483,8 +530,8 @@ pub struct PhysicsOutputState{
camera_offset:Planar64Vec3, camera_offset:Planar64Vec3,
} }
impl PhysicsOutputState{ impl PhysicsOutputState{
pub fn extrapolate(&self,mouse_pos:glam::IVec2,time:Time)->(glam::Vec3,glam::Vec2){ pub fn extrapolate(&self,mouse_delta:glam::IVec2,time:Time,alert:bool)->(glam::Vec3,glam::Vec2){
((self.body.extrapolated_position(time)+self.camera_offset).into(),self.camera.simulate_move_angles(mouse_pos)) ((self.body.extrapolated_position(time)+self.camera_offset).into(),self.camera.simulate_move_angles(mouse_delta))
} }
} }
@ -833,8 +880,7 @@ pub struct PhysicsState{
//camera must exist in state because wormholes modify the camera, also camera punch //camera must exist in state because wormholes modify the camera, also camera punch
camera:PhysicsCamera, camera:PhysicsCamera,
//input_state //input_state
pub next_mouse:MouseState,//Where is the mouse headed next pub input_state:InputState,
controls:u32,//TODO this should be a struct
//style //style
style:StyleModifiers,//mode style with custom style updates applied style:StyleModifiers,//mode style with custom style updates applied
//gameplay_state //gameplay_state
@ -958,6 +1004,7 @@ impl PhysicsState {
} }
MoveState::Air=>self.next_strafe_instruction(), MoveState::Air=>self.next_strafe_instruction(),
MoveState::Water=>None,//TODO MoveState::Water=>None,//TODO
MoveState::Fly=>None,
} }
} }
} }
@ -1067,12 +1114,13 @@ impl PhysicsContext{
//TODO get rid of this trash //TODO get rid of this trash
fn refresh_walk_target(s:&mut PhysicsState,data:&PhysicsData)->Planar64Vec3{ fn refresh_walk_target(s:&mut PhysicsState,data:&PhysicsData)->Planar64Vec3{
match &mut s.move_state{ match &mut s.move_state{
MoveState::Air|MoveState::Water=>s.touching.base_acceleration(&data.models,&s.style,&s.camera,s.controls,&s.next_mouse,s.time), MoveState::Fly=>Planar64Vec3::ZERO,
MoveState::Air|MoveState::Water=>s.touching.base_acceleration(&data.models,&s.style,&s.camera,&s.input_state,s.time),
MoveState::Walk(WalkState{state,contact,jump_direction:_})=>{ MoveState::Walk(WalkState{state,contact,jump_direction:_})=>{
let n=contact_normal(&data.models,&data.hitbox_mesh,contact); let n=contact_normal(&data.models,&data.hitbox_mesh,contact);
let gravity=s.touching.base_acceleration(&data.models,&s.style,&s.camera,s.controls,&s.next_mouse,s.time); let gravity=s.touching.base_acceleration(&data.models,&s.style,&s.camera,&s.input_state,s.time);
let a; let a;
let mut v=s.style.get_walk_target_velocity(&s.camera,s.controls,&s.next_mouse,s.time,&n); let mut v=s.style.get_walk_target_velocity(&s.camera,&s.input_state,s.time,&n);
s.touching.constrain_velocity(&data.models,&data.hitbox_mesh,&mut v); s.touching.constrain_velocity(&data.models,&data.hitbox_mesh,&mut v);
let normal_accel=-n.dot(gravity)/n.length(); let normal_accel=-n.dot(gravity)/n.length();
(*state,a)=WalkEnum::with_target_velocity(&s.body,&s.style,v,&n,s.style.walk_speed,normal_accel); (*state,a)=WalkEnum::with_target_velocity(&s.body,&s.style,v,&n,s.style.walk_speed,normal_accel);
@ -1082,7 +1130,7 @@ impl PhysicsContext{
let n=contact_normal(&data.models,&data.hitbox_mesh,contact); let n=contact_normal(&data.models,&data.hitbox_mesh,contact);
//let gravity=s.touching.base_acceleration(&data.models,&s.style,&s.camera,s.controls,&s.next_mouse,s.time); //let gravity=s.touching.base_acceleration(&data.models,&s.style,&s.camera,s.controls,&s.next_mouse,s.time);
let a; let a;
let mut v=s.style.get_ladder_target_velocity(&s.camera,s.controls,&s.next_mouse,s.time,&n); let mut v=s.style.get_ladder_target_velocity(&s.camera,&s.input_state,s.time,&n);
s.touching.constrain_velocity(&data.models,&data.hitbox_mesh,&mut v); s.touching.constrain_velocity(&data.models,&data.hitbox_mesh,&mut v);
(*state,a)=WalkEnum::with_target_velocity(&s.body,&s.style,v,&n,s.style.ladder_speed,s.style.ladder_accel); (*state,a)=WalkEnum::with_target_velocity(&s.body,&s.style,v,&n,s.style.ladder_speed,s.style.ladder_accel);
a a
@ -1123,16 +1171,17 @@ impl PhysicsContext{
fn get_walk_state(move_state:&MoveState)->Option<&WalkState>{ fn get_walk_state(move_state:&MoveState)->Option<&WalkState>{
match move_state{ match move_state{
MoveState::Walk(walk_state)|MoveState::Ladder(walk_state)=>Some(walk_state), MoveState::Walk(walk_state)
MoveState::Air|MoveState::Water=>None, |MoveState::Ladder(walk_state)
=>Some(walk_state),
MoveState::Air
|MoveState::Water
|MoveState::Fly
=>None,
} }
} }
fn jumped_velocity(models:&PhysicsModels,style:&StyleModifiers,hitbox_mesh:&HitboxMesh,walk_state:&WalkState,v:&mut Planar64Vec3){ fn jumped_velocity(models:&PhysicsModels,style:&StyleModifiers,hitbox_mesh:&HitboxMesh,jump_dir:Planar64Vec3,v:&mut Planar64Vec3){
let jump_dir=match &walk_state.jump_direction{
JumpDirection::FromContactNormal=>contact_normal(models,hitbox_mesh,&walk_state.contact),
&JumpDirection::Exactly(dir)=>dir,
};
*v=*v+jump_dir*(style.get_jump_deltav()/jump_dir.length()); *v=*v+jump_dir*(style.get_jump_deltav()/jump_dir.length());
} }
@ -1303,8 +1352,8 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,models
v=Planar64Vec3::ZERO;//model.velocity v=Planar64Vec3::ZERO;//model.velocity
} }
//ladder walkstate //ladder walkstate
let gravity=state.touching.base_acceleration(&data.models,&state.style,&state.camera,state.controls,&state.next_mouse,state.time); let gravity=state.touching.base_acceleration(&data.models,&state.style,&state.camera,&state.input_state,state.time);
let mut target_velocity=state.style.get_ladder_target_velocity(&state.camera,state.controls,&state.next_mouse,state.time,&normal); let mut target_velocity=state.style.get_ladder_target_velocity(&state.camera,&state.input_state,state.time,&normal);
state.touching.constrain_velocity(&data.models,&data.hitbox_mesh,&mut target_velocity); state.touching.constrain_velocity(&data.models,&data.hitbox_mesh,&mut target_velocity);
let (walk_state,a)=WalkState::ladder(&state.body,&state.style,gravity,target_velocity,contact.clone(),&normal); let (walk_state,a)=WalkState::ladder(&state.body,&state.style,gravity,target_velocity,contact.clone(),&normal);
state.move_state=MoveState::Ladder(walk_state); state.move_state=MoveState::Ladder(walk_state);
@ -1313,8 +1362,8 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,models
Some(gameplay_attributes::ContactingBehaviour::NoJump)=>todo!("nyi"), Some(gameplay_attributes::ContactingBehaviour::NoJump)=>todo!("nyi"),
None=>if state.style.surf_slope.map_or(true,|s|contact_normal(&data.models,&data.hitbox_mesh,contact).walkable(s,Planar64Vec3::Y)){ None=>if state.style.surf_slope.map_or(true,|s|contact_normal(&data.models,&data.hitbox_mesh,contact).walkable(s,Planar64Vec3::Y)){
//ground //ground
let gravity=state.touching.base_acceleration(&data.models,&state.style,&state.camera,state.controls,&state.next_mouse,state.time); let gravity=state.touching.base_acceleration(&data.models,&state.style,&state.camera,&state.input_state,state.time);
let mut target_velocity=state.style.get_walk_target_velocity(&state.camera,state.controls,&state.next_mouse,state.time,&normal); let mut target_velocity=state.style.get_walk_target_velocity(&state.camera,&state.input_state,state.time,&normal);
state.touching.constrain_velocity(&data.models,&data.hitbox_mesh,&mut target_velocity); state.touching.constrain_velocity(&data.models,&data.hitbox_mesh,&mut target_velocity);
let (walk_state,a)=WalkState::ground(&state.body,&state.style,gravity,target_velocity,contact.clone(),&normal); let (walk_state,a)=WalkState::ground(&state.body,&state.style,gravity,target_velocity,contact.clone(),&normal);
state.move_state=MoveState::Walk(walk_state); state.move_state=MoveState::Walk(walk_state);
@ -1340,9 +1389,9 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,models
}, },
None=>(), None=>(),
} }
let calc_move=if state.style.get_control(StyleModifiers::CONTROL_JUMP,state.controls){ let calc_move=if state.style.get_control(Controls::Jump,state.controls){
if let Some(walk_state)=get_walk_state(&state.move_state){ if let Some(walk_state)=get_walk_state(&state.move_state){
jumped_velocity(&data.models,&state.style,&data.hitbox_mesh,walk_state,&mut v); jumped_velocity(&data.models,&state.style,&data.hitbox_mesh,walk_state.jump_direction.direction(&data.models,&data.hitbox_mesh,&walk_state.contact),&mut v);
set_velocity_cull(&mut state.body,&mut state.touching,&data.models,&data.hitbox_mesh,v) set_velocity_cull(&mut state.body,&mut state.touching,&data.models,&data.hitbox_mesh,v)
}else{false} }else{false}
}else{false}; }else{false};
@ -1392,7 +1441,7 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,models
PhysicsInstruction::StrafeTick=>{ PhysicsInstruction::StrafeTick=>{
let control_dir=state.style.get_control_dir(state.controls); let control_dir=state.style.get_control_dir(state.controls);
if control_dir!=Planar64Vec3::ZERO{ if control_dir!=Planar64Vec3::ZERO{
let camera_mat=state.camera.simulate_move_rotation_y(state.camera.mouse.lerp(&state.next_mouse,state.time).x); let camera_mat=state.camera.simulate_move_rotation_y(state.input_state.lerp_delta(state.time).x);
let control_dir=camera_mat*control_dir; let control_dir=camera_mat*control_dir;
//normalize but careful for zero //normalize but careful for zero
let d=state.body.velocity.dot(control_dir); let d=state.body.velocity.dot(control_dir);
@ -1408,7 +1457,10 @@ 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::Water=>(), MoveState::Air
|MoveState::Water
|MoveState::Fly
=>println!("ReachWalkTargetVelocity fired for non-walking MoveState"),
MoveState::Walk(walk_state)|MoveState::Ladder(walk_state)=>{ MoveState::Walk(walk_state)|MoveState::Ladder(walk_state)=>{
match &mut walk_state.state{ match &mut walk_state.state{
WalkEnum::Reached=>(), WalkEnum::Reached=>(),
@ -1428,24 +1480,24 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,models
let mut b_refresh_walk_target=true; let mut b_refresh_walk_target=true;
match input_instruction{ match input_instruction{
PhysicsInputInstruction::SetNextMouse(m)=>{ PhysicsInputInstruction::SetNextMouse(m)=>{
state.camera.move_mouse(state.next_mouse.pos); state.camera.move_mouse(state.input_state.mouse_delta());
(state.camera.mouse,state.next_mouse)=(state.next_mouse.clone(),m); state.input_state.set_next_mouse(m);
}, },
PhysicsInputInstruction::ReplaceMouse(m0,m1)=>{ PhysicsInputInstruction::ReplaceMouse(m0,m1)=>{
state.camera.move_mouse(m0.pos); state.camera.move_mouse(m0.pos-state.input_state.mouse);
(state.camera.mouse,state.next_mouse)=(m0,m1); state.input_state.replace_mouse(m0,m1);
}, },
PhysicsInputInstruction::SetMoveForward(s)=>state.set_control(StyleModifiers::CONTROL_MOVEFORWARD,s), PhysicsInputInstruction::SetMoveForward(s)=>state.set_control(Controls::MoveForward,s),
PhysicsInputInstruction::SetMoveLeft(s)=>state.set_control(StyleModifiers::CONTROL_MOVELEFT,s), PhysicsInputInstruction::SetMoveLeft(s)=>state.set_control(Controls::MoveLeft,s),
PhysicsInputInstruction::SetMoveBack(s)=>state.set_control(StyleModifiers::CONTROL_MOVEBACK,s), PhysicsInputInstruction::SetMoveBack(s)=>state.set_control(Controls::MoveBackward,s),
PhysicsInputInstruction::SetMoveRight(s)=>state.set_control(StyleModifiers::CONTROL_MOVERIGHT,s), PhysicsInputInstruction::SetMoveRight(s)=>state.set_control(Controls::MoveRight,s),
PhysicsInputInstruction::SetMoveUp(s)=>state.set_control(StyleModifiers::CONTROL_MOVEUP,s), PhysicsInputInstruction::SetMoveUp(s)=>state.set_control(Controls::MoveUp,s),
PhysicsInputInstruction::SetMoveDown(s)=>state.set_control(StyleModifiers::CONTROL_MOVEDOWN,s), PhysicsInputInstruction::SetMoveDown(s)=>state.set_control(Controls::MoveDown,s),
PhysicsInputInstruction::SetJump(s)=>{ PhysicsInputInstruction::SetJump(s)=>{
state.set_control(StyleModifiers::CONTROL_JUMP,s); state.set_control(Controls::Jump,s);
if let Some(walk_state)=get_walk_state(&state.move_state){ if let Some(walk_state)=get_walk_state(&state.move_state){
let mut v=state.body.velocity; let mut v=state.body.velocity;
jumped_velocity(&data.models,&state.style,&data.hitbox_mesh,walk_state,&mut v); jumped_velocity(&data.models,&state.style,&data.hitbox_mesh,walk_state.jump_direction.direction(&data.models,&data.hitbox_mesh,&walk_state.contact),&mut v);
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){
(state.move_state,state.body.acceleration)=state.touching.get_move_state(&state.body,&data.models,&state.style,&data.hitbox_mesh,&state.camera,state.controls,&state.next_mouse,state.time); (state.move_state,state.body.acceleration)=state.touching.get_move_state(&state.body,&data.models,&state.style,&data.hitbox_mesh,&state.camera,state.controls,&state.next_mouse,state.time);
} }
@ -1453,7 +1505,7 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,models
b_refresh_walk_target=false; b_refresh_walk_target=false;
}, },
PhysicsInputInstruction::SetZoom(s)=>{ PhysicsInputInstruction::SetZoom(s)=>{
state.set_control(StyleModifiers::CONTROL_ZOOM,s); state.set_control(Controls::Zoom,s);
b_refresh_walk_target=false; b_refresh_walk_target=false;
}, },
PhysicsInputInstruction::Reset=>{ PhysicsInputInstruction::Reset=>{