generic generic generic
This commit is contained in:
parent
e1fde9b507
commit
72ebe5c9c8
@ -1,27 +1,27 @@
|
|||||||
use crate::physics::Body;
|
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::integer::{Time,Planar64,Planar64Vec3};
|
||||||
use crate::zeroes::zeroes2;
|
use crate::zeroes::zeroes2;
|
||||||
|
|
||||||
struct State{
|
struct State<FEV>{
|
||||||
fev:FEV,
|
fev:FEV,
|
||||||
time:Time,
|
time:Time,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Transition{
|
enum Transition<F,E,V>{
|
||||||
Miss,
|
Miss,
|
||||||
Next(FEV,Time),
|
Next(FEV<F,E,V>,Time),
|
||||||
Hit(FaceId,Time),
|
Hit(F,Time),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State{
|
impl<F:Copy,E:Copy,V:Copy> State<FEV<F,E,V>>{
|
||||||
fn next_transition(&self,mesh:&VirtualMesh,body:&Body,time_limit:Time)->Transition{
|
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.
|
//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.
|
//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_time=time_limit;
|
||||||
let mut best_transtition=Transition::Miss;
|
let mut best_transtition=Transition::Miss;
|
||||||
match &self.fev{
|
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
|
//test own face collision time, ignoring roots with zero or conflicting derivative
|
||||||
//n=face.normal d=face.dot
|
//n=face.normal d=face.dot
|
||||||
//n.a t^2+n.v t+n.p-d==0
|
//n.a t^2+n.v t+n.p-d==0
|
||||||
@ -40,14 +40,14 @@ impl State{
|
|||||||
let t=body.time+Time::from(t);
|
let t=body.time+Time::from(t);
|
||||||
if self.time<t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{
|
if self.time<t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{
|
||||||
best_time=t;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if none:
|
//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
|
//test each face collision time, ignoring roots with zero or conflicting derivative
|
||||||
for &test_face_id in mesh.edge_side_faces(edge_id){
|
for &test_face_id in mesh.edge_side_faces(edge_id){
|
||||||
let (n,d)=mesh.face_nd(test_face_id);
|
let (n,d)=mesh.face_nd(test_face_id);
|
||||||
@ -55,7 +55,7 @@ impl State{
|
|||||||
let t=body.time+Time::from(t);
|
let t=body.time+Time::from(t);
|
||||||
if self.time<t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{
|
if self.time<t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{
|
||||||
best_time=t;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,14 +67,14 @@ impl State{
|
|||||||
let t=body.time+Time::from(t);
|
let t=body.time+Time::from(t);
|
||||||
if self.time<t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{
|
if self.time<t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{
|
||||||
best_time=t;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if none:
|
//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
|
//test each edge collision time, ignoring roots with zero or conflicting derivative
|
||||||
for &(edge_id,test_face_id) in mesh.vert_edges(vertex_id){
|
for &(edge_id,test_face_id) in mesh.vert_edges(vertex_id){
|
||||||
let (n,d)=mesh.face_nd(test_face_id);
|
let (n,d)=mesh.face_nd(test_face_id);
|
||||||
@ -82,7 +82,7 @@ impl State{
|
|||||||
let t=body.time+Time::from(t);
|
let t=body.time+Time::from(t);
|
||||||
if self.time<t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{
|
if self.time<t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{
|
||||||
best_time=t;
|
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;
|
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{
|
let mut state=State{
|
||||||
fev:mesh.closest_fev(relative_body.position),
|
fev:mesh.closest_fev(relative_body.position),
|
||||||
time:relative_body.time,
|
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
|
//imagine the mesh without the collision face
|
||||||
//no algorithm needed, there is only one state and three cases (Face,Edge,None)
|
//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
|
//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);
|
pub struct FaceId(usize);
|
||||||
|
|
||||||
//Vertex <-> Edge <-> Face -> Collide
|
//Vertex <-> Edge <-> Face -> Collide
|
||||||
pub enum FEV{
|
pub enum FEV<F,E,V>{
|
||||||
Face(FaceId),
|
Face(F),
|
||||||
Edge(EdgeId),
|
Edge(E),
|
||||||
Vert(VertId),
|
Vert(V),
|
||||||
}
|
}
|
||||||
|
|
||||||
//use Unit32 #[repr(C)] for map files
|
//use Unit32 #[repr(C)] for map files
|
||||||
@ -19,6 +19,7 @@ struct Face{
|
|||||||
normal:Planar64Vec3,
|
normal:Planar64Vec3,
|
||||||
dot:Planar64,
|
dot:Planar64,
|
||||||
}
|
}
|
||||||
|
struct Vert(Planar64Vec3);
|
||||||
struct FaceRefs{
|
struct FaceRefs{
|
||||||
edges:Vec<(EdgeId,FaceId)>,
|
edges:Vec<(EdgeId,FaceId)>,
|
||||||
verts:Vec<VertId>,
|
verts:Vec<VertId>,
|
||||||
@ -32,25 +33,43 @@ struct VertRefs{
|
|||||||
}
|
}
|
||||||
pub struct PhysicsMesh{
|
pub struct PhysicsMesh{
|
||||||
faces:Vec<Face>,
|
faces:Vec<Face>,
|
||||||
|
verts:Vec<Vert>,
|
||||||
face_topology:Vec<FaceRefs>,
|
face_topology:Vec<FaceRefs>,
|
||||||
edge_topology:Vec<EdgeRefs>,
|
edge_topology:Vec<EdgeRefs>,
|
||||||
vert_topology:Vec<VertRefs>,
|
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)
|
(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...
|
//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
|
&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
|
&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
|
&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
|
&self.vert_topology[vert_id.0].edges
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -59,37 +78,56 @@ impl PhysicsMesh{
|
|||||||
//(face,vertex)
|
//(face,vertex)
|
||||||
//(edge,edge)
|
//(edge,edge)
|
||||||
//(vertex,face)
|
//(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,
|
mesh0:&'a PhysicsMesh,
|
||||||
mesh1:&'a PhysicsMesh,
|
mesh1:&'a PhysicsMesh,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VirtualMesh<'_>{
|
impl MinkowskiMesh<'_>{
|
||||||
pub fn minkowski_sum<'a>(mesh0:&'a PhysicsMesh,mesh1:&'a PhysicsMesh)->VirtualMesh<'a>{
|
pub fn minkowski_sum<'a>(mesh0:&'a PhysicsMesh,mesh1:&'a PhysicsMesh)->MinkowskiMesh<'a>{
|
||||||
VirtualMesh{
|
MinkowskiMesh{
|
||||||
mesh0,
|
mesh0,
|
||||||
mesh1,
|
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
|
//put some genius code right here
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
pub fn face_nd(&self,face_id:FaceId)->(Planar64Vec3,Planar64){
|
fn face_nd(&self,face_id:MinkowskiFace)->(Planar64Vec3,Planar64){
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
//ideally I never calculate the vertex position, but I have to for the graphical meshes...
|
fn vert(&self,vert_id:MinkowskiVert)->Planar64Vec3{
|
||||||
pub fn face_edges(&self,face_id:FaceId)->&Vec<(EdgeId,FaceId)>{
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
pub fn edge_side_faces(&self,edge_id:EdgeId)->&[FaceId;2]{
|
fn face_edges(&self,face_id:MinkowskiFace)->&Vec<(MinkowskiEdge,MinkowskiFace)>{
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
pub fn edge_ends(&self,edge_id:EdgeId)->&[(VertId,FaceId);2]{
|
fn edge_side_faces(&self,edge_id:MinkowskiEdge)->&[MinkowskiFace;2]{
|
||||||
todo!()
|
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!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user