This commit is contained in:
Quaternions 2023-11-16 20:08:31 -08:00
parent 8e27c404a3
commit abaf0b2939
3 changed files with 28 additions and 8 deletions

View File

@ -3,6 +3,7 @@ use crate::model_physics::{FEV,MeshQuery,DirectedEdge};
use crate::integer::{Time,Planar64}; use crate::integer::{Time,Planar64};
use crate::zeroes::zeroes2; use crate::zeroes::zeroes2;
#[derive(Debug)]
enum Transition<F,E:DirectedEdge,V>{ enum Transition<F,E:DirectedEdge,V>{
Miss, Miss,
Next(FEV<F,E,V>,Time), Next(FEV<F,E,V>,Time),
@ -20,8 +21,10 @@ enum Transition<F,E:DirectedEdge,V>{
//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
let (n,d)=mesh.face_nd(face_id); let (n,d)=mesh.face_nd(face_id);
println!("Face n={} d={}",n,d);
for t in zeroes2((n.dot(body.position)-d)*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){ for t in zeroes2((n.dot(body.position)-d)*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){
let t=body.time+Time::from(t); let t=body.time+Time::from(t);
println!("dt={} low={} upp={} into={}",t-body.time,time<=t,t<best_time,n.dot(body.extrapolated_velocity(t))<Planar64::ZERO);
if time<=t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{ if time<=t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{
best_time=t; best_time=t;
best_transtition=Transition::Hit(face_id,t); best_transtition=Transition::Hit(face_id,t);
@ -34,9 +37,11 @@ enum Transition<F,E:DirectedEdge,V>{
let n=n.cross(edge_n); let n=n.cross(edge_n);
let verts=mesh.edge_verts(directed_edge_id.as_undirected()); let verts=mesh.edge_verts(directed_edge_id.as_undirected());
let d=n.dot(mesh.vert(verts[0])+mesh.vert(verts[1])); let d=n.dot(mesh.vert(verts[0])+mesh.vert(verts[1]));
println!("Face Edge n={} d={}",n,d/2);
//WARNING: d is moved out of the *2 block because of adding two vertices! //WARNING: d is moved out of the *2 block because of adding two vertices!
for t in zeroes2(n.dot(body.position)*2-d,n.dot(body.velocity)*2,n.dot(body.acceleration)){ for t in zeroes2(n.dot(body.position)*2-d,n.dot(body.velocity)*2,n.dot(body.acceleration)){
let t=body.time+Time::from(t); let t=body.time+Time::from(t);
println!("dt={} low={} upp={} into={}",t-body.time,time<=t,t<best_time,n.dot(body.extrapolated_velocity(t))<Planar64::ZERO);
if time<=t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{ if time<=t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{
best_time=t; best_time=t;
best_transtition=Transition::Next(FEV::<F,E,V>::Edge(directed_edge_id.as_undirected()),t); best_transtition=Transition::Next(FEV::<F,E,V>::Edge(directed_edge_id.as_undirected()),t);
@ -56,9 +61,11 @@ enum Transition<F,E:DirectedEdge,V>{
//edge_n gets parity from the order of edge_faces //edge_n gets parity from the order of edge_faces
let n=face_n.cross(edge_n)*((i as i64)*2-1); let n=face_n.cross(edge_n)*((i as i64)*2-1);
let d=n.dot(vert_sum); let d=n.dot(vert_sum);
println!("Edge Face n={} d={}",n,d/2);
//WARNING yada yada d *2 //WARNING yada yada d *2
for t in zeroes2((n.dot(body.position))*2-d,n.dot(body.velocity)*2,n.dot(body.acceleration)){ for t in zeroes2((n.dot(body.position))*2-d,n.dot(body.velocity)*2,n.dot(body.acceleration)){
let t=body.time+Time::from(t); let t=body.time+Time::from(t);
println!("dt={} low={} upp={} into={}",t-body.time,time<=t,t<best_time,n.dot(body.extrapolated_velocity(t))<Planar64::ZERO);
if time<=t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{ if time<=t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{
best_time=t; best_time=t;
best_transtition=Transition::Next(FEV::<F,E,V>::Face(edge_face_id),t); best_transtition=Transition::Next(FEV::<F,E,V>::Face(edge_face_id),t);
@ -71,8 +78,10 @@ enum Transition<F,E:DirectedEdge,V>{
//vertex normal gets parity from vert index //vertex normal gets parity from vert index
let n=edge_n*(1-2*(i as i64)); let n=edge_n*(1-2*(i as i64));
let d=n.dot(mesh.vert(vert_id)); let d=n.dot(mesh.vert(vert_id));
println!("Edge Vert n={} d={}",n,d);
for t in zeroes2((n.dot(body.position)-d)*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){ for t in zeroes2((n.dot(body.position)-d)*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){
let t=body.time+Time::from(t); let t=body.time+Time::from(t);
println!("dt={} low={} upp={} into={}",t-body.time,time<=t,t<best_time,n.dot(body.extrapolated_velocity(t))<Planar64::ZERO);
if time<=t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{ if time<=t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{
best_time=t; best_time=t;
best_transtition=Transition::Next(FEV::<F,E,V>::Vert(vert_id),t); best_transtition=Transition::Next(FEV::<F,E,V>::Vert(vert_id),t);
@ -88,8 +97,10 @@ enum Transition<F,E:DirectedEdge,V>{
//edge is directed away from vertex, but we want the dot product to turn out negative //edge is directed away from vertex, but we want the dot product to turn out negative
let n=-mesh.directed_edge_n(directed_edge_id); let n=-mesh.directed_edge_n(directed_edge_id);
let d=n.dot(mesh.vert(vert_id)); let d=n.dot(mesh.vert(vert_id));
println!("Vert Edge n={} d={}",n,d);
for t in zeroes2((n.dot(body.position)-d)*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){ for t in zeroes2((n.dot(body.position)-d)*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){
let t=body.time+Time::from(t); let t=body.time+Time::from(t);
println!("dt={} low={} upp={} into={}",t-body.time,time<=t,t<best_time,n.dot(body.extrapolated_velocity(t))<Planar64::ZERO);
if time<=t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{ if time<=t&&t<best_time&&n.dot(body.extrapolated_velocity(t))<Planar64::ZERO{
best_time=t; best_time=t;
best_transtition=Transition::Next(FEV::<F,E,V>::Edge(directed_edge_id.as_undirected()),t); best_transtition=Transition::Next(FEV::<F,E,V>::Edge(directed_edge_id.as_undirected()),t);
@ -106,9 +117,10 @@ pub enum CrawlResult<F,E:DirectedEdge,V>{
Miss(FEV<F,E,V>), Miss(FEV<F,E,V>),
Hit(F,Time), Hit(F,Time),
} }
pub fn crawl_fev<F:Copy,E:Copy+DirectedEdge,V:Copy>(mut fev:FEV<F,E,V>,mesh:&impl MeshQuery<F,E,V>,relative_body:&Body,start_time:Time,time_limit:Time)->CrawlResult<F,E,V>{ pub fn crawl_fev<F:Copy+std::fmt::Debug,E:Copy+std::fmt::Debug+DirectedEdge,V:Copy+std::fmt::Debug>(mut fev:FEV<F,E,V>,mesh:&impl MeshQuery<F,E,V>,relative_body:&Body,start_time:Time,time_limit:Time)->CrawlResult<F,E,V>{
let mut time=start_time; let mut time=start_time;
for _ in 0..20{ for _ in 0..20{
println!("@ fev={:?} time={}",fev,time);
match next_transition(&fev,time,mesh,relative_body,time_limit){ match next_transition(&fev,time,mesh,relative_body,time_limit){
Transition::Miss=>return CrawlResult::Miss(fev), Transition::Miss=>return CrawlResult::Miss(fev),
Transition::Next(next_fev,next_time)=>(fev,time)=(next_fev,next_time), Transition::Next(next_fev,next_time)=>(fev,time)=(next_fev,next_time),

View File

@ -411,7 +411,7 @@ impl TryFrom<[f32;3]> for Unit32Vec3{
*/ */
///[-1.0,1.0] = [-2^32,2^32] ///[-1.0,1.0] = [-2^32,2^32]
#[derive(Clone,Copy,Hash,Eq,Ord,PartialEq,PartialOrd)] #[derive(Clone,Copy,Debug,Hash,Eq,Ord,PartialEq,PartialOrd)]
pub struct Planar64(i64); pub struct Planar64(i64);
impl Planar64{ impl Planar64{
pub const ZERO:Self=Self(0); pub const ZERO:Self=Self(0);
@ -583,7 +583,7 @@ impl std::ops::Div<Planar64> for Planar64{
///[-1.0,1.0] = [-2^32,2^32] ///[-1.0,1.0] = [-2^32,2^32]
#[derive(Clone,Copy,Default,Hash,Eq,PartialEq)] #[derive(Clone,Copy,Debug,Default,Hash,Eq,PartialEq)]
pub struct Planar64Vec3(glam::I64Vec3); pub struct Planar64Vec3(glam::I64Vec3);
impl Planar64Vec3{ impl Planar64Vec3{
pub const ZERO:Self=Planar64Vec3(glam::I64Vec3::ZERO); pub const ZERO:Self=Planar64Vec3(glam::I64Vec3::ZERO);

View File

@ -40,6 +40,7 @@ impl DirectedEdge for DirectedEdgeId{
pub struct FaceId(usize); pub struct FaceId(usize);
//Vertex <-> Edge <-> Face -> Collide //Vertex <-> Edge <-> Face -> Collide
#[derive(Debug)]
pub enum FEV<F,E:DirectedEdge,V>{ pub enum FEV<F,E:DirectedEdge,V>{
Face(F), Face(F),
Edge(E::UndirectedEdge), Edge(E::UndirectedEdge),
@ -47,10 +48,12 @@ pub enum FEV<F,E:DirectedEdge,V>{
} }
//use Unit32 #[repr(C)] for map files //use Unit32 #[repr(C)] for map files
#[derive(Debug)]
struct Face{ struct Face{
normal:Planar64Vec3, normal:Planar64Vec3,
dot:Planar64, dot:Planar64,
} }
#[derive(Debug)]
struct Vert(Planar64Vec3); struct Vert(Planar64Vec3);
pub trait MeshQuery<FACE:Clone,EDGE:Clone+DirectedEdge,VERT:Clone>{ pub trait MeshQuery<FACE:Clone,EDGE:Clone+DirectedEdge,VERT:Clone>{
fn edge_n(&self,edge_id:EDGE::UndirectedEdge)->Planar64Vec3{ fn edge_n(&self,edge_id:EDGE::UndirectedEdge)->Planar64Vec3{
@ -69,18 +72,22 @@ pub trait MeshQuery<FACE:Clone,EDGE:Clone+DirectedEdge,VERT:Clone>{
fn vert_edges(&self,vert_id:VERT)->Cow<Vec<EDGE>>; fn vert_edges(&self,vert_id:VERT)->Cow<Vec<EDGE>>;
fn vert_faces(&self,vert_id:VERT)->Cow<Vec<FACE>>; fn vert_faces(&self,vert_id:VERT)->Cow<Vec<FACE>>;
} }
#[derive(Debug)]
struct FaceRefs{ struct FaceRefs{
edges:Vec<DirectedEdgeId>, edges:Vec<DirectedEdgeId>,
//verts:Vec<VertId>, //verts:Vec<VertId>,
} }
#[derive(Debug)]
struct EdgeRefs{ struct EdgeRefs{
faces:[FaceId;2],//left, right faces:[FaceId;2],//left, right
verts:[VertId;2],//bottom, top verts:[VertId;2],//bottom, top
} }
#[derive(Debug)]
struct VertRefs{ struct VertRefs{
faces:Vec<FaceId>, faces:Vec<FaceId>,
edges:Vec<DirectedEdgeId>, edges:Vec<DirectedEdgeId>,
} }
#[derive(Debug)]
pub struct PhysicsMesh{ pub struct PhysicsMesh{
faces:Vec<Face>, faces:Vec<Face>,
verts:Vec<Vert>, verts:Vec<Vert>,
@ -301,11 +308,11 @@ impl MeshQuery<FaceId,DirectedEdgeId,VertId> for TransformedMesh<'_>{
//(face,vertex) //(face,vertex)
//(edge,edge) //(edge,edge)
//(vertex,face) //(vertex,face)
#[derive(Clone,Copy)] #[derive(Clone,Copy,Debug)]
pub enum MinkowskiVert{ pub enum MinkowskiVert{
VertVert(VertId,VertId), VertVert(VertId,VertId),
} }
#[derive(Clone,Copy)] #[derive(Clone,Copy,Debug)]
pub enum MinkowskiEdge{ pub enum MinkowskiEdge{
VertEdge(VertId,EdgeId), VertEdge(VertId,EdgeId),
EdgeVert(EdgeId,VertId), EdgeVert(EdgeId,VertId),
@ -320,7 +327,7 @@ impl UndirectedEdge for MinkowskiEdge{
} }
} }
} }
#[derive(Clone,Copy)] #[derive(Clone,Copy,Debug)]
pub enum MinkowskiDirectedEdge{ pub enum MinkowskiDirectedEdge{
VertEdge(VertId,DirectedEdgeId), VertEdge(VertId,DirectedEdgeId),
EdgeVert(DirectedEdgeId,VertId), EdgeVert(DirectedEdgeId,VertId),
@ -341,7 +348,7 @@ impl DirectedEdge for MinkowskiDirectedEdge{
} }
} }
} }
#[derive(Debug,Clone,Copy,Hash,Eq,PartialEq)] #[derive(Clone,Copy,Debug,Hash,Eq,PartialEq)]
pub enum MinkowskiFace{ pub enum MinkowskiFace{
VertFace(VertId,FaceId), VertFace(VertId,FaceId),
EdgeEdge(EdgeId,EdgeId,bool), EdgeEdge(EdgeId,EdgeId,bool),
@ -477,6 +484,7 @@ impl MinkowskiMesh<'_>{
} }
pub fn predict_collision_in(&self,relative_body:&crate::physics::Body,time_limit:crate::integer::Time)->Option<(MinkowskiFace,crate::integer::Time)>{ pub fn predict_collision_in(&self,relative_body:&crate::physics::Body,time_limit:crate::integer::Time)->Option<(MinkowskiFace,crate::integer::Time)>{
self.closest_fev_not_inside(relative_body.clone()).map_or(None,|fev|{ self.closest_fev_not_inside(relative_body.clone()).map_or(None,|fev|{
println!("@@@BEGIN REAL CRAWL@@@");
//continue forwards along the body parabola //continue forwards along the body parabola
match crate::face_crawler::crawl_fev(fev,self,relative_body,relative_body.time,time_limit){ match crate::face_crawler::crawl_fev(fev,self,relative_body,relative_body.time,time_limit){
crate::face_crawler::CrawlResult::Miss(_)=>None, crate::face_crawler::CrawlResult::Miss(_)=>None,
@ -734,4 +742,4 @@ fn build_me_a_cube(){
let unit_cube=crate::primitives::unit_cube(); let unit_cube=crate::primitives::unit_cube();
let mesh=PhysicsMesh::from(&unit_cube); let mesh=PhysicsMesh::from(&unit_cube);
//println!("mesh={:?}",mesh); //println!("mesh={:?}",mesh);
} }