From 72ebe5c9c8a7ca765aa35b70f0be5f7fc5d77e8d Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 27 Oct 2023 14:18:50 -0700 Subject: [PATCH] generic generic generic --- src/face_crawler.rs | 32 +++++++++--------- src/model_physics.rs | 80 ++++++++++++++++++++++++++++++++------------ 2 files changed, 75 insertions(+), 37 deletions(-) diff --git a/src/face_crawler.rs b/src/face_crawler.rs index 34ed8ca..d6ad1a9 100644 --- a/src/face_crawler.rs +++ b/src/face_crawler.rs @@ -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, time:Time, } -enum Transition{ +enum Transition{ Miss, - Next(FEV,Time), - Hit(FaceId,Time), + Next(FEV,Time), + Hit(F,Time), } -impl State{ - fn next_transition(&self,mesh:&VirtualMesh,body:&Body,time_limit:Time)->Transition{ +impl State>{ + fn next_transition(&self,mesh:&impl MeshQuery,body:&Body,time_limit:Time)->Transition{ //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::::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::Edge(edge_id),t); break; } } } //if none: }, - &FEV::Edge(edge_id)=>{ + &FEV::::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::Face(test_face_id),t); break; } } @@ -67,14 +67,14 @@ impl State{ let t=body.time+Time::from(t); if self.time::Vert(vert_id),t); break; } } } //if none: }, - &FEV::Vert(vertex_id)=>{ + &FEV::::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::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(mesh:&impl MeshQuery,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(mesh:&impl MeshQuery,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 diff --git a/src/model_physics.rs b/src/model_physics.rs index 23e8444..c22ea84 100644 --- a/src/model_physics.rs +++ b/src/model_physics.rs @@ -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{ + 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, @@ -32,25 +33,43 @@ struct VertRefs{ } pub struct PhysicsMesh{ faces:Vec, + verts:Vec, face_topology:Vec, edge_topology:Vec, vert_topology:Vec, } -impl PhysicsMesh{ - pub fn face_nd(&self,face_id:FaceId)->(Planar64Vec3,Planar64){ + +pub trait MeshQuery{ + fn closest_fev(&self,point:Planar64Vec3)->FEV; + 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 for PhysicsMesh{ + fn closest_fev(&self,point:Planar64Vec3)->FEV{ + //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 for MinkowskiMesh<'_>{ + fn closest_fev(&self,point:Planar64Vec3)->FEV{ //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!() } }