# geometry3Sharp 空间数据结构集成方案

## 1. 背景与动机

### 1.1 当前碰撞检测的性能瓶颈

NavisworksTransport 项目在物流路径动画中实现了碰撞检测功能，但存在以下性能问题：

**当前实现的问题**：

```csharp
// ClashDetectiveIntegration.cs - DetectCollisions()
// 线性遍历所有几何对象，O(n) 复杂度
foreach (var item in allGeometryItems)
{
    if (IsColliding(animatedObject, item))
    {
        collisions.Add(item);
    }
}
```

**性能数据**（来自实际日志）：

- 场景对象总数：290 个
- 潜在碰撞对象：108 个（经过路径包围盒预过滤）
- 每帧碰撞检测：遍历 108 个对象
- 动画总帧数：300 帧
- **总计算量**：300 × 108 = 32,400 次包围盒检测

**优化空间**：

1. 空间查询仍然是线性遍历（即使经过预过滤）
2. 包围盒距离计算不精确（AABB vs 实际几何距离）
3. 没有层次化空间索引加速
4. 动态查询效率低（物体移动时重新遍历）

### 1.2 空间数据结构的必要性

**需求场景**：

1. **动画碰撞检测**：物体每帧移动，需要快速查询"当前位置附近有哪些障碍物"
2. **潜在碰撞对象过滤**：在路径规划前，快速找到路径沿途的所有可能碰撞物体
3. **精确距离计算**：计算物体到障碍物的真实距离（不是包围盒距离）
4. **路径可达性验证**：检查两点间的直线是否被障碍物阻挡

**理想的解决方案特征**：

- ✅ O(log n) 或 O(1) 平均查询复杂度
- ✅ 支持动态位置的范围查询
- ✅ 精确的几何距离计算
- ✅ 商业友好的许可证
- ✅ 与 .NET Framework 4.8 兼容

---

## 2. geometry3Sharp 库概述

### 2.1 基本信息

**项目信息**：

- **官方名称**：geometry3Sharp (本项目使用的是 fork: geometry4Sharp)
- **GitHub**：<https://github.com/gradientspace/geometry3Sharp> (原版)
- **GitHub**：<https://github.com/NewWheelTech/geometry4Sharp> (fork)
- **许可证**：Boost Software License 1.0（商业友好，无需开源衍生代码）
- **维护状态**：原版活跃度降低（2019后），fork 有维护
- **平台兼容**：.NET Standard 2.0, .NET Framework 4.8, .NET 6.0
- **语言**：纯 C#，无 C++ 互操作

**代码来源**：

- 核心算法移植自 David Eberly 的 WildMagic5 和 GTEngine（几何计算领域的经典库）
- MeshSignedDistanceGrid 基于 Christopher Batty 的 SDFGen C++ 代码
- 经过多年实战验证，代码质量高

### 2.2 与体素网格方案的关系

**重要说明**：geometry3Sharp 不是替代体素网格方案，而是**互补关系**。

| 模块 | 用途 | 应用场景 |
|------|------|---------|
| **体素网格 (MeshSignedDistanceGrid, Bitmap3, DSparseGrid3)** | 3D 空间离散化，路径规划 | 生成可通行网格，3D A* 路径规划 |
| **空间索引 (DMeshAABBTree3, PointHashGrid3d)** | 快速空间查询，碰撞检测 | 动画碰撞检测，范围查询优化 |
| **距离查询 (DistPoint3Triangle3)** | 精确几何距离 | 碰撞容差计算，最近点查询 |
| **相交查询 (IntrRay3Triangle3)** | 射线-几何相交 | 路径可达性验证，视线检测 |

**集成策略**：

- 体素网格用于**路径规划**（已在 `体素网格路径规划方案.md` 中详细设计）
- 空间索引用于**碰撞检测加速**（本文档重点）
- 两者共用 geometry3Sharp 的基础数学类型（Vector3d, AxisAlignedBox3d 等）

---

## 3. 高价值模块详细分析

### 3.1 DMeshAABBTree3 - 层次化 AABB 树

#### 功能描述

`DMeshAABBTree3` 是三角网格的层次化轴对齐包围盒树，提供 O(log n) 复杂度的空间查询。

**核心特性**：

- 自底向上或自顶向下构建策略（可选）
- 支持三角形级别的精确相交测试
- 多种空间查询接口
- 泛型遍历接口（DoTraversal）

**可用查询**：

