From 06d707f25c517a237d301ae7422309e7a4a81c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 9 May 2013 11:51:16 +0200 Subject: [PATCH] Shape rework #8: updated documentation. --- doc/features.dox | 2 +- doc/namespaces.dox | 2 +- doc/{collision-detection.dox => shapes.dox} | 82 +++++++++------------ src/DebugTools/ShapeRenderer.h | 2 +- src/Shapes/AbstractShape.h | 3 +- src/Shapes/AxisAlignedBox.h | 3 +- src/Shapes/Box.h | 2 +- src/Shapes/Capsule.h | 3 +- src/Shapes/Composition.h | 5 +- src/Shapes/Line.h | 1 + src/Shapes/LineSegment.h | 1 + src/Shapes/Plane.h | 6 +- src/Shapes/Point.h | 1 + src/Shapes/Shape.h | 18 +++-- src/Shapes/ShapeGroup.h | 2 +- src/Shapes/Sphere.h | 3 +- 16 files changed, 67 insertions(+), 69 deletions(-) rename doc/{collision-detection.dox => shapes.dox} (53%) diff --git a/doc/features.dox b/doc/features.dox index f06747f7c..a2e0e22db 100644 --- a/doc/features.dox +++ b/doc/features.dox @@ -31,7 +31,7 @@ namespace Magnum { - @subpage matrix-vector -- @copybrief matrix-vector - @subpage transformations -- @copybrief transformations - @subpage scenegraph -- @copybrief scenegraph -- @subpage collision-detection -- @copybrief collision-detection +- @subpage shapes -- @copybrief shapes - @subpage debug-tools -- @copybrief debug-tools */ } diff --git a/doc/namespaces.dox b/doc/namespaces.dox index ba44f7f93..8a4e1b3b7 100644 --- a/doc/namespaces.dox +++ b/doc/namespaces.dox @@ -161,7 +161,7 @@ component in CMake. See @ref building and @ref cmake for more information. /** @namespace Magnum::Shapes @brief %Shape library -Collision detection system. See @ref collision-detection for introduction. +Collision detection system. See @ref shapes for introduction. This library is built when `WITH_SHAPES` is enabled and found as `%Shapes` component in CMake. See @ref building and @ref cmake for more information. diff --git a/doc/collision-detection.dox b/doc/shapes.dox similarity index 53% rename from doc/collision-detection.dox rename to doc/shapes.dox index 1288c2b8b..cb99d5454 100644 --- a/doc/collision-detection.dox +++ b/doc/shapes.dox @@ -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(object, {{}, 23.0f}); +@endcode + +See also @ref scenegraph for introduction. + */ }}} diff --git a/src/DebugTools/ShapeRenderer.h b/src/DebugTools/ShapeRenderer.h index 2e2ba75d0..0694fa528 100644 --- a/src/DebugTools/ShapeRenderer.h +++ b/src/DebugTools/ShapeRenderer.h @@ -132,7 +132,7 @@ DebugTools::ResourceManager::instance()->set("red", (new DebugTools::ShapeRender ->setColor({1.0f, 0.0f, 0.0f})); // Create debug renderer for given shape, use "red" options for it -Shapes::ObjectShape2D* shape; +Shapes::AbstractShape2D* shape; new DebugTools::ShapeRenderer2D(shape, "red", debugDrawables); @endcode diff --git a/src/Shapes/AbstractShape.h b/src/Shapes/AbstractShape.h index 7df35692e..c742b969e 100644 --- a/src/Shapes/AbstractShape.h +++ b/src/Shapes/AbstractShape.h @@ -45,7 +45,8 @@ namespace Implementation { /** @brief Base class for object shapes -This class is not directly instantiable, see Shape instead. +This class is not directly instantiable, see Shape instead. See @ref shapes for +brief introduction. @see AbstractShape2D, AbstractShape3D */ template class MAGNUM_SHAPES_EXPORT AbstractShape: public SceneGraph::AbstractGroupedFeature> { diff --git a/src/Shapes/AxisAlignedBox.h b/src/Shapes/AxisAlignedBox.h index 174596f06..5416823b5 100644 --- a/src/Shapes/AxisAlignedBox.h +++ b/src/Shapes/AxisAlignedBox.h @@ -38,8 +38,7 @@ namespace Magnum { namespace Shapes { /** @brief Axis-aligned box -Unit-size means that half extents are equal to 1, equivalent to e.g. sphere -radius. +See @ref shapes for brief introduction. @see AxisAlignedBox2D, AxisAlignedBox3D @todo Assert for rotation */ diff --git a/src/Shapes/Box.h b/src/Shapes/Box.h index ffd0db344..54686b490 100644 --- a/src/Shapes/Box.h +++ b/src/Shapes/Box.h @@ -39,7 +39,7 @@ namespace Magnum { namespace Shapes { @brief Unit-size box with assigned transformation matrix Unit-size means that half extents are equal to 1, equivalent to e.g. sphere -radius. +radius. See @ref shapes for brief introduction. @todo Use quat + position + size instead? @see Box2D, Box3D @todo Assert for skew diff --git a/src/Shapes/Capsule.h b/src/Shapes/Capsule.h index 8541e0db9..2bc001763 100644 --- a/src/Shapes/Capsule.h +++ b/src/Shapes/Capsule.h @@ -39,7 +39,8 @@ namespace Magnum { namespace Shapes { @brief %Capsule defined by cylinder start and end point and radius Unlike other elements the capsule doesn't support asymmetric scaling. When -applying transformation, the scale factor is averaged from all axes. +applying transformation, the scale factor is averaged from all axes. See +@ref shapes for brief introduction. @see Capsule2D, Capsule3D @todo Assert for asymmetric scaling */ diff --git a/src/Shapes/Composition.h b/src/Shapes/Composition.h index ae19d4239..afe400774 100644 --- a/src/Shapes/Composition.h +++ b/src/Shapes/Composition.h @@ -60,8 +60,7 @@ enum class CompositionOperation: UnsignedByte { /** @brief Composition of shapes -Result of logical operations on shapes. -See @ref collision-detection for brief introduction. +Result of logical operations on shapes. See @ref shapes for brief introduction. */ template class MAGNUM_SHAPES_EXPORT Composition { friend Implementation::AbstractShape* Implementation::getAbstractShape<>(Composition&, std::size_t); @@ -220,7 +219,7 @@ template inline Composition operator!(T a); [Short-circuit evaluation](http://en.wikipedia.org/wiki/Short-circuit_evaluation) is used here, so this operation can be used for providing simplified shape version, because collision with @p b is computed only if @p a collides. -See @ref collision-detection-shape-simplification for an example. +See @ref shapes-simplification for an example. */ template inline Composition operator&&(T a, T b); diff --git a/src/Shapes/Line.h b/src/Shapes/Line.h index be416483d..1ba8dcbed 100644 --- a/src/Shapes/Line.h +++ b/src/Shapes/Line.h @@ -37,6 +37,7 @@ namespace Magnum { namespace Shapes { /** @brief Infinite line, defined by two points +See @ref shapes for brief introduction. @see Line2D, Line3D @todo collision detection of two Line2D */ diff --git a/src/Shapes/LineSegment.h b/src/Shapes/LineSegment.h index 592ae1dcf..b53343048 100644 --- a/src/Shapes/LineSegment.h +++ b/src/Shapes/LineSegment.h @@ -35,6 +35,7 @@ namespace Magnum { namespace Shapes { /** @brief %Line segment, defined by starting and ending point +See @ref shapes for brief introduction. @see LineSegment2D, LineSegment3D */ template class LineSegment: public Line { diff --git a/src/Shapes/Plane.h b/src/Shapes/Plane.h index bc6ecce85..acf584d1a 100644 --- a/src/Shapes/Plane.h +++ b/src/Shapes/Plane.h @@ -35,7 +35,11 @@ namespace Magnum { namespace Shapes { -/** @brief Infinite plane, defined by position and normal (3D only) */ +/** +@brief Infinite plane, defined by position and normal (3D only) + +See @ref shapes for brief introduction. +*/ class MAGNUM_SHAPES_EXPORT Plane { public: enum: UnsignedInt { diff --git a/src/Shapes/Point.h b/src/Shapes/Point.h index a64f1621d..963c78e6e 100644 --- a/src/Shapes/Point.h +++ b/src/Shapes/Point.h @@ -37,6 +37,7 @@ namespace Magnum { namespace Shapes { /** @brief %Point +See @ref shapes for brief introduction. @see Point2D, Point3D */ template class MAGNUM_SHAPES_EXPORT Point { diff --git a/src/Shapes/Shape.h b/src/Shapes/Shape.h index e16274961..86a5717d0 100644 --- a/src/Shapes/Shape.h +++ b/src/Shapes/Shape.h @@ -44,18 +44,22 @@ namespace Implementation { Adds shape for collision detection to object. Each %Shape is part of some ShapeGroup, which essentially maintains a set of objects which can -collide with each other. - -@section Shape-usage Usage - -Add the feature to the object and some shape group (you can also use -ShapeGroup::add() and ShapeGroup::remove() later) and configure the -shape. +collide with each other. See @ref shapes for brief introduction. + +The shape contains original shape with relative transformation under shape() +and also caches a shape with absolute transformation under transformedShape(), +which can be used for collision detection. To conveniently use collision +detection among many object, you need to add the shape to ShapeGroup, which +then provides collision detection for given group of shapes. You can also use +ShapeGroup::add() and ShapeGroup::remove() later to manage e.g. collision +islands. @code Shapes::ShapeGroup3D shapes; Object3D* object; auto shape = new Shapes::Shape(object, {{}, 0.75f}, &shapes); + +Shapes::AbstractShape3D* firstCollision = shapes.firstCollision(shape); @endcode @see @ref scenegraph, ShapeGroup2D, ShapeGroup3D, diff --git a/src/Shapes/ShapeGroup.h b/src/Shapes/ShapeGroup.h index c71030b63..86b7a22e5 100644 --- a/src/Shapes/ShapeGroup.h +++ b/src/Shapes/ShapeGroup.h @@ -40,7 +40,7 @@ namespace Magnum { namespace Shapes { /** @brief Group of shapes -See Shape for more information. +See Shape for more information. See @ref shapes for brief introduction. @see @ref scenegraph, ShapeGroup2D, ShapeGroup3D */ template class MAGNUM_SHAPES_EXPORT ShapeGroup: public SceneGraph::FeatureGroup> { diff --git a/src/Shapes/Sphere.h b/src/Shapes/Sphere.h index 42db3cbef..9c473a39f 100644 --- a/src/Shapes/Sphere.h +++ b/src/Shapes/Sphere.h @@ -39,7 +39,8 @@ namespace Magnum { namespace Shapes { @brief %Sphere defined by position and radius Unlike other elements the sphere doesn't support asymmetric scaling. When -applying transformation, the scale factor is averaged from all axes. +applying transformation, the scale factor is averaged from all axes. See +@ref shapes for brief introduction. @see Sphere2D, Sphere3D @todo Assert for asymmetric scaling */