tinybvh_rs/layouts/
mbvh.rs1use std::{fmt::Debug, marker::PhantomData};
2
3use crate::{bvh, ffi, layouts::impl_bvh_deref, Error};
4
5#[repr(C)]
9#[derive(Clone, Copy, Default, Debug, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
10pub struct Node {
11 pub aabb_min: [f32; 3],
12 pub first_tri: u32,
13 pub aabb_max: [f32; 3],
14 pub tri_count: u32,
15 pub child: [u32; 8],
16 pub child_count: u32,
17 pub dummy: [u32; ((30 - 8) & 3) + 1],
18}
19
20impl Node {
21 pub fn is_leaf(&self) -> bool {
23 self.tri_count > 0
24 }
25}
26
27pub struct BVHData {
29 pub(crate) inner: cxx::UniquePtr<ffi::MBVH8>,
30 pub(crate) max_primitives_per_leaf: Option<u32>,
31 pub(crate) primitives_len: u32,
32}
33
34impl BVHData {
35 pub fn leaf_count(&self, node_index: u32) -> u32 {
37 self.inner.LeafCount(node_index)
38 }
39
40 pub fn bvh<'a>(self, original: &'a bvh::BVH<'a>) -> Result<BVH<'a>, Error> {
44 BVH::wrap(self).bind(original)
45 }
46
47 pub fn convert<'a>(self, original: &'a bvh::BVH<'a>) -> BVH<'a> {
53 BVH::wrap(self).convert(original)
54 }
55
56 pub fn nodes(&self) -> &[Node] {
58 ffi::MBVH8_nodes(&self.inner)
59 }
60}
61
62pub struct BVH<'a> {
66 bvh: BVHData,
67 _phantom: PhantomData<bvh::BVH<'a>>,
68}
69impl_bvh_deref!(BVH<'a>, BVHData);
70
71impl<'a> BVH<'a> {
72 fn wrap(bvh: BVHData) -> Self {
73 Self {
74 bvh,
75 _phantom: PhantomData,
76 }
77 }
78
79 pub fn new(original: &'a bvh::BVH) -> Self {
81 let data = BVHData {
82 inner: ffi::MBVH8_new(),
83 max_primitives_per_leaf: None,
84 primitives_len: 0,
85 };
86 data.convert(original)
87 }
88
89 pub fn bind<'b>(self, original: &'b bvh::BVH) -> Result<BVH<'b>, Error> {
105 let mut bvh = self.bvh;
106 crate::Error::validate_primitives_len(bvh.primitives_len, original.primitives_len)?;
107 ffi::MBVH8_setBVH(bvh.inner.pin_mut(), &original.bvh.inner);
108 Ok(BVH::wrap(bvh))
109 }
110
111 pub fn convert<'b>(self, original: &'b bvh::BVH) -> BVH<'b> {
115 let mut bvh = self.bvh;
116 bvh.inner
117 .pin_mut()
118 .ConvertFrom(original.bvh.inner.as_ref().unwrap(), true);
119 bvh.max_primitives_per_leaf = original.max_primitives_per_leaf;
120 bvh.primitives_len = original.primitives_len;
121 BVH::wrap(bvh)
122 }
123
124 pub fn refit(&mut self, node_index: u32) {
128 self.bvh.inner.pin_mut().Refit(node_index);
129 }
130
131 pub fn data(self) -> BVHData {
133 self.bvh
134 }
135}