Compare commits

..

28 Commits

Author SHA1 Message Date
6ca6e4ac3d stop being so wide 2024-09-26 18:46:04 -07:00
4eda90e178 floor(x+1)==floor(x)+1 2024-09-26 18:44:12 -07:00
72c91558e7 use one type def for dt ratio 2024-09-26 18:43:11 -07:00
9453ef17fb uniquely identify test 2024-09-26 18:04:58 -07:00
7425f1cd01 fix tests 2024-09-26 18:04:49 -07:00
682fa44741 fix fart 2024-09-26 16:39:32 -07:00
84b364313b debug things 2024-09-26 16:39:32 -07:00
6005485789 fix face_nd 2024-09-26 16:09:37 -07:00
2fc1fcfa80 Revert "det unused"
This reverts commit 6b897620e9.
2024-09-26 16:07:46 -07:00
8a1e713170 column major 2024-09-26 15:08:50 -07:00
a685c4ebe2 point to commit 2024-09-25 14:55:36 -07:00
0150bb977d optimize is_empty_volume 2024-09-25 10:18:38 -07:00
f280b65fc9 fix is_empty_volume test 2024-09-25 10:00:24 -07:00
327ba10fb4 already 8 2024-09-17 15:56:26 -07:00
6b897620e9 det unused 2024-09-17 15:06:12 -07:00
a5efbe6574 plumb time ratio everywhere and make a special spot for it in internal instructions 2024-09-16 15:05:11 -07:00
a64b81f05e precise time ratio 2024-09-16 15:04:38 -07:00
462950d526 ignore precision 2024-09-16 15:03:52 -07:00
c5f9a30c1b graphics 2024-09-16 15:03:18 -07:00
1d4a79b15e graphics: wip 2024-09-16 13:05:49 -07:00
4556bc8741 do face crawler 2024-09-16 13:05:09 -07:00
215dfab8a9 write body extrapolation from time ratio using ridiculous trait bounds 2024-09-16 13:05:09 -07:00
d6e15dea05 fix errors 2024-09-13 14:01:13 -07:00
ec8c89de9c many work 2024-09-13 13:51:33 -07:00
33c9fb0399 wip 2024-09-12 13:49:48 -07:00
bbc9a89ad7 physics.rs cleared 2024-09-12 13:49:42 -07:00
fc7d4b7e0c more wip 2024-09-12 13:12:19 -07:00
60bd926ce1 wip wip 2024-09-12 13:09:25 -07:00
6 changed files with 265 additions and 510 deletions

692
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[package] [package]
name = "strafe-client" name = "strafe-client"
version = "0.10.5" version = "0.10.3"
edition = "2021" edition = "2021"
repository = "https://git.itzana.me/StrafesNET/strafe-client" repository = "https://git.itzana.me/StrafesNET/strafe-client"
license = "Custom" license = "Custom"
@ -18,17 +18,17 @@ roblox = ["dep:strafesnet_deferred_loader", "dep:strafesnet_rbx_loader"]
bytemuck = { version = "1.13.1", features = ["derive"] } bytemuck = { version = "1.13.1", features = ["derive"] }
configparser = "3.0.2" configparser = "3.0.2"
ddsfile = "0.5.1" ddsfile = "0.5.1"
glam = "0.29.0" glam = "0.28.0"
id = { version = "0.1.0", registry = "strafesnet" } id = { version = "0.1.0", registry = "strafesnet" }
parking_lot = "0.12.1" parking_lot = "0.12.1"
pollster = "0.3.0" pollster = "0.3.0"
strafesnet_bsp_loader = { version = "0.2.1", registry = "strafesnet", optional = true } strafesnet_bsp_loader = { version = "0.1.3", registry = "strafesnet", optional = true }
strafesnet_common = { version = "0.5.2", registry = "strafesnet" } strafesnet_common = { git = "https://git.itzana.me/StrafesNET/common", rev = "c5f01d4c3ea3aa2ee3448ff42f020f5f5239dc95" }
strafesnet_deferred_loader = { version = "0.4.0", features = ["legacy"], registry = "strafesnet", optional = true } strafesnet_deferred_loader = { version = "0.3.1", features = ["legacy"], registry = "strafesnet", optional = true }
strafesnet_rbx_loader = { version = "0.5.1", registry = "strafesnet", optional = true } strafesnet_rbx_loader = { version = "0.3.2", registry = "strafesnet", optional = true }
strafesnet_snf = { version = "0.2.0", registry = "strafesnet", optional = true } strafesnet_snf = { git = "https://git.itzana.me/StrafesNET/snf", rev = "1e0095ed1583f0330d8dbdf1f56edd61bfb43eec", optional = true }
wgpu = "22.1.0" wgpu = "22.0.0"
winit = "0.30.5" winit = "0.30.4"
[profile.release] [profile.release]
#lto = true #lto = true

