本文是关于 ODA Visualize 中碰撞检测机制系列文章的一部分。有关上一篇文章,请参阅第 2 部分。
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& 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:
- 生成三角形容器。
- 将所有用于碰撞检测的容器添加到检测器:
pDetector->appendTriangleContainer(pContainer); - 手动将每个标记为“待测试”的容器处理到空间树中:
pDetector->processTrianglesIntoSpaceTree( id, false );
pDetector->addContainerToBeTested( id ); - 为每个需要与标记容器进行碰撞测试的容器调用 detectCollisions 并处理其结果:
OdList< OdInt64 > results;
pDetector->detectCollisions(id, container_extents);
pDetector->getCollisions( results );