special method converts Bvh into Bvh with weights

This commit is contained in:
Quaternions 2024-07-25 15:37:55 -07:00
parent f337c71c5b
commit 7b826e11be

View File

@ -10,26 +10,31 @@ use crate::aabb::Aabb;
//sort the centerpoints on each axis (3 lists) //sort the centerpoints on each axis (3 lists)
//bv is put into octant based on whether it is upper or lower in each list //bv is put into octant based on whether it is upper or lower in each list
enum BvhNodeContent<T>{ pub enum RecursiveContent<R,T>{
Branch(Vec<BvhNode<T>>), Branch(Vec<R>),
Leaf(T), Leaf(T),
} }
impl<T> Default for BvhNodeContent<T>{ impl<R,T> Default for RecursiveContent<R,T>{
fn default()->Self{ fn default()->Self{
Self::Branch(Vec::new()) Self::Branch(Vec::new())
} }
} }
#[derive(Default)] #[derive(Default)]
pub struct BvhNode<T>{ pub struct BvhNode<T>{
content:BvhNodeContent<T>, content:RecursiveContent<BvhNode<T>,T>,
aabb:Aabb,
}
pub struct BvhWeightNode<W,T>{
content:RecursiveContent<BvhWeightNode<W,T>,T>,
weight:W,
aabb:Aabb, aabb:Aabb,
} }
impl<T> BvhNode<T>{ impl<T> BvhNode<T>{
pub fn the_tester<F:FnMut(&T)>(&self,aabb:&Aabb,f:&mut F){ pub fn the_tester<F:FnMut(&T)>(&self,aabb:&Aabb,f:&mut F){
match &self.content{ match &self.content{
BvhNodeContent::Leaf(model)=>f(model), RecursiveContent::Leaf(model)=>f(model),
BvhNodeContent::Branch(children)=>for child in children{ RecursiveContent::Branch(children)=>for child in children{
//this test could be moved outside the match statement //this test could be moved outside the match statement
//but that would test the root node aabb //but that would test the root node aabb
//you're probably not going to spend a lot of time outside the map, //you're probably not going to spend a lot of time outside the map,
@ -42,8 +47,47 @@ impl<T> BvhNode<T>{
} }
pub fn into_visitor<F:FnMut(T)>(self,f:&mut F){ pub fn into_visitor<F:FnMut(T)>(self,f:&mut F){
match self.content{ match self.content{
BvhNodeContent::Leaf(model)=>f(model), RecursiveContent::Leaf(model)=>f(model),
BvhNodeContent::Branch(children)=>for child in children{ RecursiveContent::Branch(children)=>for child in children{
child.into_visitor(f)
},
}
}
pub fn weigh_contents<W:Copy+std::iter::Sum<W>,F:Fn(&T)->W>(self,f:&F)->BvhWeightNode<W,T>{
match self.content{
RecursiveContent::Leaf(model)=>BvhWeightNode{
weight:f(&model),
content:RecursiveContent::Leaf(model),
aabb:self.aabb,
},
RecursiveContent::Branch(children)=>{
let branch:Vec<BvhWeightNode<W,T>>=children.into_iter().map(|child|
child.weigh_contents(f)
).collect();
BvhWeightNode{
weight:branch.iter().map(|node|node.weight).sum(),
content:RecursiveContent::Branch(branch),
aabb:self.aabb,
}
},
}
}
}
impl <W,T> BvhWeightNode<W,T>{
pub const fn weight(&self)->&W{
&self.weight
}
pub const fn aabb(&self)->&Aabb{
&self.aabb
}
pub fn into_content(self)->RecursiveContent<BvhWeightNode<W,T>,T>{
self.content
}
pub fn into_visitor<F:FnMut(T)>(self,f:&mut F){
match self.content{
RecursiveContent::Leaf(model)=>f(model),
RecursiveContent::Branch(children)=>for child in children{
child.into_visitor(f) child.into_visitor(f)
}, },
} }
@ -61,12 +105,12 @@ fn generate_bvh_node<T>(boxen:Vec<(T,Aabb)>,force:bool)->BvhNode<T>{
let nodes=boxen.into_iter().map(|b|{ let nodes=boxen.into_iter().map(|b|{
aabb.join(&b.1); aabb.join(&b.1);
BvhNode{ BvhNode{
content:BvhNodeContent::Leaf(b.0), content:RecursiveContent::Leaf(b.0),
aabb:b.1, aabb:b.1,
} }
}).collect(); }).collect();
BvhNode{ BvhNode{
content:BvhNodeContent::Branch(nodes), content:RecursiveContent::Branch(nodes),
aabb, aabb,
} }
}else{ }else{
@ -123,7 +167,7 @@ fn generate_bvh_node<T>(boxen:Vec<(T,Aabb)>,force:bool)->BvhNode<T>{
generate_bvh_node(list_list.remove(0),true) generate_bvh_node(list_list.remove(0),true)
}else{ }else{
BvhNode{ BvhNode{
content:BvhNodeContent::Branch( content:RecursiveContent::Branch(
list_list.into_iter().map(|b|{ list_list.into_iter().map(|b|{
let node=generate_bvh_node(b,false); let node=generate_bvh_node(b,false);
aabb.join(&node.aabb); aabb.join(&node.aabb);