|
|
|
|
@ -23,7 +23,7 @@
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
namespace Magnum { namespace Shapes { |
|
|
|
|
/** @page collision-detection Collision detection |
|
|
|
|
/** @page shapes Collision detection |
|
|
|
|
@brief Collection of simple shapes for high performance collision detection. |
|
|
|
|
|
|
|
|
|
The essential thing in collision detection is to define a complex object with |
|
|
|
|
@ -33,35 +33,35 @@ together using various operations.
|
|
|
|
|
|
|
|
|
|
@tableofcontents |
|
|
|
|
|
|
|
|
|
@section collision-detection-shape-collection Available shapes |
|
|
|
|
@section shapes-collection Available shapes |
|
|
|
|
|
|
|
|
|
@subsection collision-detection-shapes1D One-dimensional shapes |
|
|
|
|
@subsection shapes-1D One-dimensional shapes |
|
|
|
|
|
|
|
|
|
- @ref Shapes::Point "Shapes::Point*D" - @copybrief Shapes::Point |
|
|
|
|
- @ref Shapes::Line "Shapes::Line*D" - @copybrief Shapes::Line |
|
|
|
|
- @ref Shapes::LineSegment "Shapes::LineSegment*D" - @copybrief Shapes::LineSegment |
|
|
|
|
- @ref Shapes::Point "Shapes::Point*D" -- @copybrief Shapes::Point |
|
|
|
|
- @ref Shapes::Line "Shapes::Line*D" -- @copybrief Shapes::Line |
|
|
|
|
- @ref Shapes::LineSegment "Shapes::LineSegment*D" -- @copybrief Shapes::LineSegment |
|
|
|
|
|
|
|
|
|
Because of numerical instability it's not possible to detect collisions of |
|
|
|
|
line and point. Collision of two lines can be detected only in 2D. |
|
|
|
|
|
|
|
|
|
@subsection collision-detection-shapes2D Two-dimensional shapes |
|
|
|
|
@subsection shapes-2D Two-dimensional shapes |
|
|
|
|
|
|
|
|
|
- Shapes::Plane - @copybrief Shapes::Plane |
|
|
|
|
- Shapes::Plane -- @copybrief Shapes::Plane |
|
|
|
|
|
|
|
|
|
@subsection collision-detection-shapes3D Three-dimensional shapes |
|
|
|
|
@subsection shapes-3D Three-dimensional shapes |
|
|
|
|
|
|
|
|
|
- @ref Shapes::Sphere "Shapes::Sphere*D" - @copybrief Shapes::Sphere |
|
|
|
|
- @ref Shapes::Capsule "Shapes::Capsule*D" - @copybrief Shapes::Capsule |
|
|
|
|
- @ref Shapes::AxisAlignedBox "Shapes::AxisAlignedBox*D" - @copybrief Shapes::AxisAlignedBox |
|
|
|
|
- @ref Shapes::Box "Shapes::Box*D" - @copybrief Shapes::Box |
|
|
|
|
- @ref Shapes::Sphere "Shapes::Sphere*D" -- @copybrief Shapes::Sphere |
|
|
|
|
- @ref Shapes::Capsule "Shapes::Capsule*D" -- @copybrief Shapes::Capsule |
|
|
|
|
- @ref Shapes::AxisAlignedBox "Shapes::AxisAlignedBox*D" -- @copybrief Shapes::AxisAlignedBox |
|
|
|
|
- @ref Shapes::Box "Shapes::Box*D" -- @copybrief Shapes::Box |
|
|
|
|
|
|
|
|
|
The easiest (and most efficient) shape combination for detecting collisions |
|
|
|
|
is point and sphere, followed by two spheres. Computing collision of two boxes |
|
|
|
|
is least efficient. |
|
|
|
|
|
|
|
|
|
@section collision-detection-shape-groups Creating hierarchic groups of shapes |
|
|
|
|
@section shapes-composition Creating shape compositions |
|
|
|
|
|
|
|
|
|
Shapes can be grouped together using one of three available logical |
|
|
|
|
%Shapes can be composed together using one of three available logical |
|
|
|
|
operations: AND, OR and NOT. These operations are mapped to operator&&(), |
|
|
|
|
operator||() and operator!(), so for example creating negation of logical OR |
|
|
|
|
of line segment and point is simple as this: |
|
|
|
|
@ -69,45 +69,19 @@ of line segment and point is simple as this:
|
|
|
|
|
Shapes::LineSegment3D segment; |
|
|
|
|
Shapes::Point3D point; |
|
|
|
|
|
|
|
|
|
Shapes::ShapeGroup3D group = !(segment || point); |
|
|
|
|
Shapes::Composition3D composition = !(segment || point); |
|
|
|
|
@endcode |
|
|
|
|
|
|
|
|
|
@note Logical operations are not the same as set operations -- intersection of |
|
|
|
|
two spheres will not generate any collision if they are disjoint, but |
|
|
|
|
logical AND will if the object collides with both of them. |
|
|
|
|
|
|
|
|
|
The resulting object internally stores copies of both shapes, so the original |
|
|
|
|
instances can be destroyed. For simple combinations appropriate resulting |
|
|
|
|
shape is generated (e.g. logical OR of point and sphere can be only the sphere, |
|
|
|
|
if the point lies inside) and stored inside ShapeGroup instead of two original |
|
|
|
|
objects. |
|
|
|
|
@subsection shapes-simplification Providing simplified version of shape for better performance |
|
|
|
|
|
|
|
|
|
@subsection collision-detection-shape-reference Referencing the shapes for later changes |
|
|
|
|
|
|
|
|
|
Sometimes you may want to modify the shape based on changes of the object |
|
|
|
|
itself. In previous example all the shapes were copied into ShapeGroup, so it |
|
|
|
|
was not possible to change their properties such as sphere radius without |
|
|
|
|
recreating the group again. You can, however, explicitly pass a reference to |
|
|
|
|
original object, so you can change it later: |
|
|
|
|
@code |
|
|
|
|
Shapes::LineSegment3D segment; |
|
|
|
|
Shapes::Point3D point; |
|
|
|
|
|
|
|
|
|
Shapes::ShapeGroup3D group = !(segment || std::ref(point)); |
|
|
|
|
|
|
|
|
|
point.setPosition({1.0f, -6.0f, 0.5f}); |
|
|
|
|
@endcode |
|
|
|
|
|
|
|
|
|
Note that passing a reference implies that you must not destroy the original |
|
|
|
|
instance (in this case the point). Also because the referenced instance could |
|
|
|
|
change, there are no shape optimizations done, unlike above. |
|
|
|
|
|
|
|
|
|
@subsection collision-detection-shape-simplification Providing simplified version of shape for better performance |
|
|
|
|
|
|
|
|
|
If there are many shapes grouped together, it might hurt performance of |
|
|
|
|
If there are many shapes composed together, it might hurt performance of |
|
|
|
|
collision detection, because it might be testing collision with more shapes |
|
|
|
|
than necessary. It's then good to specify simplified version of such shape, |
|
|
|
|
so the collision detection is done on the original if and only if collision |
|
|
|
|
so the collision detection is done on the complex one if and only if collision |
|
|
|
|
was detected with the simplified shape. It is in fact logical AND using |
|
|
|
|
operator&&() - the collision is initially detected on first (simplified) shape |
|
|
|
|
and then on the other: |
|
|
|
|
@ -116,12 +90,12 @@ Shapes::Sphere3D sphere;
|
|
|
|
|
Shapes::Box3D box; |
|
|
|
|
Shapes::AxisAlignedBox3D simplified; |
|
|
|
|
|
|
|
|
|
Shapes::ShapeGroup3D object = simplified && (sphere || box); |
|
|
|
|
Shapes::Composition3D composition = simplified && (sphere || box); |
|
|
|
|
@endcode |
|
|
|
|
|
|
|
|
|
@section collision-detection-shape-collisions Detecting shape collisions |
|
|
|
|
@section shapes-collisions Detecting shape collisions |
|
|
|
|
|
|
|
|
|
Shape pairs which have collision detection implemented can be tested for |
|
|
|
|
%Shape pairs which have collision detection implemented can be tested for |
|
|
|
|
collision using operator%(), for example: |
|
|
|
|
@code |
|
|
|
|
Shapes::Point3D point; |
|
|
|
|
@ -130,5 +104,17 @@ Shapes::Sphere3D sphere;
|
|
|
|
|
bool collide = point % sphere; |
|
|
|
|
@endcode |
|
|
|
|
|
|
|
|
|
@section shapes-scenegraph Integration with scene graph |
|
|
|
|
|
|
|
|
|
%Shape can be attached to object in the scene using Shapes::Shape feature and |
|
|
|
|
then used for collision detection. You can also use DebugTools::ShapeRenderer |
|
|
|
|
to visualize the shape for debugging purposes. |
|
|
|
|
@code |
|
|
|
|
Object3D object; |
|
|
|
|
auto shape = Shapes::Shape<Shapes::Sphere3D>(object, {{}, 23.0f}); |
|
|
|
|
@endcode |
|
|
|
|
|
|
|
|
|
See also @ref scenegraph for introduction. |
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
|
}}} |