この記事は、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;
このメソッドは、処理フェーズOdGiCollideProc::kPhaseDetectIntersections中にエンティティフィルタリングで使用されるOdGiPathNodeの追加リストを指定します。リストが空ではなく、現在処理中のエンティティの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 );