Browse Source

SceneGraph: there is never enough documentation.

pull/87/head
Vladimír Vondruš 11 years ago
parent
commit
9fd25a1fd8
  1. 217
      doc/scenegraph.dox
  2. 2
      src/Magnum/AbstractFramebuffer.cpp
  3. 58
      src/Magnum/SceneGraph/AbstractFeature.h
  4. 10
      src/Magnum/SceneGraph/AbstractObject.h
  5. 3
      src/Magnum/SceneGraph/AbstractTransformation.h
  6. 8
      src/Magnum/SceneGraph/AbstractTranslation.h
  7. 4
      src/Magnum/SceneGraph/AbstractTranslationRotation2D.h
  8. 4
      src/Magnum/SceneGraph/AbstractTranslationRotation3D.h
  9. 4
      src/Magnum/SceneGraph/AbstractTranslationRotationScaling2D.h
  10. 4
      src/Magnum/SceneGraph/AbstractTranslationRotationScaling3D.h
  11. 21
      src/Magnum/SceneGraph/Animable.h
  12. 8
      src/Magnum/SceneGraph/Camera2D.h
  13. 10
      src/Magnum/SceneGraph/Camera3D.h
  14. 77
      src/Magnum/SceneGraph/Drawable.h
  15. 2
      src/Magnum/SceneGraph/DualComplexTransformation.h
  16. 2
      src/Magnum/SceneGraph/DualQuaternionTransformation.h
  17. 2
      src/Magnum/SceneGraph/MatrixTransformation2D.h
  18. 3
      src/Magnum/SceneGraph/MatrixTransformation3D.h
  19. 5
      src/Magnum/SceneGraph/Object.h
  20. 2
      src/Magnum/SceneGraph/RigidMatrixTransformation2D.h
  21. 3
      src/Magnum/SceneGraph/RigidMatrixTransformation3D.h
  22. 10
      src/Magnum/SceneGraph/TranslationTransformation.h

217
doc/scenegraph.dox

