10 Commits
bvh2 ... sqrt

Author SHA1 Message Date
d4cfb9cd47 fix zero 2024-08-29 17:05:37 -07:00
b11a060042 bits don't conflict 2024-08-29 16:37:04 -07:00
e38126302e improve sqrt 2024-08-29 16:24:13 -07:00
75bd98ce19 sqrt 2024-08-29 16:17:48 -07:00
79011171cb zeroes: use ArrayVec::from_iter instead of helper function 2024-08-22 19:47:44 -07:00
cd58e20fc2 integer: give Planar64 abs 2024-08-22 19:47:44 -07:00
fbdabf449a v0.4.1 bvh tweaks + run tweaks 2024-08-22 19:47:44 -07:00
0a95f492ba run: Run is Copy 2024-08-22 19:47:44 -07:00
27dba8a90d bvh: handling for median clumps 2024-08-22 19:47:44 -07:00
2b8bb0b705 bvh: remove unnecessary work 2024-08-22 19:47:38 -07:00
6 changed files with 46 additions and 29 deletions

2
Cargo.lock generated
View File

@@ -51,7 +51,7 @@ dependencies = [
[[package]]
name = "strafesnet_common"
version = "0.4.0"
version = "0.4.1"
dependencies = [
"arrayvec",
"bitflags",

View File

@@ -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"

View File

@@ -121,13 +121,11 @@ fn generate_bvh_node<T>(boxen:Vec<(T,Aabb)>,force:bool)->BvhNode<T>{
aabb,
}
}else{
let mut octant=std::collections::HashMap::with_capacity(n);//this ids which octant the boxen is put in
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();
octant.insert(i,0);
sort_x.push((i,center.x()));
sort_y.push((i,center.y()));
sort_z.push((i,center.z()));
@@ -139,26 +137,34 @@ fn generate_bvh_node<T>(boxen:Vec<(T,Aabb)>,force:bool)->BvhNode<T>{
let median_x=sort_x[h].1;
let median_y=sort_y[h].1;
let median_z=sort_z[h].1;
for (i,c) in sort_x{
if median_x<c{
octant.insert(i,octant[&i]+1<<0);
}
//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_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[partition_point_x..]{
octant[i]+=1<<0;
}
for (i,c) in sort_y{
if median_y<c{
octant.insert(i,octant[&i]+1<<1);
}
for &(i,_) in &sort_y[partition_point_y..]{
octant[i]+=1<<1;
}
for (i,c) in sort_z{
if median_z<c{
octant.insert(i,octant[&i]+1<<2);
}
for &(i,_) in &sort_z[partition_point_z..]{
octant[i]+=1<<2;
}
//generate lists for unique octant values
let mut list_list=Vec::with_capacity(8);
let mut octant_list=Vec::with_capacity(8);
for (i,(data,aabb)) in boxen.into_iter().enumerate(){
let octant_id=octant[&i];
let octant_id=octant[i];
let list_id=if let Some(list_id)=octant_list.iter().position(|&id|id==octant_id){
list_id
}else{

View File

@@ -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{

View File

@@ -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>,

View File

@@ -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();
}