write the whole thing
This commit is contained in:
parent
aaad5d5c22
commit
e8a6f4dab3
@ -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()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user