```csharp
// 1. 最近三角形查找
int FindNearestTriangle(Point3d point, double maxDistance);

// 2. 射线-网格最近命中
int FindNearestHitTriangle(Ray3d ray, double maxDistance);

// 3. 射线-网格所有命中
List<int> FindAllHitTriangles(Ray3d ray, double maxDistance);

// 4. 三角形相交测试
bool TestIntersection(Triangle3d triangle);

// 5. 树-树相交测试
bool TestIntersection(DMeshAABBTree3 otherTree);

// 6. 树-树所有相交
List<Tuple<int,int>> FindAllIntersections(DMeshAABBTree3 otherTree);

// 7. 树-树范围内最近三角形
List<Tuple<int,int>> FindNearestTriangles(DMeshAABBTree3 otherTree, double maxDist);

// 8. 点包含测试
bool IsInside(Point3d point);

// 9. 缠绕数（Winding Number）
double WindingNumber(Point3d point);
```

#### 应用场景

场景 1：优化 GetPotentialColliders()**

当前实现（线性遍历）：

```csharp
// PathAnimationManager.cs - GetPotentialColliders()
foreach (var item in allGeometryItems)
{
    double distance = CalculateDistance(pathCenter, item);
    if (distance <= detectionGap)
    {
        potentialColliders.Add(item);
    }
}
```

使用 AABB 树优化（对数查询）：

```csharp
// 1. 预构建场景的 AABB 树（一次性）
var sceneTree = BuildSceneAABBTree(allGeometryItems);

// 2. 快速范围查询
var potentialColliders = sceneTree.FindNearestTriangles(
    animatedObjectTree,
    detectionGap
);
```

**性能提升预估**：

- 当前：O(n) = 290 次包围盒测试
- 优化后：O(log n) ≈ log₂(290) ≈ 8 次树节点遍历
- **加速比**：约 36 倍

场景 2：精确碰撞检测**

替代简单包围盒检测，使用三角形级别的精确相交：

```csharp
// 检查动画对象是否与场景相交
bool hasCollision = animatedObjectTree.TestIntersection(sceneTree);

// 获取所有相交的三角形对
var intersections = animatedObjectTree.FindAllIntersections(sceneTree);
```

#### 构建策略选择

```csharp
public enum BuildStrategy
{
    TopDownMidpoint,        // 最快（默认）
    BottomUpFromOneRings,   // 平衡但慢 2.5 倍
    TopDownMedian           // 更平衡但慢 2-4 倍
}

// 推荐：快速构建 + 大量查询场景
var tree = new DMeshAABBTree3(mesh, autoBuild: false);
tree.Build(BuildStrategy.TopDownMidpoint);
```

#### 技术挑战

挑战 1：Navisworks Geometry → DMesh3 转换

Navisworks 的 `ModelItem` 不直接暴露三角网格，需要通过几何提取：

```csharp
// 方案 A：使用 GeometryExtractor（项目已有）
// 需要扩展为输出 geometry3Sharp 的 DMesh3 格式

// 方案 B：使用包围盒代替精确网格（简化版）
// 优点：实现简单，性能好
// 缺点：精度降低（但对预过滤足够）
```

**推荐方案**：渐进式实现

1. **Phase 1**：使用包围盒近似（快速验证）
2. **Phase 2**：实现精确几何提取（提升精度）

---

### 3.2 PointHashGrid3d - 空间哈希网格

#### 功能描述

`PointHashGrid3d<T>` 是泛型的 3D 空间哈希表，提供 O(1) 平均时间复杂度的范围查询。

**核心特性**：

- 基于网格单元的哈希索引
- 支持动态插入/删除/更新
- 线程安全（SpinLock）
- 泛型设计，可存储任意类型

**关键方法**：

```csharp
// 初始化（cellSize = 查询半径的 1-2 倍）
var grid = new PointHashGrid3d<ModelItem>(cellSize: 2.0, invalidValue: null);

// 插入点（线程安全）
grid.InsertPoint(modelItem, position);

// 删除点
grid.RemovePoint(modelItem, position);

// 更新点（移动）
grid.UpdatePoint(modelItem, oldPosition, newPosition);

// 范围查询（核心功能）
var nearby = grid.FindNearestInRadius(
    queryPosition,
    radius,
    distanceFunc: (item) => Distance(queryPosition, item.Position)
);

// 批量查询
List<T> FindPointsInBox(AxisAlignedBox3d box);
```

#### 应用场景

场景 1：加速动画碰撞检测

当前问题：

- 动画每帧都要遍历 108 个潜在碰撞对象
- 300 帧 × 108 对象 = 32,400 次检测

使用空间哈希优化：

