diff --git a/src/bvh.rs b/src/bvh.rs index b76c239..729c183 100644 --- a/src/bvh.rs +++ b/src/bvh.rs @@ -1,14 +1,10 @@ use crate::aabb::Aabb; -//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 +//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 pub enum RecursiveContent{ Branch(Vec), @@ -121,18 +117,40 @@ fn generate_bvh_node(boxen:Vec<(T,Aabb)>,force:bool)->BvhNode{ aabb, } }else{ - 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 mut sort_x_min=boxen.iter() + .enumerate() + .map(|(i,(_,aabb))|(i,aabb)) + .collect::>(); + 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 h=n/2; let median_x=sort_x[h].1; let median_y=sort_y[h].1;