Struct vox_geometry_rust::bvh3::Bvh3 [−][src]
pub struct Bvh3<T: Clone> { /* fields omitted */ }
Expand description
Bounding Volume Hierarchy (BVH) in 3D
This class implements the classic bounding volume hierarchy structure in 3D. It implements IntersectionQueryEngine3 in order to support box/ray intersection tests. Also, NearestNeighborQueryEngine3 is implemented to provide nearest neighbor query.
Implementations
impl<T: Clone> Bvh3<T>
[src]
impl<T: Clone> Bvh3<T>
[src]pub fn new() -> Bvh3<T>
[src]
pub fn new() -> Bvh3<T>
[src]Default constructor.
use vox_geometry_rust::bvh3::Bvh3; use vox_geometry_rust::vector3::Vector3D; let bvh:Bvh3<Vector3D> = Bvh3::new(); assert_eq!(bvh.number_of_nodes(), 0);
pub fn build(&mut self, items: &Vec<T>, item_bounds: &Vec<BoundingBox3D>)
[src]
pub fn build(&mut self, items: &Vec<T>, item_bounds: &Vec<BoundingBox3D>)
[src]Builds bounding volume hierarchy.
use vox_geometry_rust::bvh3::Bvh3; use vox_geometry_rust::vector3::Vector3D; use vox_geometry_rust::bounding_box3::BoundingBox3D; let mut bvh:Bvh3<Vector3D> = Bvh3::new(); let points:Vec<Vector3D> = vec![Vector3D::new_default(), Vector3D::new(1.0, 1.0, 1.0)]; let mut rootBounds = BoundingBox3D::new_default(); let bounds = (0..points.len()).map(|index|{ let c = points[index]; let mut aabb = BoundingBox3D::new(c, c); aabb.expand(0.1); rootBounds.merge_box(&aabb); return aabb.clone(); }).collect(); bvh.build(&points, &bounds); assert_eq!(2, bvh.number_of_items()); assert_eq!(points[0], *bvh.item(0)); assert_eq!(points[1], *bvh.item(1)); assert_eq!(3, bvh.number_of_nodes()); assert_eq!(1, bvh.children(0).0); assert_eq!(2, bvh.children(0).1); assert_eq!(bvh.is_leaf(0), false); assert_eq!(bvh.is_leaf(1), true); assert_eq!(bvh.is_leaf(2), true); assert_eq!(rootBounds.lower_corner, bvh.node_bound(0).lower_corner); assert_eq!(rootBounds.upper_corner, bvh.node_bound(0).upper_corner); assert_eq!(bounds[0].lower_corner, bvh.node_bound(1).lower_corner); assert_eq!(bounds[0].upper_corner, bvh.node_bound(1).upper_corner); assert_eq!(bounds[1].lower_corner, bvh.node_bound(2).lower_corner); assert_eq!(bounds[1].upper_corner, bvh.node_bound(2).upper_corner);
pub fn number_of_items(&self) -> usize
[src]
pub fn number_of_items(&self) -> usize
[src]Returns the number of items.
pub fn number_of_nodes(&self) -> usize
[src]
pub fn number_of_nodes(&self) -> usize
[src]Returns the number of nodes.
pub fn children(&self, i: usize) -> (usize, usize)
[src]
pub fn children(&self, i: usize) -> (usize, usize)
[src]Returns the children indices of \p i-th node.
pub fn node_bound(&self, i: usize) -> BoundingBox3D
[src]
pub fn node_bound(&self, i: usize) -> BoundingBox3D
[src]Returns bounding box of \p i-th node.
pub fn bounding_box(&self) -> BoundingBox3D
[src]
pub fn bounding_box(&self) -> BoundingBox3D
[src]Returns bounding box of every items.
pub fn item_of_node(&self, i: usize) -> usize
[src]
pub fn item_of_node(&self, i: usize) -> usize
[src]Returns item of \p i-th node.
Trait Implementations
impl<T: Clone> IntersectionQueryEngine3<T> for Bvh3<T>
[src]
impl<T: Clone> IntersectionQueryEngine3<T> for Bvh3<T>
[src]fn intersects_aabb<Callback>(
&self,
aabb: &BoundingBox3D,
test_func: &mut Callback
) -> bool where
Callback: BoxIntersectionTestFunc3<T>,
[src]
fn intersects_aabb<Callback>(
&self,
aabb: &BoundingBox3D,
test_func: &mut Callback
) -> bool where
Callback: BoxIntersectionTestFunc3<T>,
[src]use vox_geometry_rust::bvh3::Bvh3; use vox_geometry_rust::vector3::Vector3D; use vox_geometry_rust::bounding_box3::BoundingBox3D; use vox_geometry_rust::unit_tests_utils::*; use vox_geometry_rust::nearest_neighbor_query_engine3::*; use vox_geometry_rust::intersection_query_engine3::IntersectionQueryEngine3; let mut bvh:Bvh3<Vector3D> = Bvh3::new(); let mut overlaps_func = |pt:&Vector3D, bbox:&BoundingBox3D| { let mut aabb = BoundingBox3D::new(*pt, *pt); aabb.expand(0.1); return bbox.overlaps(&aabb); }; let num_samples = get_number_of_sample_points3(); let points = (0..num_samples).map(|index| Vector3D::new_lst(get_sample_points3()[index])).collect(); let bounds = (0..num_samples).map(|index| { let c = Vector3D::new_lst(get_sample_points3()[index]); let mut aabb = BoundingBox3D::new(c, c); aabb.expand(0.1); aabb }).collect(); bvh.build(&points, &bounds); let test_box = BoundingBox3D::new(Vector3D::new(0.25, 0.15, 0.3), Vector3D::new(0.5, 0.6, 0.4)); let mut has_overlaps = false; for i in 0..num_samples { has_overlaps |= overlaps_func(&Vector3D::new_lst(get_sample_points3()[i]), &test_box); } assert_eq!(has_overlaps, bvh.intersects_aabb(&test_box, &mut overlaps_func)); let test_box3 = BoundingBox3D::new(Vector3D::new(0.3, 0.2, 0.1), Vector3D::new(0.6, 0.5, 0.4)); has_overlaps = false; for i in 0..num_samples { has_overlaps |= overlaps_func(&Vector3D::new_lst(get_sample_points3()[i]), &test_box3); } assert_eq!(has_overlaps, bvh.intersects_aabb(&test_box3, &mut overlaps_func));
fn intersects_ray<Callback>(
&self,
ray: &Ray3D,
test_func: &mut Callback
) -> bool where
Callback: RayIntersectionTestFunc3<T>,
[src]
fn intersects_ray<Callback>(
&self,
ray: &Ray3D,
test_func: &mut Callback
) -> bool where
Callback: RayIntersectionTestFunc3<T>,
[src]use vox_geometry_rust::bvh3::Bvh3; use vox_geometry_rust::vector3::Vector3D; use vox_geometry_rust::bounding_box3::BoundingBox3D; use vox_geometry_rust::ray3::Ray3D; use vox_geometry_rust::unit_tests_utils::*; use vox_geometry_rust::nearest_neighbor_query_engine3::*; use vox_geometry_rust::intersection_query_engine3::IntersectionQueryEngine3; let mut bvh:Bvh3<BoundingBox3D> = Bvh3::new(); let mut intersects_func = |a:&BoundingBox3D, ray:&Ray3D| { return a.intersects(ray); }; let num_samples = get_number_of_sample_points3(); let items = (0..num_samples / 2).map(|index| { let c = Vector3D::new_lst(get_sample_points3()[index]); let mut aabb = BoundingBox3D::new(c, c); aabb.expand(0.1); aabb }).collect(); bvh.build(&items, &items); for i in 0..num_samples / 2 { let ray = Ray3D::new(Vector3D::new_lst(get_sample_dirs3()[i + num_samples / 2]), Vector3D::new_lst(get_sample_dirs3()[i + num_samples / 2])); // ad-hoc search let mut ans_ints = false; for j in 0..num_samples / 2 { if intersects_func(&items[j], &ray) { ans_ints = true; break; } } // bvh search let oct_ints = bvh.intersects_ray(&ray, &mut intersects_func); assert_eq!(ans_ints, oct_ints); }
fn for_each_intersecting_item_aabb<Callback, Visitor>(
&self,
aabb: &BoundingBox3D,
test_func: &mut Callback,
visitor_func: &mut Visitor
) where
Callback: BoxIntersectionTestFunc3<T>,
Visitor: IntersectionVisitorFunc3<T>,
[src]
fn for_each_intersecting_item_aabb<Callback, Visitor>(
&self,
aabb: &BoundingBox3D,
test_func: &mut Callback,
visitor_func: &mut Visitor
) where
Callback: BoxIntersectionTestFunc3<T>,
Visitor: IntersectionVisitorFunc3<T>,
[src]use vox_geometry_rust::bvh3::Bvh3; use vox_geometry_rust::vector3::Vector3D; use vox_geometry_rust::bounding_box3::BoundingBox3D; use vox_geometry_rust::unit_tests_utils::*; use vox_geometry_rust::nearest_neighbor_query_engine3::*; use vox_geometry_rust::intersection_query_engine3::IntersectionQueryEngine3; let mut bvh:Bvh3<Vector3D> = Bvh3::new(); let mut overlaps_func = |pt:&Vector3D, bbox:&BoundingBox3D| { return bbox.contains(pt); }; let overlaps_func3 = |pt:&Vector3D, bbox:&BoundingBox3D| { return bbox.contains(pt); }; let num_samples = get_number_of_sample_points3(); let points = (0..num_samples).map(|index| Vector3D::new_lst(get_sample_points3()[index])).collect(); let bounds = (0..num_samples).map(|index| { let c = Vector3D::new_lst(get_sample_points3()[index]); let mut aabb = BoundingBox3D::new(c, c); aabb.expand(0.1); aabb }).collect(); bvh.build(&points, &bounds); let test_box = BoundingBox3D::new(Vector3D::new(0.3, 0.2, 0.1), Vector3D::new(0.6, 0.5, 0.4)); let mut num_overlaps = 0; for i in 0..num_samples { num_overlaps += overlaps_func(&Vector3D::new_lst(get_sample_points3()[i]), &test_box) as usize; } let mut measured = 0; bvh.for_each_intersecting_item_aabb(&test_box, &mut overlaps_func, &mut |pt:&Vector3D| { assert_eq!(overlaps_func3(pt, &test_box), true); measured += 1; }); assert_eq!(num_overlaps, measured);
fn closest_intersection<Callback>(
&self,
ray: &Ray3D,
test_func: &mut Callback
) -> ClosestIntersectionQueryResult3<T> where
Callback: GetRayIntersectionFunc3<T>,
[src]
fn closest_intersection<Callback>(
&self,
ray: &Ray3D,
test_func: &mut Callback
) -> ClosestIntersectionQueryResult3<T> where
Callback: GetRayIntersectionFunc3<T>,
[src]use vox_geometry_rust::bvh3::Bvh3; use vox_geometry_rust::vector3::Vector3D; use vox_geometry_rust::bounding_box3::BoundingBox3D; use vox_geometry_rust::ray3::Ray3D; use vox_geometry_rust::unit_tests_utils::*; use vox_geometry_rust::nearest_neighbor_query_engine3::*; use vox_geometry_rust::intersection_query_engine3::*; let mut bvh:Bvh3<BoundingBox3D> = Bvh3::new(); let mut intersects_func = |a:&BoundingBox3D, ray:&Ray3D| { let bbox_result = a.closest_intersection(ray); return if bbox_result.is_intersecting { bbox_result.t_near } else { f64::MAX }; }; let num_samples = get_number_of_sample_points3(); let items = (0..num_samples / 2).map(|index| { let c = Vector3D::new_lst(get_sample_points3()[index]); let mut aabb = BoundingBox3D::new(c, c); aabb.expand(0.1); aabb }).collect(); bvh.build(&items, &items); for i in 0..num_samples / 2 { let ray = Ray3D::new(Vector3D::new_lst(get_sample_points3()[i + num_samples / 2]), Vector3D::new_lst(get_sample_dirs3()[i + num_samples / 2])); // ad-hoc search let mut ans_ints:ClosestIntersectionQueryResult3<BoundingBox3D> = ClosestIntersectionQueryResult3::new(); for j in 0..num_samples / 2 { let dist = intersects_func(&items[j], &ray); if dist < ans_ints.distance { ans_ints.distance = dist; ans_ints.item = Some(bvh.item(j).clone()); } } // bvh search let bvh_ints = bvh.closest_intersection(&ray, &mut intersects_func); assert_eq!(ans_ints.distance, bvh_ints.distance); let ans_aabb = ans_ints.item.unwrap_or(BoundingBox3D::new_default()); let oct_aabb = bvh_ints.item.unwrap_or(BoundingBox3D::new_default()); assert_eq!(ans_aabb.upper_corner, oct_aabb.upper_corner); assert_eq!(ans_aabb.lower_corner, oct_aabb.lower_corner); }
fn for_each_intersecting_item_ray<Callback, Visitor>(
&self,
ray: &Ray3D,
test_func: &mut Callback,
visitor_func: &mut Visitor
) where
Callback: RayIntersectionTestFunc3<T>,
Visitor: IntersectionVisitorFunc3<T>,
[src]
fn for_each_intersecting_item_ray<Callback, Visitor>(
&self,
ray: &Ray3D,
test_func: &mut Callback,
visitor_func: &mut Visitor
) where
Callback: RayIntersectionTestFunc3<T>,
Visitor: IntersectionVisitorFunc3<T>,
[src]Invokes \p visitor_func for every intersecting items.
impl<T: Clone> NearestNeighborQueryEngine3<T> for Bvh3<T>
[src]
impl<T: Clone> NearestNeighborQueryEngine3<T> for Bvh3<T>
[src]fn nearest<Callback>(
&self,
pt: &Vector3D,
distance_func: &mut Callback
) -> NearestNeighborQueryResult3<T> where
Callback: NearestNeighborDistanceFunc3<T>,
[src]
fn nearest<Callback>(
&self,
pt: &Vector3D,
distance_func: &mut Callback
) -> NearestNeighborQueryResult3<T> where
Callback: NearestNeighborDistanceFunc3<T>,
[src]use vox_geometry_rust::bvh3::Bvh3; use vox_geometry_rust::vector3::Vector3D; use vox_geometry_rust::bounding_box3::BoundingBox3D; use vox_geometry_rust::unit_tests_utils::*; use vox_geometry_rust::nearest_neighbor_query_engine3::*; let mut bvh:Bvh3<Vector3D> = Bvh3::new(); let mut distance_func = |a:&Vector3D, b:&Vector3D| { return a.distance_to(*b); }; let num_samples = get_number_of_sample_points3(); let points = (0..num_samples).map(|index| Vector3D::new_lst(get_sample_points3()[index])).collect(); let bounds = (0..num_samples).map(|index| { let c = Vector3D::new_lst(get_sample_points3()[index]); let mut aabb = BoundingBox3D::new(c, c); aabb.expand(0.1); aabb }).collect(); bvh.build(&points, &bounds); let test_pt = Vector3D::new(0.5, 0.5, 0.5); let nearest = bvh.nearest(&test_pt, &mut distance_func); let mut answer_idx = 0; let mut best_dist = test_pt.distance_to(points[answer_idx]); for i in 1..num_samples { let dist = test_pt.distance_to(Vector3D::new_lst(get_sample_points3()[i])); if dist < best_dist { best_dist = dist; answer_idx = i; } } assert_eq!(nearest.item.unwrap(), *bvh.item(answer_idx));
Auto Trait Implementations
impl<T> RefUnwindSafe for Bvh3<T> where
T: RefUnwindSafe,
T: RefUnwindSafe,
impl<T> Send for Bvh3<T> where
T: Send,
T: Send,
impl<T> Sync for Bvh3<T> where
T: Sync,
T: Sync,
impl<T> Unpin for Bvh3<T> where
T: Unpin,
T: Unpin,
impl<T> UnwindSafe for Bvh3<T> where
T: UnwindSafe,
T: UnwindSafe,
Blanket Implementations
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]pub fn borrow_mut(&mut self) -> &mut T
[src]
pub fn borrow_mut(&mut self) -> &mut T
[src]Mutably borrows from an owned value. Read more
impl<T> Pointable for T
impl<T> Pointable for T
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
impl<V, T> VZip<V> for T where
V: MultiLane<T>,