Click or drag to resize
DigitalRuneCollision Detection
Collision queries

DigitalRune Geometry can compute three different types of collision queries:

  • Boolean queries: A boolean query (also known as have-contact query) checks if two objects are in contact. The result is true if the objects touch. The result is false if the objects are separated.
    Note Note

    The term boolean query is not equal to the term boolean operation used in 3D modeling. A boolean operation is an operation that combines objects using operations like AND or OR.

  • Contact queries: A contact query (also known as intersection or interference query) computes the detailed contact information for two touching objects. A set of contact points describes the geometry of the contact. If two objects are separated, a contact query reports the separation and computes no further details.
  • Closest-point queries: A closest-point query (also known as proximity query) of two objects computes a point pair consisting of a point on each object. The point pair describes the closest features of the objects. The distance of the closest-point pair is equal to the separation distance.
Collision detection

The collision detection in DigitalRune Geometry can compute collision information between collision objects (see CollisionObject). Each collision object contains a reference to a geometric object (see IGeometricObject). Besides the geometric object a collision object stores additional information for the collision detection system.

The class CollisionDetection contains methods to compute contact points for a pair of touching objects or the two closest points for a pair of separated objects.

Contacts and contact sets

For a pair of touching objects the collision detection computes contacts (see Contact) that represent points where objects touch each other.

A contact describes a single contact point (or closest-point pair) between two objects (called "object A" and "object B"). A contact consists of 2 points: a point on object A (see PositionALocal or PositionAWorld) and a point on object B (see PositionBLocal or PositionBWorld). The property Position is a point that lies halfway between those two points. The contact further stores the Normal, the PenetrationDepth and other information.

There are 3 basic types of contacts:

  • Touching Contacts: Object A and object B are touching at the surface. The penetration depth is 0. The points on object A and object B are identical.

    Touching Contact
    Figure: Contact Between Touching Objects
  • Pentrating Contacts: Object A and object B are penetrating each other. The penetration depth is greater than 0. The contact stores the points on object A and B that have maximum penetration.

    Penetrating Contact
    Figure: Contact Between Penetrating Objects
  • Closest points (separated objects): Object A and object B are separated. They are not in contact. This can be the result of a closest-point query. (Other contact queries do not compute closest points. Separated objects are simply ignored in normal queries.)

    The contact stores closest points between object A and B. The penetration depth is negative. The absolute value of penetration depth indicates the distance between object A and object B. (Remember: The penetration depth is the inverse of the separation distance.)

    Separated Objects
    Figure: Closest-Point Pair Between Separated Objects

All contacts for a pair of objects are gathered in a contact set (see ContactSet).

Contact Set
Figure: Contact Set Of Two Boxes

A ContactSetCollection is a collection of the contact sets of different pairs of collision objects.

Collision domains

Collision detection is one of the most costly part of modern computer games. A collision domain (CollisionDomain) is a way to improve the performance of collision detection. A collision domain manages a collection of collision objects. For these objects it can compute the collision information much faster by re-using old collision information.

Additionally, if the property EnableMultithreading is set, the workload is automatically distributed across multiple CPU cores to further improve performance.

Caution note Caution

The performance of closest point queries is not improved by using collision domains.

Collision algorithms and the collision algorithm matrix

The computation of collision information is performed with different collision algorithms (see namespace DigitalRune.Geometry.Collisions.Algorithms). The different collision algorithms handle collisions between different shape types. Some collision algorithms can handle several different shape types, some handle only a specific shape type.

The collision detection uses the class CollisionAlgorithmMatrix to define which collision algorithms should be used for which pair of shape types. Per default, all shapes can collide with all other shapes with following exceptions:

  • The special EmptyShape will never collide with any other shape.
  • Contacts are not computed for the following pairs of infinite shapes:
    • line vs. plane
    • line vs. height field
    • plane vs. plane
    • plane vs. height field
    • height field vs. height field
  • Two rays do not collide.
Ray casting

Ray casting can be done by using a geometric object that has a RayShape. Thus, rays can be used similar to other shape types.

A few things are specials for contacts between a ray and another object:

  • The property IsRayHit indicates whether the Contact is the result of a hit by a ray.
  • PenetrationDepth of a contact is used differently if a ray hits an object: The property stores the distance from the ray origin to the contact position. (A normal penetration depth is usually not useful for ray contacts.)
  • The property Normal of a contact is used differently if the ray hits an object: Normal describes the surface normal at the contact position on the object that was hit.
    Ray Hit
    Figure: A Ray Hit
  • If the ray origin is inside the other object, the penetration distance is 0 and the contact normal is not defined.
Margins and epsilon tolerances

Some collision algorithms are iterative algorithms that abort when the error of the result falls under a given tolerance limit. In DigitalRune Geometry this tolerance limit is defined using CollisionDetectionEpsilon.

Some shapes like points, lines, line segments are treated as infinitely thin - which mean two points will only collide if they are exactly on the same position. If you want more tolerant checks, use thick shapes like spheres, capsule, cylinder, etc. instead.

Objects do not have an "outer margin" and do not collide if their separation distance is greater than zero. Sometimes it is helpful to detect collisions if objects are separated but the separation distance is very small. To achieve this you can scale the shapes to make them slightly bigger, so that "near collisions" are also detected. To scale an object you can use one of the following methods:

Caveats

Collision algorithms have (numerical) limitations. For example:

  • The penetration information between two convex shapes is usually exact within a certain numerical tolerance. In rare cases the contact information is only a local optimum instead of global optimum. That means that the contact information can be used to separate the objects properly, but a smaller penetration depth with a different normal vector might exist.
  • The algorithms for concave shapes compute penetration information between convex sub-parts of the concave shape. The resulting contact information describes locally optimal result between the convex parts.
  • Triangle meshes are treated as hollow objects. That means the penetration information for mesh contacts is only an estimate and might not be exact for deep penetrations.

We have tried to minimize numerical problems and to filter sub-optimal contact information where possible. To get the best results please look at the tips below. If you need more tips to make your application faster and more robust, please contact our support.

Tips

Shapes

Here are some tips for choosing the right shape to get the best performance and the most accurate contact information.

Object sizes

Try to use reasonable sizes for all geometric objects. Avoid extreme sizes:

  • Do not use shapes with size 0 (e.g. a sphere with radius 0). Use the PointShape if you need an infinitely small object.
  • Do not use infinite shapes (e.g. a box where the widths are set to infinity or infinite rays). Use a smaller finite size instead. In some cases there can be different interpretations for what the collision result (e.g. "penetration depth", "normal vector") should be if an infinite object is involved. Therefore, the collision algorithms in DigitalRune Geometry do not always handle infinite objects correctly or as you would suspect.
  • Avoid large size differences. All computations are done using single-precision floating point numbers. If a collision of a large object (e.g. 1 km width) and a small object (e.g. 1 cm width) is computed, the numerical errors can be large.
  • Avoid very long stick like objects. Objects which are relatively uniform in all directions are better.

Performance tips

Here are a few tips that help to improve the performance and stability of the collision detection:

  • Boolean queries are faster than contact queries. Contact queries are faster than closest-point queries.
  • Use collision domains.
  • For objects in a collision domain, contact details are computed per default for all objects in the collision domain. Collision filtering can be used to disable the contact computation where it is not necessary.
  • The property Type can be used to set the object type to "trigger" when only a boolean result without contact details is required.
Subtopics
See Also