118 lines
3.8 KiB
Rust
118 lines
3.8 KiB
Rust
use strafesnet_physics::physics::{InternalInstruction,PhysicsData,PhysicsState,PhysicsContext};
|
|
use strafesnet_common::gameplay_modes::NormalizedModes;
|
|
use strafesnet_common::gameplay_attributes::{CollisionAttributes,CollisionAttributesId};
|
|
use strafesnet_common::integer::{vec3,mat3,Planar64Affine3,Time};
|
|
use strafesnet_common::model::{Mesh,Model,MeshId,ModelId,RenderConfigId};
|
|
use strafesnet_common::map::CompleteMap;
|
|
use strafesnet_rbx_loader::primitives::{unit_cube,CubeFaceDescription};
|
|
|
|
struct TestSceneBuilder{
|
|
meshes:Vec<Mesh>,
|
|
models:Vec<Model>,
|
|
}
|
|
impl TestSceneBuilder{
|
|
fn new()->Self{
|
|
Self{
|
|
meshes:Vec::new(),
|
|
models:Vec::new(),
|
|
}
|
|
}
|
|
fn push_mesh(&mut self,mesh:Mesh)->MeshId{
|
|
let mesh_id=self.meshes.len();
|
|
self.meshes.push(mesh);
|
|
MeshId::new(mesh_id as u32)
|
|
}
|
|
fn push_mesh_instance(&mut self,mesh:MeshId,transform:Planar64Affine3)->ModelId{
|
|
let model=Model{
|
|
mesh,
|
|
attributes:CollisionAttributesId::new(0),
|
|
color:glam::Vec4::ONE,
|
|
transform,
|
|
};
|
|
let model_id=self.models.len();
|
|
self.models.push(model);
|
|
ModelId::new(model_id as u32)
|
|
}
|
|
fn build(self)->PhysicsData{
|
|
let modes=NormalizedModes::new(Vec::new());
|
|
let attributes=vec![CollisionAttributes::contact_default()];
|
|
let meshes=self.meshes;
|
|
let models=self.models;
|
|
let textures=Vec::new();
|
|
let render_configs=Vec::new();
|
|
PhysicsData::new(&CompleteMap{
|
|
modes,
|
|
attributes,
|
|
meshes,
|
|
models,
|
|
textures,
|
|
render_configs,
|
|
})
|
|
}
|
|
}
|
|
|
|
fn test_scene()->PhysicsData{
|
|
let mut builder=TestSceneBuilder::new();
|
|
let cube_face_description=CubeFaceDescription::new(Default::default(),RenderConfigId::new(0));
|
|
let mesh=builder.push_mesh(unit_cube(cube_face_description));
|
|
// place two 5x5x5 cubes.
|
|
builder.push_mesh_instance(mesh,Planar64Affine3::new(
|
|
mat3::from_diagonal(vec3::int(5,5,5)>>1),
|
|
vec3::int(0,0,0)
|
|
));
|
|
builder.push_mesh_instance(mesh,Planar64Affine3::new(
|
|
mat3::from_diagonal(vec3::int(5,5,5)>>1),
|
|
vec3::int(5,-5,0)
|
|
));
|
|
builder.build()
|
|
}
|
|
|
|
#[test]
|
|
fn simultaneous_collision(){
|
|
let physics_data=test_scene();
|
|
let body=strafesnet_physics::physics::Body::new(
|
|
(vec3::int(5+2,0,0)>>1)+vec3::int(1,1,0),
|
|
vec3::int(-1,-1,0),
|
|
vec3::int(0,0,0),
|
|
Time::ZERO,
|
|
);
|
|
let mut physics=PhysicsState::new_with_body(body);
|
|
physics.style_mut().gravity=vec3::zero();
|
|
let mut phys_iter=PhysicsContext::iter_internal(&mut physics,&physics_data,Time::from_secs(2))
|
|
.filter(|ins|!matches!(ins.instruction,InternalInstruction::StrafeTick));
|
|
// the order that they hit does matter, but we aren't currently worrying about that.
|
|
// See multi-collision branch
|
|
assert_eq!(phys_iter.next().unwrap().time,Time::from_secs(1));
|
|
assert_eq!(phys_iter.next().unwrap().time,Time::from_secs(1));
|
|
assert!(phys_iter.next().is_none());
|
|
let body=physics.body();
|
|
assert_eq!(body.position,vec3::int(5,0,0));
|
|
assert_eq!(body.velocity,vec3::int(0,0,0));
|
|
assert_eq!(body.acceleration,vec3::int(0,0,0));
|
|
assert_eq!(body.time,Time::from_secs(1));
|
|
}
|
|
#[test]
|
|
fn bug_3(){
|
|
let physics_data=test_scene();
|
|
let body=strafesnet_physics::physics::Body::new(
|
|
(vec3::int(5+2,0,0)>>1)+vec3::int(1,2,0),
|
|
vec3::int(-1,-1,0),
|
|
vec3::int(0,0,0),
|
|
Time::ZERO,
|
|
);
|
|
let mut physics=PhysicsState::new_with_body(body);
|
|
physics.style_mut().gravity=vec3::zero();
|
|
let mut phys_iter=PhysicsContext::iter_internal(&mut physics,&physics_data,Time::from_secs(3))
|
|
.filter(|ins|!matches!(ins.instruction,InternalInstruction::StrafeTick));
|
|
// touch side of part at 0,0,0
|
|
assert_eq!(phys_iter.next().unwrap().time,Time::from_secs(1));
|
|
// touch top of part at 5,-5,0
|
|
assert_eq!(phys_iter.next().unwrap().time,Time::from_secs(2));
|
|
assert!(phys_iter.next().is_none());
|
|
let body=physics.body();
|
|
assert_eq!(body.position,vec3::int(5+2,0,0)>>1);
|
|
assert_eq!(body.velocity,vec3::int(0,0,0));
|
|
assert_eq!(body.acceleration,vec3::int(0,0,0));
|
|
assert_eq!(body.time,Time::from_secs(2));
|
|
}
|