@ -56,41 +56,83 @@ three main components:
@section scenegraph-transformation Transformations @section scenegraph-transformation Transformations
Transformation handles object position, rotation etc. and its basic property Transformation handles object position, rotation etc. and its basic property
is dimension count (2D or 3D) and underlying floating-point type. is dimension count (2D or 3D) and underlying floating-point type. All classes
in @ref SceneGraph are templated on underlying type. However, in most cases
@ref Float "Float" is used and thus nearly all classes have convenience aliases
so you don't have to explicitly specify it.
Scene graph has various transformation implementations for both 2D and 3D. Each
implementation has its own advantages and disadvantages -- for example when
using matrices you can have nearly arbitrary transformations, but composing
transformations, computing their inverse and accounting for floating-point
drift is rather costly operation. On the other hand quaternions won't allow you
to scale or shear objects, but have far better performance characteristics.
@note All classes in @ref SceneGraph are templated on underlying type. However, It's also possible to implement your own transformation class for specific
in most cases @ref Float "Float" is used and thus nearly all classes have needs, see source of builtin transformation classes for more information.
convenience aliases so you don't have to explicitly specify it.
Magnum provides the following transformation classes. See documentation of each
class for more detailed information:
- @ref SceneGraph::BasicMatrixTransformation2D "SceneGraph::MatrixTransformation2D" --
arbitrary 2D transformations but with slow inverse transformations and no
floating-point drift reduction
- @ref SceneGraph::BasicMatrixTransformation3D "SceneGraph::MatrixTransformation3D" --
arbitrary 3D transformations but with slow inverse transformations and no
floating-point drift reduction
- @ref SceneGraph::BasicRigidMatrixTransformation2D "SceneGraph::RigidMatrixTransformation2D" --
2D translation, rotation and reflection (no scaling), with relatively fast
inverse transformations and floating-point drift reduction
- @ref SceneGraph::BasicRigidMatrixTransformation3D "SceneGraph::RigidMatrixTransformation3D" --
3D translation, rotation and reflection (no scaling), with relatively fast
inverse transformations and floating-point drift reduction
- @ref SceneGraph::BasicDualComplexTransformation "SceneGraph::DualComplexTransformation" --
2D translation and rotation with fast inverse transformations and
floating-point drift reduction
- @ref SceneGraph::BasicDualQuaternionTransformation "SceneGraph::DualQuaternionTransformation" --
3D translation and rotation with fast inverse transformation and
floating-point drift reduction
- @ref SceneGraph::TranslationTransformation "SceneGraph::TranslationTransformation*D" --
Just 2D/3D translation (no rotation, scaling or anything else)
Common usage of transformation classes is to typedef Scene and Object with
desired transformation type to save unnecessary typing later:
@code
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D;
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
@endcode
Scene graph has implementation of transformations in both 2D and 3D, using @attention Note that you have to include both @ref Magnum/SceneGraph/Object.h
either matrices or combination of position and rotation. Each implementation and desired transformation class (e.g. @ref Magnum/SceneGraph/MatrixTransformation3D.h)
has its own advantages and disadvantages -- for example when using matrices to be able to use the resulting type.
you can have nearly arbitrary transformations, but composing transformations
and computing their inverse is costly operation. On the other hand quaternions
won't allow you to scale or shear objects, but are more memory efficient than
matrices.
It's also possible to implement your own transformation class for specific The object type is subclassed from the transformation type and so the
needs, see source of other transformation classes for more information. `Object3D` type will then contain all members from both @ref SceneGraph::Object
and @ref SceneGraph::MatrixTransformation3D. For convenience you can use method
chaining:
@code
Scene3D scene;
Object3D object;
object.setParent(&scene)
.rotateY(15.0_degf)
.translate(Vector3::xAxis(5.0f));
@endcode
@section scenegraph-hierarchy Scene hierarchy @section scenegraph-hierarchy Scene hierarchy
Scene hierarchy is skeleton part of scene graph. In the root there is Scene hierarchy is skeleton part of scene graph. In the root there is
@ref SceneGraph::Scene and its children are @ref SceneGraph::Object instances. @ref SceneGraph::Scene and its children are @ref SceneGraph::Object instances.
The hierarchy has some transformation type, identical for all objects (because Whole hierarchy has one transformation type, identical for all objects (because
for example having part of the tree in 2D and part in 3D just wouldn't make for example having part of the tree in 2D and part in 3D just wouldn't make
sense). Common usage is to typedef Scene and Object with desired transformation sense).
type to save unnecessary typing later:
@code
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D;
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
@endcode
Then you can start building the hierarchy by *parenting* one object to another. Then you can start building the hierarchy by *parenting* one object to another.
Parent object can be either passed in constructor or using Parent object can be either passed in constructor or set using
@ref SceneGraph::Object::setParent(). Scene is always root object, so it @ref SceneGraph::Object::setParent(). Scene is always root object, so it
naturally cannot have parent object. List of object children can be accessed naturally cannot have parent object. Parent and children relationships can be
through @ref SceneGraph::Object::children(). observed through @ref SceneGraph::Object::parent() and
@ref SceneGraph::Object::children().
@code @code
Scene3D scene; Scene3D scene;
@ -98,52 +140,62 @@ auto first = new Object3D(&scene);
auto second = new Object3D(first); auto second = new Object3D(first);
@endcode @endcode
The hierarchy takes care of memory management - when an object is destroyed, The hierarchy takes care of memory management -- when an object is destroyed,
all its children are destroyed too. See detailed explanation of all its children are destroyed too. See detailed explanation of
@ref scenegraph-object-construction-order "construction and destruction order" @ref scenegraph-object-construction-order "construction and destruction order"
for information about possible issues. below for information about possible issues.
The object is derived from the transformation you specified earlier in the
`typedef`, so you can directly transform the objects using methods of given
transformation implementation. Scene, as a root object, cannot have any
transformation. For convenience you can use method chaining:
@code
auto next = new Object3D;
next->setParent(another)
.translate(Vector3::yAxis(3.0f))
.rotateY(35.0_degf);
@endcode
@section scenegraph-features Object features @section scenegraph-features Object features
The object itself handles only parent/child relationship and transformation. The object itself handles only parent/child relationship and transformation.
To make the object renderable, animatable, add collision shape to it etc., you To make the object renderable, animable, add collision shape to it etc., you
have to add a *feature* to it. have to add a *feature* to it.
Each feature takes reference to holder object in constructor, so adding a Magnum provides the following builtin features. See documentation of each class
feature to an object might look just like this, as in some cases you don't even for more detailed information and usage examples:
need to keep the pointer to it. List of object features is accessible through
@ref SceneGraph::Object::features(). - @ref SceneGraph::AbstractCamera "SceneGraph::Camera*D" -- Handles
projection matrix, aspect ratio correction etc.. Used for rendering parts
of the scene.
- @ref SceneGraph::Drawable "SceneGraph::Drawable*D" -- Adds drawing
functionality to given object. Group of drawables can be then rendered
using the camera feature.
- @ref SceneGraph::Animable "SceneGraph::Animable*D" -- Adds animation
functionality to given object. Group of animables can be then controlled
using @ref SceneGraph::AnimableGroup "SceneGraph::AnimableGroup*D".
- @ref Shapes::Shape -- Adds collision shape to given object. Group of shapes
can be then controlled using @ref Shapes::ShapeGroup "Shapes::ShapeGroup*D".
See @ref shapes for more information.
- @ref DebugTools::ObjectRenderer "DebugTools::ObjectRenderer*D",
@ref DebugTools::ShapeRenderer "DebugTools::ShapeRenderer*D",
@ref DebugTools::ForceRenderer "DebugTools::ForceRenderer*D" -- Visualize
object properties, object shape or force vector for debugging purposes. See
@ref debug-tools for more information.
Each feature takes reference to *holder object* in constructor, so adding a
feature to an object might look just like the following, as in some cases you
don't even need to keep the pointer to it. List of object features is
accessible through @ref SceneGraph::Object::features().
@code @code
Object3D* o; Object3D* o;
new MyFeature(o); new MyFeature{*o};
@endcode @endcode
Some features are passive, some active. Passive features can be just added to Some features are passive, some active. Passive features can be just added to
an object like above, without any additional work (for example collision an object, with no additional work except for possible configuration (for
shape). Active features require the user to implement some virtual function example collision shape). Active features require the user to implement some
(for example to draw the object on screen or perform animation step). To make virtual function (for example to draw the object on screen or perform animation
things convenient, features can be added directly to object itself using step). To make things convenient, features can be added directly to object
multiple inheritance, so you can conveniently add all the active features you itself using multiple inheritance, so you can conveniently add all the active
want and implement needed functions in your own @ref SceneGraph::Object features you want and implement needed functions in your own @ref SceneGraph::Object
subclass without having to subclass each feature individually (and making the subclass without having to subclass each feature individually (and making the
code overly verbose). Simplified example: code overly verbose). Simplified example:
@code @code
class Bomb: public Object3D, SceneGraph::Drawable3D, SceneGraph::Animable3D { class BouncingBall: public Object3D, SceneGraph::Drawable3D, SceneGraph::Animable3D {
public: public:
Bomb(Object3D* parent): Object3D(parent), SceneGraph::Drawable3D(*this), SceneGraph::Animable3D(*this) {} explicit BouncingBall(Object3D* parent): Object3D{parent}, SceneGraph::Drawable3D{*this}, SceneGraph::Animable3D{*this} {}
protected: private:
// drawing implementation for Drawable feature // drawing implementation for Drawable feature
void draw(...) override; void draw(...) override;
@ -161,15 +213,15 @@ member and inherited) are destroyed. See detailed explanation of
@ref scenegraph-feature-construction-order "construction and destruction order" @ref scenegraph-feature-construction-order "construction and destruction order"
for information about possible issues. for information about possible issues.
@section scenegraph-caching Transformation caching @subsection scenegraph-features-caching Transformation caching in features
Some features need to operate with absolute transformations and their Some features need to operate with absolute transformations and their
inversions - for example camera needs its inverse transformation to render the inversions -- for example camera needs its inverse transformation to render the
scene, collision detection needs to know about positions of surrounding scene, collision detection needs to know about positions of surrounding
objects etc. To avoid computing the transformations from scratch every time, objects etc. To avoid computing the transformations from scratch every time,
the feature can cache them. the feature can cache them.
The cached data stay until the object is marked as dirty - that is by changing The cached data stay until the object is marked as dirty -- that is by changing
transformation, changing parent or explicitly calling @ref SceneGraph::Object::setDirty(). transformation, changing parent or explicitly calling @ref SceneGraph::Object::setDirty().
If the object is marked as dirty, all its children are marked as dirty too and If the object is marked as dirty, all its children are marked as dirty too and
@ref SceneGraph::AbstractFeature::markDirty() is called on every feature. @ref SceneGraph::AbstractFeature::markDirty() is called on every feature.
@ -189,17 +241,17 @@ and then implement corresponding cleaning function(s):
@code @code
class CachingObject: public Object3D, SceneGraph::AbstractFeature3D { class CachingObject: public Object3D, SceneGraph::AbstractFeature3D {
public: public:
CachingObject(Object3D* parent): SceneGraph::AbstractFeature3D(*this) { explicit CachingObject(Object3D* parent): Object3D{parent}, SceneGraph::AbstractFeature3D{*this} {
setCachedTransformations(SceneGraph::CachedTransformation::Absolute); setCachedTransformations(SceneGraph::CachedTransformation::Absolute);
} }
protected: protected:
void clean(const Matrix4& absoluteTransformation) override { void clean(const Matrix4& absoluteTransformation) override {
absolutePosition = absoluteTransformation.translation(); _absolutePosition = absoluteTransformation.translation();
} }
private: private:
Vector3 absolutePosition; Vector3 _absolutePosition;
}; };
@endcode @endcode
@ -208,7 +260,56 @@ by calling @ref SceneGraph::Object::setClean(). @ref SceneGraph::Camera3D "Camer
for example, calls it automatically before it starts rendering, as it needs its for example, calls it automatically before it starts rendering, as it needs its
own inverse transformation to properly draw the objects. own inverse transformation to properly draw the objects.
See @ref SceneGraph-AbstractFeature-subclassing-caching for more information. @subsection scenegraph-features-transformation Polymorphic access to object transformation
Features by default have access only to @ref SceneGraph::AbstractObject, which
doesn't know about any particular transformation implementation. This has the
advantage that features don't have to be implemented for all possible
transformation implementations. But, as a consequence, it is impossible to
transform the object using only pointer to @ref SceneGraph::AbstractObject.
To solve this, the transformation classes are subclassed from interfaces
sharing common functionality, so the feature can use that interface instead of
being specialized for all relevant transformation implementations. The
following interfaces are available, each having its own set of virtual
functions to control the transformation:
- @ref SceneGraph::AbstractTransformation "SceneGraph::AbstractTransformation*D" --
base for all transformations
- @ref SceneGraph::AbstractTranslation "SceneGraph::AbstractTranslation*D" --
base for all transformations providing translation
- @ref SceneGraph::AbstractBasicTranslationRotation2D "SceneGraph::AbstractTranslationRotation2D",
@ref SceneGraph::AbstractBasicTranslationRotation3D "SceneGraph::AbstractTranslationRotation3D" --
base for all transformations providing translation and rotation
- @ref SceneGraph::AbstractBasicTranslationRotationScaling2D "SceneGraph::AbstractBasicTranslationRotationScaling2D",
@ref SceneGraph::AbstractBasicTranslationRotationScaling3D "SceneGraph::AbstractBasicTranslationRotationScaling3D" --
base for all transformations providing translation, rotation and scaling
These interfaces provide virtual functions which can be used to modify object
transformations. The virtual calls are used only when calling through the
interface and not when using the concrete implementation directly to avoid
negative performance effects. There are no functions to retrieve object
transformation, you need to use the above transformation caching mechanism for
that.
In the following example we are able to get pointer to both
@ref SceneGraph::AbstractObject and needed transformation from one
constructor parameter using small trick:
@code
class TransformingFeature: public SceneGraph::AbstractFeature3D {
public:
template<class T> TransformingFeature(SceneGraph::Object<T>& object):
SceneGraph::AbstractFeature3D(object), transformation(object) {}
private:
SceneGraph::AbstractTranslationRotation3D& transformation;
};
@endcode
If we take for example @ref SceneGraph::Object "SceneGraph::Object<MatrixTransformation3D>",
it is derived from @ref SceneGraph::AbstractObject "SceneGraph::AbstractObject3D"
and @ref SceneGraph::BasicMatrixTransformation3D "SceneGraph::MatrixTransformation3D",
thus the reference to @ref SceneGraph::AbstractBasicTranslationRotation3D "SceneGraph::AbstractTranslationRotation3D",
is automatically extracted from the reference in our constructor.
@section scenegraph-construction-order Construction and destruction order @section scenegraph-construction-order Construction and destruction order

2
src/Magnum/AbstractFramebuffer.cpp

@ -224,7 +224,7 @@ void AbstractFramebuffer::setViewportInternal() {
glViewport(_viewport.left(), _viewport.bottom(), _viewport.sizeX(), _viewport.sizeY()); glViewport(_viewport.left(), _viewport.bottom(), _viewport.sizeX(), _viewport.sizeY());
} }
AbstractFramebuffer& AbstractFramebuffer::clear(FramebufferClearMask mask) { AbstractFramebuffer& AbstractFramebuffer::clear(const FramebufferClearMask mask) {
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
bindInternal(FramebufferTarget::Draw); bindInternal(FramebufferTarget::Draw);
#else #else

58
src/Magnum/SceneGraph/AbstractFeature.h

@ -40,7 +40,7 @@ namespace Magnum { namespace SceneGraph {
/** /**
@brief Which transformation to cache in given feature @brief Which transformation to cache in given feature
@see @ref scenegraph-caching, @ref CachedTransformations, @see @ref scenegraph-features-caching, @ref CachedTransformations,
@ref AbstractFeature::setCachedTransformations(), @ref AbstractFeature::clean(), @ref AbstractFeature::setCachedTransformations(), @ref AbstractFeature::clean(),
@ref AbstractFeature::cleanInverted() @ref AbstractFeature::cleanInverted()
@todo Provide also simpler representations from which could benefit @todo Provide also simpler representations from which could benefit
@ -68,7 +68,7 @@ enum class CachedTransformation: UnsignedByte {
/** /**
@brief Which transformations to cache in this feature @brief Which transformations to cache in this feature
@see @ref scenegraph-caching, @ref AbstractFeature::setCachedTransformations(), @see @ref scenegraph-features-caching, @ref AbstractFeature::setCachedTransformations(),
@ref AbstractFeature::clean(), @ref AbstractFeature::cleanInverted() @ref AbstractFeature::clean(), @ref AbstractFeature::cleanInverted()
*/ */
typedef Containers::EnumSet<CachedTransformation> CachedTransformations; typedef Containers::EnumSet<CachedTransformation> CachedTransformations;
@ -90,12 +90,11 @@ Feature is templated on dimension count and underlying transformation type, so
it can be used only on object having transformation with the same dimension it can be used only on object having transformation with the same dimension
count and type. count and type.
@anchor SceneGraph-AbstractFeature-subclassing-caching
### Caching transformations in features ### Caching transformations in features
Features can cache absolute transformation of the object instead of computing Features can cache absolute transformation of the object instead of computing
it from scratch every time to achieve better performance. See it from scratch every time to achieve better performance. See
@ref scenegraph-caching for introduction. @ref scenegraph-features-caching for introduction.
In order to have caching, you must enable it first, because by default the In order to have caching, you must enable it first, because by default the
caching is disabled. You can enable it using @ref setCachedTransformations() caching is disabled. You can enable it using @ref setCachedTransformations()
@ -104,17 +103,16 @@ and then implement corresponding cleaning function(s) -- either @ref clean(),
@code @code
class CachingFeature: public SceneGraph::AbstractFeature3D { class CachingFeature: public SceneGraph::AbstractFeature3D {
public: public:
CachingFeature(SceneGraph::AbstractObject3D& object): SceneGraph::AbstractFeature3D(object) { explicit CachingFeature(SceneGraph::AbstractObject3D& object): SceneGraph::AbstractFeature3D{object} {
setCachedTransformations(CachedTransformation::Absolute); setCachedTransformations(CachedTransformation::Absolute);
} }
protected: private:
void clean(const Matrix4& absoluteTransformationMatrix) override { void clean(const Matrix4& absoluteTransformationMatrix) override {
absolutePosition = absoluteTransformationMatrix.translation(); _absolutePosition = absoluteTransformationMatrix.translation();
} }
private: Vector3 _absolutePosition;
Vector3 absolutePosition;
}; };
@endcode @endcode
@ -123,33 +121,22 @@ Before using the cached value explicitly request object cleaning by calling
### Accessing object transformation ### Accessing object transformation
Features has by default access only to @ref AbstractObject, which is base of The feature has by default only access to @ref AbstractObject, which doesn't
@ref Object not depending on any particular transformation implementation. This know about any used transformation. By using small template trick in the
has the advantage that features doesn't have to be implemented for all possible constructor it is possible to gain access to transformation interface in the
transformation implementations, thus preventing code duplication. However it constructor:
is impossible to transform the object using only pointer to @ref AbstractObject.
The transformations have interfaces for common functionality, so the feature
can use that interface instead of being specialized for all relevant
transformation implementations. Using small trick we are able to get pointer
to both @ref AbstractObject and needed transformation from one constructor
parameter:
@code @code
class TransformingFeature: public SceneGraph::AbstractFeature3D { class TransformingFeature: public SceneGraph::AbstractFeature3D {
public: public:
template<class T> TransformingFeature(SceneGraph::Object<T>& object): template<class T> explicit TransformingFeature(SceneGraph::Object<T>& object):
SceneGraph::AbstractFeature3D(object), transformation(object) {} SceneGraph::AbstractFeature3D{object}, _transformation{object} {}
private: private:
SceneGraph::AbstractTranslationRotation3D& transformation; SceneGraph::AbstractTranslationRotation3D& _transformation;
}; };
@endcode @endcode
If we take for example @ref Object "Object<MatrixTransformation3D>", it is
derived from @ref AbstractObject "AbstractObject3D" and See @ref scenegraph-features-transformation for more detailed information.
@ref BasicMatrixTransformation3D "MatrixTransformation3D", which is derived
from @ref AbstractBasicTranslationRotationScaling3D "AbstractTranslationRotationScaling3D",
which is derived from @ref AbstractBasicTranslationRotation3D "AbstractTranslationRotation3D",
which is automatically extracted from the reference in our constructor.
## Explicit template specializations ## Explicit template specializations
@ -222,13 +209,14 @@ template<UnsignedInt dimensions, class T> class AbstractFeature
/** /**
* @{ @name Transformation caching * @{ @name Transformation caching
* *
* See @ref scenegraph-caching for more information. * See @ref scenegraph-features-caching for more information.
*/ */
/** /**
* @brief Which transformations are cached * @brief Which transformations are cached
* *
* @see @ref scenegraph-caching, @ref clean(), @ref cleanInverted() * @see @ref scenegraph-features-caching, @ref clean(),
* @ref cleanInverted()
*/ */
CachedTransformations cachedTransformations() const { CachedTransformations cachedTransformations() const {
return _cachedTransformations; return _cachedTransformations;
@ -243,7 +231,7 @@ template<UnsignedInt dimensions, class T> class AbstractFeature
* transformation. * transformation.
* *
* Nothing is enabled by default. * Nothing is enabled by default.
* @see @ref scenegraph-caching * @see @ref scenegraph-features-caching
*/ */
void setCachedTransformations(CachedTransformations transformations) { void setCachedTransformations(CachedTransformations transformations) {
_cachedTransformations = transformations; _cachedTransformations = transformations;
@ -257,7 +245,7 @@ template<UnsignedInt dimensions, class T> class AbstractFeature
* done in @ref clean() and @ref cleanInverted(). * done in @ref clean() and @ref cleanInverted().
* *
* Default implementation does nothing. * Default implementation does nothing.
* @see @ref scenegraph-caching * @see @ref scenegraph-features-caching
*/ */
virtual void markDirty(); virtual void markDirty();
@ -269,7 +257,7 @@ template<UnsignedInt dimensions, class T> class AbstractFeature
* to recalculate data based on absolute object transformation. * to recalculate data based on absolute object transformation.
* *
* Default implementation does nothing. * Default implementation does nothing.
* @see @ref scenegraph-caching, @ref cleanInverted() * @see @ref scenegraph-features-caching, @ref cleanInverted()
*/ */
virtual void clean(const MatrixTypeFor<dimensions, T>& absoluteTransformationMatrix); virtual void clean(const MatrixTypeFor<dimensions, T>& absoluteTransformationMatrix);
@ -282,7 +270,7 @@ template<UnsignedInt dimensions, class T> class AbstractFeature
* transformation. * transformation.
* *
* Default implementation does nothing. * Default implementation does nothing.
* @see @ref scenegraph-caching, @ref clean() * @see @ref scenegraph-features-caching, @ref clean()
*/ */
virtual void cleanInverted(const MatrixTypeFor<dimensions, T>& invertedAbsoluteTransformationMatrix); virtual void cleanInverted(const MatrixTypeFor<dimensions, T>& invertedAbsoluteTransformationMatrix);

10
src/Magnum/SceneGraph/AbstractObject.h

@ -212,7 +212,7 @@ template<UnsignedInt dimensions, class T> class AbstractObject
/** /**
* @{ @name Transformation caching * @{ @name Transformation caching
* *
* See @ref scenegraph-caching for more information. * See @ref scenegraph-features-caching for more information.
*/ */
/** /**
@ -251,7 +251,7 @@ template<UnsignedInt dimensions, class T> class AbstractObject
* Returns `true` if transformation of the object or any parent has * Returns `true` if transformation of the object or any parent has
* changed since last call to @ref setClean(), `false` otherwise. All * changed since last call to @ref setClean(), `false` otherwise. All
* objects are dirty by default. * objects are dirty by default.
* @see @ref scenegraph-caching * @see @ref scenegraph-features-caching
*/ */
bool isDirty() const { return doIsDirty(); } bool isDirty() const { return doIsDirty(); }
@ -262,7 +262,8 @@ template<UnsignedInt dimensions, class T> class AbstractObject
* recursively calls @ref setDirty() on every child object which is not * recursively calls @ref setDirty() on every child object which is not
* already dirty. If the object is already marked as dirty, the * already dirty. If the object is already marked as dirty, the
* function does nothing. * function does nothing.
* @see @ref scenegraph-caching, @ref setClean(), @ref isDirty() * @see @ref scenegraph-features-caching, @ref setClean(),
* @ref isDirty()
*/ */
void setDirty() { doSetDirty(); } void setDirty() { doSetDirty(); }
@ -277,7 +278,8 @@ template<UnsignedInt dimensions, class T> class AbstractObject
* See also @ref setClean(const std::vector<AbstractObject<dimensions, T>*>&), * See also @ref setClean(const std::vector<AbstractObject<dimensions, T>*>&),
* which cleans given set of objects more efficiently than when calling * which cleans given set of objects more efficiently than when calling
* @ref setClean() on each object individually. * @ref setClean() on each object individually.
* @see @ref scenegraph-caching, @ref setDirty(), @ref isDirty() * @see @ref scenegraph-features-caching, @ref setDirty(),
* @ref isDirty()
*/ */
void setClean() { doSetClean(); } void setClean() { doSetClean(); }

3
src/Magnum/SceneGraph/AbstractTransformation.h

@ -39,7 +39,8 @@ namespace Magnum { namespace SceneGraph {
/** /**
@brief Base for transformations @brief Base for transformations
Provides transformation implementation for @ref Object instances. Provides transformation implementation for @ref Object instances. See
@ref scenegraph-features-transformation for more information.
@anchor SceneGraph-AbstractTransformation-explicit-specializations @anchor SceneGraph-AbstractTransformation-explicit-specializations
## Explicit template specializations ## Explicit template specializations

8
src/Magnum/SceneGraph/AbstractTranslation.h

@ -38,13 +38,15 @@ namespace Magnum { namespace SceneGraph {
/** /**
@brief Base transformation for two-dimensional scenes supporting translation @brief Base transformation for two-dimensional scenes supporting translation
See @ref scenegraph-features-transformation for more information.
By default the translation is stored with the same underlying type as resulting By default the translation is stored with the same underlying type as resulting
transformation matrix, but it's possible to store translation in e.g. integral transformation matrix, but it's possible to store translation in e.g. integral
coordinates while having floating-point transformation matrix. coordinates while having floating-point transformation matrix.
@see @ref AbstractBasicTranslation2D, @ref AbstractBasicTranslation3D, @see @ref scenegraph, @ref AbstractBasicTranslation2D,
@ref AbstractTranslation2D, @ref AbstractTranslation3D, @ref scenegraph, @ref AbstractBasicTranslation3D, @ref AbstractTranslation2D,
@ref TranslationTransformation @ref AbstractTranslation3D, @ref TranslationTransformation
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
template<UnsignedInt dimensions, class T, class TranslationType = T> template<UnsignedInt dimensions, class T, class TranslationType = T>

4
src/Magnum/SceneGraph/AbstractTranslationRotation2D.h

@ -36,7 +36,9 @@ namespace Magnum { namespace SceneGraph {
/** /**
@brief Base transformation for two-dimensional scenes supporting translation and rotation @brief Base transformation for two-dimensional scenes supporting translation and rotation
@see @ref AbstractTranslationRotation2D, @ref scenegraph, See @ref scenegraph-features-transformation for more information.
@see @ref scenegraph, @ref AbstractTranslationRotation2D,
@ref AbstractBasicTranslationRotation3D, @ref AbstractBasicTranslationRotation3D,
@ref BasicRigidMatrixTransformation2D, @ref BasicDualComplexTransformation @ref BasicRigidMatrixTransformation2D, @ref BasicDualComplexTransformation
*/ */

4
src/Magnum/SceneGraph/AbstractTranslationRotation3D.h

@ -36,7 +36,9 @@ namespace Magnum { namespace SceneGraph {
/** /**
@brief Base transformation for three-dimensional scenes supporting translation and rotation @brief Base transformation for three-dimensional scenes supporting translation and rotation
@see @ref AbstractTranslationRotation3D @ref scenegraph, See @ref scenegraph-features-transformation for more information.
@see @ref scenegraph, @ref AbstractTranslationRotation3D,
@ref AbstractBasicTranslationRotation2D, @ref AbstractBasicTranslationRotation2D,
@ref BasicRigidMatrixTransformation3D, @ref BasicRigidMatrixTransformation3D,
@ref BasicDualQuaternionTransformation @ref BasicDualQuaternionTransformation

4
src/Magnum/SceneGraph/AbstractTranslationRotationScaling2D.h

@ -36,7 +36,9 @@ namespace Magnum { namespace SceneGraph {
/** /**
@brief Base transformation for two-dimensional scenes supporting translation, rotation and scaling @brief Base transformation for two-dimensional scenes supporting translation, rotation and scaling
@see @ref AbstractTranslationRotationScaling2D, @ref scenegraph, See @ref scenegraph-features-transformation for more information.
@see @ref scenegraph, @ref AbstractTranslationRotationScaling2D,
@ref AbstractBasicTranslationRotationScaling2D, @ref AbstractBasicTranslationRotationScaling2D,
@ref BasicMatrixTransformation2D @ref BasicMatrixTransformation2D
*/ */

4
src/Magnum/SceneGraph/AbstractTranslationRotationScaling3D.h

@ -36,7 +36,9 @@ namespace Magnum { namespace SceneGraph {
/** /**
@brief Base transformation for three-dimensional scenes supporting translation, rotation and scaling @brief Base transformation for three-dimensional scenes supporting translation, rotation and scaling
@see @ref AbstractTranslationRotationScaling3D, @ref scenegraph, See @ref scenegraph-features-transformation for more information.
@see @ref scenegraph, @ref AbstractTranslationRotationScaling3D,
@ref AbstractBasicTranslationRotationScaling2D, @ref AbstractBasicTranslationRotationScaling2D,
@ref BasicMatrixTransformation3D @ref BasicMatrixTransformation3D
*/ */

21
src/Magnum/SceneGraph/Animable.h

@ -78,22 +78,25 @@ typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D;
class AnimableObject: public Object3D, SceneGraph::Animable3D { class AnimableObject: public Object3D, SceneGraph::Animable3D {
public: public:
AnimableObject(Object* parent = nullptr, SceneGraph::DrawableGroup3D* group = nullptr): Object3D(parent), SceneGraph::Animable3D(*this, group) { AnimableObject(Object3D* parent = nullptr, SceneGraph::DrawableGroup3D* group = nullptr): Object3D{parent}, SceneGraph::Animable3D{*this, group} {
setDuration(10.0f); setDuration(10.0f);
// ... // ...
} }
private:
void animationStep(Float time, Float delta) override { void animationStep(Float time, Float delta) override {
rotateX(15.0_degf*delta); // rotate at 15 degrees per second rotateX(15.0_degf*delta); // rotate at 15 degrees per second
} }
} }
@endcode @endcode
Then add the object to your scene and some animation group. You can also use Similarly to @ref Drawable feature, there is no way to just animate all the
@ref AnimableGroup::add() and @ref AnimableGroup::remove() instead of passing objects in the scene. You need to create animable group and use it to control
the group in the constructor. The animation is initially in stopped state and given set of animations. You can also use @ref AnimableGroup::add() and
without repeat, see @ref setState(), @ref setRepeated() and @ref AnimableGroup::remove() instead of passing the group in the constructor.
@ref setRepeatCount() for more information. The animation is initially in stopped state and without repeat, see
@ref setState(), @ref setRepeated() and @ref setRepeatCount() for more
information.
@code @code
Scene3D scene; Scene3D scene;
SceneGraph::AnimableGroup3D animables; SceneGraph::AnimableGroup3D animables;
@ -120,13 +123,13 @@ void MyApplication::drawEvent() {
} }
@endcode @endcode
## Using animable groups to improve performance ## Using multiple animable groups to improve performance
@ref AnimableGroup is optimized for case when no animation is running -- it @ref AnimableGroup is optimized for case when no animation is running -- it
just puts itself to rest and waits until some animation changes its state to just puts itself to rest and waits until some animation changes its state to
@ref AnimationState::Running again. If you put animations which are not @ref AnimationState::Running again. If you put animations which are not
pernamently running to separate group, they will not be always traversed when pernamently running into separate group, they will not be traversed every time
calling @ref AnimableGroup::step(), saving precious frame time. the @ref AnimableGroup::step() gets called, saving precious frame time.
## Explicit template specializations ## Explicit template specializations

8
src/Magnum/SceneGraph/Camera2D.h

@ -36,11 +36,11 @@ namespace Magnum { namespace SceneGraph {
/** /**
@brief Camera for two-dimensional scenes @brief Camera for two-dimensional scenes
See Drawable documentation for introduction. The camera by default displays See @ref Drawable documentation for complete introduction. The camera by
OpenGL unit cube `[(-1, -1, -1); (1, 1, 1)]` and doesn't do any aspect ratio default displays OpenGL unit cube `[(-1, -1, -1); (1, 1, 1)]` and doesn't do
correction. Common setup example: any aspect ratio correction. Common setup example:
@code @code
SceneGraph::Camera2D camera(&cameraObject); SceneGraph::Camera2D camera{&cameraObject};
camera.setProjection({4.0f/3.0f, 1.0f}) camera.setProjection({4.0f/3.0f, 1.0f})
.setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend); .setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend);
@endcode @endcode

10
src/Magnum/SceneGraph/Camera3D.h

@ -41,12 +41,12 @@ namespace Magnum { namespace SceneGraph {
/** /**
@brief Camera for three-dimensional scenes @brief Camera for three-dimensional scenes
See Drawable documentation for introduction. The camera by default displays See @ref Drawable documentation for complete introduction. The camera by
OpenGL unit cube `[(-1, -1, -1); (1, 1, 1)]` with orthographic projection and default displays OpenGL unit cube `[(-1, -1, -1); (1, 1, 1)]` with orthographic
doesn't do any aspect ratio correction. Common setup example: projection and doesn't do any aspect ratio correction. Common setup example:
@code @code
SceneGraph::Camera3D camera(&cameraObject); SceneGraph::Camera3D camera{&cameraObject};
camera.setPerspective({}, 0.001f, 100.0f) camera.setPerspective(35.0_degf, 1.0f, 0.001f, 100.0f)
.setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend); .setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend);
@endcode @endcode

77
src/Magnum/SceneGraph/Drawable.h

@ -36,62 +36,94 @@ namespace Magnum { namespace SceneGraph {
/** /**
@brief Drawable @brief Drawable
Adds drawing function to the object. Each Drawable is part of some Adds drawing functionality to the object. Each Drawable is part of some
@ref DrawableGroup and the whole group is drawn with particular camera using @ref DrawableGroup and the whole group can be drawn with particular camera
@ref AbstractCamera::draw(). using @ref AbstractCamera::draw().
## Usage ## Usage
First thing is to add @ref Drawable feature to some object and implement First thing is to add @ref Drawable feature to some object and implement
@ref draw(). You can do it conveniently using multiple inheritance (see @ref draw() function. You can do it conveniently using multiple inheritance
@ref scenegraph-features for introduction). Example: (see @ref scenegraph-features for introduction). Example drawable object that
draws blue sphere:
@code @code
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D; typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D; typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D;
class DrawableObject: public Object3D, SceneGraph::Drawable3D { class RedCube: public Object3D, SceneGraph::Drawable3D {
public: public:
DrawableObject(Object* parent = nullptr, SceneGraph::DrawableGroup3D* group = nullptr): Object3D(parent), SceneGraph::Drawable3D(*this, group) { RedCube(Object3D* parent, SceneGraph::DrawableGroup3D* group): Object3D{parent}, SceneGraph::Drawable3D{*this, group} {
// ... std::tie(_mesh, _vertices, _indices) = MeshTools::compile(Primitives::UVSPhere::solid(16, 32));
} }
private:
void draw(const Matrix4& transformationMatrix, AbstractCamera3D& camera) override { void draw(const Matrix4& transformationMatrix, AbstractCamera3D& camera) override {
// ... _shader.setDiffuseColor(Color3::fromHSV(216.0_degf, 0.85f, 1.0f))
.setLightPosition({5.0f, 5.0f, 7.0f})
.setTransformationMatrix(transformationMatrix)
.setNormalMatrix(transformationMatrix.rotation())
.setProjectionMatrix(camera.projectionMatrix());
_mesh.draw(_shader);
} }
Mesh _mesh;
std::unique_ptr<Buffer> _vertices, _indices;
Shaders::Phong _shader;
} }
@endcode @endcode
Then you add these objects to your scene and some drawable group and transform The @p transformationMatrix parameter in @ref draw() function contains
them as you like. You can also use @ref DrawableGroup::add() and transformation of the object (to which the drawable is attached) relative to
@ref DrawableGroup::remove(). @p camera. The camera contains projection matrix. Some shaders (like the
@ref Shaders::Phong used in the example) have separate functions for setting
transformation and projection matrix, but some (such as @ref Shaders::Flat)
have single function to set composite transformation and projection matrix. In
that case you need to combine the two matrices manually like in the following
code. Some shaders have additional requirements for various transformation
matrices, see their respective documentation for details.
@code
Shaders::Flat3D shader;
shader.setTransformationProjectionMatrix(camera.projectionMatrix()*transformationMatrix);
@endcode
There is no way to just draw all the drawables in the scene, you need to create
some drawable group and add the drawable objects to both the scene and the
group. You can also use @ref DrawableGroup::add() and
@ref DrawableGroup::remove() instead of passing the group in the constructor.
@code @code
Scene3D scene; Scene3D scene;
SceneGraph::DrawableGroup3D drawables; SceneGraph::DrawableGroup3D drawables;
(new DrawableObject(&scene, &drawables)) (new RedCube(&scene, &drawables))
->translate(Vector3::yAxis(-0.3f)) ->translate(Vector3::yAxis(-0.3f))
.rotateX(30.0_degf); .rotateX(30.0_degf);
(new AnotherDrawableObject(&scene, &drawables))
->translate(Vector3::zAxis(0.5f));
// ... // ...
@endcode @endcode
The last thing you need is camera attached to some object (thus using its The last thing you need is camera attached to some object (thus using its
transformation) and with it you can perform drawing in your draw event transformation). Using the camera and the drawable group you can perform
drawing in your @ref Platform::Sdl2Application::drawEvent() "drawEvent()"
implementation. See @ref Camera2D and @ref Camera3D documentation for more implementation. See @ref Camera2D and @ref Camera3D documentation for more
information. information.
@code @code
Camera3D camera(&cameraObject); auto cameraObject = new Object3D(&scene);
cameraObject->translate(Vector3::zAxis(5.0f));
auto camera = new SceneGraph::Camera3D(&cameraObject);
camera->setPerspective(35.0_degf, 1.0f, 0.001f, 100.0f);
// ...
void MyApplication::drawEvent() { void MyApplication::drawEvent() {
camera.draw(drawables); camera->draw(drawables);
swapBuffers();
// ... // ...
swapBuffers();
} }
@endcode @endcode
## Using drawable groups to improve performance ## Using multiple drawable groups to improve performance
You can organize your drawables to multiple groups to minimize OpenGL state You can organize your drawables to multiple groups to minimize OpenGL state
changes -- for example put all objects using the same shader, the same light changes -- for example put all objects using the same shader, the same light
@ -158,9 +190,8 @@ template<UnsignedInt dimensions, class T> class Drawable: public AbstractGrouped
/** /**
* @brief Draw the object using given camera * @brief Draw the object using given camera
* @param transformationMatrix Object transformation relative * @param transformationMatrix Object transformation relative to camera
* to camera * @param camera Camera
* @param camera Camera
* *
* Projection matrix can be retrieved from * Projection matrix can be retrieved from
* @ref SceneGraph::AbstractCamera::projectionMatrix() "AbstractCamera::projectionMatrix()". * @ref SceneGraph::AbstractCamera::projectionMatrix() "AbstractCamera::projectionMatrix()".

2
src/Magnum/SceneGraph/DualComplexTransformation.h

@ -40,7 +40,7 @@ namespace Magnum { namespace SceneGraph {
This class allows only rigid transformation (i.e. only rotation and This class allows only rigid transformation (i.e. only rotation and
translation). Uses @ref Math::DualComplex as underlying transformation type. translation). Uses @ref Math::DualComplex as underlying transformation type.
@see @ref DualComplexTransformation, @ref scenegraph, @see @ref scenegraph, @ref DualComplexTransformation,
@ref BasicDualQuaternionTransformation @ref BasicDualQuaternionTransformation
*/ */
template<class T> class BasicDualComplexTransformation: public AbstractBasicTranslationRotation2D<T> { template<class T> class BasicDualComplexTransformation: public AbstractBasicTranslationRotation2D<T> {

2
src/Magnum/SceneGraph/DualQuaternionTransformation.h

@ -40,7 +40,7 @@ namespace Magnum { namespace SceneGraph {
This class allows only rigid transformation (i.e. only rotation and This class allows only rigid transformation (i.e. only rotation and
translation). Uses @ref Math::DualQuaternion as underlying transformation type. translation). Uses @ref Math::DualQuaternion as underlying transformation type.
@see @ref DualQuaternionTransformation @ref scenegraph, @see @ref scenegraph, @ref DualQuaternionTransformation,
@ref BasicDualComplexTransformation @ref BasicDualComplexTransformation
*/ */
template<class T> class BasicDualQuaternionTransformation: public AbstractBasicTranslationRotation3D<T> { template<class T> class BasicDualQuaternionTransformation: public AbstractBasicTranslationRotation3D<T> {

2
src/Magnum/SceneGraph/MatrixTransformation2D.h

@ -39,7 +39,7 @@ namespace Magnum { namespace SceneGraph {
@brief Two-dimensional transformation implemented using matrices @brief Two-dimensional transformation implemented using matrices
Uses @ref Math::Matrix3 as underlying transformation type. Uses @ref Math::Matrix3 as underlying transformation type.
@see @ref MatrixTransformation2D, @ref scenegraph, @see @ref scenegraph, @ref MatrixTransformation2D,
@ref BasicRigidMatrixTransformation2D, @ref BasicMatrixTransformation3D @ref BasicRigidMatrixTransformation2D, @ref BasicMatrixTransformation3D
*/ */
template<class T> class BasicMatrixTransformation2D: public AbstractBasicTranslationRotationScaling2D<T> { template<class T> class BasicMatrixTransformation2D: public AbstractBasicTranslationRotationScaling2D<T> {

3
src/Magnum/SceneGraph/MatrixTransformation3D.h

@ -39,7 +39,8 @@ namespace Magnum { namespace SceneGraph {
@brief Three-dimensional transformation implemented using matrices @brief Three-dimensional transformation implemented using matrices
Uses @ref Math::Matrix4 as underlying transformation type. Uses @ref Math::Matrix4 as underlying transformation type.
@see @ref MatrixTransformation3D, @ref scenegraph, @ref BasicRigidMatrixTransformation3D, @ref BasicMatrixTransformation2D @see @ref scenegraph, @ref MatrixTransformation3D,
@ref BasicRigidMatrixTransformation3D, @ref BasicMatrixTransformation2D
*/ */
template<class T> class BasicMatrixTransformation3D: public AbstractBasicTranslationRotationScaling3D<T> { template<class T> class BasicMatrixTransformation3D: public AbstractBasicTranslationRotationScaling3D<T> {
public: public:

5
src/Magnum/SceneGraph/Object.h

@ -335,7 +335,7 @@ template<class Transformation> class Object: public AbstractObject<Transformatio
/** /**
* @{ @name Transformation caching * @{ @name Transformation caching
* *
* See @ref scenegraph-caching for more information. * See @ref scenegraph-features-caching for more information.
*/ */
/** /**
@ -381,7 +381,8 @@ template<class Transformation> class Object: public AbstractObject<Transformatio
* See also @ref setClean(std::vector<std::reference_wrapper<Object<Transformation>>>), * See also @ref setClean(std::vector<std::reference_wrapper<Object<Transformation>>>),
* which cleans given set of objects more efficiently than when calling * which cleans given set of objects more efficiently than when calling
* @ref setClean() on each object individually. * @ref setClean() on each object individually.
* @see @ref scenegraph-caching, @ref setDirty(), @ref isDirty() * @see @ref scenegraph-features-caching, @ref setDirty(),
* @ref isDirty()
*/ */
/* note: doc verbatim copied from AbstractObject::setClean() */ /* note: doc verbatim copied from AbstractObject::setClean() */
void setClean(); void setClean();

2
src/Magnum/SceneGraph/RigidMatrixTransformation2D.h

@ -43,7 +43,7 @@ Unlike @ref BasicMatrixTransformation2D this class allows only rotation,
reflection and translation (no scaling or setting arbitrary transformations). reflection and translation (no scaling or setting arbitrary transformations).
This allows to use @ref Math::Matrix3::invertedRigid() for faster computation This allows to use @ref Math::Matrix3::invertedRigid() for faster computation
of inverse transformations. of inverse transformations.
@see @ref RigidMatrixTransformation2D, @ref scenegraph, @see @ref scenegraph, @ref RigidMatrixTransformation2D,
@ref BasicRigidMatrixTransformation3D @ref BasicRigidMatrixTransformation3D
*/ */
template<class T> class BasicRigidMatrixTransformation2D: public AbstractBasicTranslationRotation2D<T> { template<class T> class BasicRigidMatrixTransformation2D: public AbstractBasicTranslationRotation2D<T> {

3
src/Magnum/SceneGraph/RigidMatrixTransformation3D.h

@ -43,7 +43,8 @@ Unlike @ref BasicMatrixTransformation3D this class allows only rotation,
reflection and translation (no scaling or setting arbitrary transformations). reflection and translation (no scaling or setting arbitrary transformations).
This allows to use @ref Math::Matrix4::invertedRigid() for faster computation This allows to use @ref Math::Matrix4::invertedRigid() for faster computation
of inverse transformations. of inverse transformations.
@see @ref RigidMatrixTransformation3D, @ref scenegraph, @ref BasicRigidMatrixTransformation2D @see @ref scenegraph, @ref RigidMatrixTransformation3D,
@ref BasicRigidMatrixTransformation2D
*/ */
template<class T> class BasicRigidMatrixTransformation3D: public AbstractBasicTranslationRotation3D<T> { template<class T> class BasicRigidMatrixTransformation3D: public AbstractBasicTranslationRotation3D<T> {
public: public:

10
src/Magnum/SceneGraph/TranslationTransformation.h

@ -44,13 +44,9 @@ the translation is stored with the same underlying type as resulting
transformation matrix, but it's possible to store translation in e.g. integral transformation matrix, but it's possible to store translation in e.g. integral
coordinates while having floating-point transformation matrix. coordinates while having floating-point transformation matrix.
Note that translation is commutative, so all @ref TransformationType parameters @see @ref scenegraph, @ref BasicTranslationTransformation2D,
have no effect and are included only for compatibility with other @ref BasicTranslationTransformation3D, @ref TranslationTransformation2D,
transformation implementations. @ref TranslationTransformation3D
@see @ref BasicTranslationTransformation2D, @ref BasicTranslationTransformation3D,
@ref TranslationTransformation2D, @ref TranslationTransformation3D,
@ref scenegraph
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
template<UnsignedInt dimensions, class T, class TranslationType = T> template<UnsignedInt dimensions, class T, class TranslationType = T>

Loading…
Cancel
Save