|
cgv
|
A Bounding Volume Hierarchy(BVH) using axis-aligned bounding boxes to partition primitives into a binary tree structure for efficient ray intersection tests. More...
#include <bvh.h>
Public Member Functions | |
| void | build (const std::vector< const ray_intersectable * > &primitives, size_t max_depth=8) |
| Build the hierarchy over the given primitives. | |
| bvh_result | closest_intersection (const cgv::ray3 &ray) const |
| Calculate the closest intersection with positive distance, if any, of the given ray with the stored primitives. | |
A Bounding Volume Hierarchy(BVH) using axis-aligned bounding boxes to partition primitives into a binary tree structure for efficient ray intersection tests.
Nodes are split using the midpoint heuristic that splits primitives at the geometric center point of a node's longest axis, sorting primitives based on their bounding box centroid.
Example: Create a custom primitive class usable with the BVH:
struct my_primitive : public ray_intersectable { ... custom fields
cgv::box3 get_bounds() const override { ...return axis-aligned bounding box of the primitive };
bool intersect(const cgv::ray3& ray, ray_intersection_info& info) const override { ...return true if ray intersects primitive and fill out intersection info with at least the ray parameter t }; };
Create some primitives:
std::vector<ray_intersectable*> primitives; primitives.push_back(new my_primitive(...)); ...
Attention: The call-site must manage the lifetime of the primitives!
To build the BVH: bvh scene; scene.build(primitives, 8) // using depth 8 (sensible values depend on the scene complexity but are typically between 4 and 32)
To test for a closest intersection:
cgv::ray3 ray(...); // some test ray bvh_result result = scene.closest_intersection(ray);
if(result.is_hit) { // A primitive was hit. result.intersection contains the ray parameter of the intersection point and other optional attributes // result further contains the pointer to the hit primitive and the index into the 'primitives' list used to build the BVH const my_primitive* hit_primitive = result.primitive; ...or my_primitive* hit_primitive = primitives[result.primitive_index]; } else { ...no hit }
| void cgv::data::bvh::build | ( | const std::vector< const ray_intersectable * > & | primitives, |
| size_t | max_depth = 8 |
||
| ) |
Build the hierarchy over the given primitives.
Attention: The primitives are merely borrowed during the build process and afterwards by the created nodes. The call site must ensure the primitives' lifetime as long as the bvh is used. Modifying any primitive attributes that alter its bounding box after building the BVH results in undefined behaviour. The BVH must be built again after modifying such attributes to ensure correct calculation of intersections.
| primitives | The primitives to consider during building. |
| max_depth | The maximum depth of the resulting tree. |
Definition at line 11 of file bvh.cxx.
References cgv::media::axis_aligned_box< T, N >::add_axis_aligned_box().
| bvh_result cgv::data::bvh::closest_intersection | ( | const cgv::ray3 & | ray | ) | const |
Calculate the closest intersection with positive distance, if any, of the given ray with the stored primitives.
| ray | The ray to test. |
Definition at line 62 of file bvh.cxx.
References cgv::data::ray_intersectable::intersect(), cgv::data::bvh_result::intersection, cgv::data::bvh_result::is_hit, cgv::data::bvh_result::primitive, cgv::data::bvh_result::primitive_index, and cgv::data::ray_intersection_info::t.