forked from StrafesNET/strafe-client
wip
This commit is contained in:
parent
0ac1c1aa6b
commit
c55156bb92
226
src/physics.rs
226
src/physics.rs
@ -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=>{
|
||||||
|
Loading…
Reference in New Issue
Block a user