tinybvh_rs/layouts/
cwbvh.rs1use crate::{ffi, mbvh, Error};
6use std::fmt::Debug;
7
8pub struct PrimitiveIter {
9 primitive_base_index: u32,
10 child_meta: [u8; 8],
11
12 curr_meta_idx: u8,
13 curr_tri_count: u8,
14}
15
16impl PrimitiveIter {
17 fn new(base_index: u32, meta: [u8; 8]) -> Self {
18 Self {
19 primitive_base_index: base_index,
20 child_meta: meta,
21
22 curr_meta_idx: 0,
23 curr_tri_count: 0,
24 }
25 }
26}
27
28impl Iterator for PrimitiveIter {
29 type Item = u32;
30
31 fn next(&mut self) -> Option<Self::Item> {
32 if self.curr_meta_idx as usize >= self.child_meta.len() {
33 return None;
34 }
35 while self.curr_meta_idx < self.child_meta.len() as u8 {
36 let meta = self.child_meta[self.curr_meta_idx as usize];
37 let triangles_count = (meta & 0b11100000).count_ones() as u8;
38 let current_tri_count = self.curr_tri_count;
39 self.curr_tri_count += 1;
40 if current_tri_count < triangles_count {
41 let start = meta & 0b00011111;
42 return Some(self.primitive_base_index + start as u32 + current_tri_count as u32);
43 }
44 self.curr_meta_idx += 1;
45 self.curr_tri_count = 0;
46 }
47 None
48 }
49}
50
51#[repr(C)]
56#[derive(Clone, Copy, Debug, Default, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
57pub struct Node {
58 pub min: [f32; 3],
60 pub exyz: [u8; 3],
62 pub imask: u8,
64 pub child_base_idx: u32,
66 pub primitive_base_idx: u32,
68 pub child_meta: [u8; 8],
70 pub qlo_x: [u8; 8],
72 pub qlo_y: [u8; 8],
74 pub qlo_z: [u8; 8],
76 pub qhi_x: [u8; 8],
78 pub qhi_y: [u8; 8],
80 pub qhi_z: [u8; 8],
82}
83
84impl Node {
85 pub fn is_leaf(&self) -> bool {
87 self.imask == 0
88 }
89
90 pub fn primitives(&self) -> PrimitiveIter {
91 if !self.is_leaf() {
92 return PrimitiveIter::new(0, [0, 0, 0, 0, 0, 0, 0, 0]);
93 }
94 PrimitiveIter::new(self.primitive_base_idx, self.child_meta)
95 }
96}
97
98#[repr(C)]
100#[derive(Clone, Copy, Default, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
101pub struct Primitive {
102 pub edge_1: [f32; 3],
103 pub padding_0: u32,
104 pub edge_2: [f32; 3],
105 pub padding_1: u32,
106 pub vertex_0: [f32; 3],
107 pub original_primitive: u32,
108}
109
110impl Debug for Primitive {
111 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
112 f.debug_struct("cwbvh::Primitive")
113 .field("vertex_0", &self.vertex_0)
114 .field("edge_1", &self.edge_1)
115 .field("edge_2", &self.edge_2)
116 .field("original_primitive", &self.original_primitive)
117 .finish()
118 }
119}
120
121pub struct BVH {
123 inner: cxx::UniquePtr<ffi::BVH8_CWBVH>,
124}
125
126impl BVH {
127 pub fn new(original: &mbvh::BVH) -> Result<Self, Error> {
128 let bvh = BVH {
129 inner: ffi::CWBVH_new(),
130 };
131 bvh.convert(original)
132 }
133
134 pub fn convert(mut self, original: &mbvh::BVH) -> Result<Self, Error> {
135 Error::validate_leaf_count(3, original.max_primitives_per_leaf)?;
136 self.inner
137 .pin_mut()
138 .ConvertFrom(original.inner.as_ref().unwrap(), true);
139 Ok(self)
140 }
141
142 pub fn nodes(&self) -> &[Node] {
143 let ptr = ffi::CWBVH_nodes(&self.inner) as *const Node;
145 let count = ffi::CWBVH_nodes_count(&self.inner);
146 unsafe { std::slice::from_raw_parts(ptr, count as usize) }
147 }
148
149 pub fn primitives(&self) -> &[Primitive] {
154 let ptr = ffi::CWBVH_primitives(&self.inner) as *const Primitive;
156 let count = ffi::CWBVH_primitives_count(&self.inner);
157 unsafe { std::slice::from_raw_parts(ptr, count as usize) }
158 }
159}