use Range to express time range

This commit is contained in:
Quaternions 2025-01-21 12:46:21 -08:00
parent f5c3209c7c
commit 32b361b122
2 changed files with 10 additions and 9 deletions

View File

@ -1,5 +1,6 @@
use std::borrow::{Borrow,Cow};
use std::collections::{HashSet,HashMap};
use core::ops::Range;
use strafesnet_common::integer::vec3::Vector3;
use strafesnet_common::model::{self,MeshId,PolygonIter};
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
// 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|{
let infinity_fev=self.infinity_fev(-dir,infinity_body.position);
//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()
})
}
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|{
//continue forwards along the body parabola
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
let infinity_body=-relative_body.clone();
self.closest_fev_not_inside(infinity_body,-time_limit).map_or(None,|fev|{
@ -745,7 +746,7 @@ impl MinkowskiMesh<'_>{
.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)
//determine when it passes an edge ("sliding off" case)
let start_time={

View File

@ -836,7 +836,7 @@ impl TouchingState{
//detect face slide off
let model_mesh=models.contact_mesh(contact);
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{
time:relative_body.time+time.into(),
instruction:InternalInstruction::CollisionEnd(
@ -850,7 +850,7 @@ impl TouchingState{
//detect model collision in reverse
let model_mesh=models.intersect_mesh(intersect);
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{
time:relative_body.time+time.into(),
instruction:InternalInstruction::CollisionEnd(
@ -1185,7 +1185,7 @@ impl PhysicsData{
//no checks are needed because of the time limits.
let model_mesh=data.models.mesh(convex_mesh_id);
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
.map_or(None,|(face,dt)|{
// 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 platform_mesh=h0.transformed_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");
}
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 platform_mesh=h0.transformed_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");
}
fn test_collision(relative_body:Body,expected_collision_time:Option<Time>){