```csharp
// === 初始化阶段（动画开始前）===
var spatialGrid = new PointHashGrid3d<ModelItem>(
    cellSize: objectRadius * 2,  // 格子大小 = 物体直径
    invalidValue: null
);

// 索引所有障碍物（一次性）
foreach (var obstacle in potentialColliders)
{
    spatialGrid.InsertPoint(obstacle, obstacle.BoundingBox().Center);
}

// === 动画每帧 ===
// 快速查询当前位置附近的障碍物
var nearbyObstacles = spatialGrid.FindNearestInRadius(
    currentPosition,
    objectRadius + safetyMargin,
    (item) => Vector3d.Distance(item.Position, currentPosition)
);

// 只检测附近的对象（通常 < 10 个）
foreach (var obstacle in nearbyObstacles)
{
    if (IsColliding(animatedObject, obstacle))
    {
        collisions.Add(obstacle);
    }
}
```

**性能提升预估**：

- 当前：每帧检测 108 个对象
- 优化后：每帧检测 5-15 个对象（仅邻近格子）
- **加速比**：约 7-20 倍

场景 2：动态场景更新

支持障碍物动态添加/移动：

```csharp
// 添加新障碍物
spatialGrid.InsertPoint(newObstacle, newObstacle.Position);

// 移动障碍物
spatialGrid.UpdatePoint(movingObstacle, oldPosition, newPosition);

// 删除障碍物
spatialGrid.RemovePoint(removedObstacle, removedObstacle.Position);
```

#### 格子大小选择

**原则**：cellSize 应该接近查询半径

```csharp
// 推荐设置
double objectRadius = 0.3;  // 米
double safetyMargin = 0.1;   // 米
double detectionRadius = objectRadius + safetyMargin;

// cellSize = 查询半径 * 1.5
double cellSize = detectionRadius * 1.5;  // 约 0.6 米

var spatialGrid = new PointHashGrid3d<ModelItem>(cellSize, null);
```

**权衡**：

- cellSize 过小 → 格子太多，内存和查询开销大
- cellSize 过大 → 每个格子对象太多，退化为线性查询

---

### 3.3 DistPoint3Triangle3 - 精确距离查询

#### 功能描述

计算点到三角形的最短距离及最近点位置。

**核心方法**：

```csharp
var query = new DistPoint3Triangle3(point, triangle);
double distance = query.Get();             // 最短距离
Vector3d closestPoint = query.TriangleClosest;  // 三角形上最近点
int closestType = query.TriangleClosestType;    // 最近点类型（顶点/边/面）
```

**相关类**：

```csharp
DistPoint3Circle3      // 点到圆的距离
DistPoint3Cylinder3    // 点到圆柱的距离（带符号）
DistLine3Triangle3     // 线段到三角形的距离
DistSegment3Triangle3  // 线段到三角形的距离
DistTriangle3Triangle3 // 三角形到三角形的距离
```

#### 应用场景

场景 1：精确碰撞容差

当前问题：

```csharp
// BoundingBoxGeometryUtils.cs - CalculateDistance()
// 只计算包围盒中心的距离，不精确
double distance = Vector3.Distance(bbox1.Center, bbox2.Center);
```

使用精确距离：

```csharp
// 计算物体表面到障碍物表面的真实距离
foreach (var triangle1 in animatedObjectMesh.Triangles)
{
    foreach (var triangle2 in obstacleMesh.Triangles)
    {
        var query = new DistTriangle3Triangle3(triangle1, triangle2);
        double distance = query.Get();

        if (distance < collisionThreshold)
        {
            // 记录碰撞，包含精确距离和接触点
            collisions.Add(new CollisionInfo
            {
                Distance = distance,
                ContactPoint1 = query.Triangle1Closest,
                ContactPoint2 = query.Triangle2Closest
            });
        }
    }
}
```

场景 2：碰撞报告增强

在碰撞报告中显示：

- 精确的间隙距离（而非包围盒距离）
- 最近接触点的 3D 坐标
- 可视化最短距离向量

---

### 3.4 IntrRay3Triangle3 - 射线相交查询

#### 功能描述

计算射线/线段与三角形的相交。

**核心方法**：

```csharp
// 射线-三角形相交
var query = new IntrRay3Triangle3(ray, triangle);
bool intersects = query.Find();           // 是否相交
double rayParameter = query.RayParameter; // 射线参数 t (交点 = ray.Origin + t * ray.Direction)
Vector3d intersectionPoint = ray.PointAt(rayParameter);

// 线段-三角形相交
var segmentQuery = new IntrSegment3Triangle3(segment, triangle);
bool intersects = segmentQuery.Find();
```

**相关类**：

```csharp
IntrLine2Line2          // 2D 直线相交
IntrSegment2Segment2    // 2D 线段相交
IntrTriangle3Triangle3  // 3D 三角形相交
IntrRay3Box3            // 射线-AABB 相交
IntrRay3AxisAlignedBox3 // 射线-轴对齐盒相交
```

