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,
)->Planar64Vec3{
match self{
&JumpImpulse::Time(time)=>velocity-*gravity*time,
&JumpImpulse::Time(time)=>velocity-(*gravity*time).map(|t|t.divide().fix_1()),
&JumpImpulse::Height(height)=>{
//height==-v.y*v.y/(2*g.y);
//use energy to determine max height
@ -76,7 +76,7 @@ impl JumpImpulse{
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())
},
&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)=>{
//calculate energy
//let e=gravity.dot(velocity);
@ -90,10 +90,10 @@ impl JumpImpulse{
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
match self{
&JumpImpulse::Time(time)=>gravity.length()*(time/2),
&JumpImpulse::Height(height)=>(gravity.length()*height*2).sqrt(),
&JumpImpulse::Time(time)=>(gravity.length_squared().sqrt().fix_1()*time/2).divide().fix_1(),
&JumpImpulse::Height(height)=>(gravity.length_squared().sqrt()*height*2).sqrt().fix_1(),
&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,
};
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
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{
//activate booster normally, jump does nothing
boost_vel
@ -140,12 +141,13 @@ impl JumpSettings{
None=>rel_velocity,
};
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
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{
//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)=>{
@ -156,9 +158,10 @@ impl JumpSettings{
None=>rel_velocity,
};
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
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{
//activate booster normally, jump does nothing
boost_vel
@ -170,7 +173,7 @@ impl JumpSettings{
Some(booster)=>booster.boost(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{
pub fn tick_velocity(&self,velocity:Planar64Vec3,control_dir:Planar64Vec3)->Option<Planar64Vec3>{
let d=velocity.dot(control_dir);
match d<self.mv{
true=>Some(velocity+control_dir*self.air_accel_limit.map_or(self.mv-d,|limit|limit.min(self.mv-d))),
let mv=self.mv.fix_2();
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,
}
}
@ -285,7 +289,7 @@ pub struct PropulsionSettings{
}
impl PropulsionSettings{
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{
pub fn accel(&self,target_diff:Planar64Vec3,gravity:Planar64Vec3)->Planar64{
//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{
self.static_friction
}else{
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{
if control_dir==Planar64Vec3::ZERO{
if control_dir==crate::integer::vec3::ZERO{
return control_dir;
}
let m=control_dir.length();
let n=normal.length();
let nm=n*m;
let n=normal.length_squared();
let m=control_dir.length_squared();
let nm=(n*m).fix_2();
let d=normal.dot(control_dir);
if d<nm{
let cr=normal.cross(control_dir);
if cr==Planar64Vec3::ZERO{
Planar64Vec3::ZERO
if cr==crate::integer::vec3::ZERO_2{
crate::integer::vec3::ZERO
}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{
Planar64Vec3::ZERO
crate::integer::vec3::ZERO
}
}
pub fn is_slope_walkable(&self,normal:Planar64Vec3,up:Planar64Vec3)->bool{
//normal is not guaranteed to be unit length
let ny=normal.dot(up);
let h=normal.length();
let h=normal.length_squared().sqrt().fix_1();
//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
}
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;
}
let n=normal.length();
let m=control_dir.length();
let mut d=normal.dot(control_dir)/m;
if d< -self.dot*n{
control_dir=Planar64Vec3::Y*m;
d=normal.y;
}else if self.dot*n<d{
control_dir=Planar64Vec3::NEG_Y*m;
d=-normal.y;
let n=normal.length_squared();
let m=control_dir.length_squared();
let nm=(n*m).fix_2();
let mut d=normal.dot(control_dir);
if d<((-self.dot)*nm).fix_2(){
control_dir=Planar64Vec3::new([Planar64::ZERO,m.fix_1(),Planar64::ZERO]);
d=normal.y.fix_2();
}else if (self.dot*nm).fix_2()<d{
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.
//two fixes:
//- ladder movement is not allowed on walkable surfaces
//- fix the underlying issue
if d.get().unsigned_abs()<n.get().unsigned_abs(){
if d.abs()<nm.abs(){
let cr=normal.cross(control_dir);
if cr==Planar64Vec3::ZERO{
Planar64Vec3::ZERO
if cr==crate::integer::vec3::ZERO_2{
crate::integer::vec3::ZERO
}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{
Planar64Vec3::ZERO
crate::integer::vec3::ZERO
}
}
}
@ -402,22 +407,22 @@ pub struct Hitbox{
impl Hitbox{
pub fn roblox()->Self{
Self{
halfsize:int3(2,5,2)/2,
halfsize:int3(2,5,2)>>1,
mesh:HitboxMesh::Cylinder,
}
}
pub fn source()->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,
}
}
}
impl StyleModifiers{
pub const RIGHT_DIR:Planar64Vec3=Planar64Vec3::X;
pub const UP_DIR:Planar64Vec3=Planar64Vec3::Y;
pub const FORWARD_DIR:Planar64Vec3=Planar64Vec3::NEG_Z;
pub const RIGHT_DIR:Planar64Vec3=crate::integer::vec3::X;
pub const UP_DIR:Planar64Vec3=crate::integer::vec3::Y;
pub const FORWARD_DIR:Planar64Vec3=crate::integer::vec3::NEG_Z;
pub fn neo()->Self{
Self{
@ -525,15 +530,15 @@ impl StyleModifiers{
strafe:Some(StrafeSettings{
enable:ControlsActivation::full_2d(),
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(),
}),
jump:Some(JumpSettings{
impulse:JumpImpulse::Height(int(52)*VALVE_SCALE),
impulse:JumpImpulse::Height((int(52)*VALVE_SCALE).fix_1()),
calculation:JumpCalculation::JumpThenBoost,
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),
rocket:None,
walk:Some(WalkSettings{
@ -556,7 +561,7 @@ impl StyleModifiers{
magnitude:int(12),//?
}),
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{
@ -565,16 +570,16 @@ impl StyleModifiers{
controls_mask_state:Controls::all(),
strafe:Some(StrafeSettings{
enable:ControlsActivation::full_2d(),
air_accel_limit:Some(int(150)*66*VALVE_SCALE),
mv:int(30)*VALVE_SCALE,
air_accel_limit:Some((int(150)*66*VALVE_SCALE).fix_1()),
mv:(int(30)*VALVE_SCALE).fix_1(),
tick_rate:Ratio64::new(66,Time::ONE_SECOND.nanos() as u64).unwrap(),
}),
jump:Some(JumpSettings{
impulse:JumpImpulse::Height(int(52)*VALVE_SCALE),
impulse:JumpImpulse::Height((int(52)*VALVE_SCALE).fix_1()),
calculation:JumpCalculation::JumpThenBoost,
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),
rocket:None,
walk:Some(WalkSettings{
@ -597,7 +602,7 @@ impl StyleModifiers{
magnitude:int(12),//?
}),
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 Planar64Mat3=linear_ops::types::Matrix3<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{
Planar64::from(value)