write the whole thing

This commit is contained in:
Quaternions 2024-09-11 15:14:56 -07:00
parent aaad5d5c22
commit e8a6f4dab3
2 changed files with 73 additions and 57 deletions

View File

@ -65,7 +65,7 @@ impl JumpImpulse{
mass:Planar64, mass:Planar64,
)->Planar64Vec3{ )->Planar64Vec3{
match self{ match self{
&JumpImpulse::Time(time)=>velocity-*gravity*time, &JumpImpulse::Time(time)=>velocity-(*gravity*time).map(|t|t.divide().fix_1()),
&JumpImpulse::Height(height)=>{ &JumpImpulse::Height(height)=>{
//height==-v.y*v.y/(2*g.y); //height==-v.y*v.y/(2*g.y);
//use energy to determine max height //use energy to determine max height
@ -76,7 +76,7 @@ impl JumpImpulse{
let radicand=v_g*v_g+(g*height*2).fix_4(); let radicand=v_g*v_g+(g*height*2).fix_4();
velocity-(*gravity*(radicand.sqrt().fix_2()+v_g)/gg).divide().map(|t|t.fix_1()) velocity-(*gravity*(radicand.sqrt().fix_2()+v_g)/gg).divide().map(|t|t.fix_1())
}, },
&JumpImpulse::Linear(jump_speed)=>velocity+jump_dir.with_length(jump_speed), &JumpImpulse::Linear(jump_speed)=>velocity+(jump_dir*jump_speed/jump_dir.length_squared().sqrt()).divide().map(|t|t.fix_1()),
&JumpImpulse::Energy(energy)=>{ &JumpImpulse::Energy(energy)=>{
//calculate energy //calculate energy
//let e=gravity.dot(velocity); //let e=gravity.dot(velocity);
@ -90,10 +90,10 @@ impl JumpImpulse{
pub fn get_jump_deltav(&self,gravity:&Planar64Vec3,mass:Planar64)->Planar64{ pub fn get_jump_deltav(&self,gravity:&Planar64Vec3,mass:Planar64)->Planar64{
//gravity.length() is actually the proper calculation because the jump is always opposite the gravity direction //gravity.length() is actually the proper calculation because the jump is always opposite the gravity direction
match self{ match self{
&JumpImpulse::Time(time)=>gravity.length()*(time/2), &JumpImpulse::Time(time)=>(gravity.length_squared().sqrt().fix_1()*time/2).divide().fix_1(),
&JumpImpulse::Height(height)=>(gravity.length()*height*2).sqrt(), &JumpImpulse::Height(height)=>(gravity.length_squared().sqrt()*height*2).sqrt().fix_1(),
&JumpImpulse::Linear(deltav)=>deltav, &JumpImpulse::Linear(deltav)=>deltav,
&JumpImpulse::Energy(energy)=>(energy*2/mass).sqrt(), &JumpImpulse::Energy(energy)=>(energy.sqrt()*2/mass.sqrt()).divide().fix_1(),
} }
} }
} }
@ -125,9 +125,10 @@ impl JumpSettings{
None=>rel_velocity, None=>rel_velocity,
}; };
let j=boost_vel.dot(jump_dir); let j=boost_vel.dot(jump_dir);
if j<jump_speed{ let js=jump_speed.fix_2();
if j<js{
//weak booster: just do a regular jump //weak booster: just do a regular jump
boost_vel+jump_dir.with_length(jump_speed-j) boost_vel+(jump_dir*(js-j)/jump_dir.length_squared().sqrt()).divide().map(|t|t.fix_1())
}else{ }else{
//activate booster normally, jump does nothing //activate booster normally, jump does nothing
boost_vel boost_vel
@ -140,12 +141,13 @@ impl JumpSettings{
None=>rel_velocity, None=>rel_velocity,
}; };
let j=boost_vel.dot(jump_dir); let j=boost_vel.dot(jump_dir);
if j<jump_speed{ let js=jump_speed.fix_2();
if j<js{
//speed in direction of jump cannot be lower than amount //speed in direction of jump cannot be lower than amount
boost_vel+jump_dir.with_length(jump_speed-j) boost_vel+(jump_dir*(js-j)/jump_dir.length_squared().sqrt()).divide().map(|t|t.fix_1())
}else{ }else{
//boost and jump add together //boost and jump add together
boost_vel+jump_dir.with_length(jump_speed) boost_vel+(jump_dir*js/jump_dir.length_squared().sqrt()).divide().map(|t|t.fix_1())
} }
} }
(false,JumpCalculation::Max)=>{ (false,JumpCalculation::Max)=>{
@ -156,9 +158,10 @@ impl JumpSettings{
None=>rel_velocity, None=>rel_velocity,
}; };
let boost_dot=boost_vel.dot(jump_dir); let boost_dot=boost_vel.dot(jump_dir);
if boost_dot<jump_speed{ let js=jump_speed.fix_2();
if boost_dot<js{
//weak boost is extended to jump speed //weak boost is extended to jump speed
boost_vel+jump_dir.with_length(jump_speed-boost_dot) boost_vel+(jump_dir*(js-boost_dot)/jump_dir.length_squared().sqrt()).divide().map(|t|t.fix_1())
}else{ }else{
//activate booster normally, jump does nothing //activate booster normally, jump does nothing
boost_vel boost_vel
@ -170,7 +173,7 @@ impl JumpSettings{
Some(booster)=>booster.boost(rel_velocity), Some(booster)=>booster.boost(rel_velocity),
None=>rel_velocity, None=>rel_velocity,
}; };
boost_vel+jump_dir.with_length(jump_speed) boost_vel+(jump_dir*jump_speed/jump_dir.length_squared().sqrt()).divide().map(|t|t.fix_1())
}, },
} }
} }
@ -263,8 +266,9 @@ pub struct StrafeSettings{
impl StrafeSettings{ impl StrafeSettings{
pub fn tick_velocity(&self,velocity:Planar64Vec3,control_dir:Planar64Vec3)->Option<Planar64Vec3>{ pub fn tick_velocity(&self,velocity:Planar64Vec3,control_dir:Planar64Vec3)->Option<Planar64Vec3>{
let d=velocity.dot(control_dir); let d=velocity.dot(control_dir);
match d<self.mv{ let mv=self.mv.fix_2();
true=>Some(velocity+control_dir*self.air_accel_limit.map_or(self.mv-d,|limit|limit.min(self.mv-d))), match d<mv{
true=>Some(velocity+(control_dir*self.air_accel_limit.map_or(mv-d,|limit|limit.fix_2().min(mv-d))).map(|t|t.fix_1())),
false=>None, false=>None,
} }
} }
@ -285,7 +289,7 @@ pub struct PropulsionSettings{
} }
impl PropulsionSettings{ impl PropulsionSettings{
pub fn acceleration(&self,control_dir:Planar64Vec3)->Planar64Vec3{ pub fn acceleration(&self,control_dir:Planar64Vec3)->Planar64Vec3{
control_dir*self.magnitude (control_dir*self.magnitude).map(|t|t.fix_1())
} }
} }
@ -305,39 +309,39 @@ pub struct WalkSettings{
impl WalkSettings{ impl WalkSettings{
pub fn accel(&self,target_diff:Planar64Vec3,gravity:Planar64Vec3)->Planar64{ pub fn accel(&self,target_diff:Planar64Vec3,gravity:Planar64Vec3)->Planar64{
//TODO: fallible walk accel //TODO: fallible walk accel
let diff_len=target_diff.length(); let diff_len=target_diff.length_squared().sqrt().fix_1();
let friction=if diff_len<self.accelerate.topspeed{ let friction=if diff_len<self.accelerate.topspeed{
self.static_friction self.static_friction
}else{ }else{
self.kinetic_friction self.kinetic_friction
}; };
self.accelerate.accel.min(-Planar64Vec3::Y.dot(gravity)*friction) self.accelerate.accel.min((-gravity.y*friction).fix_1())
} }
pub fn get_walk_target_velocity(&self,control_dir:Planar64Vec3,normal:Planar64Vec3)->Planar64Vec3{ pub fn get_walk_target_velocity(&self,control_dir:Planar64Vec3,normal:Planar64Vec3)->Planar64Vec3{
if control_dir==Planar64Vec3::ZERO{ if control_dir==crate::integer::vec3::ZERO{
return control_dir; return control_dir;
} }
let m=control_dir.length(); let n=normal.length_squared();
let n=normal.length(); let m=control_dir.length_squared();
let nm=n*m; let nm=(n*m).fix_2();
let d=normal.dot(control_dir); let d=normal.dot(control_dir);
if d<nm{ if d<nm{
let cr=normal.cross(control_dir); let cr=normal.cross(control_dir);
if cr==Planar64Vec3::ZERO{ if cr==crate::integer::vec3::ZERO_2{
Planar64Vec3::ZERO crate::integer::vec3::ZERO
}else{ }else{
(cr.cross(normal)*self.accelerate.topspeed/(n*(nm*nm-d*d).sqrt())) (cr.cross(normal)*self.accelerate.topspeed/(n*(nm*nm-d*d).sqrt())).divide().map(|t|t.fix_1())
} }
}else{ }else{
Planar64Vec3::ZERO crate::integer::vec3::ZERO
} }
} }
pub fn is_slope_walkable(&self,normal:Planar64Vec3,up:Planar64Vec3)->bool{ pub fn is_slope_walkable(&self,normal:Planar64Vec3,up:Planar64Vec3)->bool{
//normal is not guaranteed to be unit length //normal is not guaranteed to be unit length
let ny=normal.dot(up); let ny=normal.dot(up);
let h=normal.length(); let h=normal.length_squared().sqrt().fix_1();
//remember this is a normal vector //remember this is a normal vector
Planar64::ZERO<ny&&h*self.surf_dot<ny ny.is_negative()&&h*self.surf_dot<ny
} }
} }
@ -354,32 +358,33 @@ impl LadderSettings{
self.accelerate.accel self.accelerate.accel
} }
pub fn get_ladder_target_velocity(&self,mut control_dir:Planar64Vec3,normal:Planar64Vec3)->Planar64Vec3{ pub fn get_ladder_target_velocity(&self,mut control_dir:Planar64Vec3,normal:Planar64Vec3)->Planar64Vec3{
if control_dir==Planar64Vec3::ZERO{ if control_dir==crate::integer::vec3::ZERO{
return control_dir; return control_dir;
} }
let n=normal.length(); let n=normal.length_squared();
let m=control_dir.length(); let m=control_dir.length_squared();
let mut d=normal.dot(control_dir)/m; let nm=(n*m).fix_2();
if d< -self.dot*n{ let mut d=normal.dot(control_dir);
control_dir=Planar64Vec3::Y*m; if d<((-self.dot)*nm).fix_2(){
d=normal.y; control_dir=Planar64Vec3::new([Planar64::ZERO,m.fix_1(),Planar64::ZERO]);
}else if self.dot*n<d{ d=normal.y.fix_2();
control_dir=Planar64Vec3::NEG_Y*m; }else if (self.dot*nm).fix_2()<d{
d=-normal.y; control_dir=Planar64Vec3::new([Planar64::ZERO,-m.fix_1(),Planar64::ZERO]);
d=-normal.y.fix_2();
} }
//n=d if you are standing on top of a ladder and press E. //n=d if you are standing on top of a ladder and press E.
//two fixes: //two fixes:
//- ladder movement is not allowed on walkable surfaces //- ladder movement is not allowed on walkable surfaces
//- fix the underlying issue //- fix the underlying issue
if d.get().unsigned_abs()<n.get().unsigned_abs(){ if d.abs()<nm.abs(){
let cr=normal.cross(control_dir); let cr=normal.cross(control_dir);
if cr==Planar64Vec3::ZERO{ if cr==crate::integer::vec3::ZERO_2{
Planar64Vec3::ZERO crate::integer::vec3::ZERO
}else{ }else{
cr.cross(normal)*(self.accelerate.topspeed/(n*(n*n-d*d).sqrt())) (cr.cross(normal)*self.accelerate.topspeed/(n*(nm*nm-d*d).sqrt())).divide().map(|t|t.fix_1())
} }
}else{ }else{
Planar64Vec3::ZERO crate::integer::vec3::ZERO
} }
} }
} }
@ -402,22 +407,22 @@ pub struct Hitbox{
impl Hitbox{ impl Hitbox{
pub fn roblox()->Self{ pub fn roblox()->Self{
Self{ Self{
halfsize:int3(2,5,2)/2, halfsize:int3(2,5,2)>>1,
mesh:HitboxMesh::Cylinder, mesh:HitboxMesh::Cylinder,
} }
} }
pub fn source()->Self{ pub fn source()->Self{
Self{ Self{
halfsize:int3(33,73,33)/2*VALVE_SCALE, halfsize:((int3(33,73,33)>>1)*VALVE_SCALE).map(|t|t.fix_1()),
mesh:HitboxMesh::Box, mesh:HitboxMesh::Box,
} }
} }
} }
impl StyleModifiers{ impl StyleModifiers{
pub const RIGHT_DIR:Planar64Vec3=Planar64Vec3::X; pub const RIGHT_DIR:Planar64Vec3=crate::integer::vec3::X;
pub const UP_DIR:Planar64Vec3=Planar64Vec3::Y; pub const UP_DIR:Planar64Vec3=crate::integer::vec3::Y;
pub const FORWARD_DIR:Planar64Vec3=Planar64Vec3::NEG_Z; pub const FORWARD_DIR:Planar64Vec3=crate::integer::vec3::NEG_Z;
pub fn neo()->Self{ pub fn neo()->Self{
Self{ Self{
@ -525,15 +530,15 @@ impl StyleModifiers{
strafe:Some(StrafeSettings{ strafe:Some(StrafeSettings{
enable:ControlsActivation::full_2d(), enable:ControlsActivation::full_2d(),
air_accel_limit:Some(Planar64::raw(150<<28)*100), air_accel_limit:Some(Planar64::raw(150<<28)*100),
mv:Planar64::raw(30)*VALVE_SCALE, mv:(Planar64::raw(30)*VALVE_SCALE).fix_1(),
tick_rate:Ratio64::new(100,Time::ONE_SECOND.nanos() as u64).unwrap(), tick_rate:Ratio64::new(100,Time::ONE_SECOND.nanos() as u64).unwrap(),
}), }),
jump:Some(JumpSettings{ jump:Some(JumpSettings{
impulse:JumpImpulse::Height(int(52)*VALVE_SCALE), impulse:JumpImpulse::Height((int(52)*VALVE_SCALE).fix_1()),
calculation:JumpCalculation::JumpThenBoost, calculation:JumpCalculation::JumpThenBoost,
limit_minimum:true, limit_minimum:true,
}), }),
gravity:int3(0,-800,0)*VALVE_SCALE, gravity:(int3(0,-800,0)*VALVE_SCALE).map(|t|t.fix_1()),
mass:int(1), mass:int(1),
rocket:None, rocket:None,
walk:Some(WalkSettings{ walk:Some(WalkSettings{
@ -556,7 +561,7 @@ impl StyleModifiers{
magnitude:int(12),//? magnitude:int(12),//?
}), }),
hitbox:Hitbox::source(), hitbox:Hitbox::source(),
camera_offset:(int3(0,64,0)-int3(0,73,0)/2)*VALVE_SCALE, camera_offset:((int3(0,64,0)-(int3(0,73,0)>>1))*VALVE_SCALE).map(|t|t.fix_1()),
} }
} }
pub fn source_surf()->Self{ pub fn source_surf()->Self{
@ -565,16 +570,16 @@ impl StyleModifiers{
controls_mask_state:Controls::all(), controls_mask_state:Controls::all(),
strafe:Some(StrafeSettings{ strafe:Some(StrafeSettings{
enable:ControlsActivation::full_2d(), enable:ControlsActivation::full_2d(),
air_accel_limit:Some(int(150)*66*VALVE_SCALE), air_accel_limit:Some((int(150)*66*VALVE_SCALE).fix_1()),
mv:int(30)*VALVE_SCALE, mv:(int(30)*VALVE_SCALE).fix_1(),
tick_rate:Ratio64::new(66,Time::ONE_SECOND.nanos() as u64).unwrap(), tick_rate:Ratio64::new(66,Time::ONE_SECOND.nanos() as u64).unwrap(),
}), }),
jump:Some(JumpSettings{ jump:Some(JumpSettings{
impulse:JumpImpulse::Height(int(52)*VALVE_SCALE), impulse:JumpImpulse::Height((int(52)*VALVE_SCALE).fix_1()),
calculation:JumpCalculation::JumpThenBoost, calculation:JumpCalculation::JumpThenBoost,
limit_minimum:true, limit_minimum:true,
}), }),
gravity:int3(0,-800,0)*VALVE_SCALE, gravity:(int3(0,-800,0)*VALVE_SCALE).map(|t|t.fix_1()),
mass:int(1), mass:int(1),
rocket:None, rocket:None,
walk:Some(WalkSettings{ walk:Some(WalkSettings{
@ -597,7 +602,7 @@ impl StyleModifiers{
magnitude:int(12),//? magnitude:int(12),//?
}), }),
hitbox:Hitbox::source(), hitbox:Hitbox::source(),
camera_offset:(int3(0,64,0)-int3(0,73,0)/2)*VALVE_SCALE, camera_offset:((int3(0,64,0)-(int3(0,73,0)>>1))*VALVE_SCALE).map(|t|t.fix_1()),
} }
} }
} }

View File

@ -441,6 +441,17 @@ pub type Planar64=fixed_wide::types::I32F32;
pub type Planar64Vec3=linear_ops::types::Vector3<Planar64>; pub type Planar64Vec3=linear_ops::types::Vector3<Planar64>;
pub type Planar64Mat3=linear_ops::types::Matrix3<Planar64>; pub type Planar64Mat3=linear_ops::types::Matrix3<Planar64>;
pub type Planar64Affine3=linear_ops::types::Matrix4x3<Planar64>; pub type Planar64Affine3=linear_ops::types::Matrix4x3<Planar64>;
pub mod vec3{
use super::*;
pub const ZERO:Planar64Vec3=Planar64Vec3::new([Planar64::ZERO;3]);
pub const ZERO_2:linear_ops::types::Vector3<Fixed::<2,64>>=linear_ops::types::Vector3::new([Fixed::<2,64>::ZERO;3]);
pub const X:Planar64Vec3=Planar64Vec3::new([Planar64::ONE,Planar64::ZERO,Planar64::ZERO]);
pub const Y:Planar64Vec3=Planar64Vec3::new([Planar64::ZERO,Planar64::ONE,Planar64::ZERO]);
pub const Z:Planar64Vec3=Planar64Vec3::new([Planar64::ZERO,Planar64::ZERO,Planar64::ONE]);
pub const NEG_X:Planar64Vec3=Planar64Vec3::new([Planar64::NEG_ONE,Planar64::ZERO,Planar64::ZERO]);
pub const NEG_Y:Planar64Vec3=Planar64Vec3::new([Planar64::ZERO,Planar64::NEG_ONE,Planar64::ZERO]);
pub const NEG_Z:Planar64Vec3=Planar64Vec3::new([Planar64::ZERO,Planar64::ZERO,Planar64::NEG_ONE]);
}
pub fn int(value:i32)->Planar64{ pub fn int(value:i32)->Planar64{
Planar64::from(value) Planar64::from(value)