change the MeshQuery trait and delete the code I just wrote

This commit is contained in:
Quaternions 2023-11-15 20:34:15 -08:00
parent 4c05c01b6e
commit 328c38ca38
2 changed files with 20 additions and 305 deletions

View File

@ -34,7 +34,7 @@ impl<F:Copy,E:Copy,V:Copy> State<FEV<F,E,V>>{
} }
} }
//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.face_edges(face_id).iter(){ for &edge_id in mesh.face_edges(face_id).iter(){
let edge_n=mesh.edge_n(edge_id); let edge_n=mesh.edge_n(edge_id);
let n=n.cross(edge_n); let n=n.cross(edge_n);
//picking a vert randomly is terrible //picking a vert randomly is terrible

View File

@ -43,7 +43,7 @@ impl Face{
} }
struct Vert(Planar64Vec3); struct Vert(Planar64Vec3);
struct FaceRefs{ struct FaceRefs{
edges:Vec<(EdgeId,FaceId)>, edges:Vec<EdgeId>,
//verts:Vec<VertId>, //verts:Vec<VertId>,
} }
struct EdgeRefs{ struct EdgeRefs{
@ -160,19 +160,8 @@ impl From<&crate::model::IndexedModel> for PhysicsMesh{
Self{ Self{
faces, faces,
verts, verts,
face_topology:face_ref_guys.into_iter().enumerate().map(|(i,face_ref_guy)|{ face_topology:face_ref_guys.into_iter().map(|face_ref_guy|{
let face_id=FaceId(i); FaceRefs{edges:face_ref_guy.0}
FaceRefs{edges:face_ref_guy.0.into_iter().map(|edge_id|{
//get the edge face that's not this face
let edge_faces=&edge_pool.edge_guys[edge_id.0].1.0;
if edge_faces[0]==face_id{
(edge_id,edge_faces[1])
}else if edge_faces[1]==face_id{
(edge_id,edge_faces[0])
}else{
panic!("edge does not contain face edge_faces={:?} face={:?}",edge_faces,face_id)
}
}).collect()}
}).collect(), }).collect(),
edge_topology:edge_pool.edge_guys.into_iter().map(|(edge_id_guy,edge_ref_guy)| edge_topology:edge_pool.edge_guys.into_iter().map(|(edge_id_guy,edge_ref_guy)|
EdgeRefs{faces:edge_ref_guy.0,verts:edge_id_guy.0} EdgeRefs{faces:edge_ref_guy.0,verts:edge_id_guy.0}
@ -188,14 +177,13 @@ impl From<&crate::model::IndexedModel> for PhysicsMesh{
} }
pub trait MeshQuery<FACE:Clone,EDGE:Clone,VERT:Clone>{ pub trait MeshQuery<FACE:Clone,EDGE:Clone,VERT:Clone>{
fn closest_fev(&self,point:Planar64Vec3)->FEV<FACE,EDGE,VERT>;
fn edge_n(&self,edge_id:EDGE)->Planar64Vec3{ fn edge_n(&self,edge_id:EDGE)->Planar64Vec3{
let verts=self.edge_verts(edge_id); let verts=self.edge_verts(edge_id);
self.vert(verts[1].clone())-self.vert(verts[0].clone()) self.vert(verts[1].clone())-self.vert(verts[0].clone())
} }
fn vert(&self,vert_id:VERT)->Planar64Vec3; fn vert(&self,vert_id:VERT)->Planar64Vec3;
fn face_nd(&self,face_id:FACE)->(Planar64Vec3,Planar64); fn face_nd(&self,face_id:FACE)->(Planar64Vec3,Planar64);
fn face_edges(&self,face_id:FACE)->Cow<Vec<(EDGE,FACE)>>; fn face_edges(&self,face_id:FACE)->Cow<Vec<EDGE>>;
fn edge_faces(&self,edge_id:EDGE)->Cow<[FACE;2]>; fn edge_faces(&self,edge_id:EDGE)->Cow<[FACE;2]>;
fn edge_verts(&self,edge_id:EDGE)->Cow<[VERT;2]>; fn edge_verts(&self,edge_id:EDGE)->Cow<[VERT;2]>;
fn vert_edges(&self,vert_id:VERT)->Cow<Vec<EDGE>>; fn vert_edges(&self,vert_id:VERT)->Cow<Vec<EDGE>>;
@ -205,29 +193,6 @@ impl PhysicsMesh{
pub fn verts<'a>(&'a self)->impl Iterator<Item=Planar64Vec3>+'a{ pub fn verts<'a>(&'a self)->impl Iterator<Item=Planar64Vec3>+'a{
self.verts.iter().map(|Vert(pos)|*pos) self.verts.iter().map(|Vert(pos)|*pos)
} }
pub fn brute(&self,body:&crate::physics::Body,time_limit:crate::integer::Time)->Option<(FaceId,crate::integer::Time)>{
//check each face
let mut best_time=time_limit;
let mut best_face=None;
for (i,face) in self.faces.iter().enumerate(){
let face_id=FaceId(i);
let (n,d)=face.nd();
for t in crate::zeroes::zeroes2((n.dot(body.position)-d)*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){
let t=body.time+crate::integer::Time::from(t);
if body.time<t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{
let p=body.extrapolated_position(t);
if self.face_edges(face_id).iter().all(|&(_,face_id)|{
let (n,d)=self.face_nd(face_id);
n.dot(p)<=d
}){
best_time=t;
best_face=Some(face_id);
}
}
}
}
best_face.map(|f|(f,best_time))
}
fn vert_directed_edges(&self,vert_id:VertId)->Cow<Vec<DirectedEdgeId>>{ fn vert_directed_edges(&self,vert_id:VertId)->Cow<Vec<DirectedEdgeId>>{
Cow::Borrowed(&self.vert_topology[vert_id.0].edges) Cow::Borrowed(&self.vert_topology[vert_id.0].edges)
} }
@ -237,48 +202,6 @@ impl PhysicsMesh{
} }
} }
impl MeshQuery<FaceId,EdgeId,VertId> for PhysicsMesh{ impl MeshQuery<FaceId,EdgeId,VertId> for PhysicsMesh{
fn closest_fev(&self,point:Planar64Vec3)->FEV<FaceId,EdgeId,VertId>{
//TODO: put some genius code right here
//brute force for now
let mut best_distance_squared=Planar64::MAX;
//make something up as default ret
//hopefully empty meshes don't make their way through here
let mut best_fev=FEV::<FaceId,EdgeId,VertId>::Vert(VertId(0));
//check each vert
for (i,v) in self.verts.iter().enumerate(){
let d=(v.0-point).dot(v.0-point);
if d<best_distance_squared{
best_distance_squared=d;
best_fev=FEV::<FaceId,EdgeId,VertId>::Vert(VertId(i));
}
}
//check each edge
for (i,e) in self.edge_topology.iter().enumerate(){
let v0=self.vert(e.verts[0]);
let v1=self.vert(e.verts[1]);
let n=v1-v0;
//n.cross(point-v0)=sin(t)*n*dis
let d=n.dot(point-v0);
if d<n.dot(v1)&&n.dot(v0)<d{
let c=n.cross(point-v0);
let edge_distance_squared=c.dot(c)/n.dot(n);
if edge_distance_squared<best_distance_squared{
best_distance_squared=edge_distance_squared;
best_fev=FEV::<FaceId,EdgeId,VertId>::Edge(EdgeId(i));
}
}
}
let face_dots:Vec<Planar64>=self.faces.iter().map(|f|f.normal.dot(point)).collect();
//check each face
for (i,f) in self.face_topology.iter().enumerate(){
if face_dots[i]<best_distance_squared&&f.edges.iter().all(|&(_,face_id)|face_dots[face_id.0]<=Planar64::ZERO){
best_distance_squared=face_dots[i];
best_fev=FEV::<FaceId,EdgeId,VertId>::Face(FaceId(i));
}
}
best_fev
}
fn face_nd(&self,face_id:FaceId)->(Planar64Vec3,Planar64){ 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)
} }
@ -286,7 +209,7 @@ impl MeshQuery<FaceId,EdgeId,VertId> for PhysicsMesh{
fn vert(&self,vert_id:VertId)->Planar64Vec3{ fn vert(&self,vert_id:VertId)->Planar64Vec3{
self.verts[vert_id.0].0 self.verts[vert_id.0].0
} }
fn face_edges(&self,face_id:FaceId)->Cow<Vec<(EdgeId,FaceId)>>{ fn face_edges(&self,face_id:FaceId)->Cow<Vec<EdgeId>>{
Cow::Borrowed(&self.face_topology[face_id.0].edges) Cow::Borrowed(&self.face_topology[face_id.0].edges)
} }
fn edge_faces(&self,edge_id:EdgeId)->Cow<[FaceId;2]>{ fn edge_faces(&self,edge_id:EdgeId)->Cow<[FaceId;2]>{
@ -321,68 +244,6 @@ impl TransformedMesh<'_>{
normal_transform, normal_transform,
} }
} }
pub fn brute_in(&self,body:&crate::physics::Body,time_limit:crate::integer::Time)->Option<(FaceId,crate::integer::Time)>{
//check each face
let mut best_time=time_limit;
let mut best_face=None;
for i in 0..self.mesh.faces.len(){
let face_id=FaceId(i);
let (n,d)=self.face_nd(face_id);
for t in crate::zeroes::zeroes2((n.dot(body.position)-d)*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){
let t=body.time+crate::integer::Time::from(t);
if body.time<t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{
let p=body.extrapolated_position(t);
if self.face_edges(face_id).iter().all(|&(_,face_id)|{
let (n,d)=self.face_nd(face_id);
n.dot(p)<=d
}){
best_time=t;
best_face=Some(face_id);
}
}
}
}
best_face.map(|f|(f,best_time))
}
pub fn brute_out(&self,body:&crate::physics::Body,time_limit:crate::integer::Time)->Option<(FaceId,crate::integer::Time)>{
//check each face
let mut best_time=time_limit;
let mut best_face=None;
for i in 0..self.mesh.faces.len(){
let face_id=FaceId(i);
let (n,d)=self.face_nd(face_id);
for t in crate::zeroes::zeroes2((n.dot(body.position)-d)*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){
let t=body.time+crate::integer::Time::from(t);
if body.time<t&&t<best_time&&n.dot(body.extrapolated_velocity(t))>Planar64::ZERO{
let p=body.extrapolated_position(t);
if self.face_edges(face_id).iter().all(|&(_,test_face_id)|{
let (n,d)=self.face_nd(test_face_id);
n.dot(p)<=d
}){
best_time=t;
best_face=Some(face_id);
}
}
}
}
best_face.map(|f|(f,best_time))
}
pub fn brute_out_face(&self,body:&crate::physics::Body,time_limit:crate::integer::Time,face_id:FaceId)->Option<(FaceId,crate::integer::Time)>{
//check each face
let mut best_time=time_limit;
let mut best_face=None;
for &(_,test_face_id) in self.mesh.face_edges(face_id).iter(){
let (n,d)=self.face_nd(test_face_id);
for t in crate::zeroes::zeroes2((n.dot(body.position)-d)*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){
let t=body.time+crate::integer::Time::from(t);
if body.time<t&&t<best_time&&n.dot(body.extrapolated_velocity(t))>Planar64::ZERO{
best_time=t;
best_face=Some(test_face_id);
}
}
}
best_face.map(|f|(f,best_time))
}
#[inline] #[inline]
fn vert_directed_edges(&self,vert_id:VertId)->Cow<Vec<DirectedEdgeId>>{ fn vert_directed_edges(&self,vert_id:VertId)->Cow<Vec<DirectedEdgeId>>{
self.mesh.vert_directed_edges(vert_id) self.mesh.vert_directed_edges(vert_id)
@ -393,49 +254,6 @@ impl TransformedMesh<'_>{
} }
} }
impl MeshQuery<FaceId,EdgeId,VertId> for TransformedMesh<'_>{ impl MeshQuery<FaceId,EdgeId,VertId> for TransformedMesh<'_>{
fn closest_fev(&self,point:Planar64Vec3)->FEV<FaceId,EdgeId,VertId>{
//TODO: put some genius code right here
//brute force for now
let mut best_distance_squared=Planar64::MAX;
//make something up as default ret
//hopefully empty meshes don't make their way through here
let mut best_fev=FEV::<FaceId,EdgeId,VertId>::Vert(VertId(0));
//check each vert
for i in 0..self.mesh.verts.len(){
let v=self.vert(VertId(i));
let d=(v-point).dot(v-point);
if d<best_distance_squared{
best_distance_squared=d;
best_fev=FEV::<FaceId,EdgeId,VertId>::Vert(VertId(i));
}
}
//check each edge
for (i,e) in self.mesh.edge_topology.iter().enumerate(){
let v0=self.vert(e.verts[0]);
let v1=self.vert(e.verts[1]);
let n=v1-v0;
//n.cross(point-v0)=sin(t)*n*dis
let d=n.dot(point-v0);
if d<n.dot(v1)&&n.dot(v0)<d{
let c=n.cross(point-v0);
let edge_distance_squared=c.dot(c)/n.dot(n);
if edge_distance_squared<best_distance_squared{
best_distance_squared=edge_distance_squared;
best_fev=FEV::<FaceId,EdgeId,VertId>::Edge(EdgeId(i));
}
}
}
let face_dots:Vec<Planar64>=self.mesh.faces.iter().map(|f|(*self.normal_transform*f.normal).dot(point)).collect();
//check each face
for (i,f) in self.mesh.face_topology.iter().enumerate(){
if face_dots[i]<best_distance_squared&&f.edges.iter().all(|&(_,face_id)|face_dots[face_id.0]<=Planar64::ZERO){
best_distance_squared=face_dots[i];
best_fev=FEV::<FaceId,EdgeId,VertId>::Face(FaceId(i));
}
}
best_fev
}
fn face_nd(&self,face_id:FaceId)->(Planar64Vec3,Planar64){ fn face_nd(&self,face_id:FaceId)->(Planar64Vec3,Planar64){
let (n,d)=self.mesh.face_nd(face_id); let (n,d)=self.mesh.face_nd(face_id);
let transformed_n=*self.normal_transform*n; let transformed_n=*self.normal_transform*n;
@ -446,7 +264,7 @@ impl MeshQuery<FaceId,EdgeId,VertId> for TransformedMesh<'_>{
self.transform.transform_point3(self.mesh.vert(vert_id)) self.transform.transform_point3(self.mesh.vert(vert_id))
} }
#[inline] #[inline]
fn face_edges(&self,face_id:FaceId)->Cow<Vec<(EdgeId,FaceId)>>{ fn face_edges(&self,face_id:FaceId)->Cow<Vec<EdgeId>>{
self.mesh.face_edges(face_id) self.mesh.face_edges(face_id)
} }
#[inline] #[inline]
@ -499,12 +317,12 @@ impl MinkowskiMesh<'_>{
mesh1, mesh1,
} }
} }
}
impl MeshQuery<MinkowskiFace,MinkowskiEdge,MinkowskiVert> for MinkowskiMesh<'_>{
fn closest_fev(&self,point:Planar64Vec3)->FEV<MinkowskiFace,MinkowskiEdge,MinkowskiVert>{ fn closest_fev(&self,point:Planar64Vec3)->FEV<MinkowskiFace,MinkowskiEdge,MinkowskiVert>{
//put some genius code right here //put some genius code right here
todo!() todo!()
} }
}
impl MeshQuery<MinkowskiFace,MinkowskiEdge,MinkowskiVert> for MinkowskiMesh<'_>{
fn face_nd(&self,face_id:MinkowskiFace)->(Planar64Vec3,Planar64){ fn face_nd(&self,face_id:MinkowskiFace)->(Planar64Vec3,Planar64){
match face_id{ match face_id{
MinkowskiFace::VertFace(v0,f1)=>{ MinkowskiFace::VertFace(v0,f1)=>{
@ -535,130 +353,27 @@ impl MeshQuery<MinkowskiFace,MinkowskiEdge,MinkowskiVert> for MinkowskiMesh<'_>{
}, },
} }
} }
fn face_edges(&self,face_id:MinkowskiFace)->Cow<Vec<(MinkowskiEdge,MinkowskiFace)>>{ fn face_edges(&self,face_id:MinkowskiFace)->Cow<Vec<MinkowskiEdge>>{
match face_id{ match face_id{
MinkowskiFace::VertFace(v0,f1)=>{ MinkowskiFace::VertFace(v0,f1)=>{
let face1_n=self.mesh1.face_nd(f1).0; Cow::Owned(self.mesh1.face_edges(f1).iter().map(|&edge_id1|{
Cow::Owned(self.mesh1.face_edges(f1).iter().map(|&(edge_id1,edge_face_id1)|{ MinkowskiEdge::VertEdge(v0,edge_id1)
//same as above
(MinkowskiEdge::VertEdge(v0,edge_id1),{
let mut best_edge=None;
let mut best_d=Planar64::MAX;
let edge_face1_n=self.mesh1.face_nd(edge_face_id1).0;
let v0e=self.mesh0.vert_directed_edges(v0);
for &directed_edge_id0 in v0e.iter(){
let edge0_n=self.mesh0.directed_edge_n(directed_edge_id0);
if edge_face1_n.dot(edge0_n)<Planar64::ZERO{
let d=face1_n.dot(edge0_n);
if d<best_d{
best_d=d;
best_edge=Some(directed_edge_id0);
}
}
}
best_edge.map_or(
MinkowskiFace::VertFace(v0,edge_face_id1),
|directed_edge_id0|MinkowskiFace::EdgeEdge(directed_edge_id0.as_edge_id(),edge_id1)
)
})
}).collect()) }).collect())
}, },
MinkowskiFace::EdgeEdge(e0,e1)=>{ MinkowskiFace::EdgeEdge(e0,e1)=>{
let e0v=self.mesh0.edge_verts(e0); let e0v=self.mesh0.edge_verts(e0);
let e0f=self.mesh0.edge_faces(e0);
let edge0_n=self.mesh0.edge_n(e0);
let e1v=self.mesh1.edge_verts(e1); let e1v=self.mesh1.edge_verts(e1);
let e1f=self.mesh1.edge_faces(e1);
let edge1_n=self.mesh1.edge_n(e1);
//populate algorithm variables based on known parity
//I don't like that this arbitrarily picks a face to test against!
let (e0v0_face_id1,e0v1_face_id1)=if edge0_n.dot(self.mesh1.face_nd(e1f[0]).0)<=Planar64::ZERO{
(e1f[1],e1f[0])
}else{
(e1f[0],e1f[1])
};
let [r0,r1]=[(e0v[0],e0v0_face_id1),(e0v[1],e0v1_face_id1)].map(|(vert_id0,edge_face_id1)|{
(MinkowskiEdge::VertEdge(vert_id0,e1),{
let mut best_edge=None;
let mut best_d=Planar64::MAX;
let edge_face1_n=self.mesh1.face_nd(edge_face_id1).0;
let v0e=self.mesh0.vert_directed_edges(vert_id0);
for &directed_edge_id0 in v0e.iter(){
let edge0_n=self.mesh0.directed_edge_n(directed_edge_id0);
if edge_face1_n.dot(edge0_n)<Planar64::ZERO{
//I think face_id1 == edge_face_id1 in this case
let d=edge_face1_n.dot(edge0_n);
if d<best_d{
best_d=d;
best_edge=Some(directed_edge_id0);
}
}
}
best_edge.map_or(
MinkowskiFace::VertFace(vert_id0,edge_face_id1),
|directed_edge_id0|MinkowskiFace::EdgeEdge(directed_edge_id0.as_edge_id(),e1)
)
})
});
let (e1v0_face_id0,e1v1_face_id0)=if edge1_n.dot(self.mesh0.face_nd(e0f[0]).0)<=Planar64::ZERO{
(e0f[1],e0f[0])
}else{
(e0f[0],e0f[1])
};
let [r2,r3]=[(e1v0_face_id0,e1v[0]),(e1v1_face_id0,e1v[1])].map(|(edge_face_id0,vert_id1)|{
(MinkowskiEdge::EdgeVert(e0,vert_id1),{
let mut best_edge=None;
let mut best_d=Planar64::MAX;
let edge_face0_n=self.mesh0.face_nd(edge_face_id0).0;
let v1e=self.mesh1.vert_directed_edges(vert_id1);
for &directed_edge_id1 in v1e.iter(){
let edge1_n=self.mesh1.directed_edge_n(directed_edge_id1);
if edge_face0_n.dot(edge1_n)<Planar64::ZERO{
let d=edge_face0_n.dot(edge1_n);
if d<best_d{
best_d=d;
best_edge=Some(directed_edge_id1);
}
}
}
best_edge.map_or(
MinkowskiFace::FaceVert(edge_face_id0,vert_id1),
|directed_edge_id1|MinkowskiFace::EdgeEdge(e0,directed_edge_id1.as_edge_id())
)
})
});
//could sort this if ordered edges are needed //could sort this if ordered edges are needed
Cow::Owned(vec![r0,r1,r2,r3]) Cow::Owned(vec![
MinkowskiEdge::VertEdge(e0v[0],e1),
MinkowskiEdge::VertEdge(e0v[1],e1),
MinkowskiEdge::EdgeVert(e0,e1v[0]),
MinkowskiEdge::EdgeVert(e0,e1v[1]),
])
}, },
MinkowskiFace::FaceVert(f0,v1)=>{ MinkowskiFace::FaceVert(f0,v1)=>{
let face0_n=self.mesh0.face_nd(f0).0; Cow::Owned(self.mesh0.face_edges(f0).iter().map(|&edge_id0|{
Cow::Owned(self.mesh0.face_edges(f0).iter().map(|&(edge_id0,edge_face_id0)|{ MinkowskiEdge::EdgeVert(edge_id0,v1)
//compare v1 edges
//candidate edges have negative dot with edge_face_id0 normal
//choose the edge with the smallest edgedir dot with f0 normal
//MinkowskiFace::EdgeEdge(edge_id0,edge_id1)
//if there is no candidate edges
//MinkowskiFace::FaceVert(edge_face_id0,v1)
(MinkowskiEdge::EdgeVert(edge_id0,v1),{
let mut best_edge=None;
let mut best_d=Planar64::MAX;
let edge_face0_n=self.mesh0.face_nd(edge_face_id0).0;
let v1e=self.mesh1.vert_directed_edges(v1);
for &directed_edge_id1 in v1e.iter(){
let edge1_n=self.mesh1.directed_edge_n(directed_edge_id1);
if edge_face0_n.dot(edge1_n)<Planar64::ZERO{
let d=face0_n.dot(edge1_n);
if d<best_d{
best_d=d;
best_edge=Some(directed_edge_id1);
}
}
}
best_edge.map_or(
MinkowskiFace::FaceVert(edge_face_id0,v1),
|directed_edge_id1|MinkowskiFace::EdgeEdge(edge_id0,directed_edge_id1.as_edge_id())
)
})
}).collect()) }).collect())
}, },
} }