use Range to express time range
This commit is contained in:
parent
44a58044c7
commit
5d31419370
@ -1,5 +1,6 @@
|
|||||||
use std::borrow::{Borrow,Cow};
|
use std::borrow::{Borrow,Cow};
|
||||||
use std::collections::{HashSet,HashMap};
|
use std::collections::{HashSet,HashMap};
|
||||||
|
use core::ops::Range;
|
||||||
use strafesnet_common::integer::vec3::Vector3;
|
use strafesnet_common::integer::vec3::Vector3;
|
||||||
use strafesnet_common::model::{self,MeshId,PolygonIter};
|
use strafesnet_common::model::{self,MeshId,PolygonIter};
|
||||||
use strafesnet_common::integer::{self,vec3,Fixed,Planar64,Planar64Vec3,Ratio};
|
use strafesnet_common::integer::{self,vec3,Fixed,Planar64,Planar64Vec3,Ratio};
|
||||||
@ -718,7 +719,7 @@ impl MinkowskiMesh<'_>{
|
|||||||
//
|
//
|
||||||
// Most of the calculation time is just calculating the starting point
|
// Most of the calculation time is just calculating the starting point
|
||||||
// for the "actual" crawling algorithm below (predict_collision_{in|out}).
|
// for the "actual" crawling algorithm below (predict_collision_{in|out}).
|
||||||
fn closest_fev_not_inside(&self,mut infinity_body:Body,start_time:Time,)->Option<FEV<MinkowskiMesh>>{
|
fn closest_fev_not_inside(&self,mut infinity_body:Body,start_time:Time)->Option<FEV<MinkowskiMesh>>{
|
||||||
infinity_body.infinity_dir().map_or(None,|dir|{
|
infinity_body.infinity_dir().map_or(None,|dir|{
|
||||||
let infinity_fev=self.infinity_fev(-dir,infinity_body.position);
|
let infinity_fev=self.infinity_fev(-dir,infinity_body.position);
|
||||||
//a line is simpler to solve than a parabola
|
//a line is simpler to solve than a parabola
|
||||||
@ -729,13 +730,13 @@ impl MinkowskiMesh<'_>{
|
|||||||
infinity_fev.crawl(self,&infinity_body,Time::MIN/4,start_time).miss()
|
infinity_fev.crawl(self,&infinity_body,Time::MIN/4,start_time).miss()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn predict_collision_in(&self,relative_body:&Body,start_time:Time,time_limit:Time)->Option<(MinkowskiFace,GigaTime)>{
|
pub fn predict_collision_in(&self,relative_body:&Body,Range{start:start_time,end:time_limit}:Range<Time>)->Option<(MinkowskiFace,GigaTime)>{
|
||||||
self.closest_fev_not_inside(relative_body.clone(),start_time).map_or(None,|fev|{
|
self.closest_fev_not_inside(relative_body.clone(),start_time).map_or(None,|fev|{
|
||||||
//continue forwards along the body parabola
|
//continue forwards along the body parabola
|
||||||
fev.crawl(self,relative_body,start_time,time_limit).hit()
|
fev.crawl(self,relative_body,start_time,time_limit).hit()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn predict_collision_out(&self,relative_body:&Body,start_time:Time,time_limit:Time)->Option<(MinkowskiFace,GigaTime)>{
|
pub fn predict_collision_out(&self,relative_body:&Body,Range{start:start_time,end:time_limit}:Range<Time>)->Option<(MinkowskiFace,GigaTime)>{
|
||||||
//create an extrapolated body at time_limit
|
//create an extrapolated body at time_limit
|
||||||
let infinity_body=-relative_body.clone();
|
let infinity_body=-relative_body.clone();
|
||||||
self.closest_fev_not_inside(infinity_body,-time_limit).map_or(None,|fev|{
|
self.closest_fev_not_inside(infinity_body,-time_limit).map_or(None,|fev|{
|
||||||
@ -745,7 +746,7 @@ impl MinkowskiMesh<'_>{
|
|||||||
.map(|(face,time)|(face,-time))
|
.map(|(face,time)|(face,-time))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn predict_collision_face_out(&self,relative_body:&Body,start_time:Time,time_limit:Time,contact_face_id:MinkowskiFace)->Option<(MinkowskiEdge,GigaTime)>{
|
pub fn predict_collision_face_out(&self,relative_body:&Body,Range{start:start_time,end:time_limit}:Range<Time>,contact_face_id:MinkowskiFace)->Option<(MinkowskiEdge,GigaTime)>{
|
||||||
//no algorithm needed, there is only one state and two cases (Edge,None)
|
//no algorithm needed, there is only one state and two cases (Edge,None)
|
||||||
//determine when it passes an edge ("sliding off" case)
|
//determine when it passes an edge ("sliding off" case)
|
||||||
let start_time={
|
let start_time={
|
||||||
|
@ -836,7 +836,7 @@ impl TouchingState{
|
|||||||
//detect face slide off
|
//detect face slide off
|
||||||
let model_mesh=models.contact_mesh(contact);
|
let model_mesh=models.contact_mesh(contact);
|
||||||
let minkowski=model_physics::MinkowskiMesh::minkowski_sum(model_mesh,hitbox_mesh.transformed_mesh());
|
let minkowski=model_physics::MinkowskiMesh::minkowski_sum(model_mesh,hitbox_mesh.transformed_mesh());
|
||||||
collector.collect(minkowski.predict_collision_face_out(&relative_body,start_time,collector.time(),contact.face_id).map(|(_face,time)|{
|
collector.collect(minkowski.predict_collision_face_out(&relative_body,start_time..collector.time(),contact.face_id).map(|(_face,time)|{
|
||||||
TimedInstruction{
|
TimedInstruction{
|
||||||
time:relative_body.time+time.into(),
|
time:relative_body.time+time.into(),
|
||||||
instruction:InternalInstruction::CollisionEnd(
|
instruction:InternalInstruction::CollisionEnd(
|
||||||
@ -850,7 +850,7 @@ impl TouchingState{
|
|||||||
//detect model collision in reverse
|
//detect model collision in reverse
|
||||||
let model_mesh=models.intersect_mesh(intersect);
|
let model_mesh=models.intersect_mesh(intersect);
|
||||||
let minkowski=model_physics::MinkowskiMesh::minkowski_sum(model_mesh,hitbox_mesh.transformed_mesh());
|
let minkowski=model_physics::MinkowskiMesh::minkowski_sum(model_mesh,hitbox_mesh.transformed_mesh());
|
||||||
collector.collect(minkowski.predict_collision_out(&relative_body,start_time,collector.time()).map(|(_face,time)|{
|
collector.collect(minkowski.predict_collision_out(&relative_body,start_time..collector.time()).map(|(_face,time)|{
|
||||||
TimedInstruction{
|
TimedInstruction{
|
||||||
time:relative_body.time+time.into(),
|
time:relative_body.time+time.into(),
|
||||||
instruction:InternalInstruction::CollisionEnd(
|
instruction:InternalInstruction::CollisionEnd(
|
||||||
@ -1185,7 +1185,7 @@ impl PhysicsData{
|
|||||||
//no checks are needed because of the time limits.
|
//no checks are needed because of the time limits.
|
||||||
let model_mesh=data.models.mesh(convex_mesh_id);
|
let model_mesh=data.models.mesh(convex_mesh_id);
|
||||||
let minkowski=model_physics::MinkowskiMesh::minkowski_sum(model_mesh,data.hitbox_mesh.transformed_mesh());
|
let minkowski=model_physics::MinkowskiMesh::minkowski_sum(model_mesh,data.hitbox_mesh.transformed_mesh());
|
||||||
collector.collect(minkowski.predict_collision_in(relative_body,state.time,collector.time())
|
collector.collect(minkowski.predict_collision_in(relative_body,state.time..collector.time())
|
||||||
//temp (?) code to avoid collision loops
|
//temp (?) code to avoid collision loops
|
||||||
.map_or(None,|(face,dt)|{
|
.map_or(None,|(face,dt)|{
|
||||||
// this must be rounded to avoid the infinite loop when hitting the start zone
|
// this must be rounded to avoid the infinite loop when hitting the start zone
|
||||||
@ -1922,7 +1922,7 @@ mod test{
|
|||||||
let hitbox_mesh=h1.transformed_mesh();
|
let hitbox_mesh=h1.transformed_mesh();
|
||||||
let platform_mesh=h0.transformed_mesh();
|
let platform_mesh=h0.transformed_mesh();
|
||||||
let minkowski=model_physics::MinkowskiMesh::minkowski_sum(platform_mesh,hitbox_mesh);
|
let minkowski=model_physics::MinkowskiMesh::minkowski_sum(platform_mesh,hitbox_mesh);
|
||||||
let collision=minkowski.predict_collision_in(&relative_body,Time::ZERO,Time::from_secs(10));
|
let collision=minkowski.predict_collision_in(&relative_body,Time::ZERO..Time::from_secs(10));
|
||||||
assert_eq!(collision.map(|tup|relative_body.time+tup.1.into()),expected_collision_time,"Incorrect time of collision");
|
assert_eq!(collision.map(|tup|relative_body.time+tup.1.into()),expected_collision_time,"Incorrect time of collision");
|
||||||
}
|
}
|
||||||
fn test_collision_rotated(relative_body:Body,expected_collision_time:Option<Time>){
|
fn test_collision_rotated(relative_body:Body,expected_collision_time:Option<Time>){
|
||||||
@ -1940,7 +1940,7 @@ mod test{
|
|||||||
let hitbox_mesh=h1.transformed_mesh();
|
let hitbox_mesh=h1.transformed_mesh();
|
||||||
let platform_mesh=h0.transformed_mesh();
|
let platform_mesh=h0.transformed_mesh();
|
||||||
let minkowski=model_physics::MinkowskiMesh::minkowski_sum(platform_mesh,hitbox_mesh);
|
let minkowski=model_physics::MinkowskiMesh::minkowski_sum(platform_mesh,hitbox_mesh);
|
||||||
let collision=minkowski.predict_collision_in(&relative_body,Time::ZERO,Time::from_secs(10));
|
let collision=minkowski.predict_collision_in(&relative_body,Time::ZERO..Time::from_secs(10));
|
||||||
assert_eq!(collision.map(|tup|relative_body.time+tup.1.into()),expected_collision_time,"Incorrect time of collision");
|
assert_eq!(collision.map(|tup|relative_body.time+tup.1.into()),expected_collision_time,"Incorrect time of collision");
|
||||||
}
|
}
|
||||||
fn test_collision(relative_body:Body,expected_collision_time:Option<Time>){
|
fn test_collision(relative_body:Body,expected_collision_time:Option<Time>){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user