common: bvh: sample_ray

This commit is contained in:
Quaternions 2025-02-06 13:07:10 -08:00
parent 384b42f1ff
commit e67b29148e

@ -59,33 +59,55 @@ impl<L> BvhNode<L>{
}, },
} }
} }
fn populate_nodes<T:Ord>(&self,nodes:&mut BTreeMap<T,&BvhNode<L>>,ray:&Ray,start_time:T,time_limit:T,f:&F)->Option<TimedInstruction<&L,T>>{ fn populate_nodes<T:Ord+Copy,F:Fn(&L,&Ray)->Option<T>>(
&self,
collector:&mut InstructionCollector<&L,T>,
nodes:&mut BTreeMap<T,&BvhNode<L>>,
ray:&Ray,
start_time:T,
f:&F,
){
match &self.content{ match &self.content{
RecursiveContent::Leaf(leaf)=>Some(TimedInstruction{time:f(leaf),instruction:leaf}), RecursiveContent::Leaf(leaf)=>collector.collect(f(leaf,ray).map(|time|TimedInstruction{time,instruction:leaf})),
RecursiveContent::Branch(children)=>{ RecursiveContent::Branch(children)=>for child in children{
let mut collector=InstructionCollector::new(time_limit); if child.aabb.contains(ray.origin){
for child in children{ child.populate_nodes(collector,nodes,ray,start_time,f);
if child.aabb.contains(ray.origin){ }else{
collector.collect(child.populate_nodes(nodes,ray,start_time,f)); // Am I an upcoming superstar?
}else{ if let Some(t)=child.aabb.intersect_ray(ray){
// Am I an upcoming superstar? if start_time<t&&t<collector.time(){
if let Some(t)=child.aabb.intersect_ray(ray){ nodes.insert(t,child);
if start_time<t{
nodes.insert(t,child);
}
} }
} }
} }
collector.take()
}, },
} }
} }
pub fn sample_ray<T:Ord,F:Fn(&L)->T>(&self,ray:&Ray,start_time:T,mut time_limit:Option<T>,f:&F)->Option<(T,&L)>{ pub fn sample_ray<T:Ord+Copy,F:Fn(&L,&Ray)->Option<T>>(&self,ray:&Ray,start_time:T,time_limit:T,f:&F)->Option<(T,&L)>{
let mut nodes=BTreeMap::new(); let mut nodes=BTreeMap::new();
let mut collector=InstructionCollector::new(time_limit);
// perform a normal sample aabb at point ray.origin // perform a normal sample aabb at point ray.origin
self.populate_nodes(&mut nodes,ray,start_time); self.populate_nodes(&mut collector,&mut nodes,ray,start_time,f);
// swim through nodes one at a time // swim through nodes one at a time
while let Some((t,node))=nodes.pop_first(){
if collector.time()<t{
break;
}
match &node.content{
RecursiveContent::Leaf(leaf)=>collector.collect(f(leaf,ray).map(|time|TimedInstruction{time,instruction:leaf})),
RecursiveContent::Branch(children)=>for child in children{
// Am I an upcoming superstar?
if let Some(t)=child.aabb.intersect_ray(ray){
if t<collector.time(){
nodes.insert(t,child);
}
}
},
}
}
collector.take().map(|TimedInstruction{time,instruction:leaf}|(time,leaf))
} }
pub fn into_inner(self)->(RecursiveContent<BvhNode<L>,L>,Aabb){ pub fn into_inner(self)->(RecursiveContent<BvhNode<L>,L>,Aabb){
(self.content,self.aabb) (self.content,self.aabb)