1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
//! This module defines the `BoundingHierarchy` trait. use crate::aabb::Bounded; use crate::ray::Ray; /// Describes a shape as referenced by a [`BoundingHierarchy`] leaf node. /// Knows the index of the node in the [`BoundingHierarchy`] it is in. /// /// [`BoundingHierarchy`]: struct.BoundingHierarchy.html /// pub trait BHShape: Bounded { /// Sets the index of the referenced [`BoundingHierarchy`] node. /// /// [`BoundingHierarchy`]: struct.BoundingHierarchy.html /// fn set_bh_node_index(&mut self, _: usize); /// Gets the index of the referenced [`BoundingHierarchy`] node. /// /// [`BoundingHierarchy`]: struct.BoundingHierarchy.html /// fn bh_node_index(&self) -> usize; } /// This trait defines an acceleration structure with space partitioning. /// This structure is used to efficiently compute ray-scene intersections. pub trait BoundingHierarchy { /// Creates a new [`BoundingHierarchy`] from the `shapes` slice. /// /// # Examples /// /// ``` /// use bvh::aabb::{AABB, Bounded}; /// use bvh::bounding_hierarchy::BoundingHierarchy; /// use bvh::nalgebra::{Point3, Vector3}; /// # use bvh::bounding_hierarchy::BHShape; /// # pub struct UnitBox { /// # pub id: i32, /// # pub pos: Point3<f32>, /// # node_index: usize, /// # } /// # /// # impl UnitBox { /// # pub fn new(id: i32, pos: Point3<f32>) -> UnitBox { /// # UnitBox { /// # id: id, /// # pos: pos, /// # node_index: 0, /// # } /// # } /// # } /// # /// # impl Bounded for UnitBox { /// # fn aabb(&self) -> AABB { /// # let min = self.pos + Vector3::new(-0.5, -0.5, -0.5); /// # let max = self.pos + Vector3::new(0.5, 0.5, 0.5); /// # AABB::with_bounds(min, max) /// # } /// # } /// # /// # impl BHShape for UnitBox { /// # fn set_bh_node_index(&mut self, index: usize) { /// # self.node_index = index; /// # } /// # /// # fn bh_node_index(&self) -> usize { /// # self.node_index /// # } /// # } /// # /// # fn create_bhshapes() -> Vec<UnitBox> { /// # let mut shapes = Vec::new(); /// # for i in 0..1000 { /// # let position = Point3::new(i as f32, i as f32, i as f32); /// # shapes.push(UnitBox::new(i, position)); /// # } /// # shapes /// # } /// /// let mut shapes = create_bhshapes(); /// // Construct a normal `BVH`. /// { /// use bvh::bvh::BVH; /// let bvh = BVH::build(&mut shapes); /// } /// /// // Or construct a `FlatBVH`. /// { /// use bvh::flat_bvh::FlatBVH; /// let bvh = FlatBVH::build(&mut shapes); /// } /// ``` /// /// [`BoundingHierarchy`]: trait.BoundingHierarchy.html /// fn build<Shape: BHShape>(shapes: &mut [Shape]) -> Self; /// Traverses the [`BoundingHierarchy`]. /// Returns a subset of `shapes`, in which the [`AABB`]s of the elements were hit by `ray`. /// /// # Examples /// /// ``` /// use bvh::aabb::{AABB, Bounded}; /// use bvh::bounding_hierarchy::BoundingHierarchy; /// use bvh::bvh::BVH; /// use bvh::nalgebra::{Point3, Vector3}; /// use bvh::ray::Ray; /// # use bvh::bounding_hierarchy::BHShape; /// # pub struct UnitBox { /// # pub id: i32, /// # pub pos: Point3<f32>, /// # node_index: usize, /// # } /// # /// # impl UnitBox { /// # pub fn new(id: i32, pos: Point3<f32>) -> UnitBox { /// # UnitBox { /// # id: id, /// # pos: pos, /// # node_index: 0, /// # } /// # } /// # } /// # /// # impl Bounded for UnitBox { /// # fn aabb(&self) -> AABB { /// # let min = self.pos + Vector3::new(-0.5, -0.5, -0.5); /// # let max = self.pos + Vector3::new(0.5, 0.5, 0.5); /// # AABB::with_bounds(min, max) /// # } /// # } /// # /// # impl BHShape for UnitBox { /// # fn set_bh_node_index(&mut self, index: usize) { /// # self.node_index = index; /// # } /// # /// # fn bh_node_index(&self) -> usize { /// # self.node_index /// # } /// # } /// # /// # fn create_bvh() -> (BVH, Vec<UnitBox>) { /// # let mut shapes = Vec::new(); /// # for i in 0..1000 { /// # let position = Point3::new(i as f32, i as f32, i as f32); /// # shapes.push(UnitBox::new(i, position)); /// # } /// # let bvh = BVH::build(&mut shapes); /// # (bvh, shapes) /// # } /// /// let (bvh, shapes) = create_bvh(); /// /// let origin = Point3::new(0.0, 0.0, 0.0); /// let direction = Vector3::new(1.0, 0.0, 0.0); /// let ray = Ray::new(origin, direction); /// let hit_shapes = bvh.traverse(&ray, &shapes); /// ``` /// /// [`BoundingHierarchy`]: trait.BoundingHierarchy.html /// [`AABB`]: ../aabb/struct.AABB.html /// fn traverse<'a, Shape: BHShape>(&'a self, ray: &Ray, shapes: &'a [Shape]) -> Vec<&Shape>; /// Prints the [`BoundingHierarchy`] in a tree-like visualization. /// /// [`BoundingHierarchy`]: trait.BoundingHierarchy.html /// fn pretty_print(&self) {} }