#[macro_export]
macro_rules! traverse {
($cwbvh:expr, $node:expr, $state:expr, $node_intersection:expr, $primitive_intersection:expr) => {{
use $crate::faststack::FastStack;
loop {
while $state.primitive_group.y != 0 {
let local_primitive_index = $crate::cwbvh::firstbithigh($state.primitive_group.y);
$state.primitive_group.y &= !(1u32 << local_primitive_index);
$state.primitive_id = $state.primitive_group.x + local_primitive_index;
$primitive_intersection
}
$state.primitive_group = UVec2::ZERO;
if $state.current_group.y & 0xff000000 != 0 {
let hits_imask = $state.current_group.y;
let child_index_offset = $crate::cwbvh::firstbithigh(hits_imask);
let child_index_base = $state.current_group.x;
$state.current_group.y &= !(1u32 << child_index_offset);
if $state.current_group.y & 0xff000000 != 0 {
$state.stack.push($state.current_group);
}
let slot_index = (child_index_offset - 24) ^ ($state.oct_inv4 & 0xff);
let relative_index = (hits_imask & !(0xffffffffu32 << slot_index)).count_ones();
let child_node_index = child_index_base + relative_index;
$node = &$cwbvh.nodes[child_node_index as usize];
$state.hitmask = $node_intersection;
$state.current_group.x = $node.child_base_idx;
$state.primitive_group.x = $node.primitive_base_idx;
$state.current_group.y = (&$state.hitmask & 0xff000000u32) | ($node.imask as u32);
$state.primitive_group.y = &$state.hitmask & 0x00ffffffu32;
} else {
$state.current_group = UVec2::ZERO;
}
if $state.primitive_group.y == 0 && ($state.current_group.y & 0xff000000) == 0 {
if $state.stack.is_empty() {
#[allow(unused)]
{
$state.current_group.y = 0;
}
break;
}
$state.current_group = $state.stack.pop_fast();
}
}
}};
}