From 019c7b3887e7af5d13dc3b5cda4af0bfa746dbc2 Mon Sep 17 00:00:00 2001
From: Quaternions <krakow20@gmail.com>
Date: Mon, 19 Aug 2024 12:40:32 -0700
Subject: [PATCH] wip

---
 src/bvh.rs | 60 +++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 39 insertions(+), 21 deletions(-)

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<R,T>{
 	Branch(Vec<R>),
@@ -121,18 +117,40 @@ fn generate_bvh_node<T>(boxen:Vec<(T,Aabb)>,force:bool)->BvhNode<T>{
 			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::<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 h=n/2;
 		let median_x=sort_x[h].1;
 		let median_y=sort_y[h].1;