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