#### 应用场景

场景 1：路径可达性验证

检查两点间的直线路径是否被障碍物阻挡：

```csharp
/// <summary>
/// 检查直线路径是否可达（无障碍物阻挡）
/// </summary>
public bool IsPathClear(Point3D start, Point3D end, IEnumerable<DMesh3> obstacles)
{
    Vector3d direction = (end - start).Normalized;
    double distance = Vector3d.Distance(start, end);
    var ray = new Ray3d(start, direction);

    foreach (var obstacleMesh in obstacles)
    {
        foreach (var triangleId in obstacleMesh.TriangleIndices())
        {
            var triangle = GetTriangle(obstacleMesh, triangleId);
            var query = new IntrRay3Triangle3(ray, triangle);

            if (query.Find() && query.RayParameter < distance)
            {
                // 射线在到达终点前与障碍物相交
                return false;
            }
        }
    }

    return true;  // 路径畅通
}
```

场景 2：视线检测

判断两个物体之间是否有遮挡：

```csharp
// 检查从起重机到目标物体的视线是否被遮挡
bool hasLineOfSight = IsPathClear(crane.Position, targetObject.Position, obstacles);
```

**场景 3：改进 A* 路径规划**

在 A* 算法中增加射线检测，避免规划出会穿模的路径：

```csharp
// 生成路径后，后处理优化
var optimizedPath = new List<Point3D>();
optimizedPath.Add(path[0]);

for (int i = 0; i < path.Count - 1; i++)
{
    // 尝试直接连接当前点和后续点
    for (int j = path.Count - 1; j > i + 1; j--)
    {
        if (IsPathClear(path[i], path[j], obstacles))
        {
            optimizedPath.Add(path[j]);
            i = j - 1;
            break;
        }
    }
}
```

---

## 4. 中等价值模块（可选）

### 4.1 Polygon2d - 2D 多边形操作

**功能**：

- 点在多边形内测试（Contains）
- 多边形简化（Simplify）
- 多边形裁剪
- 多边形布尔运算

**应用场景**：

- 楼层区域判断（路径点是否在楼层边界内）
- 2D 路径规划（作为 3D 规划的补充）

### 4.2 ConvexHull2 - 2D 凸包

**功能**：

- 计算点集的 2D 凸包

**应用场景**：

- 楼层边界自动识别
- 路径覆盖区域计算

### 4.3 MeshPlaneCut - 网格平面切割

**功能**：

- 用平面切割三角网格
- 返回切割边界（EdgeLoop）

**应用场景**：

- 楼层切片（按高度切分建筑模型）
- 断面分析（生成路径断面视图）

---

## 5. 集成架构设计

### 5.1 整体架构

```graph
┌─────────────────────────────────────────────────────────────┐
│                     Navisworks API                           │
│          (ModelItem, BoundingBox3D, Geometry)                │
└────────────────────────┬────────────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────────────┐
│              NavisworksGeometryAdapter (新)                  │
│  - ModelItem → DMesh3                                       │
│  - Point3D ↔ Vector3d                                       │
│  - BoundingBox3D ↔ AxisAlignedBox3d                        │
└────────────────────────┬────────────────────────────────────┘
                         │
            ┌────────────┴────────────┐
            ▼                         ▼
┌─────────────────────┐    ┌─────────────────────┐
│  SpatialIndexCache  │    │ CollisionQueryHelper│
│  (新)               │    │ (新)                │
│                     │    │                     │
│ - SceneAABBTree    │    │ - DistanceQuery     │
│ - ObstacleHashGrid │    │ - IntersectionQuery │
│ - 缓存管理         │    │ - 精确碰撞检测      │
└──────────┬──────────┘    └──────────┬──────────┘
           │                          │
           │    ┌─────────────────────┘
           │    │
           ▼    ▼
┌─────────────────────────────────────────────────────────────┐
│            ClashDetectiveIntegration (改进)                  │
│  - GetPotentialColliders() → 使用 SpatialIndexCache         │
│  - DetectCollisions() → 使用 CollisionQueryHelper           │
└─────────────────────────────────────────────────────────────┘
           │
           ▼
┌─────────────────────────────────────────────────────────────┐
│            PathAnimationManager (无需修改)                   │
└─────────────────────────────────────────────────────────────┘
```

### 5.2 核心类设计

#### 5.2.1 NavisworksGeometryAdapter - 适配层

