Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d4cfb9cd47 | |||
| b11a060042 | |||
| e38126302e | |||
| 75bd98ce19 | |||
| 79011171cb | |||
| cd58e20fc2 | |||
| fbdabf449a | |||
| 0a95f492ba | |||
| 27dba8a90d | |||
| 2b8bb0b705 |
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -51,7 +51,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "strafesnet_common"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bitflags",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "strafesnet_common"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
edition = "2021"
|
||||
repository = "https://git.itzana.me/StrafesNET/common"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
80
src/bvh.rs
80
src/bvh.rs
@@ -1,10 +1,14 @@
|
||||
use crate::aabb::Aabb;
|
||||
|
||||
//bvh 2
|
||||
//sort {x,y,z}_{min,max} (6 sets)
|
||||
//octree partitioning
|
||||
//for each axis, minimize the sum of the lower and upper partition world width
|
||||
//effectively, find the biggest gap
|
||||
//da algaritum
|
||||
//lista boxens
|
||||
//sort by {minx,maxx,miny,maxy,minz,maxz} (6 lists)
|
||||
//find the sets that minimizes the sum of surface areas
|
||||
//splitting is done when the minimum split sum of surface areas is larger than the node's own surface area
|
||||
|
||||
//start with bisection into octrees because a bad bvh is still 1000x better than no bvh
|
||||
//sort the centerpoints on each axis (3 lists)
|
||||
//bv is put into octant based on whether it is upper or lower in each list
|
||||
|
||||
pub enum RecursiveContent<R,T>{
|
||||
Branch(Vec<R>),
|
||||
@@ -117,57 +121,43 @@ fn generate_bvh_node<T>(boxen:Vec<(T,Aabb)>,force:bool)->BvhNode<T>{
|
||||
aabb,
|
||||
}
|
||||
}else{
|
||||
let mut sort_x_min=boxen.iter()
|
||||
.enumerate()
|
||||
.map(|(i,(_,aabb))|(i,aabb))
|
||||
.collect::<Vec<(usize,&Aabb)>>();
|
||||
let mut sort_x_max=sort_x_min.clone();
|
||||
let mut sort_y_min=sort_x_min.clone();
|
||||
let mut sort_y_max=sort_x_min.clone();
|
||||
let mut sort_z_min=sort_x_min.clone();
|
||||
let mut sort_z_max=sort_x_min.clone();
|
||||
//sort by x_min, but if x_min is equal, then sort by x_max reverse instead
|
||||
sort_x_min.sort_by(|&(_,aabb0),&(_,aabb1)|
|
||||
aabb0.min().x().cmp(&aabb1.min().x())
|
||||
.then(aabb0.max().x().cmp(&aabb1.max().x()).reverse())
|
||||
);
|
||||
sort_x_max.sort_by(|&(_,aabb0),&(_,aabb1)|
|
||||
aabb0.max().x().cmp(&aabb1.max().x())
|
||||
.then(aabb0.min().x().cmp(&aabb1.min().x()).reverse())
|
||||
);
|
||||
sort_y_min.sort_by(|&(_,aabb0),&(_,aabb1)|
|
||||
aabb0.min().y().cmp(&aabb1.min().y())
|
||||
.then(aabb0.max().y().cmp(&aabb1.max().y()).reverse())
|
||||
);
|
||||
sort_y_max.sort_by(|&(_,aabb0),&(_,aabb1)|
|
||||
aabb0.max().y().cmp(&aabb1.max().y())
|
||||
.then(aabb0.min().y().cmp(&aabb1.min().y()).reverse())
|
||||
);
|
||||
sort_z_min.sort_by(|&(_,aabb0),&(_,aabb1)|
|
||||
aabb0.min().z().cmp(&aabb1.min().z())
|
||||
.then(aabb0.max().z().cmp(&aabb1.max().z()).reverse())
|
||||
);
|
||||
sort_z_max.sort_by(|&(_,aabb0),&(_,aabb1)|
|
||||
aabb0.max().z().cmp(&aabb1.max().z())
|
||||
.then(aabb0.min().z().cmp(&aabb1.min().z()).reverse())
|
||||
);
|
||||
let mut sort_x=Vec::with_capacity(n);
|
||||
let mut sort_y=Vec::with_capacity(n);
|
||||
let mut sort_z=Vec::with_capacity(n);
|
||||
for (i,(_,aabb)) in boxen.iter().enumerate(){
|
||||
let center=aabb.center();
|
||||
sort_x.push((i,center.x()));
|
||||
sort_y.push((i,center.y()));
|
||||
sort_z.push((i,center.z()));
|
||||
}
|
||||
sort_x.sort_by(|tup0,tup1|tup0.1.cmp(&tup1.1));
|
||||
sort_y.sort_by(|tup0,tup1|tup0.1.cmp(&tup1.1));
|
||||
sort_z.sort_by(|tup0,tup1|tup0.1.cmp(&tup1.1));
|
||||
let h=n/2;
|
||||
let median_x=sort_x[h].1;
|
||||
let median_y=sort_y[h].1;
|
||||
let median_z=sort_z[h].1;
|
||||
//locate a run of values equal to the median
|
||||
//partition point gives the first index for which the predicate evaluates to false
|
||||
let first_index_gt_median_x=sort_x.partition_point(|tup|!(median_x<tup.1));
|
||||
let first_index_gt_median_y=sort_y.partition_point(|tup|!(median_y<tup.1));
|
||||
let first_index_gt_median_z=sort_z.partition_point(|tup|!(median_z<tup.1));
|
||||
let first_index_eq_median_x=sort_x.partition_point(|&(_,x)|x<median_x);
|
||||
let first_index_eq_median_y=sort_y.partition_point(|&(_,y)|y<median_y);
|
||||
let first_index_eq_median_z=sort_z.partition_point(|&(_,z)|z<median_z);
|
||||
let first_index_gt_median_x=sort_x.partition_point(|&(_,x)|x<=median_x);
|
||||
let first_index_gt_median_y=sort_y.partition_point(|&(_,y)|y<=median_y);
|
||||
let first_index_gt_median_z=sort_z.partition_point(|&(_,z)|z<=median_z);
|
||||
//pick which side median value copies go into such that both sides are as balanced as possible based on distance from n/2
|
||||
let partition_point_x=if n.abs_diff(2*first_index_eq_median_x)<n.abs_diff(2*first_index_gt_median_x){first_index_eq_median_x}else{first_index_gt_median_x};
|
||||
let partition_point_y=if n.abs_diff(2*first_index_eq_median_y)<n.abs_diff(2*first_index_gt_median_y){first_index_eq_median_y}else{first_index_gt_median_y};
|
||||
let partition_point_z=if n.abs_diff(2*first_index_eq_median_z)<n.abs_diff(2*first_index_gt_median_z){first_index_eq_median_z}else{first_index_gt_median_z};
|
||||
//this ids which octant the boxen is put in
|
||||
let mut octant=vec![0;n];
|
||||
for &(i,_) in &sort_x[first_index_gt_median_x..]{
|
||||
for &(i,_) in &sort_x[partition_point_x..]{
|
||||
octant[i]+=1<<0;
|
||||
}
|
||||
for &(i,_) in &sort_y[first_index_gt_median_y..]{
|
||||
for &(i,_) in &sort_y[partition_point_y..]{
|
||||
octant[i]+=1<<1;
|
||||
}
|
||||
for &(i,_) in &sort_z[first_index_gt_median_z..]{
|
||||
for &(i,_) in &sort_z[partition_point_z..]{
|
||||
octant[i]+=1<<2;
|
||||
}
|
||||
//generate lists for unique octant values
|
||||
|
||||
@@ -448,8 +448,25 @@ impl Planar64{
|
||||
self.0
|
||||
}
|
||||
#[inline]
|
||||
pub const fn abs(self)->Self{
|
||||
Self(self.0.abs())
|
||||
}
|
||||
#[inline]
|
||||
pub fn sqrt(&self)->Self{
|
||||
Planar64(unsafe{(((self.0 as i128)<<32) as f64).sqrt().to_int_unchecked()})
|
||||
const BITS:i32=64;
|
||||
const FRAC:i32=32;
|
||||
let pow=(((BITS-FRAC-(self.0.leading_zeros() as i32)+1)>>1)+FRAC)-1;
|
||||
let mut result=Self::ZERO;
|
||||
let wide_self=(self.0 as i128)<<FRAC;
|
||||
for i in (0..=pow).rev(){
|
||||
let new_result=Self::raw(result.0|1<<i);
|
||||
match wide_self.cmp(&((new_result.0 as i128)*(new_result.0 as i128))){
|
||||
core::cmp::Ordering::Less=>(),
|
||||
core::cmp::Ordering::Equal=>return new_result,
|
||||
core::cmp::Ordering::Greater=>result=new_result,
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
#[inline]
|
||||
pub const fn signum_i64(&self)->i64{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::timer::{TimerFixed,Realtime,Paused,Unpaused};
|
||||
use crate::integer::Time;
|
||||
|
||||
#[derive(Clone,Debug)]
|
||||
#[derive(Clone,Copy,Debug)]
|
||||
pub enum FlagReason{
|
||||
Anticheat,
|
||||
StyleChange,
|
||||
@@ -42,14 +42,14 @@ impl std::fmt::Display for Error{
|
||||
}
|
||||
impl std::error::Error for Error{}
|
||||
|
||||
#[derive(Clone,Debug)]
|
||||
#[derive(Clone,Copy,Debug)]
|
||||
enum RunState{
|
||||
Created,
|
||||
Started{timer:TimerFixed<Realtime,Unpaused>},
|
||||
Finished{timer:TimerFixed<Realtime,Paused>},
|
||||
}
|
||||
|
||||
#[derive(Clone,Debug)]
|
||||
#[derive(Clone,Copy,Debug)]
|
||||
pub struct Run{
|
||||
state:RunState,
|
||||
flagged:Option<FlagReason>,
|
||||
|
||||
@@ -2,12 +2,6 @@
|
||||
use arrayvec::ArrayVec;
|
||||
use crate::integer::Planar64;
|
||||
|
||||
fn one(z0:Planar64)->ArrayVec<Planar64,2>{
|
||||
let mut zeroes=ArrayVec::new();
|
||||
unsafe{zeroes.push_unchecked(z0)}
|
||||
zeroes
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn zeroes2(a0:Planar64,a1:Planar64,a2:Planar64)->ArrayVec<Planar64,2>{
|
||||
if a2==Planar64::ZERO{
|
||||
@@ -27,7 +21,7 @@ pub fn zeroes2(a0:Planar64,a1:Planar64,a2:Planar64)->ArrayVec<Planar64,2>{
|
||||
(false,false)=>[(-a1+planar_radicand)/(a2*2),(a0*2)/(-a1+planar_radicand)].into(),
|
||||
}
|
||||
}else if radicand==0{
|
||||
return one(a1/(a2*-2));
|
||||
return ArrayVec::from_iter([a1/(a2*-2)]);
|
||||
}else{
|
||||
return ArrayVec::new_const();
|
||||
}
|
||||
@@ -39,7 +33,7 @@ pub fn zeroes1(a0:Planar64,a1:Planar64)->ArrayVec<Planar64,2>{
|
||||
}else{
|
||||
let q=((-a0.get() as i128)<<32)/(a1.get() as i128);
|
||||
if i64::MIN as i128<=q&&q<=i64::MAX as i128{
|
||||
return one(Planar64::raw(q as i64));
|
||||
return ArrayVec::from_iter([Planar64::raw(q as i64)]);
|
||||
}else{
|
||||
return ArrayVec::new_const();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user