wip - notably remove camera interpolation for walking and rocket

This commit is contained in:
Quaternions 2024-02-16 17:38:16 -08:00
parent c55156bb92
commit 9396623f0c
3 changed files with 106 additions and 90 deletions

View File

@ -798,7 +798,7 @@ impl GraphicsState{
}); });
let camera=GraphicsCamera::default(); let camera=GraphicsCamera::default();
let camera_uniforms=camera.to_uniform_data(crate::physics::PhysicsOutputState::default().extrapolate(glam::IVec2::ZERO,integer::Time::ZERO)); let camera_uniforms=camera.to_uniform_data(crate::physics::PhysicsOutputState::default().extrapolate(crate::physics::MouseState::default()));
let camera_buf=device.create_buffer_init(&wgpu::util::BufferInitDescriptor{ let camera_buf=device.create_buffer_init(&wgpu::util::BufferInitDescriptor{
label:Some("Camera"), label:Some("Camera"),
contents:bytemuck::cast_slice(&camera_uniforms), contents:bytemuck::cast_slice(&camera_uniforms),
@ -875,7 +875,7 @@ impl GraphicsState{
let mut encoder=device.create_command_encoder(&wgpu::CommandEncoderDescriptor{label:None}); let mut encoder=device.create_command_encoder(&wgpu::CommandEncoderDescriptor{label:None});
// update rotation // update rotation
let camera_uniforms=self.camera.to_uniform_data(physics_output.extrapolate(mouse_pos,predicted_time)); let camera_uniforms=self.camera.to_uniform_data(physics_output.extrapolate(crate::physics::MouseState{pos:mouse_pos,time:predicted_time}));
self.staging_belt self.staging_belt
.write_buffer( .write_buffer(
&mut encoder, &mut encoder,

View File

@ -47,7 +47,7 @@ pub enum PhysicsInputInstruction {
//to be 1 instruction ahead to generate the next state for interpolation. //to be 1 instruction ahead to generate the next state for interpolation.
} }
#[derive(Clone,Hash,Default)] #[derive(Clone,Copy,Hash,Default)]
pub struct Body{ pub struct Body{
pub position:Planar64Vec3,//I64 where 2^32 = 1 u pub position:Planar64Vec3,//I64 where 2^32 = 1 u
pub velocity:Planar64Vec3,//I64 where 2^32 = 1 u/s pub velocity:Planar64Vec3,//I64 where 2^32 = 1 u/s
@ -99,19 +99,25 @@ pub struct InputState{
controls:strafesnet_common::controls_bitflag::Controls, controls:strafesnet_common::controls_bitflag::Controls,
} }
impl InputState{ impl InputState{
pub const fn get_next_mouse(&self)->&MouseState{
&self.next_mouse
}
fn set_next_mouse(&mut self,next_mouse:MouseState){ fn set_next_mouse(&mut self,next_mouse:MouseState){
(self.next_mouse,self.mouse)=(next_mouse,self.next_mouse); (self.next_mouse,self.mouse)=(next_mouse,self.next_mouse);
} }
fn replace_mouse(&mut self,mouse:MouseState,next_mouse:MouseState){ fn replace_mouse(&mut self,mouse:MouseState,next_mouse:MouseState){
(self.next_mouse,self.mouse)=(next_mouse,mouse); (self.next_mouse,self.mouse)=(next_mouse,mouse);
} }
fn time_delta(&self)->Time{ fn set_control(&mut self,control:Controls,state:bool){
self.controls.set(control,state)
}
const fn time_delta(&self)->Time{
self.next_mouse.time-self.mouse.time self.next_mouse.time-self.mouse.time
} }
fn mouse_delta(&self)->glam::IVec2{ const fn mouse_delta(&self)->glam::IVec2{
self.next_mouse.pos-self.mouse.pos self.next_mouse.pos-self.mouse.pos
} }
fn lerp_delta(&self,time:Time)->glam::IVec2{ const fn lerp_delta(&self,time:Time)->glam::IVec2{
//these are deltas //these are deltas
let dm=self.mouse_delta().as_i64vec2(); let dm=self.mouse_delta().as_i64vec2();
let t=(time-self.mouse.time).nanos(); let t=(time-self.mouse.time).nanos();
@ -221,7 +227,7 @@ impl PhysicsModels{
} }
} }
#[derive(Clone)] #[derive(Clone,Copy)]
pub struct PhysicsCamera{ pub struct PhysicsCamera{
//punch: Planar64Vec3, //punch: Planar64Vec3,
//punch_velocity: Planar64Vec3, //punch_velocity: Planar64Vec3,
@ -255,18 +261,31 @@ impl PhysicsCamera{
.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_delta:glam::IVec2)->Planar64Mat3{ #[inline]
let a=-self.sensitivity.mul_int((self.clamped_mouse_pos+mouse_delta).as_i64vec2()); fn get_rotation(&self,mouse_pos:glam::IVec2)->Planar64Mat3{
let a=-self.sensitivity.mul_int(mouse_pos.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_delta_x:i32)->Planar64Mat3{ fn rotation(&self)->Planar64Mat3{
let ax=-self.sensitivity.x.mul_int((self.clamped_mouse_pos.x+mouse_delta_x) as i64); self.get_rotation(self.clamped_mouse_pos)
}
fn simulate_move_rotation(&self,mouse_delta:glam::IVec2)->Planar64Mat3{
self.get_rotation(self.clamped_mouse_pos+mouse_delta)
}
fn get_rotation_y(&self,mouse_pos_x:i32)->Planar64Mat3{
let ax=-self.sensitivity.x.mul_int(mouse_pos_x as i64);
Planar64Mat3::from_rotation_y(Angle32::wrap_from_i64(ax)) Planar64Mat3::from_rotation_y(Angle32::wrap_from_i64(ax))
} }
fn rotation_y(&self)->Planar64Mat3{
self.get_rotation_y(self.clamped_mouse_pos.x)
}
fn simulate_move_rotation_y(&self,mouse_delta_x:i32)->Planar64Mat3{
self.get_rotation_y(self.clamped_mouse_pos.x+mouse_delta_x)
}
} }
impl std::default::Default for PhysicsCamera{ impl std::default::Default for PhysicsCamera{
@ -380,13 +399,9 @@ 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 allow_strafe(&self,controls:Controls)->bool;
fn get_control_dir(&self,controls:Controls)->Planar64Vec3; fn get_control_dir(&self,controls:Controls)->Planar64Vec3;
//fn get_jump_time(&self)->Planar64; fn get_walk_target_velocity(&self,camera:&PhysicsCamera,input_state:&InputState,normal:&Planar64Vec3)->Planar64Vec3;
//fn get_jump_height(&self)->Planar64; fn get_ladder_target_velocity(&self,camera:&PhysicsCamera,input_state:&InputState,normal:&Planar64Vec3)->Planar64Vec3;
//fn get_jump_energy(&self)->Planar64; fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,input_state:&InputState)->Planar64Vec3;
fn get_jump_deltav(&self)->Planar64;
fn get_walk_target_velocity(&self,camera:&PhysicsCamera,input_state:&InputState,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,input_state:&InputState,time:Time)->Planar64Vec3;
fn calculate_mesh(&self)->HitboxMesh; fn calculate_mesh(&self)->HitboxMesh;
} }
impl StyleHelper for StyleModifiers{ impl StyleHelper for StyleModifiers{
@ -425,12 +440,12 @@ impl StyleHelper for StyleModifiers{
return control_dir return control_dir
} }
fn get_walk_target_velocity(&self,camera:&PhysicsCamera,input_state:&InputState,time:Time,normal:&Planar64Vec3)->Planar64Vec3{ 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); 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_y(input_state.lerp_delta(time).x); let camera_mat=camera.rotation_y();
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();
@ -446,12 +461,12 @@ impl StyleHelper for StyleModifiers{
Planar64Vec3::ZERO Planar64Vec3::ZERO
} }
} }
fn get_ladder_target_velocity(&self,camera:&PhysicsCamera,input_state:&InputState,time:Time,normal:&Planar64Vec3)->Planar64Vec3{ 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); 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(input_state.lerp_delta(time)); let camera_mat=camera.rotation();
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();
@ -478,9 +493,9 @@ impl StyleHelper for StyleModifiers{
Planar64Vec3::ZERO Planar64Vec3::ZERO
} }
} }
fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,input_state:&InputState,time:Time)->Planar64Vec3{ fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,input_state:&InputState)->Planar64Vec3{
let camera_mat=camera.simulate_move_rotation(input_state.lerp_delta(time)); //don't interpolate this! discrete mouse movement, constant acceleration
camera_mat*self.get_control_dir(input_state.controls) camera.rotation()*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{
@ -500,13 +515,14 @@ enum MoveState{
Fly, Fly,
} }
impl MoveState{ impl MoveState{
fn apply_to_body(&self,body:&mut Body,touching:&TouchingState,models:&PhysicsModels,hitbox_mesh:&HitboxMesh){ fn apply_to_body(&self,touching:&TouchingState,models:&PhysicsModels,hitbox_mesh:&HitboxMesh,body:&mut Body){
match self{ match self{
MoveState::Air=>{ MoveState::Air=>{
//calculate base acceleration //calculate base acceleration
let mut a=touching.base_acceleration(models, style, camera, controls, next_mouse, time); let mut a=touching.base_acceleration(models, style, camera, input_state);
//clip according to contacts //clip according to contacts
touching.constrain_acceleration(models,hitbox_mesh,&mut a); touching.constrain_acceleration(models,hitbox_mesh,&mut a);
//something
}, },
MoveState::Water=>(), MoveState::Water=>(),
MoveState::Fly=>{ MoveState::Fly=>{
@ -528,10 +544,11 @@ pub struct PhysicsOutputState{
body:Body, body:Body,
camera:PhysicsCamera, camera:PhysicsCamera,
camera_offset:Planar64Vec3, camera_offset:Planar64Vec3,
mouse_pos:glam::IVec2,
} }
impl PhysicsOutputState{ impl PhysicsOutputState{
pub fn extrapolate(&self,mouse_delta:glam::IVec2,time:Time,alert:bool)->(glam::Vec3,glam::Vec2){ pub fn extrapolate(&self,mouse:MouseState)->(glam::Vec3,glam::Vec2){
((self.body.extrapolated_position(time)+self.camera_offset).into(),self.camera.simulate_move_angles(mouse_delta)) ((self.body.extrapolated_position(mouse.time)+self.camera_offset).into(),self.camera.simulate_move_angles(mouse.pos-self.mouse_pos))
} }
} }
@ -656,10 +673,12 @@ impl TouchingState{
Collision::Intersect(collision)=>self.intersects.remove(collision), Collision::Intersect(collision)=>self.intersects.remove(collision),
} }
} }
fn base_acceleration(&self,models:&PhysicsModels,style:&StyleModifiers,camera:&PhysicsCamera,controls:u32,next_mouse:&MouseState,time:Time)->Planar64Vec3{ fn base_acceleration(&self,models:&PhysicsModels,style:&StyleModifiers,camera:&PhysicsCamera,input_state:&InputState)->Planar64Vec3{
let mut a=style.gravity; let mut a=style.gravity;
if let Some(rocket_force)=style.rocket_force{ if let Some(rocket_settings)=style.rocket{
a+=style.get_propulsion_control_dir(camera,controls,next_mouse,time)*rocket_force; if rocket_settings.activates(input_state.controls){
a+=rocket_settings.acceleration(style.get_propulsion_control_dir(camera,input_state));
}
} }
//add accelerators //add accelerators
for contact in &self.contacts{ for contact in &self.contacts{
@ -707,11 +726,11 @@ impl TouchingState{
} }
} }
} }
fn get_move_state(&self,body:&Body,models:&PhysicsModels,style:&StyleModifiers,hitbox_mesh:&HitboxMesh,camera:&PhysicsCamera,controls:u32,next_mouse:&MouseState,time:Time)->(MoveState,Planar64Vec3){ fn get_move_state(&self,body:&Body,models:&PhysicsModels,style:&StyleModifiers,hitbox_mesh:&HitboxMesh,camera:&PhysicsCamera,input_state:&InputState,time:Time)->(MoveState,Planar64Vec3){
//check current move conditions and use heuristics to determine //check current move conditions and use heuristics to determine
//which ladder to climb on, which ground to walk on, etc //which ladder to climb on, which ground to walk on, etc
//collect move state affecting objects from contacts (accelerator,water,ladder,ground) //collect move state affecting objects from contacts (accelerator,water,ladder,ground)
let gravity=self.base_acceleration(models,style,camera,controls,next_mouse,time); let gravity=self.base_acceleration(models,style,camera,input_state);
let mut move_state=MoveState::Air; let mut move_state=MoveState::Air;
let mut a=gravity; let mut a=gravity;
for contact in &self.contacts{ for contact in &self.contacts{
@ -721,7 +740,7 @@ impl TouchingState{
match &contacting.contact_behaviour{ match &contacting.contact_behaviour{
Some(gameplay_attributes::ContactingBehaviour::Ladder(_))=>{ Some(gameplay_attributes::ContactingBehaviour::Ladder(_))=>{
//ladder walkstate //ladder walkstate
let mut target_velocity=style.get_ladder_target_velocity(camera,controls,next_mouse,time,&normal); let mut target_velocity=style.get_ladder_target_velocity(camera,input_state,&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);
@ -730,7 +749,7 @@ impl TouchingState{
}, },
None=>if style.surf_slope.map_or(true,|s|normal.walkable(s,Planar64Vec3::Y)){ None=>if style.surf_slope.map_or(true,|s|normal.walkable(s,Planar64Vec3::Y)){
//check ground //check ground
let mut target_velocity=style.get_walk_target_velocity(camera,controls,next_mouse,time,&normal); let mut target_velocity=style.get_walk_target_velocity(camera,input_state,&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);
@ -880,7 +899,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 input_state:InputState, input_state:InputState,
//style //style
style:StyleModifiers,//mode style with custom style updates applied style:StyleModifiers,//mode style with custom style updates applied
//gameplay_state //gameplay_state
@ -907,8 +926,7 @@ impl Default for PhysicsState{
touching:TouchingState::default(), touching:TouchingState::default(),
move_state: MoveState::Air, move_state: MoveState::Air,
camera:PhysicsCamera::default(), camera:PhysicsCamera::default(),
next_mouse:MouseState::default(), input_state:InputState::default(),
controls:0,
world:WorldState{}, world:WorldState{},
mode_state:ModeState::default(), mode_state:ModeState::default(),
} }
@ -929,26 +947,23 @@ impl PhysicsState {
pub fn clear(&mut self){ pub fn clear(&mut self){
self.touching.clear(); self.touching.clear();
} }
pub const fn output(&self)->PhysicsOutputState{
pub fn output(&self)->PhysicsOutputState{
PhysicsOutputState{ PhysicsOutputState{
body:self.body.clone(), body:self.body,
camera:self.camera.clone(), camera:self.camera,
camera_offset:self.style.camera_offset.clone(), camera_offset:self.style.camera_offset,
mouse_pos:self.input_state.mouse.pos,
} }
} }
pub fn load_user_settings(&mut self,user_settings:&crate::settings::UserSettings){ pub fn load_user_settings(&mut self,user_settings:&crate::settings::UserSettings){
self.camera.sensitivity=user_settings.calculate_sensitivity(); self.camera.sensitivity=user_settings.calculate_sensitivity();
} }
pub fn advance_time(&mut self, time: Time){ pub fn advance_time(&mut self, time: Time){
self.body.advance_time(time); self.body.advance_time(time);
self.time=time; self.time=time;
} }
pub const fn get_next_mouse(&self)->&MouseState{
fn set_control(&mut self,control:u32,state:bool){ self.input_state.get_next_mouse()
self.controls=if state{self.controls|control}else{self.controls&!control};
} }
fn next_strafe_instruction(&self)->Option<TimedInstruction<PhysicsInstruction>>{ fn next_strafe_instruction(&self)->Option<TimedInstruction<PhysicsInstruction>>{
@ -1115,12 +1130,12 @@ impl PhysicsContext{
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::Fly=>Planar64Vec3::ZERO, MoveState::Fly=>Planar64Vec3::ZERO,
MoveState::Air|MoveState::Water=>s.touching.base_acceleration(&data.models,&s.style,&s.camera,&s.input_state,s.time), MoveState::Air|MoveState::Water=>s.touching.base_acceleration(&data.models,&s.style,&s.camera,&s.input_state),
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.input_state,s.time); let gravity=s.touching.base_acceleration(&data.models,&s.style,&s.camera,&s.input_state);
let a; let a;
let mut v=s.style.get_walk_target_velocity(&s.camera,&s.input_state,s.time,&n); let mut v=s.style.get_walk_target_velocity(&s.camera,&s.input_state,&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);
@ -1130,7 +1145,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.input_state,s.time,&n); let mut v=s.style.get_ladder_target_velocity(&s.camera,&s.input_state,&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
@ -1182,7 +1197,8 @@ fn get_walk_state(move_state:&MoveState)->Option<&WalkState>{
} }
fn jumped_velocity(models:&PhysicsModels,style:&StyleModifiers,hitbox_mesh:&HitboxMesh,jump_dir:Planar64Vec3,v:&mut Planar64Vec3){ fn jumped_velocity(models:&PhysicsModels,style:&StyleModifiers,hitbox_mesh:&HitboxMesh,jump_dir:Planar64Vec3,v:&mut Planar64Vec3){
*v=*v+jump_dir*(style.get_jump_deltav()/jump_dir.length()); //bro what even is this function
*v=*v+jump_dir*(style.jump.get_jump_deltav()/jump_dir.length());
} }
fn contact_normal(models:&PhysicsModels,hitbox_mesh:&HitboxMesh,contact:&ContactCollision)->Planar64Vec3{ fn contact_normal(models:&PhysicsModels,hitbox_mesh:&HitboxMesh,contact:&ContactCollision)->Planar64Vec3{
@ -1352,8 +1368,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.input_state,state.time); let gravity=state.touching.base_acceleration(&data.models,&state.style,&state.camera,&state.input_state);
let mut target_velocity=state.style.get_ladder_target_velocity(&state.camera,&state.input_state,state.time,&normal); let mut target_velocity=state.style.get_ladder_target_velocity(&state.camera,&state.input_state,&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);
@ -1362,8 +1378,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.input_state,state.time); let gravity=state.touching.base_acceleration(&data.models,&state.style,&state.camera,&state.input_state);
let mut target_velocity=state.style.get_walk_target_velocity(&state.camera,&state.input_state,state.time,&normal); let mut target_velocity=state.style.get_walk_target_velocity(&state.camera,&state.input_state,&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);
@ -1389,7 +1405,7 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,models
}, },
None=>(), None=>(),
} }
let calc_move=if state.style.get_control(Controls::Jump,state.controls){ let calc_move=if state.style.get_control(Controls::Jump,state.input_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.jump_direction.direction(&data.models,&data.hitbox_mesh,&walk_state.contact),&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)
@ -1411,7 +1427,7 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,models
set_velocity(&mut state.body,&state.touching,&data.models,&data.hitbox_mesh,v); set_velocity(&mut state.body,&state.touching,&data.models,&data.hitbox_mesh,v);
//not sure if or is correct here //not sure if or is correct here
if calc_move||Planar64::ZERO<normal.dot(v){ if calc_move||Planar64::ZERO<normal.dot(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.input_state,state.time);
} }
let a=refresh_walk_target(state,data); let a=refresh_walk_target(state,data);
set_acceleration(&mut state.body,&state.touching,&data.models,&data.hitbox_mesh,a); set_acceleration(&mut state.body,&state.touching,&data.models,&data.hitbox_mesh,a);
@ -1431,7 +1447,7 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,models
PhysicsCollisionAttributes::Contact{contacting:_,general:_}=>{ PhysicsCollisionAttributes::Contact{contacting:_,general:_}=>{
state.touching.remove(&c);//remove contact before calling contact_constrain_acceleration state.touching.remove(&c);//remove contact before calling contact_constrain_acceleration
//check ground //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.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.input_state,state.time);
}, },
PhysicsCollisionAttributes::Intersect{intersecting:_,general:_}=>{ PhysicsCollisionAttributes::Intersect{intersecting:_,general:_}=>{
state.touching.remove(&c); state.touching.remove(&c);
@ -1439,18 +1455,18 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,models
} }
}, },
PhysicsInstruction::StrafeTick=>{ PhysicsInstruction::StrafeTick=>{
let control_dir=state.style.get_control_dir(state.controls); if let Some(strafe_settings)=state.style.strafe{
let control_dir=state.style.get_control_dir(state.input_state.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);
let control_dir=camera_mat*control_dir; //TODO: normalize control_dir but careful for zero
//normalize but careful for zero //(it's fun for cheating for now)
let d=state.body.velocity.dot(control_dir); if let Some(v)=strafe_settings.tick_velocity(state.body.velocity,camera_mat*control_dir){
if d<state.style.mv {
let v=state.body.velocity+control_dir*(state.style.mv-d);
//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){
(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.input_state,state.time);
}
} }
} }
} }
@ -1484,28 +1500,28 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,models
state.input_state.set_next_mouse(m); state.input_state.set_next_mouse(m);
}, },
PhysicsInputInstruction::ReplaceMouse(m0,m1)=>{ PhysicsInputInstruction::ReplaceMouse(m0,m1)=>{
state.camera.move_mouse(m0.pos-state.input_state.mouse); state.camera.move_mouse(m0.pos-state.input_state.mouse.pos);
state.input_state.replace_mouse(m0,m1); state.input_state.replace_mouse(m0,m1);
}, },
PhysicsInputInstruction::SetMoveForward(s)=>state.set_control(Controls::MoveForward,s), PhysicsInputInstruction::SetMoveForward(s)=>state.input_state.set_control(Controls::MoveForward,s),
PhysicsInputInstruction::SetMoveLeft(s)=>state.set_control(Controls::MoveLeft,s), PhysicsInputInstruction::SetMoveLeft(s)=>state.input_state.set_control(Controls::MoveLeft,s),
PhysicsInputInstruction::SetMoveBack(s)=>state.set_control(Controls::MoveBackward,s), PhysicsInputInstruction::SetMoveBack(s)=>state.input_state.set_control(Controls::MoveBackward,s),
PhysicsInputInstruction::SetMoveRight(s)=>state.set_control(Controls::MoveRight,s), PhysicsInputInstruction::SetMoveRight(s)=>state.input_state.set_control(Controls::MoveRight,s),
PhysicsInputInstruction::SetMoveUp(s)=>state.set_control(Controls::MoveUp,s), PhysicsInputInstruction::SetMoveUp(s)=>state.input_state.set_control(Controls::MoveUp,s),
PhysicsInputInstruction::SetMoveDown(s)=>state.set_control(Controls::MoveDown,s), PhysicsInputInstruction::SetMoveDown(s)=>state.input_state.set_control(Controls::MoveDown,s),
PhysicsInputInstruction::SetJump(s)=>{ PhysicsInputInstruction::SetJump(s)=>{
state.set_control(Controls::Jump,s); state.input_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.jump_direction.direction(&data.models,&data.hitbox_mesh,&walk_state.contact),&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.input_state,state.time);
} }
} }
b_refresh_walk_target=false; b_refresh_walk_target=false;
}, },
PhysicsInputInstruction::SetZoom(s)=>{ PhysicsInputInstruction::SetZoom(s)=>{
state.set_control(Controls::Zoom,s); state.input_state.set_control(Controls::Zoom,s);
b_refresh_walk_target=false; b_refresh_walk_target=false;
}, },
PhysicsInputInstruction::Reset=>{ PhysicsInputInstruction::Reset=>{
@ -1518,7 +1534,7 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,models
).unwrap_or(Planar64Vec3::ZERO); ).unwrap_or(Planar64Vec3::ZERO);
set_position(&mut state.body,&mut state.touching,spawn_point); set_position(&mut state.body,&mut state.touching,spawn_point);
set_velocity(&mut state.body,&state.touching,&data.models,&data.hitbox_mesh,Planar64Vec3::ZERO); 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.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.input_state,state.time);
b_refresh_walk_target=false; b_refresh_walk_target=false;
}, },
PhysicsInputInstruction::Idle=>{b_refresh_walk_target=false;},//literally idle! PhysicsInputInstruction::Idle=>{b_refresh_walk_target=false;},//literally idle!
@ -1526,7 +1542,7 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,models
if b_refresh_walk_target{ if b_refresh_walk_target{
let a=refresh_walk_target(state,data); let a=refresh_walk_target(state,data);
if set_acceleration_cull(&mut state.body,&mut state.touching,&data.models,&data.hitbox_mesh,a){ if set_acceleration_cull(&mut state.body,&mut state.touching,&data.models,&data.hitbox_mesh,a){
(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.input_state,state.time);
} }
} }
}, },

