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::controls_bitflag::Controls;
|
||||
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;
|
||||
|
||||
//external influence
|
||||
@ -36,7 +36,7 @@ enum PhysicsInstruction{
|
||||
Input(PhysicsInputInstruction),
|
||||
}
|
||||
|
||||
#[derive(Clone,Copy,Debug,Default,Hash)]
|
||||
#[derive(Clone,Copy,Debug,Hash)]
|
||||
pub struct Body{
|
||||
pub position:Planar64Vec3,//I64 where 2^32 = 1 u
|
||||
pub velocity:Planar64Vec3,//I64 where 2^32 = 1 u/s
|
||||
@ -124,13 +124,13 @@ struct ContactMoveState{
|
||||
}
|
||||
impl TransientAcceleration{
|
||||
fn with_target_diff(target_diff:Planar64Vec3,accel:Planar64,time:Time)->Self{
|
||||
if target_diff==Planar64Vec3::ZERO{
|
||||
if target_diff==vec3::ZERO{
|
||||
TransientAcceleration::Reached
|
||||
}else{
|
||||
//normal friction acceleration is clippedAcceleration.dot(normal)*friction
|
||||
TransientAcceleration::Reachable{
|
||||
acceleration:target_diff.with_length(accel),
|
||||
time:time+Time::from(target_diff.length()/accel)
|
||||
acceleration:target_diff.with_length(accel).divide().fix_1(),
|
||||
time:time+Time::from((target_diff.length()/accel).divide().fix_1())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -147,7 +147,7 @@ impl TransientAcceleration{
|
||||
}
|
||||
fn acceleration(&self)->Planar64Vec3{
|
||||
match self{
|
||||
TransientAcceleration::Reached=>Planar64Vec3::ZERO,
|
||||
TransientAcceleration::Reached=>vec3::ZERO,
|
||||
&TransientAcceleration::Reachable{acceleration,time:_}=>acceleration,
|
||||
&TransientAcceleration::Unreachable{acceleration}=>acceleration,
|
||||
}
|
||||
@ -158,7 +158,7 @@ impl ContactMoveState{
|
||||
Self{
|
||||
target:TransientAcceleration::ground(walk_settings,body,gravity,target_velocity),
|
||||
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{
|
||||
@ -296,7 +296,7 @@ impl PhysicsCamera{
|
||||
let ay=Angle32::clamp_from_i64(a.y)
|
||||
//clamp to actual vertical cam 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{
|
||||
self.get_rotation(self.clamped_mouse_pos)
|
||||
@ -306,7 +306,7 @@ impl PhysicsCamera{
|
||||
}
|
||||
fn get_rotation_y(&self,mouse_pos_x:i32)->Planar64Mat3{
|
||||
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{
|
||||
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{
|
||||
//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
|
||||
let controls=controls.intersection(self.controls_mask);
|
||||
if controls.contains(Controls::MoveForward){
|
||||
@ -463,19 +463,19 @@ impl StyleHelper for StyleModifiers{
|
||||
}
|
||||
|
||||
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{
|
||||
//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{
|
||||
let mesh=match self.hitbox.mesh{
|
||||
gameplay_style::HitboxMesh::Box=>PhysicsMesh::unit_cube(),
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -491,7 +491,7 @@ impl MoveState{
|
||||
//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){
|
||||
match self{
|
||||
MoveState::Fly=>body.acceleration=Planar64Vec3::ZERO,
|
||||
MoveState::Fly=>body.acceleration=vec3::ZERO,
|
||||
MoveState::Air=>{
|
||||
//calculate base acceleration
|
||||
let a=touching.base_acceleration(models,style,camera,input_state);
|
||||
@ -766,7 +766,7 @@ impl TouchingState{
|
||||
let contacts=self.contacts.iter().map(|contact|{
|
||||
let n=contact_normal(models,hitbox_mesh,contact);
|
||||
crate::push_solve::Contact{
|
||||
position:Planar64Vec3::ZERO,
|
||||
position:vec3::ZERO,
|
||||
velocity:n,
|
||||
normal:n,
|
||||
}
|
||||
@ -780,7 +780,7 @@ impl TouchingState{
|
||||
let contacts=self.contacts.iter().map(|contact|{
|
||||
let n=contact_normal(models,hitbox_mesh,contact);
|
||||
crate::push_solve::Contact{
|
||||
position:Planar64Vec3::ZERO,
|
||||
position:vec3::ZERO,
|
||||
velocity: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){
|
||||
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{
|
||||
//detect face slide off
|
||||
let model_mesh=models.contact_mesh(contact);
|
||||
@ -822,6 +822,7 @@ impl TouchingState{
|
||||
}
|
||||
|
||||
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{
|
||||
Self{
|
||||
position,
|
||||
@ -832,11 +833,13 @@ impl Body{
|
||||
}
|
||||
pub fn extrapolated_position(&self,time:Time)->Planar64Vec3{
|
||||
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{
|
||||
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){
|
||||
self.position=self.extrapolated_position(time);
|
||||
@ -844,8 +847,8 @@ impl Body{
|
||||
self.time=time;
|
||||
}
|
||||
pub fn infinity_dir(&self)->Option<Planar64Vec3>{
|
||||
if self.velocity==Planar64Vec3::ZERO{
|
||||
if self.acceleration==Planar64Vec3::ZERO{
|
||||
if self.velocity==vec3::ZERO{
|
||||
if self.acceleration==vec3::ZERO{
|
||||
None
|
||||
}else{
|
||||
Some(self.acceleration)
|
||||
@ -859,19 +862,19 @@ impl Body{
|
||||
aabb.grow(self.extrapolated_position(t1));
|
||||
//v+a*t==0
|
||||
//goober code
|
||||
if self.acceleration.x!=Planar64::ZERO{
|
||||
if !self.acceleration.x.is_zero(){
|
||||
let t=Time::from(-self.velocity.x/self.acceleration.x);
|
||||
if t0<t&&t<t1{
|
||||
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);
|
||||
if t0<t&&t<t1{
|
||||
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);
|
||||
if t0<t&&t<t1{
|
||||
aabb.grow(self.extrapolated_position(t));
|
||||
@ -947,7 +950,7 @@ pub struct PhysicsData{
|
||||
impl Default for PhysicsState{
|
||||
fn default()->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,
|
||||
style:StyleModifiers::default(),
|
||||
touching:TouchingState::default(),
|
||||
@ -1339,12 +1342,12 @@ fn set_velocity_cull(body:&mut Body,touching:&mut TouchingState,models:&PhysicsM
|
||||
let mut culled=false;
|
||||
touching.contacts.retain(|contact|{
|
||||
let n=contact_normal(models,hitbox_mesh,contact);
|
||||
let r=n.dot(v)<=Planar64::ZERO;
|
||||
if !r{
|
||||
let r=n.dot(v).is_positive();
|
||||
if r{
|
||||
culled=true;
|
||||
println!("set_velocity_cull contact={:?}",contact);
|
||||
}
|
||||
r
|
||||
!r
|
||||
});
|
||||
set_velocity(body,touching,models,hitbox_mesh,v);
|
||||
culled
|
||||
@ -1358,12 +1361,12 @@ fn set_acceleration_cull(body:&mut Body,touching:&mut TouchingState,models:&Phys
|
||||
let mut culled=false;
|
||||
touching.contacts.retain(|contact|{
|
||||
let n=contact_normal(models,hitbox_mesh,contact);
|
||||
let r=n.dot(a)<=Planar64::ZERO;
|
||||
if !r{
|
||||
let r=n.dot(a).is_positive();
|
||||
if r{
|
||||
culled=true;
|
||||
println!("set_acceleration_cull contact={:?}",contact);
|
||||
}
|
||||
r
|
||||
!r
|
||||
});
|
||||
set_acceleration(body,touching,models,hitbox_mesh,a);
|
||||
culled
|
||||
@ -1501,7 +1504,7 @@ fn run_teleport_behaviour(
|
||||
}
|
||||
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)){
|
||||
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
|
||||
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
|
||||
//actually you could do this with a booster attribute :thinking:
|
||||
//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
|
||||
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){
|
||||
let masked_controls=strafe_settings.mask(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);
|
||||
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
|
||||
//need to note which push planes activate in push solve and keep those
|
||||
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
|
||||
//which means that gravity can be fully cancelled
|
||||
//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;
|
||||
},
|
||||
//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: set camera andles to face the same way as the start zone
|
||||
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_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);
|
||||
b_refresh_walk_target=false;
|
||||
}
|
||||
@ -1919,9 +1922,10 @@ fn atomic_input_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:TimedI
|
||||
|
||||
#[cfg(test)]
|
||||
mod test{
|
||||
use strafesnet_common::integer::{vec3::{self,int as int3},mat3};
|
||||
use super::*;
|
||||
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 hitbox_mesh=h1.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>){
|
||||
let h0=HitboxMesh::new(PhysicsMesh::unit_cube(),
|
||||
integer::Planar64Affine3::new(
|
||||
integer::Planar64Mat3::from_cols(
|
||||
Planar64Vec3::int(5,0,1)/2,
|
||||
Planar64Vec3::int(0,1,0)/2,
|
||||
Planar64Vec3::int(-1,0,5)/2,
|
||||
),
|
||||
Planar64Vec3::ZERO,
|
||||
)
|
||||
integer::Planar64Mat3::from_rows([
|
||||
int3(5,0,1)>>1,
|
||||
int3(0,1,0)>>1,
|
||||
int3(-1,0,5)>>1,
|
||||
]).extend_column(vec3::ZERO),
|
||||
);
|
||||
let h1=StyleModifiers::roblox_bhop().calculate_mesh();
|
||||
let hitbox_mesh=h1.transformed_mesh();
|
||||
@ -1954,180 +1955,180 @@ mod test{
|
||||
#[test]
|
||||
fn test_collision_degenerate(){
|
||||
test_collision(Body::new(
|
||||
Planar64Vec3::int(0,5,0),
|
||||
Planar64Vec3::int(0,-1,0),
|
||||
Planar64Vec3::ZERO,
|
||||
int3(0,5,0),
|
||||
int3(0,-1,0),
|
||||
vec3::ZERO,
|
||||
Time::ZERO
|
||||
),Some(Time::from_secs(2)));
|
||||
}
|
||||
#[test]
|
||||
fn test_collision_degenerate_east(){
|
||||
test_collision(Body::new(
|
||||
Planar64Vec3::int(3,5,0),
|
||||
Planar64Vec3::int(0,-1,0),
|
||||
Planar64Vec3::ZERO,
|
||||
int3(3,5,0),
|
||||
int3(0,-1,0),
|
||||
vec3::ZERO,
|
||||
Time::ZERO
|
||||
),Some(Time::from_secs(2)));
|
||||
}
|
||||
#[test]
|
||||
fn test_collision_degenerate_south(){
|
||||
test_collision(Body::new(
|
||||
Planar64Vec3::int(0,5,3),
|
||||
Planar64Vec3::int(0,-1,0),
|
||||
Planar64Vec3::ZERO,
|
||||
int3(0,5,3),
|
||||
int3(0,-1,0),
|
||||
vec3::ZERO,
|
||||
Time::ZERO
|
||||
),Some(Time::from_secs(2)));
|
||||
}
|
||||
#[test]
|
||||
fn test_collision_degenerate_west(){
|
||||
test_collision(Body::new(
|
||||
Planar64Vec3::int(-3,5,0),
|
||||
Planar64Vec3::int(0,-1,0),
|
||||
Planar64Vec3::ZERO,
|
||||
int3(-3,5,0),
|
||||
int3(0,-1,0),
|
||||
vec3::ZERO,
|
||||
Time::ZERO
|
||||
),Some(Time::from_secs(2)));
|
||||
}
|
||||
#[test]
|
||||
fn test_collision_degenerate_north(){
|
||||
test_collision(Body::new(
|
||||
Planar64Vec3::int(0,5,-3),
|
||||
Planar64Vec3::int(0,-1,0),
|
||||
Planar64Vec3::ZERO,
|
||||
int3(0,5,-3),
|
||||
int3(0,-1,0),
|
||||
vec3::ZERO,
|
||||
Time::ZERO
|
||||
),Some(Time::from_secs(2)));
|
||||
}
|
||||
#[test]
|
||||
fn test_collision_parabola_edge_east_from_west(){
|
||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
||||
Planar64Vec3::int(3,3,0),
|
||||
Planar64Vec3::int(100,-1,0),
|
||||
Planar64Vec3::int(0,-1,0),
|
||||
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||
int3(3,3,0),
|
||||
int3(100,-1,0),
|
||||
int3(0,-1,0),
|
||||
Time::ZERO
|
||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||
}
|
||||
#[test]
|
||||
fn test_collision_parabola_edge_south_from_north(){
|
||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
||||
Planar64Vec3::int(0,3,3),
|
||||
Planar64Vec3::int(0,-1,100),
|
||||
Planar64Vec3::int(0,-1,0),
|
||||
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||
int3(0,3,3),
|
||||
int3(0,-1,100),
|
||||
int3(0,-1,0),
|
||||
Time::ZERO
|
||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||
}
|
||||
#[test]
|
||||
fn test_collision_parabola_edge_west_from_east(){
|
||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
||||
Planar64Vec3::int(-3,3,0),
|
||||
Planar64Vec3::int(-100,-1,0),
|
||||
Planar64Vec3::int(0,-1,0),
|
||||
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||
int3(-3,3,0),
|
||||
int3(-100,-1,0),
|
||||
int3(0,-1,0),
|
||||
Time::ZERO
|
||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||
}
|
||||
#[test]
|
||||
fn test_collision_parabola_edge_north_from_south(){
|
||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
||||
Planar64Vec3::int(0,3,-3),
|
||||
Planar64Vec3::int(0,-1,-100),
|
||||
Planar64Vec3::int(0,-1,0),
|
||||
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||
int3(0,3,-3),
|
||||
int3(0,-1,-100),
|
||||
int3(0,-1,0),
|
||||
Time::ZERO
|
||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||
}
|
||||
#[test]
|
||||
fn test_collision_parabola_edge_north_from_ne(){
|
||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
||||
Planar64Vec3::int(0,6,-7)/2,
|
||||
Planar64Vec3::int(-10,-1,1),
|
||||
Planar64Vec3::int(0,-1,0),
|
||||
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||
int3(0,6,-7)>>1,
|
||||
int3(-10,-1,1),
|
||||
int3(0,-1,0),
|
||||
Time::ZERO
|
||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||
}
|
||||
#[test]
|
||||
fn test_collision_parabola_edge_north_from_nw(){
|
||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
||||
Planar64Vec3::int(0,6,-7)/2,
|
||||
Planar64Vec3::int(10,-1,1),
|
||||
Planar64Vec3::int(0,-1,0),
|
||||
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||
int3(0,6,-7)>>1,
|
||||
int3(10,-1,1),
|
||||
int3(0,-1,0),
|
||||
Time::ZERO
|
||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||
}
|
||||
#[test]
|
||||
fn test_collision_parabola_edge_east_from_se(){
|
||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
||||
Planar64Vec3::int(7,6,0)/2,
|
||||
Planar64Vec3::int(-1,-1,-10),
|
||||
Planar64Vec3::int(0,-1,0),
|
||||
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||
int3(7,6,0)>>1,
|
||||
int3(-1,-1,-10),
|
||||
int3(0,-1,0),
|
||||
Time::ZERO
|
||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||
}
|
||||
#[test]
|
||||
fn test_collision_parabola_edge_east_from_ne(){
|
||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
||||
Planar64Vec3::int(7,6,0)/2,
|
||||
Planar64Vec3::int(-1,-1,10),
|
||||
Planar64Vec3::int(0,-1,0),
|
||||
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||
int3(7,6,0)>>1,
|
||||
int3(-1,-1,10),
|
||||
int3(0,-1,0),
|
||||
Time::ZERO
|
||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||
}
|
||||
#[test]
|
||||
fn test_collision_parabola_edge_south_from_se(){
|
||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
||||
Planar64Vec3::int(0,6,7)/2,
|
||||
Planar64Vec3::int(-10,-1,-1),
|
||||
Planar64Vec3::int(0,-1,0),
|
||||
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||
int3(0,6,7)>>1,
|
||||
int3(-10,-1,-1),
|
||||
int3(0,-1,0),
|
||||
Time::ZERO
|
||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||
}
|
||||
#[test]
|
||||
fn test_collision_parabola_edge_south_from_sw(){
|
||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
||||
Planar64Vec3::int(0,6,7)/2,
|
||||
Planar64Vec3::int(10,-1,-1),
|
||||
Planar64Vec3::int(0,-1,0),
|
||||
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||
int3(0,6,7)>>1,
|
||||
int3(10,-1,-1),
|
||||
int3(0,-1,0),
|
||||
Time::ZERO
|
||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||
}
|
||||
#[test]
|
||||
fn test_collision_parabola_edge_west_from_se(){
|
||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
||||
Planar64Vec3::int(-7,6,0)/2,
|
||||
Planar64Vec3::int(1,-1,-10),
|
||||
Planar64Vec3::int(0,-1,0),
|
||||
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||
int3(-7,6,0)>>1,
|
||||
int3(1,-1,-10),
|
||||
int3(0,-1,0),
|
||||
Time::ZERO
|
||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||
}
|
||||
#[test]
|
||||
fn test_collision_parabola_edge_west_from_ne(){
|
||||
test_collision(VirtualBody::relative(&Body::default(),&Body::new(
|
||||
Planar64Vec3::int(-7,6,0)/2,
|
||||
Planar64Vec3::int(1,-1,10),
|
||||
Planar64Vec3::int(0,-1,0),
|
||||
test_collision(VirtualBody::relative(&Body::ZERO,&Body::new(
|
||||
int3(-7,6,0)>>1,
|
||||
int3(1,-1,10),
|
||||
int3(0,-1,0),
|
||||
Time::ZERO
|
||||
)).body(Time::from_secs(-1)),Some(Time::from_secs(0)));
|
||||
}
|
||||
#[test]
|
||||
fn test_collision_oblique(){
|
||||
test_collision(Body::new(
|
||||
Planar64Vec3::int(0,5,0),
|
||||
Planar64Vec3::int(1,-64,2)/64,
|
||||
Planar64Vec3::ZERO,
|
||||
int3(0,5,0),
|
||||
int3(1,-64,2)>>6,// /64
|
||||
vec3::ZERO,
|
||||
Time::ZERO
|
||||
),Some(Time::from_secs(2)));
|
||||
}
|
||||
#[test]
|
||||
fn zoom_hit_nothing(){
|
||||
test_collision(Body::new(
|
||||
Planar64Vec3::int(0,10,0),
|
||||
Planar64Vec3::int(1,0,0),
|
||||
Planar64Vec3::int(0,1,0),
|
||||
int3(0,10,0),
|
||||
int3(1,0,0),
|
||||
int3(0,1,0),
|
||||
Time::ZERO
|
||||
),None);
|
||||
}
|
||||
#[test]
|
||||
fn already_inside_hit_nothing(){
|
||||
test_collision(Body::new(
|
||||
Planar64Vec3::ZERO,
|
||||
Planar64Vec3::int(1,0,0),
|
||||
Planar64Vec3::int(0,1,0),
|
||||
vec3::ZERO,
|
||||
int3(1,0,0),
|
||||
int3(0,1,0),
|
||||
Time::ZERO
|
||||
),None);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user