2023-10-26 04:31:53 +00:00
|
|
|
use crate::physics::Body;
|
2023-10-26 22:51:47 +00:00
|
|
|
use crate::integer::{Time,Planar64Vec3};
|
2023-10-26 04:31:53 +00:00
|
|
|
|
2023-10-26 04:22:28 +00:00
|
|
|
struct VertexId(usize);
|
|
|
|
struct EdgeId(usize);
|
|
|
|
struct FaceId(usize);
|
|
|
|
|
|
|
|
//Vertex <-> Edge <-> Face -> Collide
|
|
|
|
enum FEV{
|
|
|
|
Face(FaceId),
|
|
|
|
Edge(EdgeId),
|
|
|
|
Vertex(VertexId),
|
|
|
|
}
|
|
|
|
|
|
|
|
struct State{
|
|
|
|
time:Time,
|
|
|
|
fev:FEV,
|
|
|
|
}
|
|
|
|
|
|
|
|
enum Transition{
|
|
|
|
Miss,
|
|
|
|
NextState(State),
|
|
|
|
Hit(FaceId,Time),
|
|
|
|
}
|
2023-10-26 04:31:53 +00:00
|
|
|
|
|
|
|
impl State{
|
2023-10-26 22:51:47 +00:00
|
|
|
fn next_transition(&self,mesh:&VirtualMesh,body:&Body,time_limit:Time)->Transition{
|
2023-10-26 04:31:53 +00:00
|
|
|
//conflicting derivative means it crosses in the wrong direction.
|
2023-10-26 22:51:47 +00:00
|
|
|
//if the transition time is equal to an already tested transition, do not replace the current best.
|
|
|
|
match &self.fev{
|
2023-10-26 04:31:53 +00:00
|
|
|
FEV::Face(face_id)=>{
|
2023-10-26 22:51:47 +00:00
|
|
|
//test own face collision time, ignoring edges with zero or conflicting derivative
|
2023-10-26 04:31:53 +00:00
|
|
|
//test each edge collision time, ignoring edges with zero or conflicting derivative
|
2023-10-26 22:51:47 +00:00
|
|
|
//if face: Transition::Hit(Face,Time)
|
|
|
|
//if edge: Transition::NextState(State{time,fev:FEV::Edge(edge_id)})
|
|
|
|
//if none:
|
|
|
|
Transition::Miss
|
2023-10-26 04:31:53 +00:00
|
|
|
},
|
|
|
|
FEV::Edge(edge_id)=>{
|
|
|
|
//test each face collision time, ignoring faces with zero or conflicting derivative
|
|
|
|
//test each vertex collision time, ignoring vertices with zero or conflicting derivative
|
2023-10-26 22:51:47 +00:00
|
|
|
//if face: Transition::NextState(State{time,fev:FEV::Face(face_id)})
|
|
|
|
//if vert: Transition::NextState(State{time,fev:FEV::Vertex(vertex_id)})
|
|
|
|
//if none:
|
|
|
|
Transition::Miss
|
2023-10-26 04:31:53 +00:00
|
|
|
},
|
|
|
|
FEV::Vertex(vertex_id)=>{
|
|
|
|
//test each edge collision time, ignoring edges with zero or conflicting derivative
|
2023-10-26 22:51:47 +00:00
|
|
|
//if some: Transition::NextState(State{time,fev:FEV::Edge(edge_id)})
|
|
|
|
//if none:
|
|
|
|
Transition::Miss
|
2023-10-26 04:31:53 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//Note that a face on a minkowski mesh refers to a pair of fevs on the meshes it's summed from
|
|
|
|
//(face,vertex)
|
|
|
|
//(edge,edge)
|
|
|
|
//(vertex,face)
|
|
|
|
|
2023-10-26 22:51:47 +00:00
|
|
|
struct VirtualMesh<'a>{
|
|
|
|
mesh0:&'a PhysicsMesh,
|
|
|
|
mesh1:&'a PhysicsMesh,
|
2023-10-26 04:31:53 +00:00
|
|
|
}
|
|
|
|
|
2023-10-26 22:51:47 +00:00
|
|
|
impl VirtualMesh<'_>{
|
|
|
|
pub fn minkowski_sum<'a>(mesh0:&PhysicsMesh,mesh1:&PhysicsMesh)->VirtualMesh<'a>{
|
|
|
|
Self{
|
|
|
|
mesh0,
|
|
|
|
mesh1,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fn closest_fev(&self,point:Planar64Vec3)->FEV{
|
|
|
|
//put some genius code right here
|
|
|
|
todo!()
|
2023-10-26 04:31:53 +00:00
|
|
|
}
|
2023-10-26 22:51:47 +00:00
|
|
|
pub fn predict_collision(&self,relative_body:&Body,time_limit:Time)->Option<(FaceId,Time)>{
|
2023-10-26 04:31:53 +00:00
|
|
|
let mut state=State{
|
2023-10-26 22:51:47 +00:00
|
|
|
time:relative_body.time,
|
|
|
|
fev:self.closest_fev(relative_body.position),
|
2023-10-26 04:31:53 +00:00
|
|
|
};
|
|
|
|
//it would be possible to write down the point of closest approach...
|
|
|
|
loop{
|
2023-10-26 22:51:47 +00:00
|
|
|
match state.next_transition(self,relative_body,time_limit){
|
2023-10-26 04:31:53 +00:00
|
|
|
Transition::Miss=>return None,
|
|
|
|
Transition::NextState(next_state)=>state=next_state,
|
|
|
|
Transition::Hit(hit_face,hit_time)=>return Some((hit_face,hit_time)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|