```csharp
/// <summary>
/// Navisworks API 与 geometry3Sharp 之间的转换适配器
/// </summary>
public static class NavisworksGeometryAdapter
{
    #region 坐标转换

    /// <summary>
    /// Navisworks Point3D → geometry3Sharp Vector3d
    /// </summary>
    public static Vector3d ToVector3d(this Point3D point)
    {
        return new Vector3d(point.X, point.Y, point.Z);
    }

    /// <summary>
    /// geometry3Sharp Vector3d → Navisworks Point3D
    /// </summary>
    public static Point3D ToPoint3D(this Vector3d vector)
    {
        return new Point3D(vector.x, vector.y, vector.z);
    }

    /// <summary>
    /// Navisworks BoundingBox3D → geometry3Sharp AxisAlignedBox3d
    /// </summary>
    public static AxisAlignedBox3d ToAxisAlignedBox3d(this BoundingBox3D bbox)
    {
        return new AxisAlignedBox3d(
            bbox.Min.ToVector3d(),
            bbox.Max.ToVector3d()
        );
    }

    #endregion

    #region 几何提取

    /// <summary>
    /// 从 ModelItem 提取三角网格（简化版：使用包围盒）
    /// </summary>
    public static DMesh3 ExtractMeshSimple(ModelItem item)
    {
        var bbox = item.BoundingBox();
        var mesh = new DMesh3();

        // 将包围盒转为 8 个顶点 + 12 个三角形
        // （简化实现，适用于快速验证）
        AddBoxToMesh(mesh, bbox.ToAxisAlignedBox3d());

        return mesh;
    }

    /// <summary>
    /// 从 ModelItem 提取精确三角网格（完整版，Phase 2 实现）
    /// </summary>
    public static DMesh3 ExtractMeshAccurate(ModelItem item)
    {
        // TODO: 使用 GeometryExtractor 获取实际三角形
        // 需要遍历 Navisworks Geometry API
        throw new NotImplementedException("Phase 2");
    }

    #endregion
}
```

#### 5.2.2 SpatialIndexCache - 空间索引缓存

```csharp
/// <summary>
/// 场景空间索引缓存管理器
/// 在动画开始前预构建空间索引，动画过程中复用
/// </summary>
public class SpatialIndexCache
{
    private static SpatialIndexCache _instance;
    public static SpatialIndexCache Instance => _instance ??= new SpatialIndexCache();

    // 场景 AABB 树（用于精确查询）
    private DMeshAABBTree3 _sceneAABBTree;

    // 障碍物空间哈希网格（用于快速范围查询）
    private PointHashGrid3d<ModelItem> _obstacleHashGrid;

    // 缓存版本（检测场景变化）
    private int _cacheVersion = 0;

    #region 构建方法

    /// <summary>
    /// 构建场景的空间索引
    /// </summary>
    public void BuildSpatialIndex(
        IEnumerable<ModelItem> obstacles,
        double hashGridCellSize)
    {
        LogManager.Info("[空间索引] 开始构建...");
        var sw = Stopwatch.StartNew();

        // 1. 构建 AABB 树
        var sceneMesh = CombineMeshes(obstacles);
        _sceneAABBTree = new DMeshAABBTree3(sceneMesh, autoBuild: true);
        LogManager.Info($"[空间索引] AABB 树构建完成，节点数: {_sceneAABBTree.MaxLeafSize}");

        // 2. 构建空间哈希网格
        _obstacleHashGrid = new PointHashGrid3d<ModelItem>(hashGridCellSize, null);
        foreach (var obstacle in obstacles)
        {
            var center = obstacle.BoundingBox().Center.ToVector3d();
            _obstacleHashGrid.InsertPoint(obstacle, center);
        }
        LogManager.Info($"[空间索引] 哈希网格构建完成，格子大小: {hashGridCellSize}m");

        _cacheVersion++;
        sw.Stop();
        LogManager.Info($"[空间索引] 构建完成，耗时: {sw.ElapsedMilliseconds}ms");
    }

    #endregion

    #region 查询方法

    /// <summary>
    /// 快速范围查询（使用哈希网格）
    /// </summary>
    public List<ModelItem> FindNearbyObstacles(Point3D center, double radius)
    {
        if (_obstacleHashGrid == null)
            throw new InvalidOperationException("空间索引未初始化");

        var centerVec = center.ToVector3d();
        var nearby = new List<ModelItem>();

        // 哈希网格范围查询
        // 注意：PointHashGrid3d 没有直接的 FindNearestInRadius 方法
        // 需要手动实现或使用 FindPointsInBox
        var searchBox = new AxisAlignedBox3d(centerVec, radius);

        // 遍历搜索框内的所有格子（简化实现）
        // 实际应该调用哈希网格的范围查询方法
        // 这里需要根据 geometry3Sharp 的实际 API 调整

        return nearby;
    }

    /// <summary>
    /// 精确相交查询（使用 AABB 树）
    /// </summary>
    public bool TestIntersection(DMesh3 objectMesh)
    {
        if (_sceneAABBTree == null)
            throw new InvalidOperationException("空间索引未初始化");

        var objectTree = new DMeshAABBTree3(objectMesh, autoBuild: true);
        return _sceneAABBTree.TestIntersection(objectTree);
    }

    #endregion

    #region 辅助方法

    private DMesh3 CombineMeshes(IEnumerable<ModelItem> items)
    {
        var combinedMesh = new DMesh3();

        foreach (var item in items)
        {
            var itemMesh = NavisworksGeometryAdapter.ExtractMeshSimple(item);
            var editor = new MeshEditor(combinedMesh);
            editor.AppendMesh(itemMesh);
        }

        return combinedMesh;
    }

    #endregion
}
```

