2026-07-24 10:59:03 +00:00
|
|
|
/**
|
|
|
|
|
* @file spatial_index.h
|
|
|
|
|
* @brief 空间索引抽象基类
|
|
|
|
|
*
|
|
|
|
|
* 定义所有空间加速结构的统一接口。子类通过不同策略实现
|
|
|
|
|
* 空间划分与加速查询,在构建效率与查询性能之间做权衡。
|
|
|
|
|
*
|
|
|
|
|
* 子类包括:
|
|
|
|
|
* - BVH: 层次包围盒,适合静态三角形网格
|
|
|
|
|
* - Octree: 八叉树,适合均匀分布点云
|
|
|
|
|
* - KDTree: k-d 树,适合维度无关的中规模数据
|
|
|
|
|
* - RTree: R 树,适合动态插入删除场景
|
|
|
|
|
*
|
|
|
|
|
* @ingroup spatial
|
|
|
|
|
*/
|
|
|
|
|
|
2026-07-23 05:27:51 +00:00
|
|
|
#pragma once
|
|
|
|
|
#include "vde/core/aabb.h"
|
|
|
|
|
#include "vde/core/line.h"
|
2026-07-23 08:19:24 +00:00
|
|
|
#include "vde/core/triangle.h"
|
2026-07-23 05:27:51 +00:00
|
|
|
#include <vector>
|
|
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
|
|
namespace vde::spatial {
|
2026-07-23 08:19:24 +00:00
|
|
|
using core::AABB3D;
|
|
|
|
|
using core::Point3D;
|
|
|
|
|
using core::Ray3Dd;
|
|
|
|
|
using core::Triangle3D;
|
2026-07-23 05:27:51 +00:00
|
|
|
|
2026-07-24 10:59:03 +00:00
|
|
|
/**
|
|
|
|
|
* @brief 空间索引抽象基类
|
|
|
|
|
*
|
|
|
|
|
* 所有空间加速结构(BVH、Octree、KDTree、RTree)的公共接口。
|
|
|
|
|
* 模板参数 T 为被索引对象类型,需提供以下辅助函数:
|
|
|
|
|
* - get_position(T) → Point3D (空间位置)
|
|
|
|
|
* - get_aabb(T) → AABB3D (包围盒,用于范围查询)
|
|
|
|
|
* - ray_hits_item(T, Ray3Dd) → bool(与射线求交)
|
|
|
|
|
*
|
|
|
|
|
* @tparam T 被索引的空间对象类型
|
|
|
|
|
*
|
|
|
|
|
* @note 本类为纯虚接口,不可直接实例化
|
|
|
|
|
*/
|
2026-07-23 05:27:51 +00:00
|
|
|
template <typename T>
|
|
|
|
|
class SpatialIndex {
|
|
|
|
|
public:
|
|
|
|
|
virtual ~SpatialIndex() = default;
|
2026-07-24 10:59:03 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 批量构建索引
|
|
|
|
|
*
|
|
|
|
|
* 清空已有数据,将 items 全部插入并重建索引结构。
|
|
|
|
|
* 各子类实现不同的构建策略:
|
|
|
|
|
* - BVH: SAH 启发式自顶向下划分
|
|
|
|
|
* - KDTree: 中值分割递归构建
|
|
|
|
|
* - Octree: 自适应八等分递归剖分
|
|
|
|
|
* - RTree: 批量插入后优化重组
|
|
|
|
|
*
|
|
|
|
|
* @param items 待索引的对象数组
|
|
|
|
|
*/
|
2026-07-23 05:27:51 +00:00
|
|
|
virtual void build(const std::vector<T>& items) = 0;
|
2026-07-24 10:59:03 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 插入单个对象
|
|
|
|
|
*
|
|
|
|
|
* 将 item 加入索引。部分结构(如 BVH)仅支持一次性 build,
|
|
|
|
|
* 插入后可能需要重建。
|
|
|
|
|
*
|
|
|
|
|
* @param item 待插入的空间对象
|
|
|
|
|
*/
|
2026-07-23 05:27:51 +00:00
|
|
|
virtual void insert(const T& item) = 0;
|
2026-07-24 10:59:03 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 删除单个对象
|
|
|
|
|
*
|
|
|
|
|
* @param item 待删除的空间对象
|
|
|
|
|
* @return true 删除成功;false 对象不存在
|
|
|
|
|
*/
|
2026-07-23 05:27:51 +00:00
|
|
|
virtual bool remove(const T& item) = 0;
|
2026-07-24 10:59:03 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 范围查询:返回与 AABB 相交的所有对象
|
|
|
|
|
*
|
|
|
|
|
* @param range 查询的轴对齐包围盒
|
|
|
|
|
* @return 与 range 相交的对象列表
|
|
|
|
|
*/
|
2026-07-23 05:27:51 +00:00
|
|
|
virtual std::vector<T> query_range(const AABB3D& range) const = 0;
|
2026-07-24 10:59:03 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief K 近邻查询:返回距 point 最近的 k 个对象
|
|
|
|
|
*
|
|
|
|
|
* @param point 查询点
|
|
|
|
|
* @param k 需要返回的对象数量
|
|
|
|
|
* @return 按距离升序排列的 k 个最近对象
|
|
|
|
|
*/
|
2026-07-23 05:27:51 +00:00
|
|
|
virtual std::vector<T> query_knn(const Point3D& point, size_t k) const = 0;
|
2026-07-24 10:59:03 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 射线查询:返回与射线相交的所有对象
|
|
|
|
|
*
|
|
|
|
|
* @param ray 查询射线
|
|
|
|
|
* @return 按命中距离升序排列的相交对象列表
|
|
|
|
|
*/
|
2026-07-23 05:27:51 +00:00
|
|
|
virtual std::vector<T> query_ray(const Ray3Dd& ray) const = 0;
|
2026-07-24 10:59:03 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 清空索引中所有数据
|
|
|
|
|
*/
|
2026-07-23 05:27:51 +00:00
|
|
|
virtual void clear() = 0;
|
2026-07-24 10:59:03 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 当前索引中的对象数量
|
|
|
|
|
*
|
|
|
|
|
* @return 对象计数
|
|
|
|
|
*/
|
2026-07-23 05:27:51 +00:00
|
|
|
virtual size_t size() const = 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace vde::spatial
|