[返回博客](/cn/blog) # ODA Visualize 中的碰撞检测（第 3 部分，共 3 部分）

Egor Slupko 十一月 29, 2018 [\#Visualize](/cn/blog/tag/visualize) [\#getting started](/cn/blog/tag/getting-started)

<a class="a2a_button_facebook"></a><a class="a2a_button_twitter"></a><a class="a2a_button_linkedin"></a>

本文是关于 ODA Visualize 中碰撞检测机制系列文章的一部分。有关上一篇文章，请参阅[第 2 部分](https://www.opendesign.com/blog/2018/november/collision-detection-oda-visualize-part-2-3)。

#### OdGiCollideProc 概述

碰撞检测传送带节点的接口在 GiCollideProc.h 中描述。它包含以下方法：

```
virtual void set( OdGsCollisionDetectionReactor* pReactor, const OdGsCollisionDetectionContext* pCtx = NULL ) = 0;

```

此方法指定碰撞检测反应器和上下文。

```
virtual void setDrawContext(OdGiConveyorContext* pDrawCtx) = 0;

```

此方法指定提供对矢量化状态信息访问的绘图上下文。

```
enum ProcessingPhase
{
  kPhaseGatherInputData = 0,
  kPhaseDetectIntersections
};
virtual void setProcessingPhase( ProcessingPhase ) = 0;
virtual ProcessingPhase processingPhase() const = 0

```

这些方法指定当前处理阶段，允许传送带节点将三角形收集到不同的列表中。

```
virtual const OdGeExtents3d& extents() const = 0;

```

此方法返回在 OdGiCollideProc::kPhaseGatherInputData 处理阶段收集的三角形的范围。

```
virtual void setNoFilter( bool bNoFilter ) = 0;
virtual bool noFilter() const = 0;

```

这些方法禁用实体过滤。

```
virtual void setInputDrawables( OdGiPathNode const*const* pInputList, OdUInt32 nInputListSize ) = 0;

```

此方法指定用于实体过滤的 OdGiPathNode 项列表

- 在 OdGiCollideProc::kPhaseGatherInputData 处理阶段，如果当前处理实体的 OdGiPathNode 未在 pInputList 中列出，则跳过该实体。
- 在 OdGiCollideProc::kPhaseDetectIntersections 处理阶段，如果当前处理实体的 OdGiPathNode 在 pInputList 中列出，则跳过该实体以避免检测同一实体之间的碰撞。

```
virtual void setCheckWithDrawables( OdGiPathNode const*const* pInputList, OdUInt32 nInputListSize ) = 0;

```

此方法指定一个额外的 OdGiPathNode 列表，该列表在 OdGiCollideProc::kPhaseDetectIntersections 处理阶段用于实体过滤；如果该列表不为空且当前处理实体的 OdGiPathNode 未在其中列出，则跳过该实体。

```
virtual void processTriangles() = 0

```

此方法执行处理在传送带节点处理阶段收集的三角形。

#### OdGiCollisionDetector 概述

OdGiCollisionDetector 和 OdGiCollisionDetectorIntersectionsOnly 是 OdGiIntersectionsCalculator 的继承者，并在 GiIntersectionCalculator.h 中描述。它们之间唯一的区别是 OdGiCollisionDetector 将三角形相交和三角形接触都视为碰撞，而 OdGiCollisionDetectorIntersectionsOnly 仅将三角形相交视为碰撞。

最重要的 OdGiCollisionDetector 方法是：

```
virtual void initializeCalculations(OdGeExtents3d& ext, OdInt64 nObjects);

```

此方法为计算准备内部检测器数据。输入参数：

- OdGeExtents3d&amp; ext – 要测试的三角形的公共范围。
- OdInt64 nObjects – 要测试的三角形容器的数量。

```
virtual void finalizeCalculations();

```

此方法释放内部检测器数据。与 OdGiIntersectionCalculator 不同，此方法不释放通过 appendTriangleContainer 调用添加的三角形容器所分配的内存。

```
OdInt64 appendTriangleContainer( OdGiIntersectTrianglesVector* pContainer );

```

将三角形容器添加到检测器并返回其内部 ID。

```
void processTrianglesIntoSpaceTree(OdInt64 objID, bool bOtherObjectsProcessed);

```

此方法将指定的三角形容器处理到检测器空间树中。

```
OdInt64 addContainerToBeTested( OdInt64 containerID );

```

此方法将指定的三角形容器标记为“待测试容器”。

```
void clearContainersToBeTested();
```

此方法取消标记所有“待测试容器”。

```
void detectCollisions( OdInt64 containerID, const OdGeExtents3d &extents );

```

此方法在指定的三角形容器与所有标记为“待测试容器”的三角形容器之间执行碰撞检测。输入范围是指定三角形容器的范围。

```
void getCollisions( OdList< OdInt64 >& result );

```

此方法使用被检测为发生碰撞的三角形容器的内部 ID，将上次 detectCollisions 调用的结果填充到输入列表中。

#### 使用 OdGiCollisionDetector

碰撞检测器机制检测指定三角形容器与所有标记为“待测试容器”的三角形容器之间的碰撞。在调用 detectCollisions 之前，所有标记的容器都应处理到空间树中。要使用 OdGiCollisionDetector：

1. 生成三角形容器。
2. 将所有用于碰撞检测的容器添加到检测器：  
     pDetector-&gt;appendTriangleContainer(pContainer);
3. 手动将每个标记为“待测试”的容器处理到空间树中：  
     pDetector-&gt;processTrianglesIntoSpaceTree( id, false );  
     pDetector-&gt;addContainerToBeTested( id );
4. 为每个需要与标记容器进行碰撞测试的容器调用 detectCollisions 并处理其结果：  
     OdList&lt; OdInt64 &gt; results;  
     pDetector-&gt;detectCollisions(id, container\_extents);  
     pDetector-&gt;getCollisions( results );

## 今天就开始行动

**免费试用 ODA 软件 60 天。  
无风险，无需信用卡。**

[免费试用](https://www.opendesign.com/cn/free-trial)