#### 5.2.3 CollisionQueryHelper - 碰撞查询助手

```csharp
/// <summary>
/// 精确碰撞查询辅助类
/// </summary>
public static class CollisionQueryHelper
{
    /// <summary>
    /// 计算物体到障碍物的最短距离
    /// </summary>
    public static double CalculateMinDistance(
        ModelItem movingObject,
        ModelItem obstacle)
    {
        var mesh1 = NavisworksGeometryAdapter.ExtractMeshSimple(movingObject);
        var mesh2 = NavisworksGeometryAdapter.ExtractMeshSimple(obstacle);

        double minDistance = double.MaxValue;

        // 遍历所有三角形对，找到最短距离
        foreach (var tri1Id in mesh1.TriangleIndices())
        {
            var tri1 = GetTriangle(mesh1, tri1Id);

            foreach (var tri2Id in mesh2.TriangleIndices())
            {
                var tri2 = GetTriangle(mesh2, tri2Id);

                var query = new DistTriangle3Triangle3(tri1, tri2);
                double distance = query.Get();

                if (distance < minDistance)
                {
                    minDistance = distance;
                }
            }
        }

        return minDistance;
    }

    /// <summary>
    /// 检查射线路径是否畅通
    /// </summary>
    public static bool IsPathClear(
        Point3D start,
        Point3D end,
        DMeshAABBTree3 sceneTree)
    {
        var direction = (end.ToVector3d() - start.ToVector3d()).Normalized;
        var distance = Vector3d.Distance(start.ToVector3d(), end.ToVector3d());
        var ray = new Ray3d(start.ToVector3d(), direction);

        // 使用 AABB 树快速查询射线相交
        int hitTriangle = sceneTree.FindNearestHitTriangle(ray);

        if (hitTriangle == DMesh3.InvalidID)
            return true;  // 无相交

        // 检查相交点是否在起终点之间
        // TODO: 需要获取相交点位置并比较距离

        return false;
    }

    private static Triangle3d GetTriangle(DMesh3 mesh, int triangleId)
    {
        var tri = mesh.GetTriangle(triangleId);
        var v0 = mesh.GetVertex(tri.a);
        var v1 = mesh.GetVertex(tri.b);
        var v2 = mesh.GetVertex(tri.c);
        return new Triangle3d(v0, v1, v2);
    }
}
```

### 5.3 集成到现有系统

#### 修改 ClashDetectiveIntegration.cs

```csharp
// 在 GetPotentialColliders() 中使用空间索引
private List<ModelItem> GetPotentialColliders()
{
    // 1. 计算路径包围盒
    var pathBounds = CalculatePathBounds();
    var pathCenter = GetBoundingBoxCenter(pathBounds);
    var detectionRadius = GetBoundingBoxDiagonal(pathBounds) / 2;

    // 2. 使用空间哈希网格快速查询
    var potentialColliders = SpatialIndexCache.Instance.FindNearbyObstacles(
        pathCenter,
        detectionRadius
    );

    LogManager.Info($"空间索引查询结果: {potentialColliders.Count} 个潜在碰撞对象");

    return potentialColliders;
}
```

---

## 6. 实施方案

### 6.1 分阶段实施

#### Phase 1: PointHashGrid3d 集成（2-3 天，立即可用）

**目标**：使用空间哈希网格优化动画碰撞检测。

**任务**：

1. 创建 `NavisworksGeometryAdapter` 类（坐标转换）
2. 创建 `SpatialIndexCache` 类（仅哈希网格部分）
3. 修改 `ClashDetectiveIntegration.GetPotentialColliders()` 使用哈希网格
4. 修改动画碰撞检测使用哈希网格查询
5. 性能测试和日志记录

