forked from StrafesNET/strafe-client
more wip
This commit is contained in:
parent
df12b9f126
commit
4f79d6c8bf
241
src/physics.rs
241
src/physics.rs
@ -11,7 +11,7 @@ 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::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,vec3,mat3,Time,Planar64,Planar64Vec3,Planar64Mat3,Angle32,Ratio64Vec2};
|
||||||
use gameplay::ModeState;
|
use gameplay::ModeState;
|
||||||
|
|
||||||
//external influence
|
//external influence
|
||||||
@ -36,7 +36,7 @@ enum PhysicsInstruction{
|
|||||||
Input(PhysicsInputInstruction),
|
Input(PhysicsInputInstruction),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone,Copy,Debug,Default,Hash)]
|
#[derive(Clone,Copy,Debug,Hash)]
|
||||||
pub struct Body{
|
pub struct Body{
|
||||||
pub position:Planar64Vec3,//I64 where 2^32 = 1 u
|
pub position:Planar64Vec3,//I64 where 2^32 = 1 u
|
||||||
pub velocity:Planar64Vec3,//I64 where 2^32 = 1 u/s
|
pub velocity:Planar64Vec3,//I64 where 2^32 = 1 u/s
|
||||||
@ -124,13 +124,13 @@ struct ContactMoveState{
|
|||||||
}
|
}
|
||||||
impl TransientAcceleration{
|
impl TransientAcceleration{
|
||||||
fn with_target_diff(target_diff:Planar64Vec3,accel:Planar64,time:Time)->Self{
|
fn with_target_diff(target_diff:Planar64Vec3,accel:Planar64,time:Time)->Self{
|
||||||
if target_diff==Planar64Vec3::ZERO{
|
if target_diff==vec3::ZERO{
|
||||||
TransientAcceleration::Reached
|
TransientAcceleration::Reached
|
||||||
}else{
|
}else{
|
||||||
//normal friction acceleration is clippedAcceleration.dot(normal)*friction
|
//normal friction acceleration is clippedAcceleration.dot(normal)*friction
|
||||||
TransientAcceleration::Reachable{
|
TransientAcceleration::Reachable{
|
||||||
acceleration:target_diff.with_length(accel),
|
acceleration:target_diff.with_length(accel).divide().fix_1(),
|
||||||
time:time+Time::from(target_diff.length()/accel)
|
time:time+Time::from((target_diff.length()/accel).divide().fix_1())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,7 +147,7 @@ impl TransientAcceleration{
|
|||||||
}
|
}
|
||||||
fn acceleration(&self)->Planar64Vec3{
|
fn acceleration(&self)->Planar64Vec3{
|
||||||
match self{
|
match self{
|
||||||
TransientAcceleration::Reached=>Planar64Vec3::ZERO,
|
TransientAcceleration::Reached=>vec3::ZERO,
|
||||||
&TransientAcceleration::Reachable{acceleration,time:_}=>acceleration,
|
&TransientAcceleration::Reachable{acceleration,time:_}=>acceleration,
|
||||||
&TransientAcceleration::Unreachable{acceleration}=>acceleration,
|
&TransientAcceleration::Unreachable{acceleration}=>acceleration,
|
||||||
}
|
}
|
||||||
@ -158,7 +158,7 @@ impl ContactMoveState{
|
|||||||
Self{
|
Self{
|
||||||
target:TransientAcceleration::ground(walk_settings,body,gravity,target_velocity),
|
target:TransientAcceleration::ground(walk_settings,body,gravity,target_velocity),
|
||||||
contact,
|
contact,
|
||||||
jump_direction:JumpDirection::Exactly(Planar64Vec3::Y),
|
jump_direction:JumpDirection::Exactly(vec3::Y),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn ladder(ladder_settings:&gameplay_style::LadderSettings,body:&Body,gravity:Planar64Vec3,target_velocity:Planar64Vec3,contact:ContactCollision)->Self{
|
fn ladder(ladder_settings:&gameplay_style::LadderSettings,body:&Body,gravity:Planar64Vec3,target_velocity:Planar64Vec3,contact:ContactCollision)->Self{
|
||||||
@ -296,7 +296,7 @@ impl PhysicsCamera{
|
|||||||
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)
|
mat3::from_rotation_yx(ax,ay)
|
||||||
}
|
}
|
||||||
fn rotation(&self)->Planar64Mat3{
|
fn rotation(&self)->Planar64Mat3{
|
||||||
self.get_rotation(self.clamped_mouse_pos)
|
self.get_rotation(self.clamped_mouse_pos)
|
||||||
@ -306,7 +306,7 @@ impl PhysicsCamera{
|
|||||||
}
|
}
|
||||||
fn get_rotation_y(&self,mouse_pos_x:i32)->Planar64Mat3{
|
fn get_rotation_y(&self,mouse_pos_x:i32)->Planar64Mat3{
|
||||||
let ax=-self.sensitivity.x.mul_int(mouse_pos_x as i64);
|
let ax=-self.sensitivity.x.mul_int(mouse_pos_x as i64);
|
||||||
Planar64Mat3::from_rotation_y(Angle32::wrap_from_i64(ax))
|
mat3::from_rotation_y(Angle32::wrap_from_i64(ax))
|
||||||
}
|
}
|
||||||
fn rotation_y(&self)->Planar64Mat3{
|
fn rotation_y(&self)->Planar64Mat3{
|
||||||
self.get_rotation_y(self.clamped_mouse_pos.x)
|
self.get_rotation_y(self.clamped_mouse_pos.x)
|
||||||
@ -438,7 +438,7 @@ impl StyleHelper for StyleModifiers{
|
|||||||
|
|
||||||
fn get_control_dir(&self,controls:Controls)->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 = vec3::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.intersection(self.controls_mask);
|
let controls=controls.intersection(self.controls_mask);
|
||||||
if controls.contains(Controls::MoveForward){
|
if controls.contains(Controls::MoveForward){
|
||||||
@ -463,19 +463,19 @@ impl StyleHelper for StyleModifiers{
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_y_control_dir(&self,camera:&PhysicsCamera,controls:Controls)->Planar64Vec3{
|
fn get_y_control_dir(&self,camera:&PhysicsCamera,controls:Controls)->Planar64Vec3{
|
||||||
camera.rotation_y()*self.get_control_dir(controls)
|
(camera.rotation_y()*self.get_control_dir(controls)).fix_1()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,controls:Controls)->Planar64Vec3{
|
fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,controls:Controls)->Planar64Vec3{
|
||||||
//don't interpolate this! discrete mouse movement, constant acceleration
|
//don't interpolate this! discrete mouse movement, constant acceleration
|
||||||
camera.rotation()*self.get_control_dir(controls)
|
(camera.rotation()*self.get_control_dir(controls)).fix_1()
|
||||||
}
|
}
|
||||||
fn calculate_mesh(&self)->HitboxMesh{
|
fn calculate_mesh(&self)->HitboxMesh{
|
||||||
let mesh=match self.hitbox.mesh{
|
let mesh=match self.hitbox.mesh{
|
||||||
gameplay_style::HitboxMesh::Box=>PhysicsMesh::unit_cube(),
|
gameplay_style::HitboxMesh::Box=>PhysicsMesh::unit_cube(),
|
||||||
gameplay_style::HitboxMesh::Cylinder=>PhysicsMesh::unit_cylinder(),
|
gameplay_style::HitboxMesh::Cylinder=>PhysicsMesh::unit_cylinder(),
|
||||||
};
|
};
|
||||||
let transform=Planar64Mat3::from_diagonal(self.hitbox.halfsize).extend(Planar64Vec3::ZERO);
|
let transform=mat3::from_diagonal(self.hitbox.halfsize).extend_column(vec3::ZERO);
|
||||||
HitboxMesh::new(mesh,transform)
|
HitboxMesh::new(mesh,transform)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -491,7 +491,7 @@ impl MoveState{
|
|||||||
//call this after state.move_state is changed
|
//call this after state.move_state is changed
|
||||||
fn apply_enum(&self,body:&mut Body,touching:&TouchingState,models:&PhysicsModels,hitbox_mesh:&HitboxMesh,style:&StyleModifiers,camera:&PhysicsCamera,input_state:&InputState){
|
fn apply_enum(&self,body:&mut Body,touching:&TouchingState,models:&PhysicsModels,hitbox_mesh:&HitboxMesh,style:&StyleModifiers,camera:&PhysicsCamera,input_state:&InputState){
|
||||||
match self{
|
match self{
|
||||||
MoveState::Fly=>body.acceleration=Planar64Vec3::ZERO,
|
MoveState::Fly=>body.acceleration=vec3::ZERO,
|
||||||
MoveState::Air=>{
|
MoveState::Air=>{
|
||||||
//calculate base acceleration
|
//calculate base acceleration
|
||||||
let a=touching.base_acceleration(models,style,camera,input_state);
|
let a=touching.base_acceleration(models,style,camera,input_state);
|
||||||
@ -766,7 +766,7 @@ impl TouchingState{
|
|||||||
let contacts=self.contacts.iter().map(|contact|{
|
let contacts=self.contacts.iter().map(|contact|{
|
||||||
let n=contact_normal(models,hitbox_mesh,contact);
|
let n=contact_normal(models,hitbox_mesh,contact);
|
||||||
crate::push_solve::Contact{
|
crate::push_solve::Contact{
|
||||||
position:Planar64Vec3::ZERO,
|
position:vec3::ZERO,
|
||||||
velocity:n,
|
velocity:n,
|
||||||
normal:n,
|
normal:n,
|
||||||
}
|
}
|
||||||
@ -780,7 +780,7 @@ impl TouchingState{
|
|||||||
let contacts=self.contacts.iter().map(|contact|{
|
let contacts=self.contacts.iter().map(|contact|{
|
||||||
let n=contact_normal(models,hitbox_mesh,contact);
|
let n=contact_normal(models,hitbox_mesh,contact);
|
||||||
crate::push_solve::Contact{
|
crate::push_solve::Contact{
|
||||||
position:Planar64Vec3::ZERO,
|
position:vec3::ZERO,
|
||||||
velocity:n,
|
velocity:n,
|
||||||
normal:n,
|
normal:n,
|
||||||
}
|
}
|
||||||
@ -791,7 +791,7 @@ impl TouchingState{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn predict_collision_end(&self,collector:&mut instruction::InstructionCollector<PhysicsInternalInstruction>,models:&PhysicsModels,hitbox_mesh:&HitboxMesh,body:&Body,time:Time){
|
fn predict_collision_end(&self,collector:&mut instruction::InstructionCollector<PhysicsInternalInstruction>,models:&PhysicsModels,hitbox_mesh:&HitboxMesh,body:&Body,time:Time){
|
||||||
let relative_body=VirtualBody::relative(&Body::default(),body).body(time);
|
let relative_body=VirtualBody::relative(&Body::ZERO,body).body(time);
|
||||||
for contact in &self.contacts{
|
for contact in &self.contacts{
|
||||||
//detect face slide off
|
//detect face slide off
|
||||||
let model_mesh=models.contact_mesh(contact);
|
let model_mesh=models.contact_mesh(contact);
|
||||||
@ -822,6 +822,7 @@ impl TouchingState{
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Body{
|
impl Body{
|
||||||
|
pub const ZERO:Self=Self::new(vec3::ZERO,vec3::ZERO,vec3::ZERO,Time::ZERO);
|
||||||
pub const fn new(position:Planar64Vec3,velocity:Planar64Vec3,acceleration:Planar64Vec3,time:Time)->Self{
|
pub const fn new(position:Planar64Vec3,velocity:Planar64Vec3,acceleration:Planar64Vec3,time:Time)->Self{
|
||||||
Self{
|
Self{
|
||||||
position,
|
position,
|
||||||
@ -832,11 +833,13 @@ impl Body{
|
|||||||
}
|
}
|
||||||
pub fn extrapolated_position(&self,time:Time)->Planar64Vec3{
|
pub fn extrapolated_position(&self,time:Time)->Planar64Vec3{
|
||||||
let dt=time-self.time;
|
let dt=time-self.time;
|
||||||
self.position+self.velocity*dt+self.acceleration*(dt*dt/2)
|
self.position
|
||||||
|
+(self.velocity*dt).map(|elem|elem.divide().fix_1())
|
||||||
|
+self.acceleration.map(|elem|(dt*dt*elem/2).divide().fix_1())
|
||||||
}
|
}
|
||||||
pub fn extrapolated_velocity(&self,time:Time)->Planar64Vec3{
|
pub fn extrapolated_velocity(&self,time:Time)->Planar64Vec3{
|
||||||
let dt=time-self.time;
|
let dt=time-self.time;
|
||||||
self.velocity+self.acceleration*dt
|
self.velocity+(self.acceleration*dt).map(|elem|elem.divide().fix_1())
|
||||||
}
|
}
|
||||||
pub fn advance_time(&mut self,time:Time){
|
pub fn advance_time(&mut self,time:Time){
|
||||||
self.position=self.extrapolated_position(time);
|
self.position=self.extrapolated_position(time);
|
||||||
@ -844,8 +847,8 @@ impl Body{
|
|||||||
self.time=time;
|
self.time=time;
|
||||||
}
|
}
|
||||||
pub fn infinity_dir(&self)->Option<Planar64Vec3>{
|
pub fn infinity_dir(&self)->Option<Planar64Vec3>{
|
||||||
if self.velocity==Planar64Vec3::ZERO{
|
if self.velocity==vec3::ZERO{
|
||||||
if self.acceleration==Planar64Vec3::ZERO{
|
if self.acceleration==vec3::ZERO{
|
||||||
None
|
None
|
||||||
}else{
|
}else{
|
||||||
Some(self.acceleration)
|
Some(self.acceleration)
|
||||||
@ -859,19 +862,19 @@ impl Body{
|
|||||||
aabb.grow(self.extrapolated_position(t1));
|
aabb.grow(self.extrapolated_position(t1));
|
||||||
//v+a*t==0
|
//v+a*t==0
|
||||||
//goober code
|
//goober code
|
||||||
if self.acceleration.x!=Planar64::ZERO{
|
if !self.acceleration.x.is_zero(){
|
||||||
let t=Time::from(-self.velocity.x/self.acceleration.x);
|
let t=Time::from(-self.velocity.x/self.acceleration.x);
|
||||||
if t0<t&&t<t1{
|
if t0<t&&t<t1{
|
||||||
aabb.grow(self.extrapolated_position(t));
|
aabb.grow(self.extrapolated_position(t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.acceleration.y!=Planar64::ZERO{
|
if !self.acceleration.y.is_zero(){
|
||||||
let t=Time::from(-self.velocity.y/self.acceleration.y);
|
let t=Time::from(-self.velocity.y/self.acceleration.y);
|
||||||
if t0<t&&t<t1{
|
if t0<t&&t<t1{
|
||||||
aabb.grow(self.extrapolated_position(t));
|
aabb.grow(self.extrapolated_position(t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.acceleration.z!=Planar64::ZERO{
|
if !self.acceleration.z.is_zero(){
|
||||||
let t=Time::from(-self.velocity.z/self.acceleration.z);
|
let t=Time::from(-self.velocity.z/self.acceleration.z);
|
||||||
if t0<t&&t<t1{
|
if t0<t&&t<t1{
|
||||||
aabb.grow(self.extrapolated_position(t));
|
aabb.grow(self.extrapolated_position(t));
|
||||||
@ -947,7 +950,7 @@ pub struct PhysicsData{
|
|||||||
impl Default for PhysicsState{
|
impl Default for PhysicsState{
|
||||||
fn default()->Self{
|
fn default()->Self{
|
||||||
Self{
|
Self{
|
||||||
body:Body::new(Planar64Vec3::int(0,50,0),Planar64Vec3::int(0,0,0),Planar64Vec3::int(0,-100,0),Time::ZERO),
|
body:Body::new(vec3::int(0,50,0),vec3::int(0,0,0),vec3::int(0,-100,0),Time::ZERO),
|
||||||
time:Time::ZERO,
|
time:Time::ZERO,
|
||||||
style:StyleModifiers::default(),
|
style:StyleModifiers::default(),
|
||||||
touching:TouchingState::default(),
|
touching:TouchingState::default(),
|
||||||
@ -1339,12 +1342,12 @@ fn set_velocity_cull(body:&mut Body,touching:&mut TouchingState,models:&PhysicsM
|
|||||||
let mut culled=false;
|
let mut culled=false;
|
||||||
touching.contacts.retain(|contact|{
|
touching.contacts.retain(|contact|{
|
||||||
let n=contact_normal(models,hitbox_mesh,contact);
|
let n=contact_normal(models,hitbox_mesh,contact);
|
||||||
let r=n.dot(v)<=Planar64::ZERO;
|
let r=n.dot(v).is_positive();
|
||||||
if !r{
|
if r{
|
||||||
culled=true;
|
culled=true;
|
||||||
println!("set_velocity_cull contact={:?}",contact);
|
println!("set_velocity_cull contact={:?}",contact);
|
||||||
}
|
}
|
||||||
r
|
!r
|
||||||
});
|
});
|
||||||
set_velocity(body,touching,models,hitbox_mesh,v);
|
set_velocity(body,touching,models,hitbox_mesh,v);
|
||||||
culled
|
culled
|
||||||
@ -1358,12 +1361,12 @@ fn set_acceleration_cull(body:&mut Body,touching:&mut TouchingState,models:&Phys
|
|||||||
let mut culled=false;
|
let mut culled=false;
|
||||||
touching.contacts.retain(|contact|{
|
touching.contacts.retain(|contact|{
|
||||||
let n=contact_normal(models,hitbox_mesh,contact);
|
let n=contact_normal(models,hitbox_mesh,contact);
|
||||||
let r=n.dot(a)<=Planar64::ZERO;
|
let r=n.dot(a).is_positive();
|
||||||
if !r{
|
if r{
|
||||||
culled=true;
|
culled=true;
|
||||||
println!("set_acceleration_cull contact={:?}",contact);
|
println!("set_acceleration_cull contact={:?}",contact);
|
||||||
}
|
}
|
||||||
r
|
!r
|
||||||
});
|
});
|
||||||
set_acceleration(body,touching,models,hitbox_mesh,a);
|
set_acceleration(body,touching,models,hitbox_mesh,a);
|
||||||
culled
|
culled
|
||||||
@ -1501,7 +1504,7 @@ fn run_teleport_behaviour(
|
|||||||
}
|
}
|
||||||
if let Some(&gameplay_attributes::Wormhole{destination_model})=wormhole{
|
if let Some(&gameplay_attributes::Wormhole{destination_model})=wormhole{
|
||||||
if let (Some(origin),Some(destination))=(models.get_model_transform(model_id),models.get_model_transform(destination_model)){
|
if let (Some(origin),Some(destination))=(models.get_model_transform(model_id),models.get_model_transform(destination_model)){
|
||||||
let point=body.position-origin.vertex.translation+destination.vertex.translation;
|
let point=body.position-origin.vertex.col(3)+destination.vertex.col(3);
|
||||||
//TODO: camera angles
|
//TODO: camera angles
|
||||||
teleport(point,move_state,body,touching,run,mode_state,mode,models,hitbox_mesh,bvh,style,camera,input_state,time);
|
teleport(point,move_state,body,touching,run,mode_state,mode,models,hitbox_mesh,bvh,style,camera,input_state,time);
|
||||||
}
|
}
|
||||||
@ -1543,7 +1546,7 @@ fn collision_start_contact(
|
|||||||
//kill v
|
//kill v
|
||||||
//actually you could do this with a booster attribute :thinking:
|
//actually you could do this with a booster attribute :thinking:
|
||||||
//it's a little bit different because maybe you want to chain ladders together
|
//it's a little bit different because maybe you want to chain ladders together
|
||||||
set_velocity(body,touching,models,hitbox_mesh,Planar64Vec3::ZERO);//model.velocity
|
set_velocity(body,touching,models,hitbox_mesh,vec3::ZERO);//model.velocity
|
||||||
}
|
}
|
||||||
//ladder walkstate
|
//ladder walkstate
|
||||||
let (gravity,target_velocity)=ladder_things(ladder_settings,&contact,touching,models,hitbox_mesh,style,camera,input_state);
|
let (gravity,target_velocity)=ladder_things(ladder_settings,&contact,touching,models,hitbox_mesh,style,camera,input_state);
|
||||||
@ -1733,9 +1736,9 @@ fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:Tim
|
|||||||
if strafe_settings.activates(controls){
|
if strafe_settings.activates(controls){
|
||||||
let masked_controls=strafe_settings.mask(controls);
|
let masked_controls=strafe_settings.mask(controls);
|
||||||
let control_dir=state.style.get_control_dir(masked_controls);
|
let control_dir=state.style.get_control_dir(masked_controls);
|
||||||
if control_dir!=Planar64Vec3::ZERO{
|
if control_dir!=vec3::ZERO{
|
||||||
let camera_mat=state.camera.simulate_move_rotation_y(state.input_state.lerp_delta(state.time).x);
|
let camera_mat=state.camera.simulate_move_rotation_y(state.input_state.lerp_delta(state.time).x);
|
||||||
if let Some(ticked_velocity)=strafe_settings.tick_velocity(state.body.velocity,(camera_mat*control_dir).with_length(Planar64::ONE)){
|
if let Some(ticked_velocity)=strafe_settings.tick_velocity(state.body.velocity,(camera_mat*control_dir).with_length(Planar64::ONE).divide().fix_1()){
|
||||||
//this is wrong but will work ig
|
//this is wrong but will work ig
|
||||||
//need to note which push planes activate in push solve and keep those
|
//need to note which push planes activate in push solve and keep those
|
||||||
state.cull_velocity(data,ticked_velocity);
|
state.cull_velocity(data,ticked_velocity);
|
||||||
@ -1759,7 +1762,7 @@ fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:Tim
|
|||||||
//we know that the acceleration is precisely zero because the walk target is known to be reachable
|
//we know that the acceleration is precisely zero because the walk target is known to be reachable
|
||||||
//which means that gravity can be fully cancelled
|
//which means that gravity can be fully cancelled
|
||||||
//ignore moving platforms for now
|
//ignore moving platforms for now
|
||||||
set_acceleration(&mut state.body,&state.touching,&data.models,&data.hitbox_mesh,Planar64Vec3::ZERO);
|
set_acceleration(&mut state.body,&state.touching,&data.models,&data.hitbox_mesh,vec3::ZERO);
|
||||||
walk_state.target=TransientAcceleration::Reached;
|
walk_state.target=TransientAcceleration::Reached;
|
||||||
},
|
},
|
||||||
//you are not supposed to reach an unreachable walk target!
|
//you are not supposed to reach an unreachable walk target!
|
||||||
@ -1852,11 +1855,11 @@ fn atomic_input_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:TimedI
|
|||||||
//TODO: spawn at the bottom of the start zone plus the hitbox size
|
//TODO: spawn at the bottom of the start zone plus the hitbox size
|
||||||
//TODO: set camera andles to face the same way as the start zone
|
//TODO: set camera andles to face the same way as the start zone
|
||||||
data.models.get_model_transform(mode.get_start().into()).map(|transform|
|
data.models.get_model_transform(mode.get_start().into()).map(|transform|
|
||||||
transform.vertex.translation
|
transform.vertex.col(3)
|
||||||
)
|
)
|
||||||
).unwrap_or(Planar64Vec3::ZERO);
|
).unwrap_or(vec3::ZERO);
|
||||||
set_position(spawn_point,&mut state.move_state,&mut state.body,&mut state.touching,&mut state.run,&mut state.mode_state,mode,&data.models,&data.hitbox_mesh,&data.bvh,&state.style,&state.camera,&state.input_state,state.time);
|
set_position(spawn_point,&mut state.move_state,&mut state.body,&mut state.touching,&mut state.run,&mut state.mode_state,mode,&data.models,&data.hitbox_mesh,&data.bvh,&state.style,&state.camera,&state.input_state,state.time);
|
||||||
set_velocity(&mut state.body,&state.touching,&data.models,&data.hitbox_mesh,Planar64Vec3::ZERO);
|
set_velocity(&mut state.body,&state.touching,&data.models,&data.hitbox_mesh,vec3::ZERO);
|
||||||
state.set_move_state(data,MoveState::Air);
|
state.set_move_state(data,MoveState::Air);
|
||||||
b_refresh_walk_target=false;
|
b_refresh_walk_target=false;
|
||||||
}
|
}
|
||||||
@ -1919,9 +1922,10 @@ fn atomic_input_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:TimedI
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test{
|
mod test{
|
||||||
|
use strafesnet_common::integer::{vec3::{self,int as int3},mat3};
|
||||||
use super::*;
|
use super::*;
|
||||||
fn test_collision_axis_aligned(relative_body:Body,expected_collision_time:Option<Time>){
|
fn test_collision_axis_aligned(relative_body:Body,expected_collision_time:Option<Time>){
|
||||||
let h0=HitboxMesh::new(PhysicsMesh::unit_cube(),integer::Planar64Affine3::new(Planar64Mat3::from_diagonal(Planar64Vec3::int(5,1,5)/2),Planar64Vec3::ZERO));
|
let h0=HitboxMesh::new(PhysicsMesh::unit_cube(),mat3::from_diagonal(int3(5,1,5)>>1).extend_column(vec3::ZERO));
|
||||||
let h1=StyleModifiers::roblox_bhop().calculate_mesh();
|
let h1=StyleModifiers::roblox_bhop().calculate_mesh();
|
||||||
let hitbox_mesh=h1.transformed_mesh();
|
let hitbox_mesh=h1.transformed_mesh();
|
||||||
let platform_mesh=h0.transformed_mesh();
|
let platform_mesh=h0.transformed_mesh();
|
||||||
@ -1931,14 +1935,11 @@ mod test{
|
|||||||
}
|
}
|
||||||
fn test_collision_rotated(relative_body:Body,expected_collision_time:Option<Time>){
|
fn test_collision_rotated(relative_body:Body,expected_collision_time:Option<Time>){
|
||||||
let h0=HitboxMesh::new(PhysicsMesh::unit_cube(),
|
let h0=HitboxMesh::new(PhysicsMesh::unit_cube(),
|
||||||
integer::Planar64Affine3::new(
|
integer::Planar64Mat3::from_rows([
|
||||||
integer::Planar64Mat3::from_cols(
|
int3(5,0,1)>>1,
|
||||||
Planar64Vec3::int(5,0,1)/2,
|
int3(0,1,0)>>1,
|
||||||
Planar64Vec3::int(0,1,0)/2,
|
int3(-1,0,5)>>1,
|
||||||
Planar64Vec3::int(-1,0,5)/2,
|
]).extend_column(vec3::ZERO),
|
||||||
),
|
|
||||||
Planar64Vec3::ZERO,
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
let h1=StyleModifiers::roblox_bhop().calculate_mesh();
|
let h1=StyleModifiers::roblox_bhop().calculate_mesh();
|
||||||
let hitbox_mesh=h1.transformed_mesh();
|
let hitbox_mesh=h1.transformed_mesh();
|
||||||
@ -1954,180 +1955,180 @@ mod test{
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_collision_degenerate(){
|
fn test_collision_degenerate(){
|
||||||
test_collision(Body::new(
|
test_collision(Body::new(
|
||||||
Planar64Vec3::int(0,5,0),
|
int3(0,5,0),
|
||||||
Planar64Vec3::int(0,-1,0),
|
int3(0,-1,0),
|
||||||
Planar64Vec3::ZERO,
|
vec3::ZERO,
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
),Some(Time::from_secs(2)));
|
),Some(Time::from_secs(2)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collision_degenerate_east(){
|
fn test_collision_degenerate_east(){
|
||||||
test_collision(Body::new(
|
test_collision(Body::new(
|
||||||
Planar64Vec3::int(3,5,0),
|
int3(3,5,0),
|
||||||
Planar64Vec3::int(0,-1,0),
|
int3(0,-1,0),
|
||||||
Planar64Vec3::ZERO,
|
vec3::ZERO,
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
),Some(Time::from_secs(2)));
|
),Some(Time::from_secs(2)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collision_degenerate_south(){
|
fn test_collision_degenerate_south(){
|
||||||
test_collision(Body::new(
|
test_collision(Body::new(
|
||||||
Planar64Vec3::int(0,5,3),
|
int3(0,5,3),
|
||||||
Planar64Vec3::int(0,-1,0),
|
int3(0,-1,0),
|
||||||
Planar64Vec3::ZERO,
|
vec3::ZERO,
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
),Some(Time::from_secs(2)));
|
),Some(Time::from_secs(2)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collision_degenerate_west(){
|
fn test_collision_degenerate_west(){
|
||||||
test_collision(Body::new(
|
test_collision(Body::new(
|
||||||
Planar64Vec3::int(-3,5,0),
|
int3(-3,5,0),
|
||||||
Planar64Vec3::int(0,-1,0),
|
int3(0,-1,0),
|
||||||
Planar64Vec3::ZERO,
|
vec3::ZERO,
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
),Some(Time::from_secs(2)));
|
),Some(Time::from_secs(2)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collision_degenerate_north(){
|
fn test_collision_degenerate_north(){
|
||||||
test_collision(Body::new(
|
test_collision(Body::new(
|
||||||
Planar64Vec3::int(0,5,-3),
|
int3(0,5,-3),
|
||||||
Planar64Vec3::int(0,-1,0),
|
int3(0,-1,0),
|
||||||
Planar64Vec3::ZERO,
|
vec3::ZERO,
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
),Some(Time::from_secs(2)));
|
),Some(Time::from_secs(2)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collision_parabola_edge_east_from_west(){
|
fn test_collision_parabola_edge_east_from_west(){
|
||||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||||
Planar64Vec3::int(3,3,0),
|
int3(3,3,0),
|
||||||
Planar64Vec3::int(100,-1,0),
|
int3(100,-1,0),
|
||||||
Planar64Vec3::int(0,-1,0),
|
int3(0,-1,0),
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collision_parabola_edge_south_from_north(){
|
fn test_collision_parabola_edge_south_from_north(){
|
||||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||||
Planar64Vec3::int(0,3,3),
|
int3(0,3,3),
|
||||||
Planar64Vec3::int(0,-1,100),
|
int3(0,-1,100),
|
||||||
Planar64Vec3::int(0,-1,0),
|
int3(0,-1,0),
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collision_parabola_edge_west_from_east(){
|
fn test_collision_parabola_edge_west_from_east(){
|
||||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||||
Planar64Vec3::int(-3,3,0),
|
int3(-3,3,0),
|
||||||
Planar64Vec3::int(-100,-1,0),
|
int3(-100,-1,0),
|
||||||
Planar64Vec3::int(0,-1,0),
|
int3(0,-1,0),
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collision_parabola_edge_north_from_south(){
|
fn test_collision_parabola_edge_north_from_south(){
|
||||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||||
Planar64Vec3::int(0,3,-3),
|
int3(0,3,-3),
|
||||||
Planar64Vec3::int(0,-1,-100),
|
int3(0,-1,-100),
|
||||||
Planar64Vec3::int(0,-1,0),
|
int3(0,-1,0),
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collision_parabola_edge_north_from_ne(){
|
fn test_collision_parabola_edge_north_from_ne(){
|
||||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||||
Planar64Vec3::int(0,6,-7)/2,
|
int3(0,6,-7)>>1,
|
||||||
Planar64Vec3::int(-10,-1,1),
|
int3(-10,-1,1),
|
||||||
Planar64Vec3::int(0,-1,0),
|
int3(0,-1,0),
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collision_parabola_edge_north_from_nw(){
|
fn test_collision_parabola_edge_north_from_nw(){
|
||||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||||
Planar64Vec3::int(0,6,-7)/2,
|
int3(0,6,-7)>>1,
|
||||||
Planar64Vec3::int(10,-1,1),
|
int3(10,-1,1),
|
||||||
Planar64Vec3::int(0,-1,0),
|
int3(0,-1,0),
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collision_parabola_edge_east_from_se(){
|
fn test_collision_parabola_edge_east_from_se(){
|
||||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||||
Planar64Vec3::int(7,6,0)/2,
|
int3(7,6,0)>>1,
|
||||||
Planar64Vec3::int(-1,-1,-10),
|
int3(-1,-1,-10),
|
||||||
Planar64Vec3::int(0,-1,0),
|
int3(0,-1,0),
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collision_parabola_edge_east_from_ne(){
|
fn test_collision_parabola_edge_east_from_ne(){
|
||||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||||
Planar64Vec3::int(7,6,0)/2,
|
int3(7,6,0)>>1,
|
||||||
Planar64Vec3::int(-1,-1,10),
|
int3(-1,-1,10),
|
||||||
Planar64Vec3::int(0,-1,0),
|
int3(0,-1,0),
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collision_parabola_edge_south_from_se(){
|
fn test_collision_parabola_edge_south_from_se(){
|
||||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||||
Planar64Vec3::int(0,6,7)/2,
|
int3(0,6,7)>>1,
|
||||||
Planar64Vec3::int(-10,-1,-1),
|
int3(-10,-1,-1),
|
||||||
Planar64Vec3::int(0,-1,0),
|
int3(0,-1,0),
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collision_parabola_edge_south_from_sw(){
|
fn test_collision_parabola_edge_south_from_sw(){
|
||||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||||
Planar64Vec3::int(0,6,7)/2,
|
int3(0,6,7)>>1,
|
||||||
Planar64Vec3::int(10,-1,-1),
|
int3(10,-1,-1),
|
||||||
Planar64Vec3::int(0,-1,0),
|
int3(0,-1,0),
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collision_parabola_edge_west_from_se(){
|
fn test_collision_parabola_edge_west_from_se(){
|
||||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||||
Planar64Vec3::int(-7,6,0)/2,
|
int3(-7,6,0)>>1,
|
||||||
Planar64Vec3::int(1,-1,-10),
|
int3(1,-1,-10),
|
||||||
Planar64Vec3::int(0,-1,0),
|
int3(0,-1,0),
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collision_parabola_edge_west_from_ne(){
|
fn test_collision_parabola_edge_west_from_ne(){
|
||||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||||
Planar64Vec3::int(-7,6,0)/2,
|
int3(-7,6,0)>>1,
|
||||||
Planar64Vec3::int(1,-1,10),
|
int3(1,-1,10),
|
||||||
Planar64Vec3::int(0,-1,0),
|
int3(0,-1,0),
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collision_oblique(){
|
fn test_collision_oblique(){
|
||||||
test_collision(Body::new(
|
test_collision(Body::new(
|
||||||
Planar64Vec3::int(0,5,0),
|
int3(0,5,0),
|
||||||
Planar64Vec3::int(1,-64,2)/64,
|
int3(1,-64,2)>>6,// /64
|
||||||
Planar64Vec3::ZERO,
|
vec3::ZERO,
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
),Some(Time::from_secs(2)));
|
),Some(Time::from_secs(2)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn zoom_hit_nothing(){
|
fn zoom_hit_nothing(){
|
||||||
test_collision(Body::new(
|
test_collision(Body::new(
|
||||||
Planar64Vec3::int(0,10,0),
|
int3(0,10,0),
|
||||||
Planar64Vec3::int(1,0,0),
|
int3(1,0,0),
|
||||||
Planar64Vec3::int(0,1,0),
|
int3(0,1,0),
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
),None);
|
),None);
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn already_inside_hit_nothing(){
|
fn already_inside_hit_nothing(){
|
||||||
test_collision(Body::new(
|
test_collision(Body::new(
|
||||||
Planar64Vec3::ZERO,
|
vec3::ZERO,
|
||||||
Planar64Vec3::int(1,0,0),
|
int3(1,0,0),
|
||||||
Planar64Vec3::int(0,1,0),
|
int3(0,1,0),
|
||||||
Time::ZERO
|
Time::ZERO
|
||||||
),None);
|
),None);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user