View File

@ -25,7 +25,7 @@ pub enum Instruction{
pub fn new(mut physics:crate::physics::PhysicsContext,mut graphics_worker:crate::compat_worker::INWorker<crate::graphics_worker::Instruction>)->crate::compat_worker::QNWorker<TimedInstruction<Instruction>>{ pub fn new(mut physics:crate::physics::PhysicsContext,mut graphics_worker:crate::compat_worker::INWorker<crate::graphics_worker::Instruction>)->crate::compat_worker::QNWorker<TimedInstruction<Instruction>>{
let mut mouse_blocking=true; let mut mouse_blocking=true;
let mut last_mouse_time=physics.state.next_mouse.time; let mut last_mouse_time=physics.state.get_next_mouse().time;
let mut timeline=std::collections::VecDeque::new(); let mut timeline=std::collections::VecDeque::new();
crate::compat_worker::QNWorker::new(move |ins:TimedInstruction<Instruction>|{ crate::compat_worker::QNWorker::new(move |ins:TimedInstruction<Instruction>|{
if if let Some(phys_input)=match &ins.instruction{ if if let Some(phys_input)=match &ins.instruction{
@ -43,7 +43,7 @@ pub enum Instruction{
timeline.push_front(TimedInstruction{ timeline.push_front(TimedInstruction{
time:last_mouse_time, time:last_mouse_time,
instruction:PhysicsInputInstruction::ReplaceMouse( instruction:PhysicsInputInstruction::ReplaceMouse(
MouseState{time:last_mouse_time,pos:physics.state.next_mouse.pos}, MouseState{time:last_mouse_time,pos:physics.state.get_next_mouse().pos},
MouseState{time:ins.time,pos:m} MouseState{time:ins.time,pos:m}
), ),
}); });
@ -79,11 +79,11 @@ pub enum Instruction{
//shitty mice are 125Hz which is 8ms so this should cover that. //shitty mice are 125Hz which is 8ms so this should cover that.
//setting this to 100us still doesn't print even though it's 10x lower than the polling rate, //setting this to 100us still doesn't print even though it's 10x lower than the polling rate,
//so mouse events are probably not handled separately from drawing and fire right before it :( //so mouse events are probably not handled separately from drawing and fire right before it :(
if Time::from_millis(10)<ins.time-physics.state.next_mouse.time{ if Time::from_millis(10)<ins.time-physics.state.get_next_mouse().time{
//push an event to extrapolate no movement from //push an event to extrapolate no movement from
timeline.push_front(TimedInstruction{ timeline.push_front(TimedInstruction{
time:last_mouse_time, time:last_mouse_time,
instruction:PhysicsInputInstruction::SetNextMouse(MouseState{time:ins.time,pos:physics.state.next_mouse.pos}), instruction:PhysicsInputInstruction::SetNextMouse(MouseState{time:ins.time,pos:physics.state.get_next_mouse().pos}),
}); });
last_mouse_time=ins.time; last_mouse_time=ins.time;
//stop blocking. the mouse is not moving so the physics does not need to live in the past and wait for interpolation targets. //stop blocking. the mouse is not moving so the physics does not need to live in the past and wait for interpolation targets.
@ -113,7 +113,7 @@ pub enum Instruction{
} }
match ins.instruction{ match ins.instruction{
Instruction::Render=>{ Instruction::Render=>{
graphics_worker.send(crate::graphics_worker::Instruction::Render(physics.state.output(),ins.time,physics.state.next_mouse.pos)).unwrap(); graphics_worker.send(crate::graphics_worker::Instruction::Render(physics.state.output(),ins.time,physics.state.get_next_mouse().pos)).unwrap();
}, },
Instruction::Resize(size,user_settings)=>{ Instruction::Resize(size,user_settings)=>{
graphics_worker.send(crate::graphics_worker::Instruction::Resize(size,user_settings)).unwrap(); graphics_worker.send(crate::graphics_worker::Instruction::Resize(size,user_settings)).unwrap();