**验收标准**：

- ✅ 动画碰撞检测速度提升 5-10 倍
- ✅ 日志显示每帧实际检测的对象数量减少
- ✅ 功能正确性不变（碰撞结果与原方案一致）

---

#### Phase 2: DMeshAABBTree3 优化（1 周）

**目标**：构建场景 AABB 树，优化范围查询和相交检测。

**任务**：

1. 实现 `NavisworksGeometryAdapter.ExtractMeshSimple()`（使用包围盒）
2. 在 `SpatialIndexCache` 中添加 AABB 树构建
3. 使用 AABB 树优化 `FindNearestTriangles()` 查询
4. 实现精确相交检测（替代简单包围盒测试）
5. 性能对比测试

**验收标准**：

- ✅ AABB 树构建时间 < 5 秒（中等场景）
- ✅ 范围查询速度提升 10-30 倍
- ✅ 支持精确三角形级别的碰撞检测

---

#### Phase 3: 精确距离和相交查询（可选，3-5 天）

**目标**：使用精确几何查询提升碰撞报告质量。

**任务**：

1. 创建 `CollisionQueryHelper` 类
2. 实现精确距离计算（DistTriangle3Triangle3）
3. 实现路径可达性验证（IntrRay3Triangle3）
4. 在碰撞报告中显示精确距离和接触点
5. （可选）实现 `ExtractMeshAccurate()` 精确几何提取

**验收标准**：

- ✅ 碰撞报告显示精确距离（非包围盒距离）
- ✅ 支持路径可达性验证功能
- ✅ 性能可接受（精确查询耗时 < 2x 简化查询）

---

### 6.2 时间与资源估算

| 阶段 | 任务 | 工作量 | 依赖 |
|------|------|--------|------|
| Phase 1 | PointHashGrid3d 集成 | 2-3 天 | geometry3Sharp |
| Phase 2 | DMeshAABBTree3 优化 | 5-7 天 | Phase 1 |
| Phase 3 | 精确查询（可选）| 3-5 天 | Phase 2 |
| **总计** | | **10-15 天** | |

---

## 7. 技术挑战与缓解

### 7.1 Navisworks API 限制

**挑战**：Navisworks 的 `ModelItem` 不直接暴露三角网格数据。

**缓解措施**：

- ✅ **Phase 1**：使用包围盒代替精确网格（快速验证）
- ✅ **Phase 2**：研究 `GeometryExtractor` 提取实际几何
- ✅ **Phase 3**：实现 Navisworks Geometry API → DMesh3 转换器

### 7.2 坐标系转换

**挑战**：Navisworks API 和 geometry3Sharp 使用不同的类型系统。

**缓解措施**：

- ✅ 创建 `NavisworksGeometryAdapter` 适配层
- ✅ 统一使用模型单位（避免米制/英制混淆）
- ✅ 单元测试验证转换正确性

### 7.3 性能权衡

**挑战**：空间索引构建有初始开销。

**缓解措施**：

- ✅ 在动画开始前预构建（用户点击"生成动画"时）
- ✅ 缓存索引（场景不变时复用）
- ✅ 显示进度条（让用户知道正在构建）

---

## 8. 性能预期

### 8.1 性能对比（预估）

基于类似规模的空间索引系统经验：

| 操作 | 当前实现 | Phase 1 (哈希) | Phase 2 (AABB树) |
|------|---------|---------------|-----------------|
| **范围查询** | O(n) = 290次 | O(1) ≈ 10次 | O(log n) ≈ 8次 |
| **碰撞检测** | 32,400次/动画 | 3,000次/动画 | 2,400次/动画 |
| **构建开销** | 0 秒 | 0.1 秒 | 2-5 秒 |
| **内存占用** | 0 MB | +10 MB | +50 MB |

**场景假设**：

- 对象总数：290 个
- 动画帧数：300 帧
- 潜在碰撞对象：108 个（经过预过滤）

### 8.2 预期加速比

**Phase 1 完成后**：

- 每帧碰撞检测：108 对象 → 10 对象
- **加速比**：约 10 倍

**Phase 2 完成后**：

- 范围查询：O(n) → O(log n)
- **加速比**：约 30-50 倍（组合效果）

---

## 9. 与体素网格方案的关系

### 9.1 互补关系说明

| 方案 | 主要用途 | 数据结构 | 查询类型 |
|------|---------|---------|---------|
| **体素网格** | 路径规划 | 3D 网格 + SDF | 可通行性、路径搜索 |
| **空间索引** | 碰撞检测 | AABB树、哈希网格 | 范围查询、相交测试 |

### 9.2 共用基础设施

