Browse Source

SceneGraph: show how to implement object culling on the drawable group.

pull/405/head
Vladimír Vondruš 6 years ago
parent
commit
02a6747b73
  1. 31
      doc/snippets/MagnumSceneGraph.cpp
  2. 12
      src/Magnum/SceneGraph/Camera.h
  3. 21
      src/Magnum/SceneGraph/Drawable.h

31
doc/snippets/MagnumSceneGraph.cpp

@ -26,6 +26,7 @@
#include <algorithm> #include <algorithm>
#include "Magnum/Math/Matrix4.h" #include "Magnum/Math/Matrix4.h"
#include "Magnum/Math/Intersection.h"
#include "Magnum/SceneGraph/Animable.h" #include "Magnum/SceneGraph/Animable.h"
#include "Magnum/SceneGraph/AnimableGroup.h" #include "Magnum/SceneGraph/AnimableGroup.h"
#include "Magnum/SceneGraph/AbstractGroupedFeature.h" #include "Magnum/SceneGraph/AbstractGroupedFeature.h"
@ -349,4 +350,34 @@ camera.draw(drawableTransformations);
/* [Drawable-draw-order] */ /* [Drawable-draw-order] */
} }
{
Object3D cameraObject;
SceneGraph::Camera3D camera{cameraObject};
SceneGraph::DrawableGroup3D drawableGroup;
/* [Drawable-culling] */
struct CullableDrawable3D: SceneGraph::Drawable3D {
Range3D aabb; /* Relative to world origin */
// ...
};
/* Camera frustum relative to world origin */
auto frustum = Frustum::fromMatrix(camera.projectionMatrix()*camera.cameraMatrix());
/* Erase all items that don't pass the frustum check */
std::vector<std::pair<std::reference_wrapper<SceneGraph::Drawable3D>, Matrix4>>
drawableTransformations = camera.drawableTransformations(drawableGroup);
drawableTransformations.erase(std::remove_if(
drawableTransformations.begin(), drawableTransformations.end(),
[&](const std::pair<std::reference_wrapper<SceneGraph::Drawable3D>, Matrix4>& a) {
Range3D aabb = static_cast<CullableDrawable3D&>(a.first.get()).aabb;
return !Math::Intersection::rangeFrustum(aabb, frustum);
}),
drawableTransformations.end());
/* Draw just the visible part */
camera.draw(drawableTransformations);
/* [Drawable-culling] */
}
} }

12
src/Magnum/SceneGraph/Camera.h

@ -189,10 +189,10 @@ template<UnsignedInt dimensions, class T> class Camera: public AbstractFeature<d
/** /**
* @brief Drawable transformations * @brief Drawable transformations
* *
* Returns calculated transformations for given group of drawables. * Returns calculated camera-relative transformations for given group
* Useful in combination with @ref draw(const std::vector<std::pair<std::reference_wrapper<Drawable<dimensions, T>>, MatrixTypeFor<dimensions, T>>>&) * of drawables. Useful in combination with @ref draw(const std::vector<std::pair<std::reference_wrapper<Drawable<dimensions, T>>, MatrixTypeFor<dimensions, T>>>&)
* to provide custom draw order. See @ref SceneGraph-Drawable-draw-order * to implement custom draw order or object culling. See
* for more information. * @ref SceneGraph-Drawable-draw-order for more information.
*/ */
std::vector<std::pair<std::reference_wrapper<Drawable<dimensions, T>>, MatrixTypeFor<dimensions, T>>> drawableTransformations(DrawableGroup<dimensions, T>& group); std::vector<std::pair<std::reference_wrapper<Drawable<dimensions, T>>, MatrixTypeFor<dimensions, T>>> drawableTransformations(DrawableGroup<dimensions, T>& group);
@ -208,8 +208,8 @@ template<UnsignedInt dimensions, class T> class Camera: public AbstractFeature<d
* @brief Draw given drawables with transformations * @brief Draw given drawables with transformations
* *
* Useful in combination with @ref drawableTransformations() for * Useful in combination with @ref drawableTransformations() for
* drawing in a custom order. See @ref SceneGraph-Drawable-draw-order * implementing custom draw order or object culling. See
* for more information. * @ref SceneGraph-Drawable-draw-order for more information.
*/ */
void draw(const std::vector<std::pair<std::reference_wrapper<Drawable<dimensions, T>>, MatrixTypeFor<dimensions, T>>>& drawableTransformations); void draw(const std::vector<std::pair<std::reference_wrapper<Drawable<dimensions, T>>, MatrixTypeFor<dimensions, T>>>& drawableTransformations);

21
src/Magnum/SceneGraph/Drawable.h

@ -111,17 +111,28 @@ parameters once for whole group instead of setting them again in each
@snippet MagnumSceneGraph-gl.cpp Drawable-multiple-groups @snippet MagnumSceneGraph-gl.cpp Drawable-multiple-groups
@section SceneGraph-Drawable-draw-order Custom draw order @section SceneGraph-Drawable-draw-order Custom draw order and object culling
By default the contents of a drawable group are drawn in the order they were By default all contents of a drawable group are drawn, in the order they were
added. In some cases you may want to draw them in a different order (for added. In some cases you may want to draw them in a different order (for
example to have correctly sorted transparent objects) or draw just a subset example to have correctly sorted transparent objects) or draw just a subset
(for example to cull invisible objects way). That can be achieved using @ref Camera::drawableTransformations() (for example to cull invisible objects away). That can be achieved using
in combination with @ref Camera::draw(const std::vector<std::pair<std::reference_wrapper<Drawable<dimensions, T>>, MatrixTypeFor<dimensions, T>>>&) and applying @ref std::sort() with a custom @ref Camera::drawableTransformations() in combination with
predicate on the drawable transformation list: @ref Camera::draw(const std::vector<std::pair<std::reference_wrapper<Drawable<dimensions, T>>, MatrixTypeFor<dimensions, T>>>&).
For example, to have the objects sorted back-to-front, apply @ref std::sort()
with a custom predicate on the drawable transformation list:
@snippet MagnumSceneGraph.cpp Drawable-draw-order @snippet MagnumSceneGraph.cpp Drawable-draw-order
Another use case is object-level culling --- assuming each drawable instance
provides an *absolute* AABB, one can calculate the transformations, cull them
via e.g. @ref Math::Intersection::rangeFrustum() and then pass the filtered
vector to @ref Camera::draw(). To be clear, this approach depends on AABBs
provided as relative to world origin, the actual object transformations don't
get used in any way except being passed to the draw function:
@snippet MagnumSceneGraph.cpp Drawable-culling
@section SceneGraph-Drawable-explicit-specializations Explicit template specializations @section SceneGraph-Drawable-explicit-specializations Explicit template specializations
The following specializations are explicitly compiled into @ref SceneGraph The following specializations are explicitly compiled into @ref SceneGraph

Loading…
Cancel
Save