View File

@ -15,7 +15,7 @@ type MinkowskiTransition=Transition<MinkowskiFace,MinkowskiDirectedEdge,Minkowsk
fn next_transition(fev:&MinkowskiFEV,body_time:GigaTime,mesh:&MinkowskiMesh,body:&Body,mut best_time:GigaTime)->MinkowskiTransition{ fn next_transition(fev:&MinkowskiFEV,body_time:GigaTime,mesh:&MinkowskiMesh,body:&Body,mut best_time:GigaTime)->MinkowskiTransition{
//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_transition=MinkowskiTransition::Miss; let mut best_transtition=MinkowskiTransition::Miss;
match fev{ match fev{
&MinkowskiFEV::Face(face_id)=>{ &MinkowskiFEV::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
@ -24,10 +24,10 @@ type MinkowskiTransition=Transition<MinkowskiFace,MinkowskiDirectedEdge,Minkowsk
let (n,d)=mesh.face_nd(face_id); let (n,d)=mesh.face_nd(face_id);
//TODO: use higher precision d value? //TODO: use higher precision d value?
//use the mesh transform translation instead of baking it into the d value. //use the mesh transform translation instead of baking it into the d value.
for dt in Fixed::<4,128>::zeroes2((n.dot(body.position)-d)*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){ for dt in Fixed::<2,64>::zeroes2((n.dot(body.position)-d).fix_2()*2,n.dot(body.velocity).fix_2()*2,n.dot(body.acceleration).fix_2()){
if body_time.le_ratio(dt)&&dt.lt_ratio(best_time)&&n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative(){ if body_time.le_ratio(dt)&&dt.lt_ratio(best_time)&&n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative(){
best_time=dt; best_time=dt;
best_transition=MinkowskiTransition::Hit(face_id,dt); best_transtition=MinkowskiTransition::Hit(face_id,dt);
break; break;
} }
} }
@ -38,10 +38,10 @@ type MinkowskiTransition=Transition<MinkowskiFace,MinkowskiDirectedEdge,Minkowsk
let verts=mesh.edge_verts(directed_edge_id.as_undirected()); let verts=mesh.edge_verts(directed_edge_id.as_undirected());
//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!
//WARNING: precision is swept under the rug! //WARNING: precision is swept under the rug!
for dt in Fixed::<4,128>::zeroes2(n.dot(body.position*2-(mesh.vert(verts[0])+mesh.vert(verts[1]))).fix_4(),n.dot(body.velocity).fix_4()*2,n.dot(body.acceleration).fix_4()){ for dt in Fixed::<2,64>::zeroes2(n.dot(body.position*2-(mesh.vert(verts[0])+mesh.vert(verts[1]))).fix_2(),n.dot(body.velocity).fix_2()*2,n.dot(body.acceleration).fix_2()){
if body_time.le_ratio(dt)&&dt.lt_ratio(best_time)&&n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative(){ if body_time.le_ratio(dt)&&dt.lt_ratio(best_time)&&n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative(){
best_time=dt; best_time=dt;
best_transition=MinkowskiTransition::Next(MinkowskiFEV::Edge(directed_edge_id.as_undirected()),dt); best_transtition=MinkowskiTransition::Next(MinkowskiFEV::Edge(directed_edge_id.as_undirected()),dt);
break; break;
} }
} }
@ -58,10 +58,10 @@ type MinkowskiTransition=Transition<MinkowskiFace,MinkowskiDirectedEdge,Minkowsk
//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);
//WARNING yada yada d *2 //WARNING yada yada d *2
for dt in Fixed::<4,128>::zeroes2(n.dot(delta_pos).fix_4(),n.dot(body.velocity).fix_4()*2,n.dot(body.acceleration).fix_4()){ for dt in Fixed::<2,64>::zeroes2(n.dot(delta_pos).fix_2(),n.dot(body.velocity).fix_2()*2,n.dot(body.acceleration).fix_2()){
if body_time.le_ratio(dt)&&dt.lt_ratio(best_time)&&n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative(){ if body_time.le_ratio(dt)&&dt.lt_ratio(best_time)&&n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative(){
best_time=dt; best_time=dt;
best_transition=MinkowskiTransition::Next(MinkowskiFEV::Face(edge_face_id),dt); best_transtition=MinkowskiTransition::Next(MinkowskiFEV::Face(edge_face_id),dt);
break; break;
} }
} }
@ -72,9 +72,9 @@ type MinkowskiTransition=Transition<MinkowskiFace,MinkowskiDirectedEdge,Minkowsk
let n=edge_n*(1-2*(i as i64)); let n=edge_n*(1-2*(i as i64));
for dt in Fixed::<2,64>::zeroes2((n.dot(body.position-mesh.vert(vert_id)))*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){ for dt in Fixed::<2,64>::zeroes2((n.dot(body.position-mesh.vert(vert_id)))*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){
if body_time.le_ratio(dt)&&dt.lt_ratio(best_time)&&n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative(){ if body_time.le_ratio(dt)&&dt.lt_ratio(best_time)&&n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative(){
let dt=Ratio::new(dt.num.fix_4(),dt.den.fix_4()); let dt=Ratio::new(dt.num.fix_2(),dt.den.fix_2());
best_time=dt; best_time=dt;
best_transition=MinkowskiTransition::Next(MinkowskiFEV::Vert(vert_id),dt); best_transtition=MinkowskiTransition::Next(MinkowskiFEV::Vert(vert_id),dt);
break; break;
} }
} }
@ -88,9 +88,9 @@ type MinkowskiTransition=Transition<MinkowskiFace,MinkowskiDirectedEdge,Minkowsk
let n=-mesh.directed_edge_n(directed_edge_id); let n=-mesh.directed_edge_n(directed_edge_id);
for dt in Fixed::<2,64>::zeroes2((n.dot(body.position-mesh.vert(vert_id)))*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){ for dt in Fixed::<2,64>::zeroes2((n.dot(body.position-mesh.vert(vert_id)))*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){
if body_time.le_ratio(dt)&&dt.lt_ratio(best_time)&&n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative(){ if body_time.le_ratio(dt)&&dt.lt_ratio(best_time)&&n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative(){
let dt=Ratio::new(dt.num.fix_4(),dt.den.fix_4()); let dt=Ratio::new(dt.num.fix_2(),dt.den.fix_2());
best_time=dt; best_time=dt;
best_transition=MinkowskiTransition::Next(MinkowskiFEV::Edge(directed_edge_id.as_undirected()),dt); best_transtition=MinkowskiTransition::Next(MinkowskiFEV::Edge(directed_edge_id.as_undirected()),dt);
break; break;
} }
} }
@ -98,7 +98,7 @@ type MinkowskiTransition=Transition<MinkowskiFace,MinkowskiDirectedEdge,Minkowsk
//if none: //if none:
}, },
} }
best_transition best_transtition
} }
pub enum CrawlResult<F,E:DirectedEdge,V>{ pub enum CrawlResult<F,E:DirectedEdge,V>{
Miss(FEV<F,E,V>), Miss(FEV<F,E,V>),
@ -108,11 +108,11 @@ type MinkowskiCrawlResult=CrawlResult<MinkowskiFace,MinkowskiDirectedEdge,Minkow
pub fn crawl_fev(mut fev:MinkowskiFEV,mesh:&MinkowskiMesh,relative_body:&Body,start_time:Time,time_limit:Time)->MinkowskiCrawlResult{ pub fn crawl_fev(mut fev:MinkowskiFEV,mesh:&MinkowskiMesh,relative_body:&Body,start_time:Time,time_limit:Time)->MinkowskiCrawlResult{
let mut body_time={ let mut body_time={
let r=(start_time-relative_body.time).to_ratio(); let r=(start_time-relative_body.time).to_ratio();
Ratio::new(r.num.fix_4(),r.den.fix_4()) Ratio::new(r.num.fix_2(),r.den.fix_2())
}; };
let time_limit={ let time_limit={
let r=(time_limit-relative_body.time).to_ratio(); let r=(time_limit-relative_body.time).to_ratio();
Ratio::new(r.num.fix_4(),r.den.fix_4()) Ratio::new(r.num.fix_2(),r.den.fix_2())
}; };
for _ in 0..20{ for _ in 0..20{
match next_transition(&fev,body_time,mesh,relative_body,time_limit){ match next_transition(&fev,body_time,mesh,relative_body,time_limit){

View File

@ -22,7 +22,7 @@ impl std::error::Error for ReadError{}
pub enum DataStructure{ pub enum DataStructure{
#[cfg(feature="roblox")] #[cfg(feature="roblox")]
Roblox(strafesnet_rbx_loader::Model), Roblox(strafesnet_rbx_loader::Dom),
#[cfg(feature="source")] #[cfg(feature="source")]
Source(strafesnet_bsp_loader::Bsp), Source(strafesnet_bsp_loader::Bsp),
#[cfg(feature="snf")] #[cfg(feature="snf")]
@ -66,16 +66,13 @@ pub fn load<P:AsRef<std::path::Path>>(path:P)->Result<strafesnet_common::map::Co
#[cfg(feature="snf")] #[cfg(feature="snf")]
DataStructure::StrafesNET(map)=>Ok(map), DataStructure::StrafesNET(map)=>Ok(map),
#[cfg(feature="roblox")] #[cfg(feature="roblox")]
DataStructure::Roblox(model)=>{ DataStructure::Roblox(dom)=>{
let mut place=model.into_place();
place.run_scripts();
let mut loader=strafesnet_deferred_loader::roblox_legacy(); let mut loader=strafesnet_deferred_loader::roblox_legacy();
let (texture_loader,mesh_loader)=loader.get_inner_mut(); let (texture_loader,mesh_loader)=loader.get_inner_mut();
let map_step1=strafesnet_rbx_loader::convert( let map_step1=strafesnet_rbx_loader::convert(
&place, &dom,
|name|texture_loader.acquire_render_config_id(name), |name|texture_loader.acquire_render_config_id(name),
|name|mesh_loader.acquire_mesh_id(name), |name|mesh_loader.acquire_mesh_id(name),
); );
@ -113,7 +110,7 @@ pub fn load<P:AsRef<std::path::Path>>(path:P)->Result<strafesnet_common::map::Co
|name|mesh_loader.acquire_mesh_id(name), |name|mesh_loader.acquire_mesh_id(name),
); );
let prop_meshes=mesh_loader.load_meshes(bsp.as_ref()); let prop_meshes=mesh_loader.load_meshes(&bsp.as_ref());
let map_step2=map_step1.add_prop_meshes( let map_step2=map_step1.add_prop_meshes(
//the type conflagulator 9000 //the type conflagulator 9000

View File

@ -599,7 +599,7 @@ enum EV{
Edge(MinkowskiEdge), Edge(MinkowskiEdge),
} }
pub type GigaTime=Ratio<Fixed<4,128>,Fixed<4,128>>; pub type GigaTime=Ratio<Fixed<2,64>,Fixed<2,64>>;
impl MinkowskiMesh<'_>{ impl MinkowskiMesh<'_>{
pub fn minkowski_sum<'a>(mesh0:TransformedMesh<'a>,mesh1:TransformedMesh<'a>)->MinkowskiMesh<'a>{ pub fn minkowski_sum<'a>(mesh0:TransformedMesh<'a>,mesh1:TransformedMesh<'a>)->MinkowskiMesh<'a>{
@ -707,8 +707,7 @@ impl MinkowskiMesh<'_>{
infinity_body.velocity=dir; infinity_body.velocity=dir;
infinity_body.acceleration=vec3::ZERO; infinity_body.acceleration=vec3::ZERO;
//crawl in from negative infinity along a tangent line to get the closest fev //crawl in from negative infinity along a tangent line to get the closest fev
// TODO: change crawl_fev args to delta time? Optional values? match crate::face_crawler::crawl_fev(infinity_fev,self,&infinity_body,integer::Time::MIN,infinity_body.time){
match crate::face_crawler::crawl_fev(infinity_fev,self,&infinity_body,integer::Time::MIN/4,infinity_body.time){
crate::face_crawler::CrawlResult::Miss(fev)=>Some(fev), crate::face_crawler::CrawlResult::Miss(fev)=>Some(fev),
crate::face_crawler::CrawlResult::Hit(_,_)=>None, crate::face_crawler::CrawlResult::Hit(_,_)=>None,
} }
@ -744,7 +743,7 @@ impl MinkowskiMesh<'_>{
//determine when it passes an edge ("sliding off" case) //determine when it passes an edge ("sliding off" case)
let mut best_time={ let mut best_time={
let r=(time_limit-relative_body.time).to_ratio(); let r=(time_limit-relative_body.time).to_ratio();
Ratio::new(r.num.fix_4(),r.den.fix_4()) Ratio::new(r.num.fix_2(),r.den.fix_2())
}; };
let mut best_edge=None; let mut best_edge=None;
let face_n=self.face_nd(contact_face_id).0; let face_n=self.face_nd(contact_face_id).0;
@ -756,8 +755,8 @@ impl MinkowskiMesh<'_>{
let d=n.dot(self.vert(verts[0])+self.vert(verts[1])); let d=n.dot(self.vert(verts[0])+self.vert(verts[1]));
//WARNING! d outside of *2 //WARNING! d outside of *2
//WARNING: truncated precision //WARNING: truncated precision
for dt in Fixed::<4,128>::zeroes2(((n.dot(relative_body.position))*2-d).fix_4(),n.dot(relative_body.velocity).fix_4()*2,n.dot(relative_body.acceleration).fix_4()){ for dt in Fixed::<2,64>::zeroes2(((n.dot(relative_body.position))*2-d).fix_2(),n.dot(relative_body.velocity).fix_2()*2,n.dot(relative_body.acceleration).fix_2()){
if Ratio::new(Planar64::ZERO,Planar64::EPSILON).le_ratio(dt)&&dt.lt_ratio(best_time)&&n.dot(relative_body.extrapolated_velocity_ratio_dt(dt)).is_negative(){ if dt.num.is_positive()&&dt.lt_ratio(best_time)&&n.dot(relative_body.extrapolated_velocity_ratio_dt(dt)).is_negative(){
best_time=dt; best_time=dt;
best_edge=Some(directed_edge_id); best_edge=Some(directed_edge_id);
break; break;
@ -768,7 +767,7 @@ impl MinkowskiMesh<'_>{
} }
fn infinity_in(&self,infinity_body:crate::physics::Body)->Option<(MinkowskiFace,GigaTime)>{ fn infinity_in(&self,infinity_body:crate::physics::Body)->Option<(MinkowskiFace,GigaTime)>{
let infinity_fev=self.infinity_fev(-infinity_body.velocity,infinity_body.position); let infinity_fev=self.infinity_fev(-infinity_body.velocity,infinity_body.position);
match crate::face_crawler::crawl_fev(infinity_fev,self,&infinity_body,integer::Time::MIN/4,infinity_body.time){ match crate::face_crawler::crawl_fev(infinity_fev,self,&infinity_body,integer::Time::MIN,infinity_body.time){
crate::face_crawler::CrawlResult::Miss(_)=>None, crate::face_crawler::CrawlResult::Miss(_)=>None,
crate::face_crawler::CrawlResult::Hit(face,time)=>Some((face,time)), crate::face_crawler::CrawlResult::Hit(face,time)=>Some((face,time)),
} }
@ -850,7 +849,7 @@ impl MeshQuery<MinkowskiFace,MinkowskiDirectedEdge,MinkowskiVert> for MinkowskiM
let &[e1f0,e1f1]=self.mesh1.edge_faces(e1).borrow(); let &[e1f0,e1f1]=self.mesh1.edge_faces(e1).borrow();
Cow::Owned([(e1f1,false),(e1f0,true)].map(|(edge_face_id1,face_parity)|{ Cow::Owned([(e1f1,false),(e1f0,true)].map(|(edge_face_id1,face_parity)|{
let mut best_edge=None; let mut best_edge=None;
let mut best_d:Ratio<Fixed<8,256>,Fixed<8,256>>=Ratio::new(Fixed::ZERO,Fixed::ONE); let mut best_d:Ratio<Fixed<2,64>,Fixed<2,64>>=Ratio::new(Fixed::ZERO,Fixed::ONE);
let edge_face1_n=self.mesh1.face_nd(edge_face_id1).0; let edge_face1_n=self.mesh1.face_nd(edge_face_id1).0;
let edge_face1_nn=edge_face1_n.dot(edge_face1_n); let edge_face1_nn=edge_face1_n.dot(edge_face1_n);
for &directed_edge_id0 in v0e.iter(){ for &directed_edge_id0 in v0e.iter(){
@ -861,7 +860,7 @@ impl MeshQuery<MinkowskiFace,MinkowskiDirectedEdge,MinkowskiVert> for MinkowskiM
let edge0_nn=edge0_n.dot(edge0_n); let edge0_nn=edge0_n.dot(edge0_n);
// Assume not every number is huge // Assume not every number is huge
// TODO: revisit this // TODO: revisit this
let dd=(d*d)/(edge_face1_nn*edge0_nn); let dd=(d*d).fix_2()/(edge_face1_nn*edge0_nn).fix_2();
if best_d<dd{ if best_d<dd{
best_d=dd; best_d=dd;
best_edge=Some(directed_edge_id0); best_edge=Some(directed_edge_id0);
@ -880,7 +879,7 @@ impl MeshQuery<MinkowskiFace,MinkowskiDirectedEdge,MinkowskiVert> for MinkowskiM
let &[e0f0,e0f1]=self.mesh0.edge_faces(e0).borrow(); let &[e0f0,e0f1]=self.mesh0.edge_faces(e0).borrow();
Cow::Owned([(e0f0,true),(e0f1,false)].map(|(edge_face_id0,face_parity)|{ Cow::Owned([(e0f0,true),(e0f1,false)].map(|(edge_face_id0,face_parity)|{
let mut best_edge=None; let mut best_edge=None;
let mut best_d:Ratio<Fixed<8,256>,Fixed<8,256>>=Ratio::new(Fixed::ZERO,Fixed::ONE); let mut best_d:Ratio<Fixed<2,64>,Fixed<2,64>>=Ratio::new(Fixed::ZERO,Fixed::ONE);
let edge_face0_n=self.mesh0.face_nd(edge_face_id0).0; let edge_face0_n=self.mesh0.face_nd(edge_face_id0).0;
let edge_face0_nn=edge_face0_n.dot(edge_face0_n); let edge_face0_nn=edge_face0_n.dot(edge_face0_n);
for &directed_edge_id1 in v1e.iter(){ for &directed_edge_id1 in v1e.iter(){
@ -888,7 +887,7 @@ impl MeshQuery<MinkowskiFace,MinkowskiDirectedEdge,MinkowskiVert> for MinkowskiM
let d=edge_face0_n.dot(edge1_n); let d=edge_face0_n.dot(edge1_n);
if d.is_negative(){ if d.is_negative(){
let edge1_nn=edge1_n.dot(edge1_n); let edge1_nn=edge1_n.dot(edge1_n);
let dd=(d*d)/(edge_face0_nn*edge1_nn); let dd=(d*d).fix_2()/(edge_face0_nn*edge1_nn).fix_2();
if best_d<dd{ if best_d<dd{
best_d=dd; best_d=dd;
best_edge=Some(directed_edge_id1); best_edge=Some(directed_edge_id1);

View File

@ -877,7 +877,8 @@ impl Body{
T1:integer::Fix<Planar64>, T1:integer::Fix<Planar64>,
{ {
// a*dt + v // a*dt + v
self.acceleration.map(|elem|(dt*elem).divide().fix())+self.velocity self.acceleration.map(|elem|dt*elem)
.map(|elem|elem.divide().fix())+self.velocity
} }
pub fn advance_time_ratio_dt(&mut self,dt:model_physics::GigaTime){ pub fn advance_time_ratio_dt(&mut self,dt:model_physics::GigaTime){
self.position=self.extrapolated_position_ratio_dt(dt); self.position=self.extrapolated_position_ratio_dt(dt);
@ -1956,7 +1957,7 @@ fn atomic_input_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:TimedI
_=>println!("{}|{:?}",ins.time,ins.instruction), _=>println!("{}|{:?}",ins.time,ins.instruction),
} }
if ins.time<state.time{ if ins.time<state.time{
println!("@@@@ Time travel warning! state.time={} ins.time={}\nInstruction={:?}",state.time,ins.time,ins.instruction); println!("@@@@ Time travel warning! {:?}",ins);
} }
//idle is special, it is specifically a no-op to get Internal events to catch up to real time //idle is special, it is specifically a no-op to get Internal events to catch up to real time
match ins.instruction{ match ins.instruction{