generic generic generic
This commit is contained in:
parent
e1fde9b507
commit
72ebe5c9c8
@ -1,27 +1,27 @@
|
||||
use crate::physics::Body;
|
||||
use crate::model_physics::{VirtualMesh,FEV,FaceId};
|
||||
use crate::model_physics::{FEV,MeshQuery};
|
||||
use crate::integer::{Time,Planar64,Planar64Vec3};
|
||||
use crate::zeroes::zeroes2;
|
||||
|
||||
struct State{
|
||||
struct State<FEV>{
|
||||
fev:FEV,
|
||||
time:Time,
|
||||
}
|
||||
|
||||
enum Transition{
|
||||
enum Transition<F,E,V>{
|
||||
Miss,
|
||||
Next(FEV,Time),
|
||||
Hit(FaceId,Time),
|
||||
Next(FEV<F,E,V>,Time),
|
||||
Hit(F,Time),
|
||||
}
|
||||
|
||||
impl State{
|
||||
fn next_transition(&self,mesh:&VirtualMesh,body:&Body,time_limit:Time)->Transition{
|
||||
impl<F:Copy,E:Copy,V:Copy> State<FEV<F,E,V>>{
|
||||
fn next_transition(&self,mesh:&impl MeshQuery<F,E,V>,body:&Body,time_limit:Time)->Transition<F,E,V>{
|
||||
//conflicting derivative means it crosses in the wrong direction.
|
||||
//if the transition time is equal to an already tested transition, do not replace the current best.
|
||||
let mut best_time=time_limit;
|
||||
let mut best_transtition=Transition::Miss;
|
||||
match &self.fev{
|
||||
&FEV::Face(face_id)=>{
|
||||
&FEV::<F,E,V>::Face(face_id)=>{
|
||||
//test own face collision time, ignoring roots with zero or conflicting derivative
|
||||
//n=face.normal d=face.dot
|
||||
//n.a t^2+n.v t+n.p-d==0
|
||||
@ -40,14 +40,14 @@ impl State{
|
||||
let t=body.time+Time::from(t);
|
||||
if self.time<t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{
|
||||
best_time=t;
|
||||
best_transtition=Transition::Next(FEV::Edge(edge_id),t);
|
||||
best_transtition=Transition::Next(FEV::<F,E,V>::Edge(edge_id),t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//if none:
|
||||
},
|
||||
&FEV::Edge(edge_id)=>{
|
||||
&FEV::<F,E,V>::Edge(edge_id)=>{
|
||||
//test each face collision time, ignoring roots with zero or conflicting derivative
|
||||
for &test_face_id in mesh.edge_side_faces(edge_id){
|
||||
let (n,d)=mesh.face_nd(test_face_id);
|
||||
@ -55,7 +55,7 @@ impl State{
|
||||
let t=body.time+Time::from(t);
|
||||
if self.time<t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{
|
||||
best_time=t;
|
||||
best_transtition=Transition::Next(FEV::Face(test_face_id),t);
|
||||
best_transtition=Transition::Next(FEV::<F,E,V>::Face(test_face_id),t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -67,14 +67,14 @@ impl State{
|
||||
let t=body.time+Time::from(t);
|
||||
if self.time<t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{
|
||||
best_time=t;
|
||||
best_transtition=Transition::Next(FEV::Vert(vert_id),t);
|
||||
best_transtition=Transition::Next(FEV::<F,E,V>::Vert(vert_id),t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//if none:
|
||||
},
|
||||
&FEV::Vert(vertex_id)=>{
|
||||
&FEV::<F,E,V>::Vert(vertex_id)=>{
|
||||
//test each edge collision time, ignoring roots with zero or conflicting derivative
|
||||
for &(edge_id,test_face_id) in mesh.vert_edges(vertex_id){
|
||||
let (n,d)=mesh.face_nd(test_face_id);
|
||||
@ -82,7 +82,7 @@ impl State{
|
||||
let t=body.time+Time::from(t);
|
||||
if self.time<t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{
|
||||
best_time=t;
|
||||
best_transtition=Transition::Next(FEV::Edge(edge_id),t);
|
||||
best_transtition=Transition::Next(FEV::<F,E,V>::Edge(edge_id),t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -94,7 +94,7 @@ impl State{
|
||||
}
|
||||
}
|
||||
|
||||
pub fn predict_collision(mesh:&VirtualMesh,relative_body:&Body,time_limit:Time)->Option<(FaceId,Time)>{
|
||||
pub fn predict_collision<F:Copy,E:Copy,V:Copy>(mesh:&impl MeshQuery<F,E,V>,relative_body:&Body,time_limit:Time)->Option<(F,Time)>{
|
||||
let mut state=State{
|
||||
fev:mesh.closest_fev(relative_body.position),
|
||||
time:relative_body.time,
|
||||
@ -109,7 +109,7 @@ pub fn predict_collision(mesh:&VirtualMesh,relative_body:&Body,time_limit:Time)-
|
||||
}
|
||||
}
|
||||
|
||||
pub fn predict_collision_end(mesh:&VirtualMesh,relative_body:&Body,time_limit:Time,c:&crate::physics::RelativeCollision)->Option<(FaceId,Time)>{
|
||||
pub fn predict_collision_end<F:Copy,E:Copy,V:Copy>(mesh:&impl MeshQuery<F,E,V>,relative_body:&Body,time_limit:Time,c:&crate::physics::RelativeCollision)->Option<(F,Time)>{
|
||||
//imagine the mesh without the collision face
|
||||
//no algorithm needed, there is only one state and three cases (Face,Edge,None)
|
||||
//determine when it passes an edge ("sliding off" case) or if it leaves the surface directly
|
||||
|
@ -8,10 +8,10 @@ pub struct EdgeId(usize);
|
||||
pub struct FaceId(usize);
|
||||
|
||||
//Vertex <-> Edge <-> Face -> Collide
|
||||
pub enum FEV{
|
||||
Face(FaceId),
|
||||
Edge(EdgeId),
|
||||
Vert(VertId),
|
||||
pub enum FEV<F,E,V>{
|
||||
Face(F),
|
||||
Edge(E),
|
||||
Vert(V),
|
||||
}
|
||||
|
||||
//use Unit32 #[repr(C)] for map files
|
||||
@ -19,6 +19,7 @@ struct Face{
|
||||
normal:Planar64Vec3,
|
||||
dot:Planar64,
|
||||
}
|
||||
struct Vert(Planar64Vec3);
|
||||
struct FaceRefs{
|
||||
edges:Vec<(EdgeId,FaceId)>,
|
||||
verts:Vec<VertId>,
|
||||
@ -32,25 +33,43 @@ struct VertRefs{
|
||||
}
|
||||
pub struct PhysicsMesh{
|
||||
faces:Vec<Face>,
|
||||
verts:Vec<Vert>,
|
||||
face_topology:Vec<FaceRefs>,
|
||||
edge_topology:Vec<EdgeRefs>,
|
||||
vert_topology:Vec<VertRefs>,
|
||||
}
|
||||
impl PhysicsMesh{
|
||||
pub fn face_nd(&self,face_id:FaceId)->(Planar64Vec3,Planar64){
|
||||
|
||||
pub trait MeshQuery<FACE,EDGE,VERT>{
|
||||
fn closest_fev(&self,point:Planar64Vec3)->FEV<FACE,EDGE,VERT>;
|
||||
fn face_nd(&self,face_id:FACE)->(Planar64Vec3,Planar64);
|
||||
fn vert(&self,vert_id:VERT)->Planar64Vec3;
|
||||
fn face_edges(&self,face_id:FACE)->&Vec<(EDGE,FACE)>;
|
||||
fn edge_side_faces(&self,edge_id:EDGE)->&[FACE;2];
|
||||
fn edge_ends(&self,edge_id:EDGE)->&[(VERT,FACE);2];
|
||||
fn vert_edges(&self,vert_id:VERT)->&Vec<(EDGE,FACE)>;
|
||||
}
|
||||
impl MeshQuery<FaceId,EdgeId,VertId> for PhysicsMesh{
|
||||
fn closest_fev(&self,point:Planar64Vec3)->FEV<FaceId,EdgeId,VertId>{
|
||||
//put some genius code right here
|
||||
todo!()
|
||||
}
|
||||
fn face_nd(&self,face_id:FaceId)->(Planar64Vec3,Planar64){
|
||||
(self.faces[face_id.0].normal,self.faces[face_id.0].dot)
|
||||
}
|
||||
//ideally I never calculate the vertex position, but I have to for the graphical meshes...
|
||||
pub fn face_edges(&self,face_id:FaceId)->&Vec<(EdgeId,FaceId)>{
|
||||
fn vert(&self,vert_id:VertId)->Planar64Vec3{
|
||||
todo!()
|
||||
}
|
||||
fn face_edges(&self,face_id:FaceId)->&Vec<(EdgeId,FaceId)>{
|
||||
&self.face_topology[face_id.0].edges
|
||||
}
|
||||
pub fn edge_side_faces(&self,edge_id:EdgeId)->&[FaceId;2]{
|
||||
fn edge_side_faces(&self,edge_id:EdgeId)->&[FaceId;2]{
|
||||
&self.edge_topology[edge_id.0].faces
|
||||
}
|
||||
pub fn edge_ends(&self,edge_id:EdgeId)->&[(VertId,FaceId);2]{
|
||||
fn edge_ends(&self,edge_id:EdgeId)->&[(VertId,FaceId);2]{
|
||||
&self.edge_topology[edge_id.0].verts
|
||||
}
|
||||
pub fn vert_edges(&self,vert_id:VertId)->&Vec<(EdgeId,FaceId)>{
|
||||
fn vert_edges(&self,vert_id:VertId)->&Vec<(EdgeId,FaceId)>{
|
||||
&self.vert_topology[vert_id.0].edges
|
||||
}
|
||||
}
|
||||
@ -59,37 +78,56 @@ impl PhysicsMesh{
|
||||
//(face,vertex)
|
||||
//(edge,edge)
|
||||
//(vertex,face)
|
||||
#[derive(Clone,Copy)]
|
||||
enum MinkowskiVert{
|
||||
VertVert(VertId,VertId),
|
||||
}
|
||||
#[derive(Clone,Copy)]
|
||||
enum MinkowskiEdge{
|
||||
VertEdge(VertId,EdgeId),
|
||||
EdgeVert(EdgeId,VertId),
|
||||
}
|
||||
#[derive(Clone,Copy)]
|
||||
enum MinkowskiFace{
|
||||
FaceVert(FaceId,VertId),
|
||||
EdgeEdge(EdgeId,EdgeId),
|
||||
VertFace(VertId,FaceId),
|
||||
}
|
||||
|
||||
pub struct VirtualMesh<'a>{
|
||||
pub struct MinkowskiMesh<'a>{
|
||||
mesh0:&'a PhysicsMesh,
|
||||
mesh1:&'a PhysicsMesh,
|
||||
}
|
||||
|
||||
impl VirtualMesh<'_>{
|
||||
pub fn minkowski_sum<'a>(mesh0:&'a PhysicsMesh,mesh1:&'a PhysicsMesh)->VirtualMesh<'a>{
|
||||
VirtualMesh{
|
||||
impl MinkowskiMesh<'_>{
|
||||
pub fn minkowski_sum<'a>(mesh0:&'a PhysicsMesh,mesh1:&'a PhysicsMesh)->MinkowskiMesh<'a>{
|
||||
MinkowskiMesh{
|
||||
mesh0,
|
||||
mesh1,
|
||||
}
|
||||
}
|
||||
pub fn closest_fev(&self,point:Planar64Vec3)->FEV{
|
||||
}
|
||||
impl MeshQuery<MinkowskiFace,MinkowskiEdge,MinkowskiVert> for MinkowskiMesh<'_>{
|
||||
fn closest_fev(&self,point:Planar64Vec3)->FEV<MinkowskiFace,MinkowskiEdge,MinkowskiVert>{
|
||||
//put some genius code right here
|
||||
todo!()
|
||||
}
|
||||
pub fn face_nd(&self,face_id:FaceId)->(Planar64Vec3,Planar64){
|
||||
fn face_nd(&self,face_id:MinkowskiFace)->(Planar64Vec3,Planar64){
|
||||
todo!()
|
||||
}
|
||||
//ideally I never calculate the vertex position, but I have to for the graphical meshes...
|
||||
pub fn face_edges(&self,face_id:FaceId)->&Vec<(EdgeId,FaceId)>{
|
||||
fn vert(&self,vert_id:MinkowskiVert)->Planar64Vec3{
|
||||
todo!()
|
||||
}
|
||||
pub fn edge_side_faces(&self,edge_id:EdgeId)->&[FaceId;2]{
|
||||
fn face_edges(&self,face_id:MinkowskiFace)->&Vec<(MinkowskiEdge,MinkowskiFace)>{
|
||||
todo!()
|
||||
}
|
||||
pub fn edge_ends(&self,edge_id:EdgeId)->&[(VertId,FaceId);2]{
|
||||
fn edge_side_faces(&self,edge_id:MinkowskiEdge)->&[MinkowskiFace;2]{
|
||||
todo!()
|
||||
}
|
||||
pub fn vert_edges(&self,vert_id:VertId)->&Vec<(EdgeId,FaceId)>{
|
||||
fn edge_ends(&self,edge_id:MinkowskiEdge)->&[(MinkowskiVert,MinkowskiFace);2]{
|
||||
todo!()
|
||||
}
|
||||
fn vert_edges(&self,vert_id:MinkowskiVert)->&Vec<(MinkowskiEdge,MinkowskiFace)>{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user