两个方案共享 geometry3Sharp 的基础组件：

- 数学类型（Vector3d, AxisAlignedBox3d）
- 坐标转换适配器（NavisworksGeometryAdapter）
- 几何提取工具

### 9.3 集成策略

```graph
geometry3Sharp 基础库
├── 体素网格模块 (用于路径规划)
│   ├── MeshSignedDistanceGrid
│   ├── Bitmap3 / DSparseGrid3
│   └── VoxelGrid (自定义)
│
└── 空间索引模块 (用于碰撞检测)
    ├── DMeshAABBTree3
    ├── PointHashGrid3d
    └── Distance/Intersection 查询
```

---

## 10. 不适用的模块

以下 geometry3Sharp 模块**不适用于本项目**：

### 10.1 网格编辑类

- **Remesher**, **Reducer**, **MeshEditor**
- **原因**：Navisworks 是只读查看器，不支持修改网格几何

### 10.2 曲线生成类

- **NURBSCurve2**, **BezierCurve**
- **原因**：项目使用折线路径，不需要复杂曲线拟合

### 10.3 网格修复类

- **MeshAutoRepair**, **RemoveDuplicateTriangles**
- **原因**：Navisworks 模型已优化，无法运行时修改

### 10.4 布尔运算类

- **MeshBoolean**
- **原因**：文档明确说"不是健壮的布尔运算"，且 Navisworks API 不支持

---

## 11. 实施建议

### 11.1 推荐的实施优先级

**立即实施（高优先级）**：

1. ✅ **PointHashGrid3d** → 快速见效，大幅提升动画碰撞检测性能

**短期实施（中优先级）**：
2. ✅ **DMeshAABBTree3** → 进一步优化，支持精确相交检测

**长期考虑（低优先级）**：
3. ⚠️ **精确距离查询** → 功能增强，非关键路径
4. ⚠️ **射线相交查询** → 路径验证功能，可选

### 11.2 风险提示

**不要全盘集成 geometry3Sharp**，应该：

- ✅ 只提取需要的类（避免依赖膨胀）
- ✅ 创建适配层（隔离外部依赖）
- ✅ 渐进式验证（每个 Phase 独立验收）

---

## 12. 参考资料

### 12.1 geometry3Sharp 资源

- **GitHub（原版）**：<https://github.com/gradientspace/geometry3Sharp>
- **GitHub（fork）**：<https://github.com/NewWheelTech/geometry4Sharp>
- **NuGet**：geometry4Sharp 1.0.0
- **原作者**：Ryan Schmidt (@rms80)
- **算法来源**：WildMagic5/GTEngine (David Eberly)

### 12.2 理论基础

- **空间哈希网格**：
  - "Spatial Hashing for 3D Grids" - Teschner et al., 2003
  - "Optimized Spatial Hashing for Collision Detection of Deformable Objects"

- **AABB 树**：
  - "OBBTree: A Hierarchical Structure for Rapid Interference Detection" (Gottschalk et al., 1996)
  - "Fast Collision Detection Using AABB Trees" - Real-Time Rendering

- **距离查询**：
  - "Distance Between Point and Triangle in 3D" - David Eberly, Geometric Tools
  - "Fast Distance Queries for Triangles, Lines and Points using SSE"

### 12.3 相关文档

- 《体素网格路径规划方案.md》- 路径规划部分
- 《PATHFINDING_DESIGN.md》- A* 算法设计
- 《寻路算法的对比.md》- 算法选型依据

---

## 13. 总结

### 13.1 核心价值

1. ✅ **显著的性能提升**：碰撞检测加速 10-50 倍
2. ✅ **商业友好许可证**：Boost License，无需开源
3. ✅ **成熟稳定的代码**：源自经典几何库 WildMagic5
4. ✅ **渐进式集成**：分阶段实施，风险可控
5. ✅ **互补体素方案**：两者协同，各司其职

### 13.2 建议行动

**立即行动**：

1. 安装 geometry4Sharp NuGet 包
2. 实施 Phase 1（PointHashGrid3d）
3. 测试性能提升

**后续行动**：

- Phase 1 验证后，评估是否继续 Phase 2
- 与体素网格方案协同推进

### 13.3 成功标准

- ✅ 动画碰撞检测速度提升 10 倍以上
- ✅ 构建开销可接受（< 5 秒）
- ✅ 内存占用增加 < 100 MB
- ✅ 功能正确性保持不变
- ✅ 代码可维护性良好

---

**文档版本**: v1.0
**创建日期**: 2025-10-14
**最后更新**: 2025-10-14
**作者**: NavisworksTransport 开发团队
**相关文档**: 《体素网格路径规划方案.md》
