53 lines
1.5 KiB
C++
53 lines
1.5 KiB
C++
|
|
#pragma once
|
||
|
|
#include "vde/spatial/bvh.h"
|
||
|
|
#include <functional>
|
||
|
|
#include <vector>
|
||
|
|
|
||
|
|
namespace vde::spatial {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Incremental BVH that supports insert/remove without full rebuild
|
||
|
|
*
|
||
|
|
* Wraps the standard BVH with a dirty flag. Triangles can be inserted,
|
||
|
|
* removed, or updated incrementally. The tree is lazily rebuilt on the
|
||
|
|
* next query when dirty. Suitable for moderately dynamic scenes where
|
||
|
|
* queries are less frequent than modifications.
|
||
|
|
*
|
||
|
|
* @ingroup spatial
|
||
|
|
*/
|
||
|
|
class IncrementalBVH {
|
||
|
|
public:
|
||
|
|
/// @brief Build from initial set of triangles
|
||
|
|
void build(const std::vector<core::Triangle3D>& triangles);
|
||
|
|
|
||
|
|
/// @brief Insert a new triangle (marks dirty, no immediate rebuild)
|
||
|
|
void insert(const core::Triangle3D& tri);
|
||
|
|
|
||
|
|
/// @brief Remove a triangle by index (marks dirty)
|
||
|
|
void remove(size_t index);
|
||
|
|
|
||
|
|
/// @brief Update a triangle's geometry in-place (marks dirty)
|
||
|
|
void update(size_t index, const core::Triangle3D& tri);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Ray query (rebuilds if dirty, then delegates to BVH)
|
||
|
|
*
|
||
|
|
* @param ray Query ray
|
||
|
|
* @return All hit results (t, triangle, hit point)
|
||
|
|
*/
|
||
|
|
std::vector<BVH::HitResult> ray_query(const Ray3Dd& ray) const;
|
||
|
|
|
||
|
|
/// @brief Number of triangles
|
||
|
|
[[nodiscard]] size_t size() const { return triangles_.size(); }
|
||
|
|
|
||
|
|
private:
|
||
|
|
std::vector<core::Triangle3D> triangles_;
|
||
|
|
std::vector<core::AABB3D> bboxes_;
|
||
|
|
BVH bvh_;
|
||
|
|
bool dirty_ = true;
|
||
|
|
|
||
|
|
void rebuild_if_dirty();
|
||
|
|
};
|
||
|
|
|
||
|
|
} // namespace vde::spatial
|