Collision Detection in ODA Visualize (Part 3 of 3)

Egor Slupko

November 29, 2018

This article is part of a series of articles about the collision detection mechanism in ODA Visualize. For the previous article, see Part 2.

Overview of OdGiCollideProc

The interface of the collision detection conveyor node is described in GiCollideProc.h. It contains the following methods:

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

This method specifies the collision detection reactor and context.

virtual void setDrawContext(OdGiConveyorContext* pDrawCtx) = 0;

This method specifies the drawing context that provides access to the vectorization status information.

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

These methods specify the current processing phase that allows conveyor node collecting of triangles to different lists.

virtual const OdGeExtents3d& extents() const = 0;

This method returns the extents of triangles that were collected during the OdGiCollideProc::kPhaseGatherInputData processing phase.

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

These methods disable entity filtering.

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

This method specifies a list of OdGiPathNode items that are used in entity filtering

  • During the processing phase OdGiCollideProc::kPhaseGatherInputData, if OdGiPathNode of the currently processing entity is not listed in pInputList, the entity is skipped.
  • During the processing phase OdGiCollideProc::kPhaseDetectIntersections, if OdGiPathNode of the currently processing entity is listed in pInputList, the entity is skipped to avoid detecting collisions between the same entity
virtual void setCheckWithDrawables( OdGiPathNode const*const* pInputList, OdUInt32 nInputListSize ) = 0;

This method specifies an additional list of OdGiPathNode that is used in entity filtering during the processing phase OdGiCollideProc::kPhaseDetectIntersections; if the list is not empty and OdGiPathNode of the currently processing entity is not listed in it, the entity is skipped.

virtual void processTriangles() = 0

This method performs processing triangles that were gathered during conveyor node processing phases.

Overview of OdGiCollisionDetector

OdGiCollisionDetector and OdGiCollisionDetectorIntersectionsOnly are heirs of OdGiIntersectionsCalculator and are described in GiIntersectionCalculator.h. The only difference between them is that OdGiCollisionDetector treats both triangle intersections and triangle touching as collisions while OdGiCollisionDetectorIntersectionsOnly treats only triangle intersections as collisions.

The most important OdGiCollisionDetector methods are:

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

This method prepares internal detector data for calculations. Input parameters:

  • OdGeExtents3d& ext – Common extents of triangles to be tested.
  • OdInt64 nObjects – Number of triangle containers to be tested.
virtual void finalizeCalculations();

This method releases internal detector data. Unlike OdGiIntersectionCalculator, this method does not release memory allocated for triangle containers that was added through an appendTriangleContainer call.

OdInt64 appendTriangleContainer( OdGiIntersectTrianglesVector* pContainer );

Adds a triangle container to the detector and returns its internal ID.

void processTrianglesIntoSpaceTree(OdInt64 objID, bool bOtherObjectsProcessed);

This method processes a specified triangle container into a detector space tree.

OdInt64 addContainerToBeTested( OdInt64 containerID );

This method marks the specified triangle container as “container to be tested.”

void clearContainersToBeTested();

This method unmarks all “container to be tested” containers.

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

This method performs collision detection between a specified triangle container and all triangle containers that are marked as “container to be tested.” Input extents are extents of the specified triangle container.

void getCollisions( OdList< OdInt64 >& result );

This method fills the input list with results of the last detectCollisions call using internal IDs of triangle containers that were detected as colliding.

Using OdGiCollisionDetector

The collision detector mechanism detects collisions between a specified triangle container and all triangle containers that are marked as “container to be tested.” All marked containers should be processed into the space tree before a detectCollisions call. To use OdGiCollisionDetector:

  1. Generate triangle containers.
  2. Add all containers for collision detection to the detector:
    pDetector->appendTriangleContainer(pContainer);
  3. Manually process each container marked as “to be tested” into the space tree:
    pDetector->processTrianglesIntoSpaceTree( id, false );
    pDetector->addContainerToBeTested( id );
  4. Call detectCollisions and process its results for each container that needs to be tested for collisions with marked containers:
    OdList< OdInt64 > results;
    pDetector->detectCollisions(id, container_extents);
    pDetector->getCollisions( results );