Browse Source

Merge branch 'master' into compatibility

Conflicts:
	src/SceneGraph/AbstractFeature.hpp
	src/SceneGraph/AbstractTranslationRotation2D.h
	src/SceneGraph/AbstractTranslationRotation3D.h
	src/SceneGraph/AbstractTranslationRotationScaling2D.h
	src/SceneGraph/AbstractTranslationRotationScaling3D.h
	src/SceneGraph/DualComplexTransformation.h
	src/SceneGraph/DualQuaternionTransformation.h
	src/SceneGraph/FeatureGroup.h
	src/SceneGraph/FeatureGroup.hpp
	src/SceneGraph/MatrixTransformation2D.h
	src/SceneGraph/MatrixTransformation3D.h
	src/SceneGraph/RigidMatrixTransformation2D.h
	src/SceneGraph/RigidMatrixTransformation3D.h
	src/Test/SwizzleTest.cpp
Vladimír Vondruš 13 years ago
parent
commit
36af88e5cc
  1. 22
      doc/scenegraph.dox
  2. 4
      src/AbstractShaderProgram.h
  3. 2
      src/AbstractTexture.h
  4. 138
      src/Color.h
  5. 2
      src/CubeMapTexture.h
  6. 2
      src/CubeMapTextureArray.h
  7. 4
      src/DebugTools/ForceRenderer.cpp
  8. 15
      src/DebugTools/ForceRenderer.h
  9. 12
      src/DebugTools/ObjectRenderer.cpp
  10. 7
      src/DebugTools/ObjectRenderer.h
  11. 4
      src/DebugTools/ShapeRenderer.cpp
  12. 12
      src/DebugTools/ShapeRenderer.h
  13. 6
      src/Magnum.h
  14. 2
      src/Mesh.h
  15. 2
      src/MeshTools/Interleave.h
  16. 4
      src/Renderer.cpp
  17. 4
      src/Renderer.h
  18. 55
      src/SceneGraph/AbstractCamera.h
  19. 18
      src/SceneGraph/AbstractCamera.hpp
  20. 104
      src/SceneGraph/AbstractFeature.h
  21. 12
      src/SceneGraph/AbstractFeature.hpp
  22. 64
      src/SceneGraph/AbstractGroupedFeature.h
  23. 81
      src/SceneGraph/AbstractObject.h
  24. 50
      src/SceneGraph/AbstractTransformation.h
  25. 32
      src/SceneGraph/AbstractTranslationRotation2D.h
  26. 38
      src/SceneGraph/AbstractTranslationRotation3D.h
  27. 38
      src/SceneGraph/AbstractTranslationRotationScaling2D.h
  28. 48
      src/SceneGraph/AbstractTranslationRotationScaling3D.h
  29. 8
      src/SceneGraph/Animable.cpp
  30. 111
      src/SceneGraph/Animable.h
  31. 22
      src/SceneGraph/Animable.hpp
  32. 47
      src/SceneGraph/AnimableGroup.h
  33. 36
      src/SceneGraph/Camera2D.h
  34. 8
      src/SceneGraph/Camera2D.hpp
  35. 36
      src/SceneGraph/Camera3D.h
  36. 20
      src/SceneGraph/Camera3D.hpp
  37. 103
      src/SceneGraph/Drawable.h
  38. 60
      src/SceneGraph/DualComplexTransformation.h
  39. 60
      src/SceneGraph/DualQuaternionTransformation.h
  40. 92
      src/SceneGraph/FeatureGroup.h
  41. 8
      src/SceneGraph/FeatureGroup.hpp
  42. 53
      src/SceneGraph/MatrixTransformation2D.h
  43. 66
      src/SceneGraph/MatrixTransformation3D.h
  44. 10
      src/SceneGraph/Object.h
  45. 16
      src/SceneGraph/Object.hpp
  46. 64
      src/SceneGraph/RigidMatrixTransformation2D.h
  47. 77
      src/SceneGraph/RigidMatrixTransformation3D.h
  48. 121
      src/SceneGraph/SceneGraph.h
  49. 30
      src/SceneGraph/Test/AnimableTest.cpp
  50. 16
      src/SceneGraph/Test/CameraTest.cpp
  51. 12
      src/SceneGraph/Test/DualComplexTransformationTest.cpp
  52. 12
      src/SceneGraph/Test/DualQuaternionTransformationTest.cpp
  53. 12
      src/SceneGraph/Test/MatrixTransformation2DTest.cpp
  54. 12
      src/SceneGraph/Test/MatrixTransformation3DTest.cpp
  55. 20
      src/SceneGraph/Test/ObjectTest.cpp
  56. 14
      src/SceneGraph/Test/RigidMatrixTransformation2DTest.cpp
  57. 14
      src/SceneGraph/Test/RigidMatrixTransformation3DTest.cpp
  58. 4
      src/SceneGraph/Test/SceneTest.cpp
  59. 42
      src/SceneGraph/instantiation.cpp
  60. 4
      src/Shaders/DistanceFieldVector.h
  61. 2
      src/Shaders/Flat.h
  62. 4
      src/Shaders/MeshVisualizer.cpp
  63. 4
      src/Shaders/MeshVisualizer.h
  64. 8
      src/Shaders/Phong.h
  65. 2
      src/Shaders/Vector.h
  66. 2
      src/Shaders/VertexColor.h
  67. 6
      src/Shapes/AbstractShape.cpp
  68. 4
      src/Shapes/AbstractShape.h
  69. 6
      src/Shapes/Shape.h
  70. 4
      src/Shapes/ShapeGroup.cpp
  71. 2
      src/Shapes/ShapeGroup.h
  72. 8
      src/Shapes/Test/ShapeTest.cpp
  73. 8
      src/Swizzle.h
  74. 94
      src/Test/ColorTest.cpp
  75. 12
      src/Test/SwizzleTest.cpp
  76. 4
      src/Text/TextRenderer.h
  77. 2
      src/Texture.h

22
doc/scenegraph.dox

@ -45,13 +45,11 @@ 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 (by default is dimension count (2D or 3D) and underlying floating-point type.
@ref Float type is used everywhere, but you can use @ref Double too).
@note All classes in SceneGraph have Float as default underlying floating-point @note All classes in SceneGraph are templated on underlying type. However, in
type, which means that you can omit that template parameter and write just most cases Float is used and thus nearly all classes have convenience
<tt>%AbstractObject<2></tt> or <tt>%MatrixTransformation3D<></tt> instead of aliases so you don't have to explicitly specify it.
<tt>%AbstractObject<2, Float></tt> and <tt>%MatrixTransformation3D&lt;Float&gt;</tt>.
%Scene graph has implementation of transformations in both 2D and 3D, using %Scene graph has implementation of transformations in both 2D and 3D, using
either matrices or combination of position and rotation. Each implementation either matrices or combination of position and rotation. Each implementation
@ -74,8 +72,8 @@ in 2D and part in 3D just wouldn't make sense). Common usage is to typedef
%Scene and %Object with desired transformation type to save unnecessary typing %Scene and %Object with desired transformation type to save unnecessary typing
later: later:
@code @code
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D<>> Scene3D; typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D;
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D<>> Object3D; typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
@endcode @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.
@ -149,9 +147,9 @@ implement needed functions in your own Object subclass without having to
subclass each feature individually (and making the code overly verbose). subclass each feature individually (and making the code overly verbose).
Simplified example: Simplified example:
@code @code
class Bomb: public Object3D, SceneGraph::Drawable3D<>, SceneGraph:.Animable3D<> { class Bomb: public Object3D, SceneGraph::Drawable3D, SceneGraph:.Animable3D {
public: public:
Bomb(Object3D* parent): Object3D(parent), SceneGraph::Drawable3D<>(this), SceneGraph::Animable3D<>(this) {} Bomb(Object3D* parent): Object3D(parent), SceneGraph::Drawable3D(this), SceneGraph::Animable3D(this) {}
protected: protected:
// drawing implementation for Drawable feature // drawing implementation for Drawable feature
@ -195,9 +193,9 @@ it first, because by default the caching is disabled. You can enable it using
AbstractFeature::setCachedTransformations() and then implement corresponding AbstractFeature::setCachedTransformations() and then implement corresponding
cleaning function(s): 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) { CachingObject(Object3D* parent): SceneGraph::AbstractFeature3D(this) {
setCachedTransformations(CachedTransformation::Absolute); setCachedTransformations(CachedTransformation::Absolute);
} }

4
src/AbstractShaderProgram.h

@ -1457,8 +1457,8 @@ template<std::size_t size_> struct Attribute<Math::Vector<size_, Double>>: Doubl
template<class T> struct Attribute<Math::Vector2<T>>: Attribute<Math::Vector<2, T>> {}; template<class T> struct Attribute<Math::Vector2<T>>: Attribute<Math::Vector<2, T>> {};
template<class T> struct Attribute<Math::Vector3<T>>: Attribute<Math::Vector<3, T>> {}; template<class T> struct Attribute<Math::Vector3<T>>: Attribute<Math::Vector<3, T>> {};
template<class T> struct Attribute<Math::Vector4<T>>: Attribute<Math::Vector<4, T>> {}; template<class T> struct Attribute<Math::Vector4<T>>: Attribute<Math::Vector<4, T>> {};
template<class T> struct Attribute<Color3<T>>: Attribute<Math::Vector3<T>> {}; template<class T> struct Attribute<BasicColor3<T>>: Attribute<Math::Vector3<T>> {};
template<class T> struct Attribute<Color4<T>>: Attribute<Math::Vector4<T>> {}; template<class T> struct Attribute<BasicColor4<T>>: Attribute<Math::Vector4<T>> {};
/* Common float and double rectangular matrix attributes */ /* Common float and double rectangular matrix attributes */
template<std::size_t cols, std::size_t rows> struct Attribute<Math::RectangularMatrix<cols, rows, Float>>: FloatAttribute, SizedAttribute<cols, rows> {}; template<std::size_t cols, std::size_t rows> struct Attribute<Math::RectangularMatrix<cols, rows, Float>>: FloatAttribute, SizedAttribute<cols, rows> {};

2
src/AbstractTexture.h

@ -208,7 +208,7 @@ class MAGNUM_EXPORT AbstractTexture {
* with @def_gl{TEXTURE_BORDER_COLOR} * with @def_gl{TEXTURE_BORDER_COLOR}
* @requires_es_extension %Extension @es_extension{NV,texture_border_clamp} * @requires_es_extension %Extension @es_extension{NV,texture_border_clamp}
*/ */
AbstractTexture* setBorderColor(const Color4<>& color) { AbstractTexture* setBorderColor(const Color4& color) {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
(this->*parameterfvImplementation)(GL_TEXTURE_BORDER_COLOR, color.data()); (this->*parameterfvImplementation)(GL_TEXTURE_BORDER_COLOR, color.data());
#else #else

138
src/Color.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Color3, Magnum::Color4 * @brief Class Magnum::BasicColor3, Magnum::BasicColor4, typedef Magnum::Color3, Magnum::Color4
*/ */
#include <tuple> #include <tuple>
@ -39,7 +39,7 @@ namespace Magnum {
namespace Implementation { namespace Implementation {
/* Convert color from HSV */ /* Convert color from HSV */
template<class T> typename std::enable_if<std::is_floating_point<T>::value, Color3<T>>::type fromHSV(typename Color3<T>::HSV hsv) { template<class T> typename std::enable_if<std::is_floating_point<T>::value, BasicColor3<T>>::type fromHSV(typename BasicColor3<T>::HSV hsv) {
Math::Deg<T> hue; Math::Deg<T> hue;
T saturation, value; T saturation, value;
std::tie(hue, saturation, value) = hsv; std::tie(hue, saturation, value) = hsv;
@ -65,12 +65,12 @@ template<class T> typename std::enable_if<std::is_floating_point<T>::value, Colo
default: CORRADE_ASSERT_UNREACHABLE(); default: CORRADE_ASSERT_UNREACHABLE();
} }
} }
template<class T> inline typename std::enable_if<std::is_integral<T>::value, Color3<T>>::type fromHSV(typename Color3<T>::HSV hsv) { template<class T> inline typename std::enable_if<std::is_integral<T>::value, BasicColor3<T>>::type fromHSV(typename BasicColor3<T>::HSV hsv) {
return Math::denormalize<Color3<T>>(fromHSV<typename Color3<T>::FloatingPointType>(hsv)); return Math::denormalize<BasicColor3<T>>(fromHSV<typename BasicColor3<T>::FloatingPointType>(hsv));
} }
/* Internal hue computing function */ /* Internal hue computing function */
template<class T> Math::Deg<T> hue(const Color3<T>& color, T max, T delta) { template<class T> Math::Deg<T> hue(const BasicColor3<T>& color, T max, T delta) {
T deltaInv60 = T(60)/delta; T deltaInv60 = T(60)/delta;
T hue(0); T hue(0);
@ -87,40 +87,40 @@ template<class T> Math::Deg<T> hue(const Color3<T>& color, T max, T delta) {
} }
/* Hue, saturation, value for floating-point types */ /* Hue, saturation, value for floating-point types */
template<class T> inline Math::Deg<T> hue(typename std::enable_if<std::is_floating_point<T>::value, const Color3<T>&>::type color) { template<class T> inline Math::Deg<T> hue(typename std::enable_if<std::is_floating_point<T>::value, const BasicColor3<T>&>::type color) {
T max = color.max(); T max = color.max();
T delta = max - color.min(); T delta = max - color.min();
return hue(color, max, delta); return hue(color, max, delta);
} }
template<class T> inline T saturation(typename std::enable_if<std::is_floating_point<T>::value, const Color3<T>&>::type color) { template<class T> inline T saturation(typename std::enable_if<std::is_floating_point<T>::value, const BasicColor3<T>&>::type color) {
T max = color.max(); T max = color.max();
T delta = max - color.min(); T delta = max - color.min();
return max != T(0) ? delta/max : T(0); return max != T(0) ? delta/max : T(0);
} }
template<class T> inline T value(typename std::enable_if<std::is_floating_point<T>::value, const Color3<T>&>::type color) { template<class T> inline T value(typename std::enable_if<std::is_floating_point<T>::value, const BasicColor3<T>&>::type color) {
return color.max(); return color.max();
} }
/* Hue, saturation, value for integral types */ /* Hue, saturation, value for integral types */
template<class T> inline Math::Deg<typename Color3<T>::FloatingPointType> hue(typename std::enable_if<std::is_integral<T>::value, const Color3<T>&>::type color) { template<class T> inline Math::Deg<typename BasicColor3<T>::FloatingPointType> hue(typename std::enable_if<std::is_integral<T>::value, const BasicColor3<T>&>::type color) {
return hue<typename Color3<T>::FloatingPointType>(Math::normalize<Color3<typename Color3<T>::FloatingPointType>>(color)); return hue<typename BasicColor3<T>::FloatingPointType>(Math::normalize<BasicColor3<typename BasicColor3<T>::FloatingPointType>>(color));
} }
template<class T> inline typename Color3<T>::FloatingPointType saturation(typename std::enable_if<std::is_integral<T>::value, const Color3<T>&>::type& color) { template<class T> inline typename BasicColor3<T>::FloatingPointType saturation(typename std::enable_if<std::is_integral<T>::value, const BasicColor3<T>&>::type& color) {
return saturation<typename Color3<T>::FloatingPointType>(Math::normalize<Color3<typename Color3<T>::FloatingPointType>>(color)); return saturation<typename BasicColor3<T>::FloatingPointType>(Math::normalize<BasicColor3<typename BasicColor3<T>::FloatingPointType>>(color));
} }
template<class T> inline typename Color3<T>::FloatingPointType value(typename std::enable_if<std::is_integral<T>::value, const Color3<T>&>::type color) { template<class T> inline typename BasicColor3<T>::FloatingPointType value(typename std::enable_if<std::is_integral<T>::value, const BasicColor3<T>&>::type color) {
return Math::normalize<typename Color3<T>::FloatingPointType>(color.max()); return Math::normalize<typename BasicColor3<T>::FloatingPointType>(color.max());
} }
/* Convert color to HSV */ /* Convert color to HSV */
template<class T> inline typename Color3<T>::HSV toHSV(typename std::enable_if<std::is_floating_point<T>::value, const Color3<T>&>::type color) { template<class T> inline typename BasicColor3<T>::HSV toHSV(typename std::enable_if<std::is_floating_point<T>::value, const BasicColor3<T>&>::type color) {
T max = color.max(); T max = color.max();
T delta = max - color.min(); T delta = max - color.min();
return typename Color3<T>::HSV(hue<typename Color3<T>::FloatingPointType>(color, max, delta), max != T(0) ? delta/max : T(0), max); return typename BasicColor3<T>::HSV(hue<typename BasicColor3<T>::FloatingPointType>(color, max, delta), max != T(0) ? delta/max : T(0), max);
} }
template<class T> inline typename Color3<T>::HSV toHSV(typename std::enable_if<std::is_integral<T>::value, const Color3<T>&>::type color) { template<class T> inline typename BasicColor3<T>::HSV toHSV(typename std::enable_if<std::is_integral<T>::value, const BasicColor3<T>&>::type color) {
return toHSV<typename Color3<T>::FloatingPointType>(Math::normalize<Color3<typename Color3<T>::FloatingPointType>>(color)); return toHSV<typename BasicColor3<T>::FloatingPointType>(Math::normalize<BasicColor3<typename BasicColor3<T>::FloatingPointType>>(color));
} }
/* Default alpha value */ /* Default alpha value */
@ -144,16 +144,11 @@ Conversion from and to HSV is done always using floating-point types, so hue
is always in range in range @f$ [0.0, 360.0] @f$, saturation and value in is always in range in range @f$ [0.0, 360.0] @f$, saturation and value in
range @f$ [0.0, 1.0] @f$. range @f$ [0.0, 1.0] @f$.
@see Color4 @see @ref Color3, @ref BasicColor4
*/ */
/* Not using template specialization because some internal functions are /* Not using template specialization because some internal functions are
impossible to explicitly instantiate */ impossible to explicitly instantiate */
#ifndef DOXYGEN_GENERATING_OUTPUT template<class T> class BasicColor3: public Math::Vector3<T> {
template<class T>
#else
template<class T = Float>
#endif
class Color3: public Math::Vector3<T> {
public: public:
/** @brief Corresponding floating-point type for HSV computation */ /** @brief Corresponding floating-point type for HSV computation */
typedef typename Math::TypeTraits<T>::FloatingPointType FloatingPointType; typedef typename Math::TypeTraits<T>::FloatingPointType FloatingPointType;
@ -172,11 +167,11 @@ class Color3: public Math::Vector3<T> {
* *
* Hue can overflow the range @f$ [0.0, 360.0] @f$. * Hue can overflow the range @f$ [0.0, 360.0] @f$.
*/ */
constexpr static Color3<T> fromHSV(HSV hsv) { constexpr static BasicColor3<T> fromHSV(HSV hsv) {
return Implementation::fromHSV<T>(hsv); return Implementation::fromHSV<T>(hsv);
} }
/** @overload */ /** @overload */
constexpr static Color3<T> fromHSV(Math::Deg<FloatingPointType> hue, FloatingPointType saturation, FloatingPointType value) { constexpr static BasicColor3<T> fromHSV(Math::Deg<FloatingPointType> hue, FloatingPointType saturation, FloatingPointType value) {
return fromHSV(std::make_tuple(hue, saturation, value)); return fromHSV(std::make_tuple(hue, saturation, value));
} }
@ -185,13 +180,13 @@ class Color3: public Math::Vector3<T> {
* *
* All components are set to zero. * All components are set to zero.
*/ */
constexpr /*implicit*/ Color3() {} constexpr /*implicit*/ BasicColor3() {}
/** /**
* @brief Gray constructor * @brief Gray constructor
* @param rgb RGB value * @param rgb RGB value
*/ */
constexpr explicit Color3(T rgb): Math::Vector3<T>(rgb) {} constexpr explicit BasicColor3(T rgb): Math::Vector3<T>(rgb) {}
/** /**
* @brief Constructor * @brief Constructor
@ -199,13 +194,13 @@ class Color3: public Math::Vector3<T> {
* @param g G value * @param g G value
* @param b B value * @param b B value
*/ */
constexpr /*implicit*/ Color3(T r, T g, T b): Math::Vector3<T>(r, g, b) {} constexpr /*implicit*/ BasicColor3(T r, T g, T b): Math::Vector3<T>(r, g, b) {}
/** @copydoc Math::Vector::Vector(const Vector<size, U>&) */ /** @copydoc Math::Vector::Vector(const Vector<size, U>&) */
template<class U> constexpr explicit Color3(const Math::Vector<3, U>& other): Math::Vector3<T>(other) {} template<class U> constexpr explicit BasicColor3(const Math::Vector<3, U>& other): Math::Vector3<T>(other) {}
/** @brief Copy constructor */ /** @brief Copy constructor */
constexpr Color3(const Math::Vector<3, T>& other): Math::Vector3<T>(other) {} constexpr BasicColor3(const Math::Vector<3, T>& other): Math::Vector3<T>(other) {}
T& r() { return Math::Vector3<T>::x(); } /**< @brief R component */ T& r() { return Math::Vector3<T>::x(); } /**< @brief R component */
constexpr T r() const { return Math::Vector3<T>::x(); } /**< @overload */ constexpr T r() const { return Math::Vector3<T>::x(); } /**< @overload */
@ -259,15 +254,19 @@ class Color3: public Math::Vector3<T> {
return Implementation::value<T>(*this); return Implementation::value<T>(*this);
} }
MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(Color3, 3) MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(BasicColor3, 3)
}; };
MAGNUM_VECTOR_SUBCLASS_OPERATOR_IMPLEMENTATION(Color3, 3) /** @brief Three-component (RGB) float color */
typedef BasicColor3<Float> Color3;
MAGNUM_VECTOR_SUBCLASS_OPERATOR_IMPLEMENTATION(BasicColor3, 3)
/** /**
@brief Four-component (RGBA) color @brief Four-component (RGBA) color
See Color3 for more information. See @ref BasicColor3 for more information.
@see @ref Color4
*/ */
/* Not using template specialization because some internal functions are /* Not using template specialization because some internal functions are
impossible to explicitly instantiate */ impossible to explicitly instantiate */
@ -276,24 +275,24 @@ template<class T>
#else #else
template<class T = Float> template<class T = Float>
#endif #endif
class Color4: public Math::Vector4<T> { class BasicColor4: public Math::Vector4<T> {
public: public:
/** @copydoc Color3::FloatingPointType */ /** @copydoc BasicColor3::FloatingPointType */
typedef typename Color3<T>::FloatingPointType FloatingPointType; typedef typename BasicColor3<T>::FloatingPointType FloatingPointType;
/** @copydoc Color3::HSV */ /** @copydoc BasicColor3::HSV */
typedef typename Color3<T>::HSV HSV; typedef typename BasicColor3<T>::HSV HSV;
/** /**
* @copydoc Color3::fromHSV() * @copydoc BasicColor3::fromHSV()
* @param a Alpha value, defaults to 1.0 for floating-point types * @param a Alpha value, defaults to 1.0 for floating-point types
* and maximum positive value for integral types. * and maximum positive value for integral types.
*/ */
constexpr static Color4<T> fromHSV(HSV hsv, T a = Implementation::defaultAlpha<T>()) { constexpr static BasicColor4<T> fromHSV(HSV hsv, T a = Implementation::defaultAlpha<T>()) {
return Color4<T>(Implementation::fromHSV<T>(hsv), a); return BasicColor4<T>(Implementation::fromHSV<T>(hsv), a);
} }
/** @overload */ /** @overload */
constexpr static Color4<T> fromHSV(Math::Deg<FloatingPointType> hue, FloatingPointType saturation, FloatingPointType value, T alpha) { constexpr static BasicColor4<T> fromHSV(Math::Deg<FloatingPointType> hue, FloatingPointType saturation, FloatingPointType value, T alpha) {
return fromHSV(std::make_tuple(hue, saturation, value), alpha); return fromHSV(std::make_tuple(hue, saturation, value), alpha);
} }
@ -303,14 +302,14 @@ class Color4: public Math::Vector4<T> {
* RGB components are set to zero, A component is set to 1.0 for * RGB components are set to zero, A component is set to 1.0 for
* floating-point types and maximum positive value for integral types. * floating-point types and maximum positive value for integral types.
*/ */
constexpr /*implicit*/ Color4(): Math::Vector4<T>(T(0), T(0), T(0), Implementation::defaultAlpha<T>()) {} constexpr /*implicit*/ BasicColor4(): Math::Vector4<T>(T(0), T(0), T(0), Implementation::defaultAlpha<T>()) {}
/** /**
* @copydoc Color3::Color3(T) * @copydoc BasicColor3::BasicColor3(T)
* @param alpha Alpha value, defaults to 1.0 for floating-point types * @param alpha Alpha value, defaults to 1.0 for floating-point types
* and maximum positive value for integral types. * and maximum positive value for integral types.
*/ */
constexpr explicit Color4(T rgb, T alpha = Implementation::defaultAlpha<T>()): Math::Vector4<T>(rgb, rgb, rgb, alpha) {} constexpr explicit BasicColor4(T rgb, T alpha = Implementation::defaultAlpha<T>()): Math::Vector4<T>(rgb, rgb, rgb, alpha) {}
/** /**
* @brief Constructor * @brief Constructor
@ -320,22 +319,22 @@ class Color4: public Math::Vector4<T> {
* @param a A value, defaults to 1.0 for floating-point types and * @param a A value, defaults to 1.0 for floating-point types and
* maximum positive value for integral types. * maximum positive value for integral types.
*/ */
constexpr /*implicit*/ Color4(T r, T g, T b, T a = Implementation::defaultAlpha<T>()): Math::Vector4<T>(r, g, b, a) {} constexpr /*implicit*/ BasicColor4(T r, T g, T b, T a = Implementation::defaultAlpha<T>()): Math::Vector4<T>(r, g, b, a) {}
/** /**
* @brief Constructor * @brief Constructor
* @param rgb Three-component color * @param rgb Three-component color
* @param a A value * @param a A value
*/ */
/* Not marked as explicit, because conversion from Color3 to Color4 /* Not marked as explicit, because conversion from BasicColor3 to BasicColor4
is fairly common, nearly always with A set to 1 */ is fairly common, nearly always with A set to 1 */
constexpr /*implicit*/ Color4(const Math::Vector3<T>& rgb, T a = Implementation::defaultAlpha<T>()): Math::Vector4<T>(rgb[0], rgb[1], rgb[2], a) {} constexpr /*implicit*/ BasicColor4(const Math::Vector3<T>& rgb, T a = Implementation::defaultAlpha<T>()): Math::Vector4<T>(rgb[0], rgb[1], rgb[2], a) {}
/** @copydoc Math::Vector::Vector(const Vector<size, U>&) */ /** @copydoc Math::Vector::Vector(const Vector<size, U>&) */
template<class U> constexpr explicit Color4(const Math::Vector<4, U>& other): Math::Vector4<T>(other) {} template<class U> constexpr explicit BasicColor4(const Math::Vector<4, U>& other): Math::Vector4<T>(other) {}
/** @brief Copy constructor */ /** @brief Copy constructor */
constexpr Color4(const Math::Vector<4, T>& other): Math::Vector4<T>(other) {} constexpr BasicColor4(const Math::Vector<4, T>& other): Math::Vector4<T>(other) {}
T& r() { return Math::Vector4<T>::x(); } /**< @brief R component */ T& r() { return Math::Vector4<T>::x(); } /**< @brief R component */
constexpr T r() const { return Math::Vector4<T>::x(); } /**< @overload */ constexpr T r() const { return Math::Vector4<T>::x(); } /**< @overload */
@ -352,52 +351,55 @@ class Color4: public Math::Vector4<T> {
* *
* @see swizzle() * @see swizzle()
*/ */
Color3<T>& rgb() { return Color3<T>::from(Math::Vector4<T>::data()); } BasicColor3<T>& rgb() { return BasicColor3<T>::from(Math::Vector4<T>::data()); }
constexpr Color3<T> rgb() const { return Color3<T>::from(Math::Vector4<T>::data()); } /**< @overload */ constexpr BasicColor3<T> rgb() const { return BasicColor3<T>::from(Math::Vector4<T>::data()); } /**< @overload */
/** @copydoc Color3::toHSV() */ /** @copydoc BasicColor3::toHSV() */
constexpr HSV toHSV() const { constexpr HSV toHSV() const {
return Implementation::toHSV<T>(rgb()); return Implementation::toHSV<T>(rgb());
} }
/** @copydoc Color3::hue() */ /** @copydoc BasicColor3::hue() */
constexpr Math::Deg<FloatingPointType> hue() const { constexpr Math::Deg<FloatingPointType> hue() const {
return Implementation::hue<T>(rgb()); return Implementation::hue<T>(rgb());
} }
/** @copydoc Color3::saturation() */ /** @copydoc BasicColor3::saturation() */
constexpr FloatingPointType saturation() const { constexpr FloatingPointType saturation() const {
return Implementation::saturation<T>(rgb()); return Implementation::saturation<T>(rgb());
} }
/** @copydoc Color3::value() */ /** @copydoc BasicColor3::value() */
constexpr FloatingPointType value() const { constexpr FloatingPointType value() const {
return Implementation::value<T>(rgb()); return Implementation::value<T>(rgb());
} }
MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(Color4, 4) MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(BasicColor4, 4)
}; };
MAGNUM_VECTOR_SUBCLASS_OPERATOR_IMPLEMENTATION(Color4, 4) /** @brief Four-component (RGBA) float color */
typedef BasicColor4<Float> Color4;
MAGNUM_VECTOR_SUBCLASS_OPERATOR_IMPLEMENTATION(BasicColor4, 4)
/** @debugoperator{Magnum::Color3} */ /** @debugoperator{Magnum::BasicColor3} */
template<class T> inline Debug operator<<(Debug debug, const Color3<T>& value) { template<class T> inline Debug operator<<(Debug debug, const BasicColor3<T>& value) {
return debug << static_cast<const Math::Vector3<T>&>(value); return debug << static_cast<const Math::Vector3<T>&>(value);
} }
/** @debugoperator{Magnum::Color4} */ /** @debugoperator{Magnum::BasicColor4} */
template<class T> inline Debug operator<<(Debug debug, const Color4<T>& value) { template<class T> inline Debug operator<<(Debug debug, const BasicColor4<T>& value) {
return debug << static_cast<const Math::Vector4<T>&>(value); return debug << static_cast<const Math::Vector4<T>&>(value);
} }
} }
namespace Corrade { namespace Utility { namespace Corrade { namespace Utility {
/** @configurationvalue{Magnum::Color3} */ /** @configurationvalue{Magnum::BasicColor3} */
template<class T> struct ConfigurationValue<Magnum::Color3<T>>: public ConfigurationValue<Magnum::Math::Vector<3, T>> {}; template<class T> struct ConfigurationValue<Magnum::BasicColor3<T>>: public ConfigurationValue<Magnum::Math::Vector<3, T>> {};
/** @configurationvalue{Magnum::Color4} */ /** @configurationvalue{Magnum::BasicColor4} */
template<class T> struct ConfigurationValue<Magnum::Color4<T>>: public ConfigurationValue<Magnum::Math::Vector<4, T>> {}; template<class T> struct ConfigurationValue<Magnum::BasicColor4<T>>: public ConfigurationValue<Magnum::Math::Vector<4, T>> {};
}} }}
#endif #endif

2
src/CubeMapTexture.h

@ -233,7 +233,7 @@ class CubeMapTexture: public AbstractTexture {
return this; return this;
} }
#ifndef MAGNUM_TARGET_GLES3 #ifndef MAGNUM_TARGET_GLES3
CubeMapTexture* setBorderColor(const Color4<>& color) { CubeMapTexture* setBorderColor(const Color4& color) {
AbstractTexture::setBorderColor(color); AbstractTexture::setBorderColor(color);
return this; return this;
} }

2
src/CubeMapTextureArray.h

@ -243,7 +243,7 @@ class CubeMapTextureArray: public AbstractTexture {
return this; return this;
} }
#ifndef MAGNUM_TARGET_GLES3 #ifndef MAGNUM_TARGET_GLES3
CubeMapTextureArray* setBorderColor(const Color4<>& color) { CubeMapTextureArray* setBorderColor(const Color4& color) {
AbstractTexture::setBorderColor(color); AbstractTexture::setBorderColor(color);
return this; return this;
} }

4
src/DebugTools/ForceRenderer.cpp

@ -64,7 +64,7 @@ const std::array<UnsignedByte, 6> indices{{
} }
template<UnsignedInt dimensions> ForceRenderer<dimensions>::ForceRenderer(SceneGraph::AbstractObject<dimensions>* object, const typename DimensionTraits<dimensions, Float>::VectorType& forcePosition, const typename DimensionTraits<dimensions, Float>::VectorType* force, ResourceKey options, SceneGraph::DrawableGroup<dimensions>* drawables): SceneGraph::Drawable<dimensions>(object, drawables), forcePosition(forcePosition), force(force), options(ResourceManager::instance()->get<ForceRendererOptions>(options)) { template<UnsignedInt dimensions> ForceRenderer<dimensions>::ForceRenderer(SceneGraph::AbstractBasicObject<dimensions, Float>* object, const typename DimensionTraits<dimensions, Float>::VectorType& forcePosition, const typename DimensionTraits<dimensions, Float>::VectorType* force, ResourceKey options, SceneGraph::BasicDrawableGroup<dimensions, Float>* drawables): SceneGraph::BasicDrawable<dimensions, Float>(object, drawables), forcePosition(forcePosition), force(force), options(ResourceManager::instance()->get<ForceRendererOptions>(options)) {
/* Shader */ /* Shader */
shader = ResourceManager::instance()->get<AbstractShaderProgram, Shaders::Flat<dimensions>>(shaderKey<dimensions>()); shader = ResourceManager::instance()->get<AbstractShaderProgram, Shaders::Flat<dimensions>>(shaderKey<dimensions>());
if(!shader) ResourceManager::instance()->set<AbstractShaderProgram>(shader.key(), new Shaders::Flat<dimensions>); if(!shader) ResourceManager::instance()->set<AbstractShaderProgram>(shader.key(), new Shaders::Flat<dimensions>);
@ -94,7 +94,7 @@ template<UnsignedInt dimensions> ForceRenderer<dimensions>::ForceRenderer(SceneG
ResourceManager::instance()->set<Mesh>(this->mesh.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual); ResourceManager::instance()->set<Mesh>(this->mesh.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual);
} }
template<UnsignedInt dimensions> void ForceRenderer<dimensions>::draw(const typename DimensionTraits<dimensions>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions>* camera) { template<UnsignedInt dimensions> void ForceRenderer<dimensions>::draw(const typename DimensionTraits<dimensions>::MatrixType& transformationMatrix, SceneGraph::AbstractBasicCamera<dimensions, Float>* camera) {
shader->setTransformationProjectionMatrix(camera->projectionMatrix()*Implementation::forceRendererTransformation<dimensions>(transformationMatrix.transformPoint(forcePosition), *force)*DimensionTraits<dimensions>::MatrixType::scaling(typename DimensionTraits<dimensions>::VectorType(options->scale()))) shader->setTransformationProjectionMatrix(camera->projectionMatrix()*Implementation::forceRendererTransformation<dimensions>(transformationMatrix.transformPoint(forcePosition), *force)*DimensionTraits<dimensions>::MatrixType::scaling(typename DimensionTraits<dimensions>::VectorType(options->scale())))
->setColor(options->color()) ->setColor(options->color())
->use(); ->use();

15
src/DebugTools/ForceRenderer.h

@ -47,7 +47,7 @@ class ForceRendererOptions {
constexpr ForceRendererOptions(): _color(1.0f), _size(1.0f) {} constexpr ForceRendererOptions(): _color(1.0f), _size(1.0f) {}
/** @brief Color of rendered arrow */ /** @brief Color of rendered arrow */
constexpr Color4<> color() const { return _color; } constexpr Color4 color() const { return _color; }
/** /**
* @brief Set color of rendered arrow * @brief Set color of rendered arrow
@ -55,7 +55,7 @@ class ForceRendererOptions {
* *
* Default is 100% opaque white. * Default is 100% opaque white.
*/ */
ForceRendererOptions* setColor(const Color4<>& color) { ForceRendererOptions* setColor(const Color4& color) {
_color = color; _color = color;
return this; return this;
} }
@ -75,7 +75,7 @@ class ForceRendererOptions {
} }
private: private:
Color4<> _color; Color4 _color;
Float _size; Float _size;
}; };
@ -91,7 +91,7 @@ Example code:
@code @code
// Create some options // Create some options
DebugTools::ResourceManager::instance()->set("my", (new DebugTools::ForceRendererOptions) DebugTools::ResourceManager::instance()->set("my", (new DebugTools::ForceRendererOptions)
->setScale(5.0f)->setColor(Color3<>::fromHSV(120.0_degf, 1.0f, 0.7f))); ->setScale(5.0f)->setColor(Color3::fromHSV(120.0_degf, 1.0f, 0.7f)));
// Create debug renderer for given object, use "my" options for it // Create debug renderer for given object, use "my" options for it
Object3D* object; Object3D* object;
@ -101,7 +101,7 @@ new DebugTools::ForceRenderer2D(object, {0.3f, 1.5f, -0.7f}, &force, "my", debug
@see ForceRenderer2D, ForceRenderer3D @see ForceRenderer2D, ForceRenderer3D
*/ */
template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ForceRenderer: public SceneGraph::Drawable<dimensions> { template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ForceRenderer: public SceneGraph::BasicDrawable<dimensions, Float> {
public: public:
/** /**
* @brief Constructor * @brief Constructor
@ -117,11 +117,10 @@ template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ForceRenderer: p
* saved as reference to original vector and thus it must be available * saved as reference to original vector and thus it must be available
* for the whole lifetime of the renderer. * for the whole lifetime of the renderer.
*/ */
explicit ForceRenderer(SceneGraph::AbstractObject<dimensions>* object, const typename DimensionTraits<dimensions, Float>::VectorType& forcePosition, const typename DimensionTraits<dimensions, Float>::VectorType* force, ResourceKey options = ResourceKey(), SceneGraph::DrawableGroup<dimensions>* drawables = nullptr); explicit ForceRenderer(SceneGraph::AbstractBasicObject<dimensions, Float>* object, const typename DimensionTraits<dimensions, Float>::VectorType& forcePosition, const typename DimensionTraits<dimensions, Float>::VectorType* force, ResourceKey options = ResourceKey(), SceneGraph::BasicDrawableGroup<dimensions, Float>* drawables = nullptr);
protected: protected:
/** @todoc Remove Float when Doxygen properly treats this as override */ void draw(const typename DimensionTraits<dimensions, Float>::MatrixType& transformationMatrix, SceneGraph::AbstractBasicCamera<dimensions, Float>* camera) override;
void draw(const typename DimensionTraits<dimensions, Float>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions, Float>* camera) override;
private: private:
const typename DimensionTraits<dimensions, Float>::VectorType forcePosition; const typename DimensionTraits<dimensions, Float>::VectorType forcePosition;

12
src/DebugTools/ObjectRenderer.cpp

@ -43,7 +43,7 @@ template<> struct Renderer<2> {
static ResourceKey mesh() { return {"object2d"}; } static ResourceKey mesh() { return {"object2d"}; }
static const std::array<Vector2, 8> positions; static const std::array<Vector2, 8> positions;
static const std::array<Color3<>, 8> colors; static const std::array<Color3, 8> colors;
static const std::array<UnsignedByte, 12> indices; static const std::array<UnsignedByte, 12> indices;
}; };
@ -59,7 +59,7 @@ const std::array<Vector2, 8> Renderer<2>::positions{{
{-0.1f, 0.9f} {-0.1f, 0.9f}
}}; }};
const std::array<Color3<>, 8> Renderer<2>::colors{{ const std::array<Color3, 8> Renderer<2>::colors{{
{1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f},
{1.0f, 0.0f, 0.0f}, /* X axis */ {1.0f, 0.0f, 0.0f}, /* X axis */
{1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f},
@ -88,7 +88,7 @@ template<> struct Renderer<3> {
static ResourceKey mesh() { return {"object3d"}; } static ResourceKey mesh() { return {"object3d"}; }
static const std::array<Vector3, 12> positions; static const std::array<Vector3, 12> positions;
static const std::array<Color3<>, 12> colors; static const std::array<Color3, 12> colors;
static const std::array<uint8_t, 18> indices; static const std::array<uint8_t, 18> indices;
}; };
@ -109,7 +109,7 @@ const std::array<Vector3, 12> Renderer<3>::positions{{
{-0.1f, 0.0f, 0.9f} {-0.1f, 0.0f, 0.9f}
}}; }};
const std::array<Color3<>, 12> Renderer<3>::colors{{ const std::array<Color3, 12> Renderer<3>::colors{{
{1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f},
{1.0f, 0.0f, 0.0f}, /* X axis */ {1.0f, 0.0f, 0.0f}, /* X axis */
{1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f},
@ -142,7 +142,7 @@ const std::array<UnsignedByte, 18> Renderer<3>::indices{{
} }
template<UnsignedInt dimensions> ObjectRenderer<dimensions>::ObjectRenderer(SceneGraph::AbstractObject<dimensions>* object, ResourceKey options, SceneGraph::DrawableGroup<dimensions>* drawables): SceneGraph::Drawable<dimensions>(object, drawables), options(ResourceManager::instance()->get<ObjectRendererOptions>(options)) { template<UnsignedInt dimensions> ObjectRenderer<dimensions>::ObjectRenderer(SceneGraph::AbstractBasicObject<dimensions, Float>* object, ResourceKey options, SceneGraph::BasicDrawableGroup<dimensions, Float>* drawables): SceneGraph::BasicDrawable<dimensions, Float>(object, drawables), options(ResourceManager::instance()->get<ObjectRendererOptions>(options)) {
/* Shader */ /* Shader */
shader = ResourceManager::instance()->get<AbstractShaderProgram, Shaders::VertexColor<dimensions>>(Renderer<dimensions>::shader()); shader = ResourceManager::instance()->get<AbstractShaderProgram, Shaders::VertexColor<dimensions>>(Renderer<dimensions>::shader());
if(!shader) ResourceManager::instance()->set<AbstractShaderProgram>(shader.key(), new Shaders::VertexColor<dimensions>); if(!shader) ResourceManager::instance()->set<AbstractShaderProgram>(shader.key(), new Shaders::VertexColor<dimensions>);
@ -173,7 +173,7 @@ template<UnsignedInt dimensions> ObjectRenderer<dimensions>::ObjectRenderer(Scen
ResourceManager::instance()->set<Mesh>(this->mesh.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual); ResourceManager::instance()->set<Mesh>(this->mesh.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual);
} }
template<UnsignedInt dimensions> void ObjectRenderer<dimensions>::draw(const typename DimensionTraits<dimensions>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions>* camera) { template<UnsignedInt dimensions> void ObjectRenderer<dimensions>::draw(const typename DimensionTraits<dimensions>::MatrixType& transformationMatrix, SceneGraph::AbstractBasicCamera<dimensions, Float>* camera) {
shader->setTransformationProjectionMatrix(camera->projectionMatrix()*transformationMatrix*DimensionTraits<dimensions>::MatrixType::scaling(typename DimensionTraits<dimensions>::VectorType(options->size()))) shader->setTransformationProjectionMatrix(camera->projectionMatrix()*transformationMatrix*DimensionTraits<dimensions>::MatrixType::scaling(typename DimensionTraits<dimensions>::VectorType(options->size())))
->use(); ->use();

7
src/DebugTools/ObjectRenderer.h

@ -84,7 +84,7 @@ new DebugTools::ObjectRenderer2D(object, "my", debugDrawables);
@see ObjectRenderer2D, ObjectRenderer3D @see ObjectRenderer2D, ObjectRenderer3D
*/ */
template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ObjectRenderer: public SceneGraph::Drawable<dimensions> { template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ObjectRenderer: public SceneGraph::BasicDrawable<dimensions, Float> {
public: public:
/** /**
* @brief Constructor * @brief Constructor
@ -96,11 +96,10 @@ template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ObjectRenderer:
* *
* The renderer is automatically added to object's features. * The renderer is automatically added to object's features.
*/ */
explicit ObjectRenderer(SceneGraph::AbstractObject<dimensions>* object, ResourceKey options = ResourceKey(), SceneGraph::DrawableGroup<dimensions>* drawables = nullptr); explicit ObjectRenderer(SceneGraph::AbstractBasicObject<dimensions, Float>* object, ResourceKey options = ResourceKey(), SceneGraph::BasicDrawableGroup<dimensions, Float>* drawables = nullptr);
protected: protected:
/** @todoc Remove Float when Doxygen properly treats this as override */ void draw(const typename DimensionTraits<dimensions, Float>::MatrixType& transformationMatrix, SceneGraph::AbstractBasicCamera<dimensions, Float>* camera) override;
void draw(const typename DimensionTraits<dimensions, Float>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions, Float>* camera) override;
private: private:
Resource<ObjectRendererOptions> options; Resource<ObjectRendererOptions> options;

4
src/DebugTools/ShapeRenderer.cpp

@ -94,7 +94,7 @@ template<> void createDebugMesh(ShapeRenderer<3>* renderer, const Shapes::Implem
} }
template<UnsignedInt dimensions> ShapeRenderer<dimensions>::ShapeRenderer(Shapes::AbstractShape<dimensions>* shape, ResourceKey options, SceneGraph::DrawableGroup<dimensions>* drawables): SceneGraph::Drawable<dimensions>(shape->object(), drawables), options(ResourceManager::instance()->get<ShapeRendererOptions>(options)) { template<UnsignedInt dimensions> ShapeRenderer<dimensions>::ShapeRenderer(Shapes::AbstractShape<dimensions>* shape, ResourceKey options, SceneGraph::BasicDrawableGroup<dimensions, Float>* drawables): SceneGraph::BasicDrawable<dimensions, Float>(shape->object(), drawables), options(ResourceManager::instance()->get<ShapeRendererOptions>(options)) {
Implementation::createDebugMesh(this, Shapes::Implementation::getAbstractShape(shape)); Implementation::createDebugMesh(this, Shapes::Implementation::getAbstractShape(shape));
} }
@ -103,7 +103,7 @@ template<UnsignedInt dimensions> ShapeRenderer<dimensions>::~ShapeRenderer() {
delete *it; delete *it;
} }
template<UnsignedInt dimensions> void ShapeRenderer<dimensions>::draw(const typename DimensionTraits<dimensions>::MatrixType&, SceneGraph::AbstractCamera<dimensions>* camera) { template<UnsignedInt dimensions> void ShapeRenderer<dimensions>::draw(const typename DimensionTraits<dimensions>::MatrixType&, SceneGraph::AbstractBasicCamera<dimensions, Float>* camera) {
typename DimensionTraits<dimensions>::MatrixType projectionMatrix = camera->projectionMatrix()*camera->cameraMatrix(); typename DimensionTraits<dimensions>::MatrixType projectionMatrix = camera->projectionMatrix()*camera->cameraMatrix();
for(auto it = renderers.begin(); it != renderers.end(); ++it) for(auto it = renderers.begin(); it != renderers.end(); ++it)
(*it)->draw(options, projectionMatrix); (*it)->draw(options, projectionMatrix);

12
src/DebugTools/ShapeRenderer.h

@ -83,7 +83,7 @@ class ShapeRendererOptions {
} }
/** @brief Color of rendered shape */ /** @brief Color of rendered shape */
constexpr Color4<> color() const { return _color; } constexpr Color4 color() const { return _color; }
/** /**
* @brief Set color of rendered shape * @brief Set color of rendered shape
@ -91,7 +91,7 @@ class ShapeRendererOptions {
* *
* Default is 100% opaque white. * Default is 100% opaque white.
*/ */
ShapeRendererOptions* setColor(const Color4<>& color) { ShapeRendererOptions* setColor(const Color4& color) {
_color = color; _color = color;
return this; return this;
} }
@ -112,7 +112,7 @@ class ShapeRendererOptions {
} }
private: private:
Color4<> _color; Color4 _color;
Float _pointSize; Float _pointSize;
RenderMode _renderMode; RenderMode _renderMode;
}; };
@ -138,7 +138,7 @@ new DebugTools::ShapeRenderer2D(shape, "red", debugDrawables);
@see ShapeRenderer2D, ShapeRenderer3D @see ShapeRenderer2D, ShapeRenderer3D
*/ */
template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ShapeRenderer: public SceneGraph::Drawable<dimensions> { template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ShapeRenderer: public SceneGraph::BasicDrawable<dimensions, Float> {
friend void Implementation::createDebugMesh<>(ShapeRenderer<dimensions>*, const Shapes::Implementation::AbstractShape<dimensions>*); friend void Implementation::createDebugMesh<>(ShapeRenderer<dimensions>*, const Shapes::Implementation::AbstractShape<dimensions>*);
public: public:
@ -154,13 +154,13 @@ template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ShapeRenderer: p
* @p shape must be available for the whole lifetime of the renderer * @p shape must be available for the whole lifetime of the renderer
* and if it is group, it must not change its internal structure. * and if it is group, it must not change its internal structure.
*/ */
explicit ShapeRenderer(Shapes::AbstractShape<dimensions>* shape, ResourceKey options = ResourceKey(), SceneGraph::DrawableGroup<dimensions>* drawables = nullptr); explicit ShapeRenderer(Shapes::AbstractShape<dimensions>* shape, ResourceKey options = ResourceKey(), SceneGraph::BasicDrawableGroup<dimensions, Float>* drawables = nullptr);
~ShapeRenderer(); ~ShapeRenderer();
protected: protected:
/** @todoc Remove Float when Doxygen properly treats this as override */ /** @todoc Remove Float when Doxygen properly treats this as override */
void draw(const typename DimensionTraits<dimensions, Float>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions, Float>* camera) override; void draw(const typename DimensionTraits<dimensions, Float>::MatrixType& transformationMatrix, SceneGraph::AbstractBasicCamera<dimensions, Float>* camera) override;
private: private:
Resource<ShapeRendererOptions> options; Resource<ShapeRendererOptions> options;

6
src/Magnum.h

@ -354,8 +354,10 @@ enum class BufferTextureFormat: GLenum;
#endif #endif
#endif #endif
template<class T = Float> class Color3; template<class> class BasicColor3;
template<class T = Float> class Color4; template<class> class BasicColor4;
typedef BasicColor3<Float> Color3;
typedef BasicColor4<Float> Color4;
#ifndef CORRADE_GCC45_COMPATIBILITY #ifndef CORRADE_GCC45_COMPATIBILITY
enum class Version: Int; enum class Version: Int;

2
src/Mesh.h

@ -173,7 +173,7 @@ mesh->setPrimitive(plane.primitive())
class MyShader: public AbstractShaderProgram { class MyShader: public AbstractShaderProgram {
public: public:
typedef Attribute<0, Vector3> Position; typedef Attribute<0, Vector3> Position;
typedef Attribute<1, Color4<>> Color; typedef Attribute<1, Color4> Color;
// ... // ...
}; };

2
src/MeshTools/Interleave.h

@ -160,7 +160,7 @@ achieve that, you can specify gaps between the attributes:
@code @code
std::vector<Vector4> positions; std::vector<Vector4> positions;
std::vector<GLushort> weights; std::vector<GLushort> weights;
std::vector<Color3<GLubyte>> vertexColors; std::vector<BasicColor3<GLubyte>> vertexColors;
std::size_t attributeCount; std::size_t attributeCount;
std::size_t stride; std::size_t stride;
char* data; char* data;

4
src/Renderer.cpp

@ -50,7 +50,7 @@ void Renderer::setHint(const Hint target, const HintMode mode) {
glHint(GLenum(target), GLenum(mode)); glHint(GLenum(target), GLenum(mode));
} }
void Renderer::setClearColor(const Color4<>& color) { void Renderer::setClearColor(const Color4& color) {
glClearColor(color.r(), color.g(), color.b(), color.a()); glClearColor(color.r(), color.g(), color.b(), color.a());
} }
@ -152,7 +152,7 @@ void Renderer::setBlendFunction(const BlendFunction sourceRgb, const BlendFuncti
glBlendFuncSeparate(GLenum(sourceRgb), GLenum(destinationRgb), GLenum(sourceAlpha), GLenum(destinationAlpha)); glBlendFuncSeparate(GLenum(sourceRgb), GLenum(destinationRgb), GLenum(sourceAlpha), GLenum(destinationAlpha));
} }
void Renderer::setBlendColor(const Color4<>& color) { void Renderer::setBlendColor(const Color4& color) {
glBlendColor(color.r(), color.g(), color.b(), color.a()); glBlendColor(color.r(), color.g(), color.b(), color.a());
} }

4
src/Renderer.h

@ -238,7 +238,7 @@ class MAGNUM_EXPORT Renderer {
* Initial value is fully opaque black. * Initial value is fully opaque black.
* @see @fn_gl{ClearColor} * @see @fn_gl{ClearColor}
*/ */
static void setClearColor(const Color4<>& color); static void setClearColor(const Color4& color);
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
/** /**
@ -809,7 +809,7 @@ class MAGNUM_EXPORT Renderer {
* @see @ref Feature "Feature::Blending", setBlendEquation(), * @see @ref Feature "Feature::Blending", setBlendEquation(),
* setBlendFunction(), @fn_gl{BlendColor} * setBlendFunction(), @fn_gl{BlendColor}
*/ */
static void setBlendColor(const Color4<>& color); static void setBlendColor(const Color4& color);
/*@}*/ /*@}*/

55
src/SceneGraph/AbstractCamera.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::AbstractCamera, enum Magnum::SceneGraph::AspectRatioPolicy, alias Magnum::SceneGraph::AbstractCamera2D, Magnum::SceneGraph::AbstractCamera3D * @brief Class Magnum::SceneGraph::AbstractBasicCamera, enum Magnum::SceneGraph::AspectRatioPolicy, typedef Magnum::SceneGraph::AbstractCamera2D, Magnum::SceneGraph::AbstractCamera3D
*/ */
#include "Math/Matrix3.h" #include "Math/Matrix3.h"
@ -39,7 +39,7 @@ namespace Magnum { namespace SceneGraph {
/** /**
@brief Camera aspect ratio policy @brief Camera aspect ratio policy
@see AbstractCamera::setAspectRatioPolicy() @see AbstractBasicCamera::setAspectRatioPolicy()
*/ */
enum class AspectRatioPolicy: UnsignedByte { enum class AspectRatioPolicy: UnsignedByte {
NotPreserved, /**< Don't preserve aspect ratio (default) */ NotPreserved, /**< Don't preserve aspect ratio (default) */
@ -67,25 +67,20 @@ relevant sections in
@ref Camera3D-explicit-specializations "Camera3D" class documentation or @ref Camera3D-explicit-specializations "Camera3D" class documentation or
@ref compilation-speedup-hpp for more information. @ref compilation-speedup-hpp for more information.
- @ref AbstractCamera "AbstractCamera<2, Float>" - @ref AbstractBasicCamera "AbstractBasicCamera<2, Float>"
- @ref AbstractCamera "AbstractCamera<3, Float>" - @ref AbstractBasicCamera "AbstractBasicCamera<3, Float>"
@see @ref scenegraph, Drawable, DrawableGroup, AbstractCamera2D, AbstractCamera3D @see AbstractCamera2D, AbstractCamera3D, @ref scenegraph, Drawable, DrawableGroup
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT AbstractBasicCamera: public AbstractBasicFeature<dimensions, T> {
template<UnsignedInt dimensions, class T>
#else
template<UnsignedInt dimensions, class T = Float>
#endif
class MAGNUM_SCENEGRAPH_EXPORT AbstractCamera: public AbstractFeature<dimensions, T> {
public: public:
/** /**
* @brief Constructor * @brief Constructor
* @param object Object holding the camera * @param object Object holding the camera
*/ */
explicit AbstractCamera(AbstractObject<dimensions, T>* object); explicit AbstractBasicCamera(AbstractBasicObject<dimensions, T>* object);
virtual ~AbstractCamera() = 0; virtual ~AbstractBasicCamera() = 0;
/** @brief Aspect ratio policy */ /** @brief Aspect ratio policy */
AspectRatioPolicy aspectRatioPolicy() const { return _aspectRatioPolicy; } AspectRatioPolicy aspectRatioPolicy() const { return _aspectRatioPolicy; }
@ -94,7 +89,7 @@ class MAGNUM_SCENEGRAPH_EXPORT AbstractCamera: public AbstractFeature<dimensions
* @brief Set aspect ratio policy * @brief Set aspect ratio policy
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
*/ */
AbstractCamera<dimensions, T>* setAspectRatioPolicy(AspectRatioPolicy policy); AbstractBasicCamera<dimensions, T>* setAspectRatioPolicy(AspectRatioPolicy policy);
/** /**
* @brief Camera matrix * @brief Camera matrix
@ -103,7 +98,7 @@ class MAGNUM_SCENEGRAPH_EXPORT AbstractCamera: public AbstractFeature<dimensions
* applied as first. * applied as first.
*/ */
typename DimensionTraits<dimensions, T>::MatrixType cameraMatrix() { typename DimensionTraits<dimensions, T>::MatrixType cameraMatrix() {
AbstractFeature<dimensions, T>::object()->setClean(); AbstractBasicFeature<dimensions, T>::object()->setClean();
return _cameraMatrix; return _cameraMatrix;
} }
@ -143,7 +138,7 @@ class MAGNUM_SCENEGRAPH_EXPORT AbstractCamera: public AbstractFeature<dimensions
* *
* Draws given group of drawables. * Draws given group of drawables.
*/ */
virtual void draw(DrawableGroup<dimensions, T>& group); virtual void draw(BasicDrawableGroup<dimensions, T>& group);
protected: protected:
/** Recalculates camera matrix */ /** Recalculates camera matrix */
@ -167,37 +162,19 @@ class MAGNUM_SCENEGRAPH_EXPORT AbstractCamera: public AbstractFeature<dimensions
Vector2i _viewport; Vector2i _viewport;
}; };
#ifndef CORRADE_GCC46_COMPATIBILITY
/** /**
@brief Base for two-dimensional cameras @brief Base camera for two-dimensional float scenes
Convenience alternative to <tt>%AbstractCamera<2, T></tt>. See AbstractCamera
for more information.
@note Not available on GCC < 4.7. Use <tt>%AbstractCamera<2, T></tt> instead.
@see AbstractCamera3D @see AbstractCamera3D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT typedef AbstractBasicCamera<2, Float> AbstractCamera2D;
template<class T = Float>
#else
template<class T>
#endif
using AbstractCamera2D = AbstractCamera<2, T>;
/** /**
@brief Base for three-dimensional cameras @brief Base camera for three-dimensional float scenes
Convenience alternative to <tt>%AbstractCamera<3, T></tt>. See AbstractCamera @see AbstractBasicCamera2D
for more information.
@note Not available on GCC < 4.7. Use <tt>%AbstractCamera<3, T></tt> instead.
@see AbstractCamera2D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT typedef AbstractBasicCamera<3, Float> AbstractCamera3D;
template<class T = Float>
#else
template<class T>
#endif
using AbstractCamera3D = AbstractCamera<3, T>;
#endif
}} }}

18
src/SceneGraph/AbstractCamera.hpp

@ -70,32 +70,32 @@ template<UnsignedInt dimensions, class T> typename DimensionTraits<dimensions, T
} }
template<UnsignedInt dimensions, class T> AbstractCamera<dimensions, T>::AbstractCamera(AbstractObject<dimensions, T>* object): AbstractFeature<dimensions, T>(object), _aspectRatioPolicy(AspectRatioPolicy::NotPreserved) { template<UnsignedInt dimensions, class T> AbstractBasicCamera<dimensions, T>::AbstractBasicCamera(AbstractBasicObject<dimensions, T>* object): AbstractBasicFeature<dimensions, T>(object), _aspectRatioPolicy(AspectRatioPolicy::NotPreserved) {
AbstractFeature<dimensions, T>::setCachedTransformations(CachedTransformation::InvertedAbsolute); AbstractBasicFeature<dimensions, T>::setCachedTransformations(CachedTransformation::InvertedAbsolute);
} }
template<UnsignedInt dimensions, class T> AbstractCamera<dimensions, T>::~AbstractCamera() {} template<UnsignedInt dimensions, class T> AbstractBasicCamera<dimensions, T>::~AbstractBasicCamera() {}
template<UnsignedInt dimensions, class T> AbstractCamera<dimensions, T>* AbstractCamera<dimensions, T>::setAspectRatioPolicy(AspectRatioPolicy policy) { template<UnsignedInt dimensions, class T> AbstractBasicCamera<dimensions, T>* AbstractBasicCamera<dimensions, T>::setAspectRatioPolicy(AspectRatioPolicy policy) {
_aspectRatioPolicy = policy; _aspectRatioPolicy = policy;
fixAspectRatio(); fixAspectRatio();
return this; return this;
} }
template<UnsignedInt dimensions, class T> void AbstractCamera<dimensions, T>::setViewport(const Vector2i& size) { template<UnsignedInt dimensions, class T> void AbstractBasicCamera<dimensions, T>::setViewport(const Vector2i& size) {
_viewport = size; _viewport = size;
fixAspectRatio(); fixAspectRatio();
} }
template<UnsignedInt dimensions, class T> void AbstractCamera<dimensions, T>::draw(DrawableGroup<dimensions, T>& group) { template<UnsignedInt dimensions, class T> void AbstractBasicCamera<dimensions, T>::draw(BasicDrawableGroup<dimensions, T>& group) {
AbstractObject<dimensions, T>* scene = AbstractFeature<dimensions, T>::object()->scene(); AbstractBasicObject<dimensions, T>* scene = AbstractBasicFeature<dimensions, T>::object()->scene();
CORRADE_ASSERT(scene, "Camera::draw(): cannot draw when camera is not part of any scene", ); CORRADE_ASSERT(scene, "Camera::draw(): cannot draw when camera is not part of any scene", );
/* Compute camera matrix */ /* Compute camera matrix */
AbstractFeature<dimensions, T>::object()->setClean(); AbstractBasicFeature<dimensions, T>::object()->setClean();
/* Compute transformations of all objects in the group relative to the camera */ /* Compute transformations of all objects in the group relative to the camera */
std::vector<AbstractObject<dimensions, T>*> objects(group.size()); std::vector<AbstractBasicObject<dimensions, T>*> objects(group.size());
for(std::size_t i = 0; i != group.size(); ++i) for(std::size_t i = 0; i != group.size(); ++i)
objects[i] = group[i]->object(); objects[i] = group[i]->object();
std::vector<typename DimensionTraits<dimensions, T>::MatrixType> transformations = std::vector<typename DimensionTraits<dimensions, T>::MatrixType> transformations =

104
src/SceneGraph/AbstractFeature.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::AbstractFeature, alias Magnum::SceneGraph::AbstractFeature2D, Magnum::SceneGraph::AbstractFeature3D, enum Magnum::SceneGraph::CachedTransformation, enum set Magnum::SceneGraph::CachedTransformations * @brief Class Magnum::SceneGraph::AbstractBasicFeature, typedef Magnum::SceneGraph::AbstractFeature2D, Magnum::SceneGraph::AbstractFeature3D, enum Magnum::SceneGraph::CachedTransformation, enum set Magnum::SceneGraph::CachedTransformations
*/ */
#include <Containers/EnumSet.h> #include <Containers/EnumSet.h>
@ -40,8 +40,8 @@ namespace Magnum { namespace SceneGraph {
@brief Which transformation to cache in given feature @brief Which transformation to cache in given feature
@see @ref scenegraph-caching, CachedTransformations, @see @ref scenegraph-caching, CachedTransformations,
AbstractFeature::setCachedTransformations(), AbstractFeature::clean(), AbstractBasicFeature::setCachedTransformations(), AbstractBasicFeature::clean(),
AbstractFeature::cleanInverted() AbstractBasicFeature::cleanInverted()
@todo Provide also simpler representations from which could benefit @todo Provide also simpler representations from which could benefit
other transformation implementations, as they won't need to other transformation implementations, as they won't need to
e.g. create transformation matrix from quaternion? e.g. create transformation matrix from quaternion?
@ -65,8 +65,8 @@ enum class CachedTransformation: UnsignedByte {
/** /**
@brief Which transformations to cache in this feature @brief Which transformations to cache in this feature
@see @ref scenegraph-caching, AbstractFeature::setCachedTransformations(), @see @ref scenegraph-caching, AbstractBasicFeature::setCachedTransformations(),
AbstractFeature::clean(), AbstractFeature::cleanInverted() AbstractBasicFeature::clean(), AbstractBasicFeature::cleanInverted()
*/ */
typedef Containers::EnumSet<CachedTransformation, UnsignedByte> CachedTransformations; typedef Containers::EnumSet<CachedTransformation, UnsignedByte> CachedTransformations;
@ -98,9 +98,9 @@ caching is disabled. You can enable it using setCachedTransformations() and
then implement corresponding cleaning function(s) -- either clean(), then implement corresponding cleaning function(s) -- either clean(),
cleanInverted() or both. Example: cleanInverted() or both. Example:
@code @code
class CachingFeature: public SceneGraph::AbstractFeature3D<> { class CachingFeature: public SceneGraph::AbstractFeature3D {
public: public:
CachingFeature(SceneGraph::AbstractObject3D<>* object): SceneGraph::AbstractFeature3D<>(object) { CachingFeature(SceneGraph::AbstractObject3D* object): SceneGraph::AbstractFeature3D(object) {
setCachedTransformations(CachedTransformation::Absolute); setCachedTransformations(CachedTransformation::Absolute);
} }
@ -131,21 +131,20 @@ transformation implementations. Using small trick we are able to get pointer
to both AbstractObject and needed transformation from one constructor to both AbstractObject and needed transformation from one constructor
parameter: 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> 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 If we take for example @ref Object "Object<MatrixTransformation3D>", it is
derived from @ref AbstractObject "AbstractObject3D<>" and derived from @ref AbstractBasicObject "AbstractObject3D" and
@ref MatrixTransformation3D "MatrixTransformation3D<>", which is derived from @ref BasicMatrixTransformation3D "MatrixTransformation3D", which is derived
@ref AbstractTranslationRotationScaling3D "AbstractTranslationRotationScaling3D<>", from @ref BasicAbstractTranslationRotationScaling3D "AbstractTranslationRotationScaling3D",
which is derived from which is derived from @ref BasicAbstractTranslationRotation3D "AbstractTranslationRotation3D",
@ref AbstractTranslationRotation3D "AbstractTranslationRotation3D<>",
which is automatically extracted from the pointer in our constructor. which is automatically extracted from the pointer in our constructor.
@section AbstractFeature-explicit-specializations Explicit template specializations @section AbstractFeature-explicit-specializations Explicit template specializations
@ -155,19 +154,18 @@ For other specializations (e.g. using Double type) you have to use
AbstractFeature.hpp implementation file to avoid linker errors. See also AbstractFeature.hpp implementation file to avoid linker errors. See also
@ref compilation-speedup-hpp for more information. @ref compilation-speedup-hpp for more information.
- @ref AbstractFeature "AbstractFeature<2, Float>" - @ref AbstractBasicFeature "AbstractBasicFeature<2, Float>"
- @ref AbstractFeature "AbstractFeature<3, Float>" - @ref AbstractBasicFeature "AbstractBasicFeature<3, Float>"
@see AbstractFeature2D, AbstractFeature3D @see @ref AbstractFeature2D, @ref AbstractFeature3D
*/ */
template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT AbstractBasicFeature
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT AbstractFeature: private Containers::LinkedListItem<AbstractFeature<dimensions, T>, AbstractObject<dimensions, T>> : private Containers::LinkedListItem<AbstractBasicFeature<dimensions, T>, AbstractBasicObject<dimensions, T>>
#else
template<UnsignedInt dimensions, class T = Float> class AbstractFeature
#endif #endif
{ {
friend class Containers::LinkedList<AbstractFeature<dimensions, T>>; friend class Containers::LinkedList<AbstractBasicFeature<dimensions, T>>;
friend class Containers::LinkedListItem<AbstractFeature<dimensions, T>, AbstractObject<dimensions, T>>; friend class Containers::LinkedListItem<AbstractBasicFeature<dimensions, T>, AbstractBasicObject<dimensions, T>>;
template<class Transformation> friend class Object; template<class Transformation> friend class Object;
public: public:
@ -175,38 +173,38 @@ template<UnsignedInt dimensions, class T = Float> class AbstractFeature
* @brief Constructor * @brief Constructor
* @param object %Object holding this feature * @param object %Object holding this feature
*/ */
explicit AbstractFeature(AbstractObject<dimensions, T>* object); explicit AbstractBasicFeature(AbstractBasicObject<dimensions, T>* object);
virtual ~AbstractFeature() = 0; virtual ~AbstractBasicFeature() = 0;
/** @brief %Object holding this feature */ /** @brief %Object holding this feature */
AbstractObject<dimensions, T>* object() { AbstractBasicObject<dimensions, T>* object() {
return Containers::LinkedListItem<AbstractFeature<dimensions, T>, AbstractObject<dimensions, T>>::list(); return Containers::LinkedListItem<AbstractBasicFeature<dimensions, T>, AbstractBasicObject<dimensions, T>>::list();
} }
/** @overload */ /** @overload */
const AbstractObject<dimensions, T>* object() const { const AbstractBasicObject<dimensions, T>* object() const {
return Containers::LinkedListItem<AbstractFeature<dimensions, T>, AbstractObject<dimensions, T>>::list(); return Containers::LinkedListItem<AbstractBasicFeature<dimensions, T>, AbstractBasicObject<dimensions, T>>::list();
} }
/** @brief Previous feature or `nullptr`, if this is first feature */ /** @brief Previous feature or `nullptr`, if this is first feature */
AbstractFeature<dimensions, T>* previousFeature() { AbstractBasicFeature<dimensions, T>* previousFeature() {
return Containers::LinkedListItem<AbstractFeature<dimensions, T>, AbstractObject<dimensions, T>>::previous(); return Containers::LinkedListItem<AbstractBasicFeature<dimensions, T>, AbstractBasicObject<dimensions, T>>::previous();
} }
/** @overload */ /** @overload */
const AbstractFeature<dimensions, T>* previousFeature() const { const AbstractBasicFeature<dimensions, T>* previousFeature() const {
return Containers::LinkedListItem<AbstractFeature<dimensions, T>, AbstractObject<dimensions, T>>::previous(); return Containers::LinkedListItem<AbstractBasicFeature<dimensions, T>, AbstractBasicObject<dimensions, T>>::previous();
} }
/** @brief Next feature or `nullptr`, if this is last feature */ /** @brief Next feature or `nullptr`, if this is last feature */
AbstractFeature<dimensions, T>* nextFeature() { AbstractBasicFeature<dimensions, T>* nextFeature() {
return Containers::LinkedListItem<AbstractFeature<dimensions, T>, AbstractObject<dimensions, T>>::next(); return Containers::LinkedListItem<AbstractBasicFeature<dimensions, T>, AbstractBasicObject<dimensions, T>>::next();
} }
/** @overload */ /** @overload */
const AbstractFeature<dimensions, T>* nextFeature() const { const AbstractBasicFeature<dimensions, T>* nextFeature() const {
return Containers::LinkedListItem<AbstractFeature<dimensions, T>, AbstractObject<dimensions, T>>::next(); return Containers::LinkedListItem<AbstractBasicFeature<dimensions, T>, AbstractBasicObject<dimensions, T>>::next();
} }
/** /**
@ -284,37 +282,19 @@ template<UnsignedInt dimensions, class T = Float> class AbstractFeature
CachedTransformations _cachedTransformations; CachedTransformations _cachedTransformations;
}; };
#ifndef CORRADE_GCC46_COMPATIBILITY
/** /**
@brief Base for two-dimensional features @brief Base feature for two-dimensional float scenes
Convenience alternative to <tt>%AbstractFeature<2, T></tt>. See AbstractFeature @see @ref AbstractFeature3D
for more information.
@note Not available on GCC < 4.7. Use <tt>%AbstractFeature<2, T></tt> instead.
@see AbstractFeature3D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT typedef AbstractBasicFeature<2, Float> AbstractFeature2D;
template<class T = Float>
#else
template<class T>
#endif
using AbstractFeature2D = AbstractFeature<2, T>;
/** /**
@brief Base for three-dimensional features @brief Base feature for three-dimensional float scenes
Convenience alternative to <tt>%AbstractFeature<3, T></tt>. See AbstractFeature @see @ref AbstractFeature2D
for more information.
@note Not available on GCC < 4.7. Use <tt>%AbstractFeature<3, T></tt> instead.
@see AbstractFeature2D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT typedef AbstractBasicFeature<3, Float> AbstractFeature3D;
template<class T = Float>
#else
template<class T>
#endif
using AbstractFeature3D = AbstractFeature<3, T>;
#endif
}} }}

12
src/SceneGraph/AbstractFeature.hpp

@ -32,18 +32,18 @@
namespace Magnum { namespace SceneGraph { namespace Magnum { namespace SceneGraph {
template<UnsignedInt dimensions, class T> AbstractFeature<dimensions, T>::AbstractFeature(AbstractObject<dimensions, T>* object) { template<UnsignedInt dimensions, class T> AbstractBasicFeature<dimensions, T>::AbstractBasicFeature(AbstractBasicObject<dimensions, T>* object) {
object->Containers::template LinkedList<AbstractFeature<dimensions, T>>::insert(this); object->Containers::template LinkedList<AbstractBasicFeature<dimensions, T>>::insert(this);
} }
/* `= default` causes linker errors in GCC 4.5 */ /* `= default` causes linker errors in GCC 4.5 */
template<UnsignedInt dimensions, class T> AbstractFeature<dimensions, T>::~AbstractFeature() {} template<UnsignedInt dimensions, class T> AbstractBasicFeature<dimensions, T>::~AbstractBasicFeature() {}
template<UnsignedInt dimensions, class T> void AbstractFeature<dimensions, T>::markDirty() {} template<UnsignedInt dimensions, class T> void AbstractBasicFeature<dimensions, T>::markDirty() {}
template<UnsignedInt dimensions, class T> void AbstractFeature<dimensions, T>::clean(const typename DimensionTraits<dimensions, T>::MatrixType&) {} template<UnsignedInt dimensions, class T> void AbstractBasicFeature<dimensions, T>::clean(const typename DimensionTraits<dimensions, T>::MatrixType&) {}
template<UnsignedInt dimensions, class T> void AbstractFeature<dimensions, T>::cleanInverted(const typename DimensionTraits<dimensions, T>::MatrixType&) {} template<UnsignedInt dimensions, class T> void AbstractBasicFeature<dimensions, T>::cleanInverted(const typename DimensionTraits<dimensions, T>::MatrixType&) {}
}} }}

64
src/SceneGraph/AbstractGroupedFeature.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::AbstractGroupedFeature, alias Magnum::SceneGraph::AbstractGroupedFeature2D, Magnum::SceneGraph::AbstractGroupedFeature3D * @brief Class Magnum::SceneGraph::AbstractBasicGroupedFeature, alias Magnum::SceneGraph::AbstractGroupedFeature2D, Magnum::SceneGraph::AbstractGroupedFeature3D
*/ */
#include <vector> #include <vector>
@ -38,12 +38,12 @@ namespace Magnum { namespace SceneGraph {
/** /**
@brief Base for grouped features @brief Base for grouped features
Used together with FeatureGroup. Used together with BasicFeatureGroup.
@section AbstractGroupedFeature-subclassing Subclassing @section AbstractGroupedFeature-subclassing Subclassing
Usage is via subclassing the feature using [CRTP](http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern) Usage is via subclassing the feature using [CRTP](http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)
and typedef'ing FeatureGroup to accept only given type, e.g.: and typedef'ing BasicFeatureGroup to accept only given type, e.g.:
@code @code
class Drawable: public SceneGraph::AbstractGroupedFeature3D<Drawable> { class Drawable: public SceneGraph::AbstractGroupedFeature3D<Drawable> {
// ... // ...
@ -59,19 +59,15 @@ For other specializations (e.g. using Double type) you have to use
AbstractGroupedFeature.hpp implementation file to avoid linker errors. See also AbstractGroupedFeature.hpp implementation file to avoid linker errors. See also
@ref compilation-speedup-hpp for more information. @ref compilation-speedup-hpp for more information.
- @ref AbstractFeatureGroup "AbstractFeatureGroup<2, Float>" - @ref AbstractBasicFeatureGroup "AbstractBasicFeatureGroup<2, Float>"
- @ref AbstractFeatureGroup "AbstractFeatureGroup<3, Float>" - @ref AbstractBasicFeatureGroup "AbstractBasicFeatureGroup<3, Float>"
@see @ref scenegraph, AbstractGroupedFeature2D, AbstractGroupedFeature3D, @see @ref AbstractGroupedFeature2D, @ref AbstractGroupedFeature3D,
FeatureGroup, FeatureGroup2D, FeatureGroup3D @ref scenegraph, @ref BasicFeatureGroup, @ref FeatureGroup2D,
@ref FeatureGroup3D
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<UnsignedInt dimensions, class Derived, class T> class AbstractBasicGroupedFeature: public AbstractBasicFeature<dimensions, T> {
template<UnsignedInt dimensions, class Derived, class T> friend class BasicFeatureGroup<dimensions, Derived, T>;
#else
template<UnsignedInt dimensions, class Derived, class T = Float>
#endif
class AbstractGroupedFeature: public AbstractFeature<dimensions, T> {
friend class FeatureGroup<dimensions, Derived, T>;
public: public:
/** /**
@ -82,7 +78,7 @@ class AbstractGroupedFeature: public AbstractFeature<dimensions, T> {
* Adds the feature to the object and to group, if specified. * Adds the feature to the object and to group, if specified.
* @see FeatureGroup::add() * @see FeatureGroup::add()
*/ */
explicit AbstractGroupedFeature(AbstractObject<dimensions, T>* object, FeatureGroup<dimensions, Derived, T>* group = nullptr): AbstractFeature<dimensions, T>(object), _group(nullptr) { explicit AbstractBasicGroupedFeature(AbstractBasicObject<dimensions, T>* object, BasicFeatureGroup<dimensions, Derived, T>* group = nullptr): AbstractBasicFeature<dimensions, T>(object), _group(nullptr) {
if(group) group->add(static_cast<Derived*>(this)); if(group) group->add(static_cast<Derived*>(this));
} }
@ -92,56 +88,44 @@ class AbstractGroupedFeature: public AbstractFeature<dimensions, T> {
* Removes the feature from object and from group, if it belongs to * Removes the feature from object and from group, if it belongs to
* any. * any.
*/ */
~AbstractGroupedFeature() { ~AbstractBasicGroupedFeature() {
if(_group) _group->remove(static_cast<Derived*>(this)); if(_group) _group->remove(static_cast<Derived*>(this));
} }
/** @brief Group this feature belongs to */ /** @brief Group this feature belongs to */
FeatureGroup<dimensions, Derived, T>* group() { BasicFeatureGroup<dimensions, Derived, T>* group() {
return _group; return _group;
} }
/** @overload */ /** @overload */
const FeatureGroup<dimensions, Derived, T>* group() const { const BasicFeatureGroup<dimensions, Derived, T>* group() const {
return _group; return _group;
} }
private: private:
FeatureGroup<dimensions, Derived, T>* _group; BasicFeatureGroup<dimensions, Derived, T>* _group;
}; };
#ifndef CORRADE_GCC46_COMPATIBILITY #ifndef CORRADE_GCC46_COMPATIBILITY
/** /**
@brief Base for two-dimensional grouped features @brief Base grouped feature for two-dimensional float scenes
Convenience alternative to <tt>%AbstractGroupedFeature<2, Derived, T></tt>. See Convenience alternative to <tt>%AbstractBasicGroupedFeature<2, Derived, Float></tt>.
AbstractGroupedFeature for more information. @note Not available on GCC < 4.7. Use <tt>%AbstractBasicGroupedFeature<2, Derived, Float></tt>
@note Not available on GCC < 4.7. Use <tt>%AbstractGroupedFeature<2, Derived, T></tt>
instead. instead.
@see AbstractGroupedFeature3D @see @ref AbstractGroupedFeature3D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT template<class Derived> using AbstractGroupedFeature2D = AbstractBasicGroupedFeature<2, Derived, Float>;
template<class Derived, class T = Float>
#else
template<class Derived, class T>
#endif
using AbstractGroupedFeature2D = AbstractGroupedFeature<2, Derived, T>;
/** /**
@brief Base for three-dimensional grouped features @brief Base for three-dimensional grouped features
Convenience alternative to <tt>%AbstractGroupedFeature<3, Derived, T></tt>. See Convenience alternative to <tt>%AbstractBasicGroupedFeature<3, Derived, Float></tt>.
AbstractGroupedFeature for more information. @note Not available on GCC < 4.7. Use <tt>%AbstractBasicGroupedFeature<3, Derived, Float></tt>
@note Not available on GCC < 4.7. Use <tt>%AbstractGroupedFeature<3, Derived, T></tt>
instead. instead.
@see AbstractGroupedFeature2D @see @ref AbstractGroupedFeature2D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT template<class Derived> using AbstractGroupedFeature3D = AbstractBasicGroupedFeature<3, Derived, Float>;
template<class Derived, class T = Float>
#else
template<class Derived, class T>
#endif
using AbstractGroupedFeature3D = AbstractGroupedFeature<3, Derived, T>;
#endif #endif
}} }}

81
src/SceneGraph/AbstractObject.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::AbstractObject, alias Magnum::SceneGraph::AbstractObject2D, Magnum::SceneGraph::AbstractObject3D * @brief Class Magnum::SceneGraph::AbstractBasicObject, alias Magnum::SceneGraph::AbstractObject2D, Magnum::SceneGraph::AbstractObject3D
*/ */
#include <vector> #include <vector>
@ -54,61 +54,60 @@ for(AbstractFeature* feature = o->firstFeature(); feature; feature = feature->ne
} }
@endcode @endcode
@see AbstractObject2D, AbstractObject3D @see @ref AbstractObject2D, @ref AbstractObject3D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT AbstractBasicObject
template<UnsignedInt dimensions, class T = Float> class AbstractObject #ifndef DOXYGEN_GENERATING_OUTPUT
#else : private Containers::LinkedList<AbstractBasicFeature<dimensions, T>>
template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT AbstractObject: private Containers::LinkedList<AbstractFeature<dimensions, T>> #endif
#endif
{ {
friend class Containers::LinkedList<AbstractFeature<dimensions, T>>; friend class Containers::LinkedList<AbstractBasicFeature<dimensions, T>>;
friend class Containers::LinkedListItem<AbstractFeature<dimensions, T>, AbstractObject<dimensions, T>>; friend class Containers::LinkedListItem<AbstractBasicFeature<dimensions, T>, AbstractBasicObject<dimensions, T>>;
friend class AbstractFeature<dimensions, T>; friend class AbstractBasicFeature<dimensions, T>;
public: public:
/** @brief Matrix type */ /** @brief Matrix type */
typedef typename DimensionTraits<dimensions, T>::MatrixType MatrixType; typedef typename DimensionTraits<dimensions, T>::MatrixType MatrixType;
/** @brief Feature object type */ /** @brief Feature object type */
typedef AbstractFeature<dimensions, T> FeatureType; typedef AbstractBasicFeature<dimensions, T> FeatureType;
explicit AbstractObject(); explicit AbstractBasicObject();
virtual ~AbstractObject(); virtual ~AbstractBasicObject();
/** @brief Whether this object has features */ /** @brief Whether this object has features */
bool hasFeatures() const { bool hasFeatures() const {
return !Containers::LinkedList<AbstractFeature<dimensions, T>>::isEmpty(); return !Containers::LinkedList<AbstractBasicFeature<dimensions, T>>::isEmpty();
} }
/** @brief First object feature or `nullptr`, if this object has no features */ /** @brief First object feature or `nullptr`, if this object has no features */
FeatureType* firstFeature() { FeatureType* firstFeature() {
return Containers::LinkedList<AbstractFeature<dimensions, T>>::first(); return Containers::LinkedList<AbstractBasicFeature<dimensions, T>>::first();
} }
/** @overload */ /** @overload */
const FeatureType* firstFeature() const { const FeatureType* firstFeature() const {
return Containers::LinkedList<AbstractFeature<dimensions, T>>::first(); return Containers::LinkedList<AbstractBasicFeature<dimensions, T>>::first();
} }
/** @brief Last object feature or `nullptr`, if this object has no features */ /** @brief Last object feature or `nullptr`, if this object has no features */
FeatureType* lastFeature() { FeatureType* lastFeature() {
return Containers::LinkedList<AbstractFeature<dimensions, T>>::last(); return Containers::LinkedList<AbstractBasicFeature<dimensions, T>>::last();
} }
/** @overload */ /** @overload */
const FeatureType* lastFeature() const { const FeatureType* lastFeature() const {
return Containers::LinkedList<AbstractFeature<dimensions, T>>::last(); return Containers::LinkedList<AbstractBasicFeature<dimensions, T>>::last();
} }
/** /**
* @brief %Scene * @brief %Scene
* @return %Scene or `nullptr`, if the object is not part of any scene. * @return %Scene or `nullptr`, if the object is not part of any scene.
*/ */
AbstractObject<dimensions, T>* scene() { return doScene(); } AbstractBasicObject<dimensions, T>* scene() { return doScene(); }
/** @overload */ /** @overload */
const AbstractObject<dimensions, T>* scene() const { return doScene(); } const AbstractBasicObject<dimensions, T>* scene() const { return doScene(); }
/** @{ @name Object transformation */ /** @{ @name Object transformation */
@ -139,7 +138,7 @@ template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT Abstrac
* Object type, use typesafe Object::transformationMatrices() when * Object type, use typesafe Object::transformationMatrices() when
* possible. * possible.
*/ */
std::vector<MatrixType> transformationMatrices(const std::vector<AbstractObject<dimensions, T>*>& objects, const MatrixType& initialTransformationMatrix = MatrixType()) const { std::vector<MatrixType> transformationMatrices(const std::vector<AbstractBasicObject<dimensions, T>*>& objects, const MatrixType& initialTransformationMatrix = MatrixType()) const {
return doTransformationMatrices(objects, initialTransformationMatrix); return doTransformationMatrices(objects, initialTransformationMatrix);
} }
@ -158,7 +157,7 @@ template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT Abstrac
* @warning This function cannot check if all objects are of the same * @warning This function cannot check if all objects are of the same
* Object type, use typesafe Object::setClean() when possible. * Object type, use typesafe Object::setClean() when possible.
*/ */
static void setClean(const std::vector<AbstractObject<dimensions, T>*>& objects) { static void setClean(const std::vector<AbstractBasicObject<dimensions, T>*>& objects) {
if(objects.empty()) return; if(objects.empty()) return;
objects.front()->doSetClean(objects); objects.front()->doSetClean(objects);
} }
@ -204,50 +203,32 @@ template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT Abstrac
/*@}*/ /*@}*/
private: private:
virtual AbstractObject<dimensions, T>* doScene() = 0; virtual AbstractBasicObject<dimensions, T>* doScene() = 0;
virtual const AbstractObject<dimensions, T>* doScene() const = 0; virtual const AbstractBasicObject<dimensions, T>* doScene() const = 0;
virtual MatrixType doTransformationMatrix() const = 0; virtual MatrixType doTransformationMatrix() const = 0;
virtual MatrixType doAbsoluteTransformationMatrix() const = 0; virtual MatrixType doAbsoluteTransformationMatrix() const = 0;
virtual std::vector<MatrixType> doTransformationMatrices(const std::vector<AbstractObject<dimensions, T>*>& objects, const MatrixType& initialTransformationMatrix) const = 0; virtual std::vector<MatrixType> doTransformationMatrices(const std::vector<AbstractBasicObject<dimensions, T>*>& objects, const MatrixType& initialTransformationMatrix) const = 0;
virtual bool doIsDirty() const = 0; virtual bool doIsDirty() const = 0;
virtual void doSetDirty() = 0; virtual void doSetDirty() = 0;
virtual void doSetClean() = 0; virtual void doSetClean() = 0;
virtual void doSetClean(const std::vector<AbstractObject<dimensions, T>*>& objects) = 0; virtual void doSetClean(const std::vector<AbstractBasicObject<dimensions, T>*>& objects) = 0;
}; };
#ifndef CORRADE_GCC46_COMPATIBILITY
/** /**
@brief Base for two-dimensional objects @brief Base object for two-dimensional float scenes
Convenience alternative to <tt>%AbstractObject<2, T></tt>. See AbstractObject @see @ref AbstractObject3D
for more information.
@note Not available on GCC < 4.7. Use <tt>%AbstractObject<2, T></tt> instead.
@see AbstractObject3D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT typedef AbstractBasicObject<2, Float> AbstractObject2D;
template<class T = Float>
#else
template<class T>
#endif
using AbstractObject2D = AbstractObject<2, T>;
/** /**
@brief Base for three-dimensional objects @brief Base object for three-dimensional float scenes
Convenience alternative to <tt>%AbstractObject<3, T></tt>. See AbstractObject @see @ref AbstractObject2D
for more information.
@note Not available on GCC < 4.7. Use <tt>%AbstractObject<3, T></tt> instead.
@see AbstractObject2D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT typedef AbstractBasicObject<3, Float> AbstractObject3D;
template<class T = Float>
#else
template<class T>
#endif
using AbstractObject3D = AbstractObject<3, T>;
#endif
}} }}

50
src/SceneGraph/AbstractTransformation.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::AbstractTransformation, enum Magnum::SceneGraph::TransformationType, alias Magnum::SceneGraph::AbstractTransformation2D, Magnum::SceneGraph::AbstractTransformation3D * @brief Class Magnum::SceneGraph::AbstractBasicTransformation, enum Magnum::SceneGraph::TransformationType, typedef Magnum::SceneGraph::AbstractTransformation2D, Magnum::SceneGraph::AbstractTransformation3D
*/ */
#include <vector> #include <vector>
@ -50,14 +50,10 @@ When subclassing, you have to:
- Implement all members listed in **Subclass implementation** group above - Implement all members listed in **Subclass implementation** group above
- Provide implicit (parameterless) constructor - Provide implicit (parameterless) constructor
@see @ref scenegraph, AbstractTransformation2D, AbstractTransformation3D @see @ref AbstractTransformation2D, @ref AbstractTransformation3D,
@ref scenegraph
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT AbstractBasicTransformation {
template<UnsignedInt dimensions, class T>
#else
template<UnsignedInt dimensions, class T = Float>
#endif
class MAGNUM_SCENEGRAPH_EXPORT AbstractTransformation {
public: public:
/** @brief Underlying floating-point type */ /** @brief Underlying floating-point type */
typedef T Type; typedef T Type;
@ -65,8 +61,8 @@ class MAGNUM_SCENEGRAPH_EXPORT AbstractTransformation {
/** @brief Dimension count */ /** @brief Dimension count */
static const UnsignedInt Dimensions = dimensions; static const UnsignedInt Dimensions = dimensions;
explicit AbstractTransformation(); explicit AbstractBasicTransformation();
virtual ~AbstractTransformation() = 0; virtual ~AbstractBasicTransformation() = 0;
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
/** /**
@ -142,7 +138,7 @@ class MAGNUM_SCENEGRAPH_EXPORT AbstractTransformation {
* @brief Reset object transformation * @brief Reset object transformation
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
*/ */
AbstractTransformation<dimensions, T>* resetTransformation() { AbstractBasicTransformation<dimensions, T>* resetTransformation() {
doResetTransformation(); doResetTransformation();
return this; return this;
} }
@ -165,39 +161,19 @@ enum class TransformationType: UnsignedByte {
Local = 0x01 Local = 0x01
}; };
#ifndef CORRADE_GCC46_COMPATIBILITY
/** /**
@brief Base for two-dimensional transformations @brief Base transformation for two-dimensional float scenes
Convenience alternative to <tt>%AbstractTransformation<2, T></tt>. See @see @ref AbstractTransformation3D
AbstractTransformation for more information.
@note Not available on GCC < 4.7. Use <tt>%AbstractTransformation<2, T></tt>
instead.
@see AbstractTransformation3D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT typedef AbstractBasicTransformation<2, Float> AbstractTransformation2D;
template<class T = Float>
#else
template<class T>
#endif
using AbstractTransformation2D = AbstractTransformation<2, T>;
/** /**
@brief Base for three-dimensional transformations @brief Base transformation for three-dimensional float scenes
Convenience alternative to <tt>%AbstractTransformation<3, T></tt>. See @see @ref AbstractTransformation2D
AbstractTransformation for more information.
@note Not available on GCC < 4.7. Use <tt>%AbstractTransformation<3, T></tt>
instead.
@see AbstractTransformation2D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT typedef AbstractBasicTransformation<3, Float> AbstractTransformation3D;
template<class T = Float>
#else
template<class T>
#endif
using AbstractTransformation3D = AbstractTransformation<3, T>;
#endif
}} }}

32
src/SceneGraph/AbstractTranslationRotation2D.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::AbstractTranslationRotation2D * @brief Class Magnum::SceneGraph::AbstractBasicTranslationRotation2D, typedef Magnum::SceneGraph::AbstractTranslationRotation2D
*/ */
#include "AbstractTransformation.h" #include "AbstractTransformation.h"
@ -33,18 +33,13 @@
namespace Magnum { namespace SceneGraph { namespace Magnum { namespace SceneGraph {
/** /**
@brief Base for two-dimensional transformations supporting translation and rotation @brief Base translation for two-dimensional scenes supporting translation and rotation
@see @ref scenegraph, AbstractTranslationRotation3D @see @ref AbstractTranslationRotation2D, @ref scenegraph, @ref AbstractBasicTranslationRotation3D
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<class T> class AbstractBasicTranslationRotation2D: public AbstractBasicTransformation<2, T> {
template<class T>
#else
template<class T = Float>
#endif
class AbstractTranslationRotation2D: public AbstractTransformation<2, T> {
public: public:
explicit AbstractTranslationRotation2D(); explicit AbstractBasicTranslationRotation2D();
/** /**
* @brief Translate object * @brief Translate object
@ -54,7 +49,7 @@ class AbstractTranslationRotation2D: public AbstractTransformation<2, T> {
* *
* @see Vector2::xAxis(), Vector2::yAxis() * @see Vector2::xAxis(), Vector2::yAxis()
*/ */
AbstractTranslationRotation2D<T>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) { AbstractBasicTranslationRotation2D<T>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
doTranslate(vector, type); doTranslate(vector, type);
return this; return this;
} }
@ -65,15 +60,15 @@ class AbstractTranslationRotation2D: public AbstractTransformation<2, T> {
* @param type Transformation type * @param type Transformation type
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
*/ */
AbstractTranslationRotation2D<T>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { AbstractBasicTranslationRotation2D<T>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
doRotate(angle, type); doRotate(angle, type);
return this; return this;
} }
/* Overloads to remove WTF-factor from method chaining order */ /* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
AbstractTranslationRotation2D<T>* resetTransformation() { AbstractBasicTranslationRotation2D<T>* resetTransformation() {
AbstractTransformation<2, T>::resetTransformation(); AbstractBasicTransformation<2, T>::resetTransformation();
return this; return this;
} }
#endif #endif
@ -90,7 +85,14 @@ class AbstractTranslationRotation2D: public AbstractTransformation<2, T> {
virtual void doRotate(Math::Rad<T> angle, TransformationType type) = 0; virtual void doRotate(Math::Rad<T> angle, TransformationType type) = 0;
}; };
template<class T> inline AbstractTranslationRotation2D<T>::AbstractTranslationRotation2D() = default; template<class T> inline AbstractBasicTranslationRotation2D<T>::AbstractBasicTranslationRotation2D() = default;
/**
@brief Base transformation for two-dimensional float scenes supporting translation and rotation
@see @ref AbstractTranslationRotation3D
*/
typedef AbstractBasicTranslationRotation2D<Float> AbstractTranslationRotation2D;
}} }}

38
src/SceneGraph/AbstractTranslationRotation3D.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::AbstractTranslationRotation3D * @brief Class Magnum::SceneGraph::AbstractBasicTranslationRotation3D, typedef Magnum::SceneGraph::AbstractTranslationRotation3D
*/ */
#include "AbstractTransformation.h" #include "AbstractTransformation.h"
@ -34,18 +34,13 @@
namespace Magnum { namespace SceneGraph { namespace Magnum { namespace SceneGraph {
/** /**
@brief Base for three-dimensional transformations supporting translation and rotation @brief Base translation for three-dimensional scenes supporting translation and rotation
@see @ref scenegraph, AbstractTranslationRotation2D @see @ref AbstractTranslationRotation3D @ref scenegraph, @ref AbstractBasicTranslationRotation2D
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<class T> class AbstractBasicTranslationRotation3D: public AbstractBasicTransformation<3, T> {
template<class T>
#else
template<class T = Float>
#endif
class AbstractTranslationRotation3D: public AbstractTransformation<3, T> {
public: public:
explicit AbstractTranslationRotation3D(); explicit AbstractBasicTranslationRotation3D();
/** /**
* @brief Translate object * @brief Translate object
@ -55,7 +50,7 @@ class AbstractTranslationRotation3D: public AbstractTransformation<3, T> {
* *
* @see Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis() * @see Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis()
*/ */
AbstractTranslationRotation3D<T>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) { AbstractBasicTranslationRotation3D<T>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
doTranslate(vector, type); doTranslate(vector, type);
return this; return this;
} }
@ -70,7 +65,7 @@ class AbstractTranslationRotation3D: public AbstractTransformation<3, T> {
* @see rotateX(), rotateY(), rotateZ(), Vector3::xAxis(), * @see rotateX(), rotateY(), rotateZ(), Vector3::xAxis(),
* Vector3::yAxis(), Vector3::zAxis() * Vector3::yAxis(), Vector3::zAxis()
*/ */
AbstractTranslationRotation3D<T>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) { AbstractBasicTranslationRotation3D<T>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
doRotate(angle, normalizedAxis, type); doRotate(angle, normalizedAxis, type);
return this; return this;
} }
@ -84,7 +79,7 @@ class AbstractTranslationRotation3D: public AbstractTransformation<3, T> {
* In some implementations faster than calling * In some implementations faster than calling
* `rotate(angle, Vector3::xAxis())`. * `rotate(angle, Vector3::xAxis())`.
*/ */
AbstractTranslationRotation3D<T>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { AbstractBasicTranslationRotation3D<T>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
doRotateX(angle, type); doRotateX(angle, type);
return this; return this;
} }
@ -98,7 +93,7 @@ class AbstractTranslationRotation3D: public AbstractTransformation<3, T> {
* In some implementations faster than calling * In some implementations faster than calling
* `rotate(angle, Vector3::yAxis())`. * `rotate(angle, Vector3::yAxis())`.
*/ */
AbstractTranslationRotation3D<T>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { AbstractBasicTranslationRotation3D<T>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
doRotateX(angle, type); doRotateX(angle, type);
return this; return this;
} }
@ -112,15 +107,15 @@ class AbstractTranslationRotation3D: public AbstractTransformation<3, T> {
* In some implementations faster than calling * In some implementations faster than calling
* `rotate(angle, Vector3::zAxis())`. * `rotate(angle, Vector3::zAxis())`.
*/ */
AbstractTranslationRotation3D<T>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { AbstractBasicTranslationRotation3D<T>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
doRotateZ(angle, type); doRotateZ(angle, type);
return this; return this;
} }
/* Overloads to remove WTF-factor from method chaining order */ /* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
AbstractTranslationRotation3D<T>* resetTransformation() { AbstractBasicTranslationRotation3D<T>* resetTransformation() {
AbstractTransformation<3, T>::resetTransformation(); AbstractBasicTransformation<3, T>::resetTransformation();
return this; return this;
} }
#endif #endif
@ -164,7 +159,14 @@ class AbstractTranslationRotation3D: public AbstractTransformation<3, T> {
} }
}; };
template<class T> inline AbstractTranslationRotation3D<T>::AbstractTranslationRotation3D() = default; template<class T> inline AbstractBasicTranslationRotation3D<T>::AbstractBasicTranslationRotation3D() = default;
/**
@brief Base transformation for three-dimensional float scenes supporting translation and rotation
@see @ref AbstractTranslationRotation2D
*/
typedef AbstractBasicTranslationRotation3D<Float> AbstractTranslationRotation3D;
}} }}

38
src/SceneGraph/AbstractTranslationRotationScaling2D.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::AbstractTranslationRotationScaling2D * @brief Class Magnum::SceneGraph::AbstractBasicTranslationRotationScaling2D, typedef Magnum::SceneGraph::AbstractTranslationRotationScaling2D
*/ */
#include "AbstractTranslationRotation2D.h" #include "AbstractTranslationRotation2D.h"
@ -33,18 +33,13 @@
namespace Magnum { namespace SceneGraph { namespace Magnum { namespace SceneGraph {
/** /**
@brief Base for two-dimensional transformations supporting translation, rotation and scaling @brief Base transformation for two-dimensional scenes supporting translation, rotation and scaling
@see @ref scenegraph, AbstractTranslationRotationScaling2D @see @ref AbstractTranslationRotationScaling2D, @ref scenegraph, @ref AbstractBasicTranslationRotationScaling2D
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<class T> class AbstractBasicTranslationRotationScaling2D: public AbstractBasicTranslationRotation2D<T> {
template<class T>
#else
template<class T = Float>
#endif
class AbstractTranslationRotationScaling2D: public AbstractTranslationRotation2D<T> {
public: public:
explicit AbstractTranslationRotationScaling2D(); explicit AbstractBasicTranslationRotationScaling2D();
/** /**
* @brief Scale object * @brief Scale object
@ -54,23 +49,23 @@ class AbstractTranslationRotationScaling2D: public AbstractTranslationRotation2D
* *
* @see Vector2::xScale(), Vector2::yScale() * @see Vector2::xScale(), Vector2::yScale()
*/ */
AbstractTranslationRotationScaling2D<T>* scale(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) { AbstractBasicTranslationRotationScaling2D<T>* scale(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
doScale(vector, type); doScale(vector, type);
return this; return this;
} }
/* Overloads to remove WTF-factor from method chaining order */ /* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
AbstractTranslationRotationScaling2D<T>* resetTransformation() { AbstractBasicTranslationRotationScaling2D<T>* resetTransformation() {
AbstractTranslationRotation2D<T>::resetTransformation(); AbstractBasicTranslationRotation2D<T>::resetTransformation();
return this; return this;
} }
AbstractTranslationRotationScaling2D<T>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) { AbstractBasicTranslationRotationScaling2D<T>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
AbstractTranslationRotation2D<T>::translate(vector, type); AbstractBasicTranslationRotation2D<T>::translate(vector, type);
return this; return this;
} }
AbstractTranslationRotationScaling2D<T>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { AbstractBasicTranslationRotationScaling2D<T>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractTranslationRotation2D<T>::rotate(angle, type); AbstractBasicTranslationRotation2D<T>::rotate(angle, type);
return this; return this;
} }
#endif #endif
@ -84,7 +79,14 @@ class AbstractTranslationRotationScaling2D: public AbstractTranslationRotation2D
virtual void doScale(const Math::Vector2<T>& vector, TransformationType type) = 0; virtual void doScale(const Math::Vector2<T>& vector, TransformationType type) = 0;
}; };
template<class T> inline AbstractTranslationRotationScaling2D<T>::AbstractTranslationRotationScaling2D() = default; template<class T> inline AbstractBasicTranslationRotationScaling2D<T>::AbstractBasicTranslationRotationScaling2D() = default;
/**
@brief Base transformation for two-dimensional float scenes supporting translation, rotation and scaling
@see @ref AbstractTranslationRotationScaling3D
*/
typedef AbstractBasicTranslationRotationScaling2D<Float> AbstractTranslationRotationScaling2D;
}} }}

48
src/SceneGraph/AbstractTranslationRotationScaling3D.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::AbstractTranslationRotationScaling3D * @brief Class Magnum::SceneGraph::AbstractBasicTranslationRotationScaling3D, typedef Magnum::SceneGraph::AbstractTranslationRotationScaling3D
*/ */
#include "AbstractTranslationRotation3D.h" #include "AbstractTranslationRotation3D.h"
@ -35,16 +35,11 @@ namespace Magnum { namespace SceneGraph {
/** /**
@brief Base for three-dimensional transformations supporting translation, rotation and scaling @brief Base for three-dimensional transformations supporting translation, rotation and scaling
@see @ref scenegraph, AbstractTranslationRotationScaling2D @see @ref AbstractTranslationRotationScaling3D, @ref scenegraph, @ref AbstractBasicTranslationRotationScaling2D
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<class T> class AbstractBasicTranslationRotationScaling3D: public AbstractBasicTranslationRotation3D<T> {
template<class T>
#else
template<class T = Float>
#endif
class AbstractTranslationRotationScaling3D: public AbstractTranslationRotation3D<T> {
public: public:
explicit AbstractTranslationRotationScaling3D(); explicit AbstractBasicTranslationRotationScaling3D();
/** /**
* @brief Scale object * @brief Scale object
@ -54,35 +49,35 @@ class AbstractTranslationRotationScaling3D: public AbstractTranslationRotation3D
* *
* @see Vector3::xScale(), Vector3::yScale(), Vector3::zScale() * @see Vector3::xScale(), Vector3::yScale(), Vector3::zScale()
*/ */
AbstractTranslationRotationScaling3D<T>* scale(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) { AbstractBasicTranslationRotationScaling3D<T>* scale(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
doScale(vector, type); doScale(vector, type);
return this; return this;
} }
/* Overloads to remove WTF-factor from method chaining order */ /* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
AbstractTranslationRotationScaling3D<T>* resetTransformation() { AbstractBasicTranslationRotationScaling3D<T>* resetTransformation() {
AbstractTranslationRotation3D<T>::resetTransformation(); AbstractBasicTranslationRotation3D<T>::resetTransformation();
return this; return this;
} }
AbstractTranslationRotationScaling3D<T>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) { AbstractBasicTranslationRotationScaling3D<T>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
AbstractTranslationRotation3D<T>::translate(vector, type); AbstractBasicTranslationRotation3D<T>::translate(vector, type);
return this; return this;
} }
AbstractTranslationRotationScaling3D<T>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) { AbstractBasicTranslationRotationScaling3D<T>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
AbstractTranslationRotation3D<T>::rotate(angle, normalizedAxis, type); AbstractBasicTranslationRotation3D<T>::rotate(angle, normalizedAxis, type);
return this; return this;
} }
AbstractTranslationRotationScaling3D<T>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { AbstractBasicTranslationRotationScaling3D<T>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractTranslationRotation3D<T>::rotateX(angle, type); AbstractBasicTranslationRotation3D<T>::rotateX(angle, type);
return this; return this;
} }
AbstractTranslationRotationScaling3D<T>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { AbstractBasicTranslationRotationScaling3D<T>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractTranslationRotation3D<T>::rotateY(angle, type); AbstractBasicTranslationRotation3D<T>::rotateY(angle, type);
return this; return this;
} }
AbstractTranslationRotationScaling3D<T>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { AbstractBasicTranslationRotationScaling3D<T>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractTranslationRotation3D<T>::rotateZ(angle, type); AbstractBasicTranslationRotation3D<T>::rotateZ(angle, type);
return this; return this;
} }
#endif #endif
@ -96,7 +91,14 @@ class AbstractTranslationRotationScaling3D: public AbstractTranslationRotation3D
virtual void doScale(const Math::Vector3<T>& vector, TransformationType type) = 0; virtual void doScale(const Math::Vector3<T>& vector, TransformationType type) = 0;
}; };
template<class T> inline AbstractTranslationRotationScaling3D<T>::AbstractTranslationRotationScaling3D() = default; template<class T> inline AbstractBasicTranslationRotationScaling3D<T>::AbstractBasicTranslationRotationScaling3D() = default;
/**
@brief Base transformation for three-dimensional float scenes supporting translation, rotation and scaling
@see @ref AbstractTranslationRotationScaling2D
*/
typedef AbstractBasicTranslationRotationScaling3D<Float> AbstractTranslationRotationScaling3D;
}} }}

8
src/SceneGraph/Animable.cpp

@ -27,10 +27,10 @@
namespace Magnum { namespace SceneGraph { namespace Magnum { namespace SceneGraph {
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
template class MAGNUM_SCENEGRAPH_EXPORT Animable<2, Float>; template class MAGNUM_SCENEGRAPH_EXPORT BasicAnimable<2, Float>;
template class MAGNUM_SCENEGRAPH_EXPORT Animable<3, Float>; template class MAGNUM_SCENEGRAPH_EXPORT BasicAnimable<3, Float>;
template class MAGNUM_SCENEGRAPH_EXPORT AnimableGroup<2, Float>; template class MAGNUM_SCENEGRAPH_EXPORT BasicAnimableGroup<2, Float>;
template class MAGNUM_SCENEGRAPH_EXPORT AnimableGroup<3, Float>; template class MAGNUM_SCENEGRAPH_EXPORT BasicAnimableGroup<3, Float>;
#endif #endif
Debug operator<<(Debug debug, AnimationState value) { Debug operator<<(Debug debug, AnimationState value) {

111
src/SceneGraph/Animable.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::Animable, enum Magnum::SceneGraph::AnimationState * @brief Class Magnum::SceneGraph::BasicAnimable, typedef Magnum::SceneGraph::Animable2D, Magnum::SceneGraph::Animable3D, enum Magnum::SceneGraph::AnimationState
*/ */
#include "AbstractGroupedFeature.h" #include "AbstractGroupedFeature.h"
@ -37,7 +37,7 @@ namespace Magnum { namespace SceneGraph {
/** /**
@brief Animation state @brief Animation state
@see Animable::setState() @see BasicAnimable::setState()
*/ */
enum class AnimationState: UnsignedByte { enum class AnimationState: UnsignedByte {
/** /**
@ -56,7 +56,7 @@ enum class AnimationState: UnsignedByte {
Running Running
}; };
/** @debugoperator{Magnum::SceneGraph::Animable} */ /** @debugoperator{Magnum::SceneGraph::BasicAnimable} */
Debug MAGNUM_SCENEGRAPH_EXPORT operator<<(Debug debug, AnimationState value); Debug MAGNUM_SCENEGRAPH_EXPORT operator<<(Debug debug, AnimationState value);
/** /**
@ -73,12 +73,12 @@ animationStep(). You can do it conveniently using multiple inheritance (see
implement your animation, the function provides both absolute animation implement your animation, the function provides both absolute animation
time and time delta. Example: time and time delta. Example:
@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 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(Object* parent = nullptr, SceneGraph::DrawableGroup3D* group = nullptr): Object3D(parent), SceneGraph::Animable3D(this, group) {
setDuration(10.0f); setDuration(10.0f);
// ... // ...
} }
@ -90,22 +90,23 @@ class AnimableObject: public Object3D, SceneGraph::Animable3D<> {
@endcode @endcode
Then add the object to your scene and some animation group. You can also use Then add the object to your scene and some animation group. You can also use
AnimableGroup::add() and AnimableGroup::remove() instead of passing the group BasicAnimableGroup::add() and BasicAnimableGroup::remove() instead of passing
in the constructor. The animation is initially in stopped state and without the group in the constructor. The animation is initially in stopped state and
repeat, see setState(), setRepeated() and setRepeatCount() for more information. without repeat, see setState(), setRepeated() and setRepeatCount() for more
information.
@code @code
Scene3D scene; Scene3D scene;
SceneGraph::AnimableGroup3D<> animables; SceneGraph::AnimableGroup3D animables;
(new AnimableObject(&scene, &animables)) (new AnimableObject(&scene, &animables))
->setState(SceneGraph::AnimationState::Running); ->setState(SceneGraph::AnimationState::Running);
// ... // ...
@endcode @endcode
Animation step is performed by calling AnimableGroup::step() in your draw event Animation step is performed by calling BasicAnimableGroup::step() in your draw
implementation. The function expects absolute time from relative to some fixed event implementation. The function expects absolute time from relative to some
point in the past and time delta (i.e. duration of the frame). You can use fixed point in the past and time delta (i.e. duration of the frame). You can
Timeline for that, see its documentation for more information. use Timeline for that, see its documentation for more information.
@code @code
Timeline timeline; Timeline timeline;
timeline.start(); timeline.start();
@ -121,11 +122,11 @@ void MyApplication::drawEvent() {
@section Animable-performance Using animable groups to improve performance @section Animable-performance Using animable groups to improve performance
AnimableGroup is optimized for case when no animation is running - it just Animable group is optimized for case when no animation is running - it just
puts itself to rest and waits until some animation changes its state to puts itself to rest and waits until some animation changes its state to
@ref AnimationState "AnimationState::Running" again. If you put animations @ref AnimationState "AnimationState::Running" again. If you put animations
which are not pernamently running to separate group, they will not be always which are not pernamently running to separate group, they will not be always
traversed when calling AnimableGroup::step(), saving precious frame time. traversed when calling BasicAnimableGroup::step(), saving precious frame time.
@section Animable-explicit-specializations Explicit template specializations @section Animable-explicit-specializations Explicit template specializations
@ -134,18 +135,14 @@ For other specializations (e.g. using Double type) you have to use
Animable.hpp implementation file to avoid linker errors. See also Animable.hpp implementation file to avoid linker errors. See also
@ref compilation-speedup-hpp for more information. @ref compilation-speedup-hpp for more information.
- @ref Animable "Animable<2, Float>", @ref AnimableGroup "AnimableGroup<2, Float>" - @ref BasicAnimable "BasicAnimable<2, Float>", @ref BasicAnimableGroup "BasicAnimableGroup<2, Float>"
- @ref Animable "Animable<3, Float>", @ref AnimableGroup "AnimableGroup<3, Float>" - @ref BasicAnimable "BasicAnimable<3, Float>", @ref BasicAnimableGroup "BasicAnimableGroup<3, Float>"
@see @ref scenegraph, Animable2D, Animable3D, AnimableGroup2D, AnimableGroup3D @see @ref Animable2D, @ref Animable3D, @ref scenegraph, @ref AnimableGroup2D,
@ref AnimableGroup3D
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT BasicAnimable: public AbstractBasicGroupedFeature<dimensions, BasicAnimable<dimensions, T>, T> {
template<UnsignedInt dimensions, class T> friend class BasicAnimableGroup<dimensions, T>;
#else
template<UnsignedInt dimensions, class T = Float>
#endif
class MAGNUM_SCENEGRAPH_EXPORT Animable: public AbstractGroupedFeature<dimensions, Animable<dimensions, T>, T> {
friend class AnimableGroup<dimensions, T>;
public: public:
/** /**
@ -155,11 +152,11 @@ class MAGNUM_SCENEGRAPH_EXPORT Animable: public AbstractGroupedFeature<dimension
* *
* Creates stopped non-repeating animation with infinite duration, * Creates stopped non-repeating animation with infinite duration,
* adds the feature to the object and also to group, if specified. * adds the feature to the object and also to group, if specified.
* @see setDuration(), setState(), setRepeated(), AnimableGroup::add() * @see setDuration(), setState(), setRepeated(), BasicAnimableGroup::add()
*/ */
explicit Animable(AbstractObject<dimensions, T>* object, AnimableGroup<dimensions, T>* group = nullptr); explicit BasicAnimable(AbstractBasicObject<dimensions, T>* object, BasicAnimableGroup<dimensions, T>* group = nullptr);
~Animable(); ~BasicAnimable();
/** @brief Animation duration */ /** @brief Animation duration */
Float duration() const { return _duration; } Float duration() const { return _duration; }
@ -178,7 +175,7 @@ class MAGNUM_SCENEGRAPH_EXPORT Animable: public AbstractGroupedFeature<dimension
* @see animationStarted(), animationPaused(), animationResumed(), * @see animationStarted(), animationPaused(), animationResumed(),
* animationStopped() * animationStopped()
*/ */
Animable<dimensions, T>* setState(AnimationState state); BasicAnimable<dimensions, T>* setState(AnimationState state);
/** /**
* @brief Whether the animation is repeated * @brief Whether the animation is repeated
@ -194,7 +191,7 @@ class MAGNUM_SCENEGRAPH_EXPORT Animable: public AbstractGroupedFeature<dimension
* Default is `false`. * Default is `false`.
* @see setRepeatCount() * @see setRepeatCount()
*/ */
Animable<dimensions, T>* setRepeated(bool repeated) { BasicAnimable<dimensions, T>* setRepeated(bool repeated) {
_repeated = repeated; _repeated = repeated;
return this; return this;
} }
@ -214,7 +211,7 @@ class MAGNUM_SCENEGRAPH_EXPORT Animable: public AbstractGroupedFeature<dimension
* infinitely repeated animation. Default is `0`. * infinitely repeated animation. Default is `0`.
* @see setRepeated() * @see setRepeated()
*/ */
Animable<dimensions, T>* setRepeatCount(UnsignedShort count) { BasicAnimable<dimensions, T>* setRepeatCount(UnsignedShort count) {
_repeatCount = count; _repeatCount = count;
return this; return this;
} }
@ -224,8 +221,8 @@ class MAGNUM_SCENEGRAPH_EXPORT Animable: public AbstractGroupedFeature<dimension
* *
* If the animable doesn't belong to any group, returns `nullptr`. * If the animable doesn't belong to any group, returns `nullptr`.
*/ */
AnimableGroup<dimensions, T>* group(); BasicAnimableGroup<dimensions, T>* group();
const AnimableGroup<dimensions, T>* group() const; /**< @overload */ const BasicAnimableGroup<dimensions, T>* group() const; /**< @overload */
protected: protected:
/** /**
@ -236,7 +233,7 @@ class MAGNUM_SCENEGRAPH_EXPORT Animable: public AbstractGroupedFeature<dimension
* infinite non-repeating animation. Default is `0.0f`. * infinite non-repeating animation. Default is `0.0f`.
*/ */
/* Protected so only animation implementer can change it */ /* Protected so only animation implementer can change it */
Animable<dimensions, T>* setDuration(Float duration) { BasicAnimable<dimensions, T>* setDuration(Float duration) {
_duration = duration; _duration = duration;
return this; return this;
} }
@ -246,8 +243,8 @@ class MAGNUM_SCENEGRAPH_EXPORT Animable: public AbstractGroupedFeature<dimension
* @param time Time from start of the animation * @param time Time from start of the animation
* @param delta Time delta for current frame * @param delta Time delta for current frame
* *
* This function is periodically called from AnimableGroup::step() if * This function is periodically called from BasicAnimableGroup::step()
* the animation state is set to @ref AnimationState "AnimationState::Running". * if the animation state is set to @ref AnimationState "AnimationState::Running".
* After animation duration is exceeded and repeat is not enabled or * After animation duration is exceeded and repeat is not enabled or
* repeat count is exceeded, the animation state is set to * repeat count is exceeded, the animation state is set to
* @ref AnimationState "AnimationState::Stopped". * @ref AnimationState "AnimationState::Stopped".
@ -265,7 +262,7 @@ class MAGNUM_SCENEGRAPH_EXPORT Animable: public AbstractGroupedFeature<dimension
/** /**
* @brief Action on animation start * @brief Action on animation start
* *
* Called from AnimableGroup::step() when state is changed from * Called from BasicAnimableGroup::step() when state is changed from
* @ref AnimationState "AnimationState::Stopped" to * @ref AnimationState "AnimationState::Stopped" to
* @ref AnimationState "AnimationState::Running" and before first * @ref AnimationState "AnimationState::Running" and before first
* animationStep() is called. * animationStep() is called.
@ -279,7 +276,7 @@ class MAGNUM_SCENEGRAPH_EXPORT Animable: public AbstractGroupedFeature<dimension
/** /**
* @brief Action on animation pause * @brief Action on animation pause
* *
* Called from AnimableGroup::step() when state changes from * Called from BasicAnimableGroup::step() when state changes from
* @ref AnimationState "AnimationState::Running" to * @ref AnimationState "AnimationState::Running" to
* @ref AnimationState "AnimationState::Paused" and after last * @ref AnimationState "AnimationState::Paused" and after last
* animationStep() is called. * animationStep() is called.
@ -293,7 +290,7 @@ class MAGNUM_SCENEGRAPH_EXPORT Animable: public AbstractGroupedFeature<dimension
/** /**
* @brief Action on animation resume * @brief Action on animation resume
* *
* Called from AnimableGroup::step() when state changes from * Called from BasicAnimableGroup::step() when state changes from
* @ref AnimationState "AnimationState::Paused" to * @ref AnimationState "AnimationState::Paused" to
* @ref AnimationState "AnimationState::Running" and before first * @ref AnimationState "AnimationState::Running" and before first
* animationStep() is called. * animationStep() is called.
@ -307,7 +304,7 @@ class MAGNUM_SCENEGRAPH_EXPORT Animable: public AbstractGroupedFeature<dimension
/** /**
* @brief Action on animation stop * @brief Action on animation stop
* *
* Called from AnimableGroup::step() when state changes from either * Called from BasicAnimableGroup::step() when state changes from either
* @ref AnimationState "AnimationState::Running" or * @ref AnimationState "AnimationState::Running" or
* @ref AnimationState "AnimationState::Paused" to * @ref AnimationState "AnimationState::Paused" to
* @ref AnimationState "AnimationState::Stopped" and after last * @ref AnimationState "AnimationState::Stopped" and after last
@ -331,37 +328,19 @@ class MAGNUM_SCENEGRAPH_EXPORT Animable: public AbstractGroupedFeature<dimension
UnsignedShort repeats; UnsignedShort repeats;
}; };
#ifndef CORRADE_GCC46_COMPATIBILITY
/** /**
@brief Two-dimensional drawable @brief Animable for two-dimensional float scenes
Convenience alternative to <tt>%Animable<2, T></tt>. See Animable for more @see @ref Animable3D
information.
@note Not available on GCC < 4.7. Use <tt>%Animable<2, T></tt> instead.
@see Animable3D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT typedef BasicAnimable<2, Float> Animable2D;
template<class T = Float>
#else
template<class T>
#endif
using Animable2D = Animable<2, T>;
/** /**
@brief Three-dimensional animable @brief Animable for three-dimensional float scenes
Convenience alternative to <tt>%Animable<3, T></tt>. See Animable for more @see @ref Animable2D
information.
@note Not available on GCC < 4.7. Use <tt>%Animable<3, T></tt> instead.
@see Animable2D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT typedef BasicAnimable<3, Float> Animable3D;
template<class T = Float>
#else
template<class T>
#endif
using Animable3D = Animable<3, T>;
#endif
}} }}

22
src/SceneGraph/Animable.hpp

@ -35,11 +35,11 @@
namespace Magnum { namespace SceneGraph { namespace Magnum { namespace SceneGraph {
template<UnsignedInt dimensions, class T> Animable<dimensions, T>::Animable(AbstractObject<dimensions, T>* object, AnimableGroup<dimensions, T>* group): AbstractGroupedFeature<dimensions, Animable<dimensions, T>, T>(object, group), _duration(0.0f), startTime(std::numeric_limits<Float>::infinity()), pauseTime(-std::numeric_limits<Float>::infinity()), previousState(AnimationState::Stopped), currentState(AnimationState::Stopped), _repeated(false), _repeatCount(0), repeats(0) {} template<UnsignedInt dimensions, class T> BasicAnimable<dimensions, T>::BasicAnimable(AbstractBasicObject<dimensions, T>* object, BasicAnimableGroup<dimensions, T>* group): AbstractBasicGroupedFeature<dimensions, BasicAnimable<dimensions, T>, T>(object, group), _duration(0.0f), startTime(std::numeric_limits<Float>::infinity()), pauseTime(-std::numeric_limits<Float>::infinity()), previousState(AnimationState::Stopped), currentState(AnimationState::Stopped), _repeated(false), _repeatCount(0), repeats(0) {}
template<UnsignedInt dimensions, class T> Animable<dimensions, T>::~Animable() {} template<UnsignedInt dimensions, class T> BasicAnimable<dimensions, T>::~BasicAnimable() {}
template<UnsignedInt dimensions, class T> Animable<dimensions, T>* Animable<dimensions, T>::setState(AnimationState state) { template<UnsignedInt dimensions, class T> BasicAnimable<dimensions, T>* BasicAnimable<dimensions, T>::setState(AnimationState state) {
if(currentState == state) return this; if(currentState == state) return this;
/* Not allowed (for sanity) */ /* Not allowed (for sanity) */
@ -52,20 +52,20 @@ template<UnsignedInt dimensions, class T> Animable<dimensions, T>* Animable<dime
return this; return this;
} }
template<UnsignedInt dimensions, class T> AnimableGroup<dimensions, T>* Animable<dimensions, T>::group() { template<UnsignedInt dimensions, class T> BasicAnimableGroup<dimensions, T>* BasicAnimable<dimensions, T>::group() {
return static_cast<AnimableGroup<dimensions, T>*>(AbstractGroupedFeature<dimensions, Animable<dimensions, T>, T>::group()); return static_cast<BasicAnimableGroup<dimensions, T>*>(AbstractBasicGroupedFeature<dimensions, BasicAnimable<dimensions, T>, T>::group());
} }
template<UnsignedInt dimensions, class T> const AnimableGroup<dimensions, T>* Animable<dimensions, T>::group() const { template<UnsignedInt dimensions, class T> const BasicAnimableGroup<dimensions, T>* BasicAnimable<dimensions, T>::group() const {
return static_cast<const AnimableGroup<dimensions, T>*>(AbstractGroupedFeature<dimensions, Animable<dimensions, T>, T>::group()); return static_cast<const BasicAnimableGroup<dimensions, T>*>(AbstractBasicGroupedFeature<dimensions, BasicAnimable<dimensions, T>, T>::group());
} }
template<UnsignedInt dimensions, class T> void AnimableGroup<dimensions, T>::step(const Float time, const Float delta) { template<UnsignedInt dimensions, class T> void BasicAnimableGroup<dimensions, T>::step(const Float time, const Float delta) {
if(!_runningCount && !wakeUp) return; if(!_runningCount && !wakeUp) return;
wakeUp = false; wakeUp = false;
for(std::size_t i = 0; i != this->size(); ++i) { for(std::size_t i = 0; i != this->size(); ++i) {
Animable<dimensions, T>* animable = (*this)[i]; BasicAnimable<dimensions, T>* animable = (*this)[i];
/* The animation was stopped recently, just decrease count of running /* The animation was stopped recently, just decrease count of running
animations if the animation was running before */ animations if the animation was running before */
@ -126,9 +126,9 @@ template<UnsignedInt dimensions, class T> void AnimableGroup<dimensions, T>::ste
/* Animation is still running, perform animation step */ /* Animation is still running, perform animation step */
CORRADE_ASSERT(time-animable->startTime >= 0.0f, CORRADE_ASSERT(time-animable->startTime >= 0.0f,
"SceneGraph::AnimableGroup::step(): animation was started in future - probably wrong time passed", ); "SceneGraph::BasicAnimableGroup::step(): animation was started in future - probably wrong time passed", );
CORRADE_ASSERT(delta >= 0.0f, CORRADE_ASSERT(delta >= 0.0f,
"SceneGraph::AnimableGroup::step(): negative delta passed", ); "SceneGraph::BasicAnimableGroup::step(): negative delta passed", );
animable->animationStep(time - animable->startTime, delta); animable->animationStep(time - animable->startTime, delta);
} }

47
src/SceneGraph/AnimableGroup.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::AnimableGroup * @brief Class Magnum::SceneGraph::BasicAnimableGroup, typedef Magnum::SceneGraph::AnimableGroup2D, Magnum::SceneGraph::AnimableGroup3D
*/ */
#include "FeatureGroup.h" #include "FeatureGroup.h"
@ -37,22 +37,17 @@ namespace Magnum { namespace SceneGraph {
/** /**
@brief Group of animables @brief Group of animables
See Animable for more information. See BasicAnimable for more information.
@see @ref scenegraph, AnimableGroup2D, AnimableGroup3D @see @ref AnimableGroup2D, @ref AnimableGroup3D, @ref scenegraph
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT BasicAnimableGroup: public BasicFeatureGroup<dimensions, BasicAnimable<dimensions, T>, T> {
template<UnsignedInt dimensions, class T> friend class BasicAnimable<dimensions, T>;
#else
template<UnsignedInt dimensions, class T = Float>
#endif
class MAGNUM_SCENEGRAPH_EXPORT AnimableGroup: public FeatureGroup<dimensions, Animable<dimensions, T>, T> {
friend class Animable<dimensions, T>;
public: public:
/** /**
* @brief Constructor * @brief Constructor
*/ */
explicit AnimableGroup(): _runningCount(0), wakeUp(false) {} explicit BasicAnimableGroup(): _runningCount(0), wakeUp(false) {}
/** /**
* @brief Count of running animations * @brief Count of running animations
@ -76,37 +71,19 @@ class MAGNUM_SCENEGRAPH_EXPORT AnimableGroup: public FeatureGroup<dimensions, An
bool wakeUp; bool wakeUp;
}; };
#ifndef CORRADE_GCC46_COMPATIBILITY
/** /**
@brief Two-dimensional drawable @brief Animable group for two-dimensional float scenes
Convenience alternative to <tt>%AnimableGroup<2, T></tt>. See Animable for @see @ref AnimableGroup3D
more information.
@note Not available on GCC < 4.7. Use <tt>%AnimableGroup<2, T></tt> instead.
@see AnimableGroup3D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT typedef BasicAnimableGroup<2, Float> AnimableGroup2D;
template<class T = Float>
#else
template<class T>
#endif
using AnimableGroup2D = AnimableGroup<2, T>;
/** /**
@brief Three-dimensional animable @brief Animable group for three-dimensional float scenes
Convenience alternative to <tt>%AnimableGroup<3, T></tt>. See Animable for @see @ref AnimableGroup2D
more information.
@note Not available on GCC < 4.7. Use <tt>%AnimableGroup<3, T></tt> instead.
@see AnimableGroup2D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT typedef BasicAnimableGroup<3, Float> AnimableGroup3D;
template<class T = Float>
#else
template<class T>
#endif
using AnimableGroup3D = AnimableGroup<3, T>;
#endif
}} }}

36
src/SceneGraph/Camera2D.h

@ -1,5 +1,5 @@
#ifndef Magnum_SceneGraph_Camera2D_h #ifndef Magnum_SceneGraph_BasicCamera2D_h
#define Magnum_SceneGraph_Camera2D_h #define Magnum_SceneGraph_BasicCamera2D_h
/* /*
This file is part of Magnum. This file is part of Magnum.
@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::Camera2D * @brief Class Magnum::SceneGraph::BasicCamera2D, typedef Magnum::SceneGraph::Camera2D
*/ */
#include "AbstractCamera.h" #include "AbstractCamera.h"
@ -39,7 +39,7 @@ See Drawable documentation for introduction. The camera by default displays
OpenGL unit cube `[(-1, -1, -1); (1, 1, 1)]` and doesn't do any aspect ratio OpenGL unit cube `[(-1, -1, -1); (1, 1, 1)]` and doesn't do any aspect ratio
correction. Common setup example: correction. Common setup example:
@code @code
SceneGraph::Camera2D<>* camera = new SceneGraph::Camera2D<>(&cameraObject); SceneGraph::BasicCamera2D* camera = new SceneGraph::BasicCamera2D(&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
@ -48,19 +48,14 @@ camera->setProjection({4.0f/3.0f, 1.0f})
The following specialization are explicitly compiled into SceneGraph library. The following specialization are explicitly compiled into SceneGraph library.
For other specializations (e.g. using Double type) you have to use For other specializations (e.g. using Double type) you have to use
Camera2D.hpp implementation file to avoid linker errors. See BasicCamera2D.hpp implementation file to avoid linker errors. See
@ref compilation-speedup-hpp for more information. @ref compilation-speedup-hpp for more information.
- @ref Camera2D "Camera2D<Float>" - @ref BasicCamera2D "BasicCamera2D<Float>"
@see @ref scenegraph, Camera3D, Drawable, DrawableGroup @see @ref Camera2D, @ref scenegraph, @ref BasicCamera3D, @ref BasicDrawable, @ref BasicDrawableGroup
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<class T> class MAGNUM_SCENEGRAPH_EXPORT BasicCamera2D: public AbstractBasicCamera<2, T> {
template<class T>
#else
template<class T = Float>
#endif
class MAGNUM_SCENEGRAPH_EXPORT Camera2D: public AbstractCamera<2, T> {
public: public:
/** /**
* @brief Constructor * @brief Constructor
@ -69,7 +64,7 @@ class MAGNUM_SCENEGRAPH_EXPORT Camera2D: public AbstractCamera<2, T> {
* Sets orthographic projection to the default OpenGL cube (range @f$ [-1; 1] @f$ in all directions). * Sets orthographic projection to the default OpenGL cube (range @f$ [-1; 1] @f$ in all directions).
* @see setProjection() * @see setProjection()
*/ */
explicit Camera2D(AbstractObject<2, T>* object); explicit BasicCamera2D(AbstractBasicObject<2, T>* object);
/** /**
* @brief Set projection * @brief Set projection
@ -78,17 +73,24 @@ class MAGNUM_SCENEGRAPH_EXPORT Camera2D: public AbstractCamera<2, T> {
* *
* @see Matrix3::projection() * @see Matrix3::projection()
*/ */
Camera2D<T>* setProjection(const Math::Vector2<T>& size); BasicCamera2D<T>* setProjection(const Math::Vector2<T>& size);
/* Overloads to remove WTF-factor from method chaining order */ /* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
Camera2D<T>* setAspectRatioPolicy(AspectRatioPolicy policy) { BasicCamera2D<T>* setAspectRatioPolicy(AspectRatioPolicy policy) {
AbstractCamera<2, T>::setAspectRatioPolicy(policy); AbstractBasicCamera<2, T>::setAspectRatioPolicy(policy);
return this; return this;
} }
#endif #endif
}; };
/**
@brief Camera for two-dimensional float scenes
@see @ref Camera3D
*/
typedef BasicCamera2D<Float> Camera2D;
}} }}
#endif #endif

8
src/SceneGraph/Camera2D.hpp

@ -35,12 +35,12 @@ using namespace std;
namespace Magnum { namespace SceneGraph { namespace Magnum { namespace SceneGraph {
template<class T> Camera2D<T>::Camera2D(AbstractObject<2, T>* object): AbstractCamera<2, T>(object) {} template<class T> BasicCamera2D<T>::BasicCamera2D(AbstractBasicObject<2, T>* object): AbstractBasicCamera<2, T>(object) {}
template<class T> Camera2D<T>* Camera2D<T>::setProjection(const Math::Vector2<T>& size) { template<class T> BasicCamera2D<T>* BasicCamera2D<T>::setProjection(const Math::Vector2<T>& size) {
AbstractCamera<2, T>::rawProjectionMatrix = Math::Matrix3<T>::projection(size); AbstractBasicCamera<2, T>::rawProjectionMatrix = Math::Matrix3<T>::projection(size);
AbstractCamera<2, T>::fixAspectRatio(); AbstractBasicCamera<2, T>::fixAspectRatio();
return this; return this;
} }

36
src/SceneGraph/Camera3D.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::Camera3D * @brief Class Magnum::SceneGraph::BasicCamera3D, typedef Magnum::SceneGraph::Camera3D
*/ */
#include "AbstractCamera.h" #include "AbstractCamera.h"
@ -44,7 +44,7 @@ See Drawable documentation for introduction. The camera by default displays
OpenGL unit cube `[(-1, -1, -1); (1, 1, 1)]` with orthographic projection and OpenGL unit cube `[(-1, -1, -1); (1, 1, 1)]` with orthographic projection and
doesn't do any aspect ratio correction. Common setup example: doesn't do any aspect ratio correction. Common setup example:
@code @code
SceneGraph::Camera3D<>* camera = new SceneGraph::Camera3D<>(&cameraObject); SceneGraph::BasicCamera3D* camera = new SceneGraph::BasicCamera3D(&cameraObject);
camera->setPerspective({}, 0.001f, 100.0f) camera->setPerspective({}, 0.001f, 100.0f)
->setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend); ->setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend);
@endcode @endcode
@ -53,25 +53,20 @@ camera->setPerspective({}, 0.001f, 100.0f)
The following specialization are explicitly compiled into SceneGraph library. The following specialization are explicitly compiled into SceneGraph library.
For other specializations (e.g. using Double type) you have to use For other specializations (e.g. using Double type) you have to use
Camera3D.hpp implementation file to avoid linker errors. See BasicCamera3D.hpp implementation file to avoid linker errors. See
@ref compilation-speedup-hpp for more information. @ref compilation-speedup-hpp for more information.
- @ref Camera3D "Camera3D<Float>" - @ref BasicCamera3D "BasicCamera3D<Float>"
@see @ref scenegraph, Camera2D, Drawable, DrawableGroup @see @ref Camera3D, @ref scenegraph, @ref BasicCamera2D, @ref BasicDrawable, @ref BasicDrawableGroup
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<class T> class MAGNUM_SCENEGRAPH_EXPORT BasicCamera3D: public AbstractBasicCamera<3, T> {
template<class T>
#else
template<class T = Float>
#endif
class MAGNUM_SCENEGRAPH_EXPORT Camera3D: public AbstractCamera<3, T> {
public: public:
/** /**
* @brief Constructor * @brief Constructor
* @param object %Object holding this feature * @param object %Object holding this feature
*/ */
explicit Camera3D(AbstractObject<3, T>* object); explicit BasicCamera3D(AbstractBasicObject<3, T>* object);
/** /**
* @brief Set orthographic projection * @brief Set orthographic projection
@ -82,7 +77,7 @@ class MAGNUM_SCENEGRAPH_EXPORT Camera3D: public AbstractCamera<3, T> {
* *
* @see setPerspective(), Matrix4::orthographicProjection() * @see setPerspective(), Matrix4::orthographicProjection()
*/ */
Camera3D<T>* setOrthographic(const Math::Vector2<T>& size, T near, T far); BasicCamera3D<T>* setOrthographic(const Math::Vector2<T>& size, T near, T far);
/** /**
* @brief Set perspective projection * @brief Set perspective projection
@ -93,7 +88,7 @@ class MAGNUM_SCENEGRAPH_EXPORT Camera3D: public AbstractCamera<3, T> {
* *
* @see setOrthographic(), Matrix4::perspectiveProjection() * @see setOrthographic(), Matrix4::perspectiveProjection()
*/ */
Camera3D<T>* setPerspective(const Math::Vector2<T>& size, T near, T far); BasicCamera3D<T>* setPerspective(const Math::Vector2<T>& size, T near, T far);
/** /**
* @brief Set perspective projection * @brief Set perspective projection
@ -105,7 +100,7 @@ class MAGNUM_SCENEGRAPH_EXPORT Camera3D: public AbstractCamera<3, T> {
* *
* @see setOrthographic(), Matrix4::perspectiveProjection() * @see setOrthographic(), Matrix4::perspectiveProjection()
*/ */
Camera3D<T>* setPerspective(Math::Rad<T> fov, T aspectRatio, T near, T far); BasicCamera3D<T>* setPerspective(Math::Rad<T> fov, T aspectRatio, T near, T far);
/** @brief Near clipping plane */ /** @brief Near clipping plane */
T near() const { return _near; } T near() const { return _near; }
@ -115,8 +110,8 @@ class MAGNUM_SCENEGRAPH_EXPORT Camera3D: public AbstractCamera<3, T> {
/* Overloads to remove WTF-factor from method chaining order */ /* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
Camera3D<T>* setAspectRatioPolicy(AspectRatioPolicy policy) { BasicCamera3D<T>* setAspectRatioPolicy(AspectRatioPolicy policy) {
AbstractCamera<3, T>::setAspectRatioPolicy(policy); AbstractBasicCamera<3, T>::setAspectRatioPolicy(policy);
return this; return this;
} }
#endif #endif
@ -125,6 +120,13 @@ class MAGNUM_SCENEGRAPH_EXPORT Camera3D: public AbstractCamera<3, T> {
T _near, _far; T _near, _far;
}; };
/**
@brief Camera for three-dimensional float scenes
@see @ref Camera2D
*/
typedef BasicCamera3D<Float> Camera3D;
}} }}
#endif #endif

20
src/SceneGraph/Camera3D.hpp

@ -33,35 +33,35 @@
namespace Magnum { namespace SceneGraph { namespace Magnum { namespace SceneGraph {
template<class T> Camera3D<T>::Camera3D(AbstractObject<3, T>* object): AbstractCamera<3, T>(object), _near(T(0)), _far(T(0)) {} template<class T> BasicCamera3D<T>::BasicCamera3D(AbstractBasicObject<3, T>* object): AbstractBasicCamera<3, T>(object), _near(T(0)), _far(T(0)) {}
template<class T> Camera3D<T>* Camera3D<T>::setOrthographic(const Math::Vector2<T>& size, T near, T far) { template<class T> BasicCamera3D<T>* BasicCamera3D<T>::setOrthographic(const Math::Vector2<T>& size, T near, T far) {
/** @todo Get near/far from the matrix */ /** @todo Get near/far from the matrix */
_near = near; _near = near;
_far = far; _far = far;
AbstractCamera<3, T>::rawProjectionMatrix = Math::Matrix4<T>::orthographicProjection(size, near, far); AbstractBasicCamera<3, T>::rawProjectionMatrix = Math::Matrix4<T>::orthographicProjection(size, near, far);
AbstractCamera<3, T>::fixAspectRatio(); AbstractBasicCamera<3, T>::fixAspectRatio();
return this; return this;
} }
template<class T> Camera3D<T>* Camera3D<T>::setPerspective(const Math::Vector2<T>& size, T near, T far) { template<class T> BasicCamera3D<T>* BasicCamera3D<T>::setPerspective(const Math::Vector2<T>& size, T near, T far) {
/** @todo Get near/far from the matrix */ /** @todo Get near/far from the matrix */
_near = near; _near = near;
_far = far; _far = far;
AbstractCamera<3, T>::rawProjectionMatrix = Math::Matrix4<T>::perspectiveProjection(size, near, far); AbstractBasicCamera<3, T>::rawProjectionMatrix = Math::Matrix4<T>::perspectiveProjection(size, near, far);
AbstractCamera<3, T>::fixAspectRatio(); AbstractBasicCamera<3, T>::fixAspectRatio();
return this; return this;
} }
template<class T> Camera3D<T>* Camera3D<T>::setPerspective(Math::Rad<T> fov, T aspectRatio, T near, T far) { template<class T> BasicCamera3D<T>* BasicCamera3D<T>::setPerspective(Math::Rad<T> fov, T aspectRatio, T near, T far) {
/** @todo Get near/far from the matrix */ /** @todo Get near/far from the matrix */
_near = near; _near = near;
_far = far; _far = far;
AbstractCamera<3, T>::rawProjectionMatrix = Math::Matrix4<T>::perspectiveProjection(fov, aspectRatio, near, far); AbstractBasicCamera<3, T>::rawProjectionMatrix = Math::Matrix4<T>::perspectiveProjection(fov, aspectRatio, near, far);
AbstractCamera<3, T>::fixAspectRatio(); AbstractBasicCamera<3, T>::fixAspectRatio();
return this; return this;
} }

103
src/SceneGraph/Drawable.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::Drawable, Magnum::SceneGraph::DrawableGroup, alias Magnum::SceneGraph::Drawable2D, Magnum::SceneGraph::Drawable3D, Magnum::SceneGraph::DrawableGroup2D, Magnum::SceneGraph::DrawableGroup3D * @brief Class Magnum::SceneGraph::BasicDrawable, Magnum::SceneGraph::BasicDrawableGroup, typedef Magnum::SceneGraph::Drawable2D, Magnum::SceneGraph::Drawable3D, Magnum::SceneGraph::DrawableGroup2D, Magnum::SceneGraph::DrawableGroup3D
*/ */
#include "AbstractGroupedFeature.h" #include "AbstractGroupedFeature.h"
@ -35,7 +35,7 @@ namespace Magnum { namespace SceneGraph {
/** /**
@brief %Drawable @brief %Drawable
Adds drawing function to the object. Each %Drawable is part of some DrawableGroup Adds drawing function to the object. Each Drawable is part of some DrawableGroup
and the whole group is drawn with particular camera using AbstractCamera::draw(). and the whole group is drawn with particular camera using AbstractCamera::draw().
@section Drawable-usage Usage @section Drawable-usage Usage
@ -44,27 +44,27 @@ First thing is add Drawable feature to some object and implement draw(). You
can do it conveniently using multiple inheritance (see @ref scenegraph-features can do it conveniently using multiple inheritance (see @ref scenegraph-features
for introduction). Example: for introduction). Example:
@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 DrawableObject: public Object3D, SceneGraph::Drawable3D {
public: public:
DrawableObject(Object* parent = nullptr, SceneGraph::DrawableGroup3D<>* group = nullptr): Object3D(parent), SceneGraph::Drawable3D<>(this, group) { DrawableObject(Object* parent = nullptr, SceneGraph::DrawableGroup3D* group = nullptr): Object3D(parent), SceneGraph::Drawable3D(this, group) {
// ... // ...
} }
void draw(const Matrix4& transformationMatrix, AbstractCamera3D<>* camera) override { void draw(const Matrix4& transformationMatrix, AbstractCamera3D* camera) override {
// ... // ...
} }
} }
@endcode @endcode
Then you add these objects to your scene and some drawable group and transform Then you add these objects to your scene and some drawable group and transform
them as you like. You can also use DrawableGroup::add() and them as you like. You can also use BasicDrawableGroup::add() and
DrawableGroup::remove(). BasicDrawableGroup::remove().
@code @code
Scene3D scene; Scene3D scene;
SceneGraph::DrawableGroup3D<> drawables; SceneGraph::DrawableGroup3D drawables;
(new DrawableObject(&scene, &drawables)) (new DrawableObject(&scene, &drawables))
->translate(Vector3::yAxis(-0.3f)) ->translate(Vector3::yAxis(-0.3f))
@ -97,7 +97,7 @@ parameters once for whole group instead of setting them again in each draw()
implementation. Example: implementation. Example:
@code @code
Shaders::PhongShader* shader; Shaders::PhongShader* shader;
SceneGraph::DrawableGroup3D<> phongObjects, transparentObjects; SceneGraph::DrawableGroup3D phongObjects, transparentObjects;
void MyApplication::drawEvent() { void MyApplication::drawEvent() {
shader->setProjectionMatrix(camera->projectionMatrix()) shader->setProjectionMatrix(camera->projectionMatrix())
@ -114,14 +114,9 @@ void MyApplication::drawEvent() {
} }
@endcode @endcode
@see @ref scenegraph, Drawable2D, Drawable3D, DrawableGroup2D, DrawableGroup3D @see Drawable2D, Drawable3D, @ref scenegraph, DrawableGroup2D, DrawableGroup3D
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<UnsignedInt dimensions, class T> class BasicDrawable: public AbstractBasicGroupedFeature<dimensions, BasicDrawable<dimensions, T>, T> {
template<UnsignedInt dimensions, class T>
#else
template<UnsignedInt dimensions, class T = Float>
#endif
class Drawable: public AbstractGroupedFeature<dimensions, Drawable<dimensions, T>, T> {
public: public:
/** /**
* @brief Constructor * @brief Constructor
@ -129,9 +124,9 @@ class Drawable: public AbstractGroupedFeature<dimensions, Drawable<dimensions, T
* @param drawables Group this drawable belongs to * @param drawables Group this drawable belongs to
* *
* Adds the feature to the object and also to the group, if specified. * Adds the feature to the object and also to the group, if specified.
* Otherwise you can use DrawableGroup::add(). * Otherwise you can use BasicDrawableGroup::add().
*/ */
explicit Drawable(AbstractObject<dimensions, T>* object, DrawableGroup<dimensions, T>* drawables = nullptr): AbstractGroupedFeature<dimensions, Drawable<dimensions, T>, T>(object, drawables) {} explicit BasicDrawable(AbstractBasicObject<dimensions, T>* object, BasicDrawableGroup<dimensions, T>* drawables = nullptr): AbstractBasicGroupedFeature<dimensions, BasicDrawable<dimensions, T>, T>(object, drawables) {}
/** /**
* @brief Draw the object using given camera * @brief Draw the object using given camera
@ -141,40 +136,22 @@ class Drawable: public AbstractGroupedFeature<dimensions, Drawable<dimensions, T
* *
* Projection matrix can be retrieved from AbstractCamera::projectionMatrix(). * Projection matrix can be retrieved from AbstractCamera::projectionMatrix().
*/ */
virtual void draw(const typename DimensionTraits<dimensions, T>::MatrixType& transformationMatrix, AbstractCamera<dimensions, T>* camera) = 0; virtual void draw(const typename DimensionTraits<dimensions, T>::MatrixType& transformationMatrix, AbstractBasicCamera<dimensions, T>* camera) = 0;
}; };
#ifndef CORRADE_GCC46_COMPATIBILITY
/** /**
@brief Two-dimensional drawable @brief Two-dimensional drawable for float scenes
Convenience alternative to <tt>%Drawable<2, T></tt>. See Drawable for more
information.
@note Not available on GCC < 4.7. Use <tt>%Drawable<2, T></tt> instead.
@see Drawable3D @see Drawable3D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT typedef BasicDrawable<2, Float> Drawable2D;
template<class T = Float>
#else
template<class T>
#endif
using Drawable2D = Drawable<2, T>;
/** /**
@brief Three-dimensional drawable @brief Three-dimensional drawable for float scenes
Convenience alternative to <tt>%Drawable<3, T></tt>. See Drawable for more
information.
@note Not available on GCC < 4.7. Use <tt>%Drawable<3, T></tt> instead.
@see Drawable2D @see Drawable2D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT typedef BasicDrawable<3, Float> Drawable3D;
template<class T = Float>
#else
template<class T>
#endif
using Drawable3D = Drawable<3, T>;
#endif
/** /**
@brief Group of drawables @brief Group of drawables
@ -183,52 +160,24 @@ See Drawable for more information.
@see @ref scenegraph, DrawableGroup2D, DrawableGroup3D @see @ref scenegraph, DrawableGroup2D, DrawableGroup3D
*/ */
#ifndef CORRADE_GCC46_COMPATIBILITY #ifndef CORRADE_GCC46_COMPATIBILITY
#ifdef DOXYGEN_GENERATING_OUTPUT template<UnsignedInt dimensions, class T> using BasicDrawableGroup = BasicFeatureGroup<dimensions, BasicDrawable<dimensions, T>, T>;
template<UnsignedInt dimensions, class T = Float>
#else
template<UnsignedInt dimensions, class T>
#endif
using DrawableGroup = FeatureGroup<dimensions, Drawable<dimensions, T>, T>;
#else
#ifdef DOXYGEN_GENERATING_OUTPUT
template<UnsignedInt dimensions, class T = Float>
#else #else
template<UnsignedInt dimensions, class T> template<UnsignedInt dimensions, class T> class BasicDrawableGroup: public BasicFeatureGroup<dimensions, BasicDrawable<dimensions, T>, T> {};
#endif
class DrawableGroup: public FeatureGroup<dimensions, Drawable<dimensions, T>, T> {};
#endif #endif
#ifndef CORRADE_GCC46_COMPATIBILITY
/** /**
@brief Group of two-dimensional drawables @brief Group of two-dimensional drawables for float scenes
Convenience alternative to <tt>%DrawableGroup<2, T></tt>. See Drawable for
more information.
@note Not available on GCC < 4.7. Use <tt>%Drawable<2, T></tt> instead.
@see DrawableGroup3D @see DrawableGroup3D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT typedef BasicDrawableGroup<2, Float> DrawableGroup2D;
template<class T = Float>
#else
template<class T>
#endif
using DrawableGroup2D = DrawableGroup<2, T>;
/** /**
@brief Group of three-dimensional drawables @brief Group of three-dimensional drawables for float scenes
Convenience alternative to <tt>%DrawableGroup<3, T></tt>. See Drawable for
more information.
@note Not available on GCC < 4.7. Use <tt>%Drawable<3, T></tt> instead.
@see DrawableGroup2D @see DrawableGroup2D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT typedef BasicDrawableGroup<3, Float> DrawableGroup3D;
template<class T = Float>
#else
template<class T>
#endif
using DrawableGroup3D = DrawableGroup<3, T>;
#endif
}} }}

60
src/SceneGraph/DualComplexTransformation.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::DualComplexTransformation * @brief Class Magnum::SceneGraph::BasicDualComplexTransformation, typedef Magnum::SceneGraph::DualComplexTransformation
*/ */
#include "Math/DualComplex.h" #include "Math/DualComplex.h"
@ -39,14 +39,9 @@ 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). translation).
@see @ref scenegraph, Math::DualComplex, DualQuaternionTransformation @see @ref DualComplexTransformation, @ref scenegraph, Math::DualComplex, @ref BasicDualQuaternionTransformation
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<class T> class BasicDualComplexTransformation: public AbstractBasicTranslationRotation2D<T> {
template<class T>
#else
template<class T = Float>
#endif
class DualComplexTransformation: public AbstractTranslationRotation2D<T> {
public: public:
/** @brief Transformation type */ /** @brief Transformation type */
typedef Math::DualComplex<T> DataType; typedef Math::DualComplex<T> DataType;
@ -81,9 +76,9 @@ class DualComplexTransformation: public AbstractTranslationRotation2D<T> {
* the object subsequently. * the object subsequently.
* @see DualComplex::normalized() * @see DualComplex::normalized()
*/ */
Object<DualComplexTransformation<T>>* normalizeRotation() { Object<BasicDualComplexTransformation<T>>* normalizeRotation() {
setTransformationInternal(_transformation.normalized()); setTransformationInternal(_transformation.normalized());
return static_cast<Object<DualComplexTransformation<T>>*>(this); return static_cast<Object<BasicDualComplexTransformation<T>>*>(this);
} }
/** /**
@ -93,18 +88,18 @@ class DualComplexTransformation: public AbstractTranslationRotation2D<T> {
* Expects that the dual complex number is normalized. * Expects that the dual complex number is normalized.
* @see DualComplex::isNormalized() * @see DualComplex::isNormalized()
*/ */
Object<DualComplexTransformation<T>>* setTransformation(const Math::DualComplex<T>& transformation) { Object<BasicDualComplexTransformation<T>>* setTransformation(const Math::DualComplex<T>& transformation) {
CORRADE_ASSERT(transformation.isNormalized(), CORRADE_ASSERT(transformation.isNormalized(),
"SceneGraph::DualComplexTransformation::setTransformation(): the dual complex number is not normalized", "SceneGraph::DualComplexTransformation::setTransformation(): the dual complex number is not normalized",
static_cast<Object<DualComplexTransformation<T>>*>(this)); static_cast<Object<BasicDualComplexTransformation<T>>*>(this));
setTransformationInternal(transformation); setTransformationInternal(transformation);
return static_cast<Object<DualComplexTransformation<T>>*>(this); return static_cast<Object<BasicDualComplexTransformation<T>>*>(this);
} }
/** @copydoc AbstractTranslationRotationScaling2D::resetTransformation() */ /** @copydoc AbstractTranslationRotationScaling2D::resetTransformation() */
Object<DualComplexTransformation<T>>* resetTransformation() { Object<BasicDualComplexTransformation<T>>* resetTransformation() {
setTransformationInternal({}); setTransformationInternal({});
return static_cast<Object<DualComplexTransformation<T>>*>(this); return static_cast<Object<BasicDualComplexTransformation<T>>*>(this);
} }
/** /**
@ -116,21 +111,21 @@ class DualComplexTransformation: public AbstractTranslationRotation2D<T> {
* Expects that the dual complex number is normalized. * Expects that the dual complex number is normalized.
* @see DualComplex::isNormalized() * @see DualComplex::isNormalized()
*/ */
Object<DualComplexTransformation<T>>* transform(const Math::DualComplex<T>& transformation, TransformationType type = TransformationType::Global) { Object<BasicDualComplexTransformation<T>>* transform(const Math::DualComplex<T>& transformation, TransformationType type = TransformationType::Global) {
CORRADE_ASSERT(transformation.isNormalized(), CORRADE_ASSERT(transformation.isNormalized(),
"SceneGraph::DualComplexTransformation::transform(): the dual complex number is not normalized", "SceneGraph::DualComplexTransformation::transform(): the dual complex number is not normalized",
static_cast<Object<DualComplexTransformation<T>>*>(this)); static_cast<Object<BasicDualComplexTransformation<T>>*>(this));
transformInternal(transformation, type); transformInternal(transformation, type);
return static_cast<Object<DualComplexTransformation<T>>*>(this); return static_cast<Object<BasicDualComplexTransformation<T>>*>(this);
} }
/** /**
* @copydoc AbstractTranslationRotationScaling2D::translate() * @copydoc AbstractTranslationRotationScaling2D::translate()
* Same as calling transform() with DualComplex::translation(). * Same as calling transform() with DualComplex::translation().
*/ */
Object<DualComplexTransformation<T>>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) { Object<BasicDualComplexTransformation<T>>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
transformInternal(Math::DualComplex<T>::translation(vector), type); transformInternal(Math::DualComplex<T>::translation(vector), type);
return static_cast<Object<DualComplexTransformation<T>>*>(this); return static_cast<Object<BasicDualComplexTransformation<T>>*>(this);
} }
/** /**
@ -142,9 +137,9 @@ class DualComplexTransformation: public AbstractTranslationRotation2D<T> {
* Same as calling transform() with DualComplex::rotation(). * Same as calling transform() with DualComplex::rotation().
* @see normalizeRotation() * @see normalizeRotation()
*/ */
Object<DualComplexTransformation<T>>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { Object<BasicDualComplexTransformation<T>>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transformInternal(Math::DualComplex<T>::rotation(angle), type); transformInternal(Math::DualComplex<T>::rotation(angle), type);
return static_cast<Object<DualComplexTransformation<T>>*>(this); return static_cast<Object<BasicDualComplexTransformation<T>>*>(this);
} }
/** /**
@ -153,14 +148,14 @@ class DualComplexTransformation: public AbstractTranslationRotation2D<T> {
* if you want to move it above all. * if you want to move it above all.
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
*/ */
Object<DualComplexTransformation<T>>* move(Object<DualComplexTransformation<T>>* under) { Object<BasicDualComplexTransformation<T>>* move(Object<BasicDualComplexTransformation<T>>* under) {
static_cast<Object<DualComplexTransformation>*>(this)->Containers::template LinkedList<Object<DualComplexTransformation<T>>>::move(this, under); static_cast<Object<BasicDualComplexTransformation>*>(this)->Containers::template LinkedList<Object<BasicDualComplexTransformation<T>>>::move(this, under);
return static_cast<Object<DualComplexTransformation<T>>*>(this); return static_cast<Object<BasicDualComplexTransformation<T>>*>(this);
} }
protected: protected:
/* Allow construction only from Object */ /* Allow construction only from Object */
explicit DualComplexTransformation(); explicit BasicDualComplexTransformation();
private: private:
void doResetTransformation() override final { resetTransformation(); } void doResetTransformation() override final { resetTransformation(); }
@ -178,9 +173,9 @@ class DualComplexTransformation: public AbstractTranslationRotation2D<T> {
/* Setting transformation is forbidden for the scene */ /* Setting transformation is forbidden for the scene */
/** @todo Assert for this? */ /** @todo Assert for this? */
/** @todo Do this in some common code so we don't need to include Object? */ /** @todo Do this in some common code so we don't need to include Object? */
if(!static_cast<Object<DualComplexTransformation<T>>*>(this)->isScene()) { if(!static_cast<Object<BasicDualComplexTransformation<T>>*>(this)->isScene()) {
_transformation = transformation; _transformation = transformation;
static_cast<Object<DualComplexTransformation<T>>*>(this)->setDirty(); static_cast<Object<BasicDualComplexTransformation<T>>*>(this)->setDirty();
} }
} }
@ -193,7 +188,14 @@ class DualComplexTransformation: public AbstractTranslationRotation2D<T> {
Math::DualComplex<T> _transformation; Math::DualComplex<T> _transformation;
}; };
template<class T> inline DualComplexTransformation<T>::DualComplexTransformation() = default; template<class T> inline BasicDualComplexTransformation<T>::BasicDualComplexTransformation() = default;
/**
@brief Two-dimensional transformation for float scenes implemented using dual complex numbers
@see @ref DualQuaternionTransformation
*/
typedef BasicDualComplexTransformation<Float> DualComplexTransformation;
}} }}

60
src/SceneGraph/DualQuaternionTransformation.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::DualQuaternionTransformation * @brief Class Magnum::SceneGraph::BasicDualQuaternionTransformation, typedef Magnum::SceneGraph::DualQuaternionTransformation
*/ */
#include "Math/DualQuaternion.h" #include "Math/DualQuaternion.h"
@ -39,14 +39,9 @@ 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). translation).
@see @ref scenegraph, Math::DualQuaternion, DualComplexTransformation @see @ref DualQuaternionTransformation @ref scenegraph, Math::DualQuaternion, @ref BasicDualComplexTransformation
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<class T> class BasicDualQuaternionTransformation: public AbstractBasicTranslationRotation3D<T> {
template<class T>
#else
template<class T = Float>
#endif
class DualQuaternionTransformation: public AbstractTranslationRotation3D<T> {
public: public:
/** @brief Underlying transformation type */ /** @brief Underlying transformation type */
typedef Math::DualQuaternion<T> DataType; typedef Math::DualQuaternion<T> DataType;
@ -83,9 +78,9 @@ class DualQuaternionTransformation: public AbstractTranslationRotation3D<T> {
* the object subsequently. * the object subsequently.
* @see DualQuaternion::normalized() * @see DualQuaternion::normalized()
*/ */
Object<DualQuaternionTransformation<T>>* normalizeRotation() { Object<BasicDualQuaternionTransformation<T>>* normalizeRotation() {
setTransformation(_transformation.normalized()); setTransformation(_transformation.normalized());
return static_cast<Object<DualQuaternionTransformation<T>>*>(this); return static_cast<Object<BasicDualQuaternionTransformation<T>>*>(this);
} }
/** /**
@ -95,18 +90,18 @@ class DualQuaternionTransformation: public AbstractTranslationRotation3D<T> {
* Expects that the dual quaternion is normalized. * Expects that the dual quaternion is normalized.
* @see DualQuaternion::isNormalized() * @see DualQuaternion::isNormalized()
*/ */
Object<DualQuaternionTransformation<T>>* setTransformation(const Math::DualQuaternion<T>& transformation) { Object<BasicDualQuaternionTransformation<T>>* setTransformation(const Math::DualQuaternion<T>& transformation) {
CORRADE_ASSERT(transformation.isNormalized(), CORRADE_ASSERT(transformation.isNormalized(),
"SceneGraph::DualQuaternionTransformation::setTransformation(): the dual quaternion is not normalized", "SceneGraph::DualQuaternionTransformation::setTransformation(): the dual quaternion is not normalized",
static_cast<Object<DualQuaternionTransformation<T>>*>(this)); static_cast<Object<BasicDualQuaternionTransformation<T>>*>(this));
setTransformationInternal(transformation); setTransformationInternal(transformation);
return static_cast<Object<DualQuaternionTransformation<T>>*>(this); return static_cast<Object<BasicDualQuaternionTransformation<T>>*>(this);
} }
/** @copydoc AbstractTranslationRotationScaling3D::resetTransformation() */ /** @copydoc AbstractTranslationRotationScaling3D::resetTransformation() */
Object<DualQuaternionTransformation<T>>* resetTransformation() { Object<BasicDualQuaternionTransformation<T>>* resetTransformation() {
setTransformation({}); setTransformation({});
return static_cast<Object<DualQuaternionTransformation<T>>*>(this); return static_cast<Object<BasicDualQuaternionTransformation<T>>*>(this);
} }
/** /**
@ -118,21 +113,21 @@ class DualQuaternionTransformation: public AbstractTranslationRotation3D<T> {
* Expects that the dual quaternion is normalized. * Expects that the dual quaternion is normalized.
* @see DualQuaternion::isNormalized() * @see DualQuaternion::isNormalized()
*/ */
Object<DualQuaternionTransformation<T>>* transform(const Math::DualQuaternion<T>& transformation, TransformationType type = TransformationType::Global) { Object<BasicDualQuaternionTransformation<T>>* transform(const Math::DualQuaternion<T>& transformation, TransformationType type = TransformationType::Global) {
CORRADE_ASSERT(transformation.isNormalized(), CORRADE_ASSERT(transformation.isNormalized(),
"SceneGraph::DualQuaternionTransformation::transform(): the dual quaternion is not normalized", "SceneGraph::DualQuaternionTransformation::transform(): the dual quaternion is not normalized",
static_cast<Object<DualQuaternionTransformation<T>>*>(this)); static_cast<Object<BasicDualQuaternionTransformation<T>>*>(this));
transformInternal(transformation, type); transformInternal(transformation, type);
return static_cast<Object<DualQuaternionTransformation<T>>*>(this); return static_cast<Object<BasicDualQuaternionTransformation<T>>*>(this);
} }
/** /**
* @copydoc AbstractTranslationRotationScaling3D::translate() * @copydoc AbstractTranslationRotationScaling3D::translate()
* Same as calling transform() with DualQuaternion::translation(). * Same as calling transform() with DualQuaternion::translation().
*/ */
Object<DualQuaternionTransformation<T>>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) { Object<BasicDualQuaternionTransformation<T>>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
transformInternal(Math::DualQuaternion<T>::translation(vector), type); transformInternal(Math::DualQuaternion<T>::translation(vector), type);
return static_cast<Object<DualQuaternionTransformation<T>>*>(this); return static_cast<Object<BasicDualQuaternionTransformation<T>>*>(this);
} }
/** /**
@ -146,27 +141,27 @@ class DualQuaternionTransformation: public AbstractTranslationRotation3D<T> {
* @see Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis(), * @see Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis(),
* normalizeRotation() * normalizeRotation()
*/ */
Object<DualQuaternionTransformation<T>>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) { Object<BasicDualQuaternionTransformation<T>>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
transformInternal(Math::DualQuaternion<T>::rotation(angle, normalizedAxis), type); transformInternal(Math::DualQuaternion<T>::rotation(angle, normalizedAxis), type);
return static_cast<Object<DualQuaternionTransformation<T>>*>(this); return static_cast<Object<BasicDualQuaternionTransformation<T>>*>(this);
} }
/* Overloads to remove WTF-factor from method chaining order */ /* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
Object<DualQuaternionTransformation<T>>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { Object<BasicDualQuaternionTransformation<T>>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
return rotate(angle, Math::Vector3<T>::xAxis(), type); return rotate(angle, Math::Vector3<T>::xAxis(), type);
} }
Object<DualQuaternionTransformation<T>>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { Object<BasicDualQuaternionTransformation<T>>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
return rotate(angle, Math::Vector3<T>::yAxis(), type); return rotate(angle, Math::Vector3<T>::yAxis(), type);
} }
Object<DualQuaternionTransformation<T>>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { Object<BasicDualQuaternionTransformation<T>>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
return rotate(angle, Math::Vector3<T>::zAxis(), type); return rotate(angle, Math::Vector3<T>::zAxis(), type);
} }
#endif #endif
protected: protected:
/* Allow construction only from Object */ /* Allow construction only from Object */
explicit DualQuaternionTransformation(); explicit BasicDualQuaternionTransformation();
private: private:
void doResetTransformation() override final { resetTransformation(); } void doResetTransformation() override final { resetTransformation(); }
@ -184,9 +179,9 @@ class DualQuaternionTransformation: public AbstractTranslationRotation3D<T> {
/* Setting transformation is forbidden for the scene */ /* Setting transformation is forbidden for the scene */
/** @todo Assert for this? */ /** @todo Assert for this? */
/** @todo Do this in some common code so we don't need to include Object? */ /** @todo Do this in some common code so we don't need to include Object? */
if(!static_cast<Object<DualQuaternionTransformation<T>>*>(this)->isScene()) { if(!static_cast<Object<BasicDualQuaternionTransformation<T>>*>(this)->isScene()) {
_transformation = transformation; _transformation = transformation;
static_cast<Object<DualQuaternionTransformation<T>>*>(this)->setDirty(); static_cast<Object<BasicDualQuaternionTransformation<T>>*>(this)->setDirty();
} }
} }
@ -199,7 +194,14 @@ class DualQuaternionTransformation: public AbstractTranslationRotation3D<T> {
Math::DualQuaternion<T> _transformation; Math::DualQuaternion<T> _transformation;
}; };
template<class T> inline DualQuaternionTransformation<T>::DualQuaternionTransformation() = default; template<class T> inline BasicDualQuaternionTransformation<T>::BasicDualQuaternionTransformation() = default;
/**
@brief Three-dimensional transformation for float scenes implemented using dual quaternions
@see @ref DualComplexTransformation
*/
typedef BasicDualQuaternionTransformation<Float> DualQuaternionTransformation;
}} }}

92
src/SceneGraph/FeatureGroup.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::FeatureGroup, alias Magnum::SceneGraph::FeatureGroup2D, Magnum::SceneGraph::FeatureGroup3D * @brief Class Magnum::SceneGraph::AbstractBasicFeatureGroup, Magnum::SceneGraph::BasicFeatureGroup, alias Magnum::SceneGraph::FeatureGroup2D, Magnum::SceneGraph::FeatureGroup3D
*/ */
#include <vector> #include <vector>
@ -39,48 +39,38 @@ namespace Magnum { namespace SceneGraph {
/** /**
@brief Base for group of features @brief Base for group of features
See FeatureGroup. See BasicFeatureGroup.
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT AbstractBasicFeatureGroup {
template<UnsignedInt dimensions, class T> template<UnsignedInt, class, class> friend class BasicFeatureGroup;
#else
template<UnsignedInt dimensions, class T = Float>
#endif
class MAGNUM_SCENEGRAPH_EXPORT AbstractFeatureGroup {
template<UnsignedInt, class, class> friend class FeatureGroup;
explicit AbstractFeatureGroup(); explicit AbstractBasicFeatureGroup();
virtual ~AbstractFeatureGroup(); virtual ~AbstractBasicFeatureGroup();
void add(AbstractFeature<dimensions, T>* feature); void add(AbstractBasicFeature<dimensions, T>* feature);
void remove(AbstractFeature<dimensions, T>* feature); void remove(AbstractBasicFeature<dimensions, T>* feature);
std::vector<AbstractFeature<dimensions, T>*> features; std::vector<AbstractBasicFeature<dimensions, T>*> features;
}; };
/** /**
@brief Group of features @brief Group of features
See AbstractGroupedFeature for more information. See AbstractBasicGroupedFeature for more information.
@see @ref scenegraph, FeatureGroup2D, FeatureGroup3D @see @ref FeatureGroup2D, @ref FeatureGroup3D, @ref scenegraph
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<UnsignedInt dimensions, class Feature, class T> class BasicFeatureGroup: public AbstractBasicFeatureGroup<dimensions, T> {
template<UnsignedInt dimensions, class Feature, class T> friend class AbstractBasicGroupedFeature<dimensions, Feature, T>;
#else
template<UnsignedInt dimensions, class Feature, class T = Float>
#endif
class FeatureGroup: public AbstractFeatureGroup<dimensions, T> {
friend class AbstractGroupedFeature<dimensions, Feature, T>;
public: public:
explicit FeatureGroup(); explicit BasicFeatureGroup();
/** /**
* @brief Destructor * @brief Destructor
* *
* Removes all features belonging to this group, but not deletes them. * Removes all features belonging to this group, but not deletes them.
*/ */
~FeatureGroup(); ~BasicFeatureGroup();
/** @brief Whether the group is empty */ /** @brief Whether the group is empty */
bool isEmpty() const { return this->features.empty(); } bool isEmpty() const { return this->features.empty(); }
@ -103,9 +93,9 @@ class FeatureGroup: public AbstractFeatureGroup<dimensions, T> {
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
* *
* If the features is part of another group, it is removed from it. * If the features is part of another group, it is removed from it.
* @see remove(), AbstractGroupedFeature::AbstractGroupedFeature() * @see remove(), AbstractBasicGroupedFeature::AbstractBasicGroupedFeature()
*/ */
FeatureGroup<dimensions, Feature, T>* add(Feature* feature); BasicFeatureGroup<dimensions, Feature, T>* add(Feature* feature);
/** /**
* @brief Remove feature from the group * @brief Remove feature from the group
@ -114,66 +104,54 @@ class FeatureGroup: public AbstractFeatureGroup<dimensions, T> {
* The feature must be part of the group. * The feature must be part of the group.
* @see add() * @see add()
*/ */
FeatureGroup<dimensions, Feature, T>* remove(Feature* feature); BasicFeatureGroup<dimensions, Feature, T>* remove(Feature* feature);
}; };
template<UnsignedInt dimensions, class Feature, class T> inline FeatureGroup<dimensions, Feature, T>::FeatureGroup() = default; template<UnsignedInt dimensions, class Feature, class T> inline BasicFeatureGroup<dimensions, Feature, T>::BasicFeatureGroup() = default;
#ifndef CORRADE_GCC46_COMPATIBILITY #ifndef CORRADE_GCC46_COMPATIBILITY
/** /**
@brief Base for two-dimensional object features @brief Base feature for two-dimensional float scenes
Convenience alternative to <tt>%FeatureGroup<2, Feature, T></tt>. See Convenience alternative to <tt>%BasicFeatureGroup<2, Feature, Float></tt>.
AbstractGroupedFeature for more information. @note Not available on GCC < 4.7. Use <tt>%BasicFeatureGroup<2, Feature, Float></tt>
@note Not available on GCC < 4.7. Use <tt>%FeatureGroup<2, Feature, T></tt>
instead. instead.
@see FeatureGroup3D @see @ref FeatureGroup3D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT template<class Feature> using FeatureGroup2D = BasicFeatureGroup<2, Feature, Float>;
template<class Feature, class T = Float>
#else
template<class Feature, class T>
#endif
using FeatureGroup2D = FeatureGroup<2, Feature, T>;
/** /**
@brief Base for three-dimensional object features @brief Base feature for three-dimensional float scenes
Convenience alternative to <tt>%FeatureGroup<3, Feature, T></tt>. See Convenience alternative to <tt>%BasicFeatureGroup<3, Feature, Float></tt>.
AbstractGroupedFeature for more information. @note Not available on GCC < 4.7. Use <tt>%FeatureGroup<3, Feature, Float></tt>
@note Not available on GCC < 4.7. Use <tt>%FeatureGroup<3, Feature, T></tt>
instead. instead.
@see FeatureGroup2D @see @ref FeatureGroup2D
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT template<class Feature> using FeatureGroup3D = BasicFeatureGroup<3, Feature, Float>;
template<class Feature, class T = Float>
#else
template<class Feature, class T>
#endif
using FeatureGroup3D = FeatureGroup<3, Feature, T>;
#endif #endif
template<UnsignedInt dimensions, class Feature, class T> FeatureGroup<dimensions, Feature, T>::~FeatureGroup() { template<UnsignedInt dimensions, class Feature, class T> BasicFeatureGroup<dimensions, Feature, T>::~BasicFeatureGroup() {
for(auto it = this->features.begin(); it != this->features.end(); ++it) for(auto it = this->features.begin(); it != this->features.end(); ++it)
static_cast<Feature*>(*it)->_group = nullptr; static_cast<Feature*>(*it)->_group = nullptr;
} }
template<UnsignedInt dimensions, class Feature, class T> FeatureGroup<dimensions, Feature, T>* FeatureGroup<dimensions, Feature, T>::add(Feature* feature) { template<UnsignedInt dimensions, class Feature, class T> BasicFeatureGroup<dimensions, Feature, T>* BasicFeatureGroup<dimensions, Feature, T>::add(Feature* feature) {
/* Remove from previous group */ /* Remove from previous group */
if(feature->_group) if(feature->_group)
feature->_group->remove(feature); feature->_group->remove(feature);
/* Crossreference the feature and group together */ /* Crossreference the feature and group together */
AbstractFeatureGroup<dimensions, T>::add(feature); AbstractBasicFeatureGroup<dimensions, T>::add(feature);
feature->_group = this; feature->_group = this;
return this; return this;
} }
template<UnsignedInt dimensions, class Feature, class T> FeatureGroup<dimensions, Feature, T>* FeatureGroup<dimensions, Feature, T>::remove(Feature* feature) { template<UnsignedInt dimensions, class Feature, class T> BasicFeatureGroup<dimensions, Feature, T>* BasicFeatureGroup<dimensions, Feature, T>::remove(Feature* feature) {
CORRADE_ASSERT(feature->_group == this, CORRADE_ASSERT(feature->_group == this,
"SceneGraph::AbstractFeatureGroup::remove(): feature is not part of this group", this); "SceneGraph::AbstractBasicFeatureGroup::remove(): feature is not part of this group", this);
AbstractFeatureGroup<dimensions, T>::remove(feature); AbstractBasicFeatureGroup<dimensions, T>::remove(feature);
feature->_group = nullptr; feature->_group = nullptr;
return this; return this;
} }

8
src/SceneGraph/FeatureGroup.hpp

@ -35,16 +35,16 @@
namespace Magnum { namespace SceneGraph { namespace Magnum { namespace SceneGraph {
/* `= default` causes linker errors in GCC 4.5 */ /* `= default` causes linker errors in GCC 4.5 */
template<UnsignedInt dimensions, class T> AbstractFeatureGroup<dimensions, T>::AbstractFeatureGroup() {} template<UnsignedInt dimensions, class T> AbstractBasicFeatureGroup<dimensions, T>::AbstractBasicFeatureGroup() {}
/* `= default` causes linker errors in GCC 4.4 */ /* `= default` causes linker errors in GCC 4.4 */
template<UnsignedInt dimensions, class T> AbstractFeatureGroup<dimensions, T>::~AbstractFeatureGroup() {} template<UnsignedInt dimensions, class T> AbstractBasicFeatureGroup<dimensions, T>::~AbstractBasicFeatureGroup() {}
template<UnsignedInt dimensions, class T> void AbstractFeatureGroup<dimensions, T>::add(AbstractFeature<dimensions, T>* feature) { template<UnsignedInt dimensions, class T> void AbstractBasicFeatureGroup<dimensions, T>::add(AbstractBasicFeature<dimensions, T>* feature) {
features.push_back(feature); features.push_back(feature);
} }
template<UnsignedInt dimensions, class T> void AbstractFeatureGroup<dimensions, T>::remove(AbstractFeature<dimensions, T>* feature) { template<UnsignedInt dimensions, class T> void AbstractBasicFeatureGroup<dimensions, T>::remove(AbstractBasicFeature<dimensions, T>* feature) {
features.erase(std::find(features.begin(), features.end(), feature)); features.erase(std::find(features.begin(), features.end(), feature));
} }

53
src/SceneGraph/MatrixTransformation2D.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::MatrixTransformation2D * @brief Class Magnum::SceneGraph::BasicMatrixTransformation2D, typedef Magnum::SceneGraph::MatrixTransformation2D
*/ */
#include "Math/Matrix3.h" #include "Math/Matrix3.h"
@ -38,14 +38,9 @@ namespace Magnum { namespace SceneGraph {
@brief Two-dimensional transformation implemented using matrices @brief Two-dimensional transformation implemented using matrices
Uses Math::Matrix3 as underlying type. Uses Math::Matrix3 as underlying type.
@see @ref scenegraph, RigidMatrixTransformation2D, MatrixTransformation3D @see @ref MatrixTransformation2D, @ref scenegraph, @ref RigidBasicMatrixTransformation2D, @ref BasicMatrixTransformation3D
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<class T> class BasicMatrixTransformation2D: public AbstractBasicTranslationRotationScaling2D<T> {
template<class T>
#else
template<class T = Float>
#endif
class MatrixTransformation2D: public AbstractTranslationRotationScaling2D<T> {
public: public:
/** @brief Underlying transformation type */ /** @brief Underlying transformation type */
typedef Math::Matrix3<T> DataType; typedef Math::Matrix3<T> DataType;
@ -76,16 +71,16 @@ class MatrixTransformation2D: public AbstractTranslationRotationScaling2D<T> {
* @brief Set transformation * @brief Set transformation
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
*/ */
Object<MatrixTransformation2D<T>>* setTransformation(const Math::Matrix3<T>& transformation) { Object<BasicMatrixTransformation2D<T>>* setTransformation(const Math::Matrix3<T>& transformation) {
/* Setting transformation is forbidden for the scene */ /* Setting transformation is forbidden for the scene */
/** @todo Assert for this? */ /** @todo Assert for this? */
/** @todo Do this in some common code so we don't need to include Object? */ /** @todo Do this in some common code so we don't need to include Object? */
if(!static_cast<Object<MatrixTransformation2D<T>>*>(this)->isScene()) { if(!static_cast<Object<BasicMatrixTransformation2D<T>>*>(this)->isScene()) {
_transformation = transformation; _transformation = transformation;
static_cast<Object<MatrixTransformation2D<T>>*>(this)->setDirty(); static_cast<Object<BasicMatrixTransformation2D<T>>*>(this)->setDirty();
} }
return static_cast<Object<MatrixTransformation2D<T>>*>(this); return static_cast<Object<BasicMatrixTransformation2D<T>>*>(this);
} }
/** /**
@ -94,43 +89,43 @@ class MatrixTransformation2D: public AbstractTranslationRotationScaling2D<T> {
* @param type Transformation type * @param type Transformation type
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
*/ */
Object<MatrixTransformation2D<T>>* transform(const Math::Matrix3<T>& transformation, TransformationType type = TransformationType::Global) { Object<BasicMatrixTransformation2D<T>>* transform(const Math::Matrix3<T>& transformation, TransformationType type = TransformationType::Global) {
setTransformation(type == TransformationType::Global ? setTransformation(type == TransformationType::Global ?
transformation*_transformation : _transformation*transformation); transformation*_transformation : _transformation*transformation);
return static_cast<Object<MatrixTransformation2D<T>>*>(this); return static_cast<Object<BasicMatrixTransformation2D<T>>*>(this);
} }
/** @copydoc AbstractTranslationRotationScaling2D::resetTransformation() */ /** @copydoc AbstractTranslationRotationScaling2D::resetTransformation() */
Object<MatrixTransformation2D<T>>* resetTransformation() { Object<BasicMatrixTransformation2D<T>>* resetTransformation() {
setTransformation({}); setTransformation({});
return static_cast<Object<MatrixTransformation2D<T>>*>(this); return static_cast<Object<BasicMatrixTransformation2D<T>>*>(this);
} }
/** /**
* @copydoc AbstractTranslationRotationScaling2D::translate() * @copydoc AbstractTranslationRotationScaling2D::translate()
* Same as calling transform() with Matrix3::translation(). * Same as calling transform() with Matrix3::translation().
*/ */
Object<MatrixTransformation2D<T>>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) { Object<BasicMatrixTransformation2D<T>>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
transform(Math::Matrix3<T>::translation(vector), type); transform(Math::Matrix3<T>::translation(vector), type);
return static_cast<Object<MatrixTransformation2D<T>>*>(this); return static_cast<Object<BasicMatrixTransformation2D<T>>*>(this);
} }
/** /**
* @copydoc AbstractTranslationRotationScaling2D::rotate() * @copydoc AbstractTranslationRotationScaling2D::rotate()
* Same as calling transform() with Matrix3::rotation(). * Same as calling transform() with Matrix3::rotation().
*/ */
Object<MatrixTransformation2D<T>>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { Object<BasicMatrixTransformation2D<T>>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transform(Math::Matrix3<T>::rotation(angle), type); transform(Math::Matrix3<T>::rotation(angle), type);
return static_cast<Object<MatrixTransformation2D<T>>*>(this); return static_cast<Object<BasicMatrixTransformation2D<T>>*>(this);
} }
/** /**
* @copydoc AbstractTranslationRotationScaling2D::scale() * @copydoc AbstractTranslationRotationScaling2D::scale()
* Same as calling transform() with Matrix3::scaling(). * Same as calling transform() with Matrix3::scaling().
*/ */
Object<MatrixTransformation2D<T>>* scale(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) { Object<BasicMatrixTransformation2D<T>>* scale(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
transform(Math::Matrix3<T>::scaling(vector), type); transform(Math::Matrix3<T>::scaling(vector), type);
return static_cast<Object<MatrixTransformation2D<T>>*>(this); return static_cast<Object<BasicMatrixTransformation2D<T>>*>(this);
} }
/** /**
@ -142,9 +137,9 @@ class MatrixTransformation2D: public AbstractTranslationRotationScaling2D<T> {
* *
* Same as calling transform() with Matrix3::reflection(). * Same as calling transform() with Matrix3::reflection().
*/ */
Object<MatrixTransformation2D<T>>* reflect(const Math::Vector2<T>& normal, TransformationType type = TransformationType::Global) { Object<BasicMatrixTransformation2D<T>>* reflect(const Math::Vector2<T>& normal, TransformationType type = TransformationType::Global) {
transform(Math::Matrix3<T>::reflection(normal), type); transform(Math::Matrix3<T>::reflection(normal), type);
return static_cast<Object<MatrixTransformation2D<T>>*>(this); return static_cast<Object<BasicMatrixTransformation2D<T>>*>(this);
} }
/** /**
@ -153,14 +148,14 @@ class MatrixTransformation2D: public AbstractTranslationRotationScaling2D<T> {
* if you want to move it above all. * if you want to move it above all.
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
*/ */
Object<MatrixTransformation2D<T>>* move(Object<MatrixTransformation2D<T>>* under) { Object<BasicMatrixTransformation2D<T>>* move(Object<BasicMatrixTransformation2D<T>>* under) {
static_cast<Object<MatrixTransformation2D>*>(this)->Containers::template LinkedList<Object<MatrixTransformation2D<T>>>::move(this, under); static_cast<Object<BasicMatrixTransformation2D>*>(this)->Containers::template LinkedList<Object<BasicMatrixTransformation2D<T>>>::move(this, under);
return static_cast<Object<MatrixTransformation2D<T>>*>(this); return static_cast<Object<BasicMatrixTransformation2D<T>>*>(this);
} }
protected: protected:
/* Allow construction only from Object */ /* Allow construction only from Object */
explicit MatrixTransformation2D(); explicit BasicMatrixTransformation2D();
private: private:
void doResetTransformation() override final { resetTransformation(); } void doResetTransformation() override final { resetTransformation(); }
@ -180,7 +175,7 @@ class MatrixTransformation2D: public AbstractTranslationRotationScaling2D<T> {
Math::Matrix3<T> _transformation; Math::Matrix3<T> _transformation;
}; };
template<class T> inline MatrixTransformation2D<T>::MatrixTransformation2D() = default; template<class T> inline BasicMatrixTransformation2D<T>::BasicMatrixTransformation2D() = default;
}} }}

66
src/SceneGraph/MatrixTransformation3D.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::MatrixTransformation3D * @brief Class Magnum::SceneGraph::BasicMatrixTransformation3D, typedef Magnum::SceneGraph::MatrixTransformation3D
*/ */
#include "Math/Matrix4.h" #include "Math/Matrix4.h"
@ -38,14 +38,9 @@ namespace Magnum { namespace SceneGraph {
@brief Three-dimensional transformation implemented using matrices @brief Three-dimensional transformation implemented using matrices
Uses Math::Matrix4 as underlying type. Uses Math::Matrix4 as underlying type.
@see @ref scenegraph, RigidMatrixTransformation3D, MatrixTransformation2D @see @ref MatrixTransformation3D, @ref scenegraph, @ref BasicRigidMatrixTransformation3D, @ref BasicMatrixTransformation2D
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<class T> class BasicMatrixTransformation3D: public AbstractBasicTranslationRotationScaling3D<T> {
template<class T>
#else
template<class T = Float>
#endif
class MatrixTransformation3D: public AbstractTranslationRotationScaling3D<T> {
public: public:
/** @brief Underlying transformation type */ /** @brief Underlying transformation type */
typedef Math::Matrix4<T> DataType; typedef Math::Matrix4<T> DataType;
@ -76,22 +71,22 @@ class MatrixTransformation3D: public AbstractTranslationRotationScaling3D<T> {
* @brief Set transformation * @brief Set transformation
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
*/ */
Object<MatrixTransformation3D<T>>* setTransformation(const Math::Matrix4<T>& transformation) { Object<BasicMatrixTransformation3D<T>>* setTransformation(const Math::Matrix4<T>& transformation) {
/* Setting transformation is forbidden for the scene */ /* Setting transformation is forbidden for the scene */
/** @todo Assert for this? */ /** @todo Assert for this? */
/** @todo Do this in some common code so we don't need to include Object? */ /** @todo Do this in some common code so we don't need to include Object? */
if(!static_cast<Object<MatrixTransformation3D<T>>*>(this)->isScene()) { if(!static_cast<Object<BasicMatrixTransformation3D<T>>*>(this)->isScene()) {
_transformation = transformation; _transformation = transformation;
static_cast<Object<MatrixTransformation3D<T>>*>(this)->setDirty(); static_cast<Object<BasicMatrixTransformation3D<T>>*>(this)->setDirty();
} }
return static_cast<Object<MatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
} }
/** @copydoc AbstractTranslationRotationScaling3D::resetTransformation() */ /** @copydoc AbstractTranslationRotationScaling3D::resetTransformation() */
Object<MatrixTransformation3D<T>>* resetTransformation() { Object<BasicMatrixTransformation3D<T>>* resetTransformation() {
setTransformation({}); setTransformation({});
return static_cast<Object<MatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
} }
/** /**
@ -100,28 +95,28 @@ class MatrixTransformation3D: public AbstractTranslationRotationScaling3D<T> {
* @param type Transformation type * @param type Transformation type
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
*/ */
Object<MatrixTransformation3D<T>>* transform(const Math::Matrix4<T>& transformation, TransformationType type = TransformationType::Global) { Object<BasicMatrixTransformation3D<T>>* transform(const Math::Matrix4<T>& transformation, TransformationType type = TransformationType::Global) {
setTransformation(type == TransformationType::Global ? setTransformation(type == TransformationType::Global ?
transformation*_transformation : _transformation*transformation); transformation*_transformation : _transformation*transformation);
return static_cast<Object<MatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
} }
/** /**
* @copydoc AbstractTranslationRotationScaling3D::translate() * @copydoc AbstractTranslationRotationScaling3D::translate()
* Same as calling transform() with Matrix4::translation(). * Same as calling transform() with Matrix4::translation().
*/ */
Object<MatrixTransformation3D<T>>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) { Object<BasicMatrixTransformation3D<T>>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::translation(vector), type); transform(Math::Matrix4<T>::translation(vector), type);
return static_cast<Object<MatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
} }
/** /**
* @copydoc AbstractTranslationRotationScaling3D::rotate() * @copydoc AbstractTranslationRotationScaling3D::rotate()
* Same as calling transform() with Matrix4::rotation(). * Same as calling transform() with Matrix4::rotation().
*/ */
Object<MatrixTransformation3D<T>>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) { Object<BasicMatrixTransformation3D<T>>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::rotation(angle, normalizedAxis), type); transform(Math::Matrix4<T>::rotation(angle, normalizedAxis), type);
return static_cast<Object<MatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
} }
/** /**
@ -132,9 +127,9 @@ class MatrixTransformation3D: public AbstractTranslationRotationScaling3D<T> {
* *
* Same as calling transform() with Matrix4::rotationX(). * Same as calling transform() with Matrix4::rotationX().
*/ */
Object<MatrixTransformation3D<T>>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { Object<BasicMatrixTransformation3D<T>>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::rotationX(angle), type); transform(Math::Matrix4<T>::rotationX(angle), type);
return static_cast<Object<MatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
} }
/** /**
@ -145,9 +140,9 @@ class MatrixTransformation3D: public AbstractTranslationRotationScaling3D<T> {
* *
* Same as calling transform() with Matrix4::rotationY(). * Same as calling transform() with Matrix4::rotationY().
*/ */
Object<MatrixTransformation3D<T>>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { Object<BasicMatrixTransformation3D<T>>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::rotationY(angle), type); transform(Math::Matrix4<T>::rotationY(angle), type);
return static_cast<Object<MatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
} }
/** /**
@ -158,18 +153,18 @@ class MatrixTransformation3D: public AbstractTranslationRotationScaling3D<T> {
* *
* Same as calling transform() with Matrix4::rotationZ(). * Same as calling transform() with Matrix4::rotationZ().
*/ */
Object<MatrixTransformation3D<T>>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { Object<BasicMatrixTransformation3D<T>>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::rotationZ(angle), type); transform(Math::Matrix4<T>::rotationZ(angle), type);
return static_cast<Object<MatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
} }
/** /**
* @copydoc AbstractTranslationRotationScaling3D::scale() * @copydoc AbstractTranslationRotationScaling3D::scale()
* Same as calling transform() with Matrix4::scaling(). * Same as calling transform() with Matrix4::scaling().
*/ */
Object<MatrixTransformation3D<T>>* scale(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) { Object<BasicMatrixTransformation3D<T>>* scale(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::scaling(vector), type); transform(Math::Matrix4<T>::scaling(vector), type);
return static_cast<Object<MatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
} }
/** /**
@ -181,14 +176,14 @@ class MatrixTransformation3D: public AbstractTranslationRotationScaling3D<T> {
* *
* Same as calling transform() with Matrix4::reflection(). * Same as calling transform() with Matrix4::reflection().
*/ */
Object<MatrixTransformation3D<T>>* reflect(const Math::Vector3<T>& normal, TransformationType type = TransformationType::Global) { Object<BasicMatrixTransformation3D<T>>* reflect(const Math::Vector3<T>& normal, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::reflection(normal), type); transform(Math::Matrix4<T>::reflection(normal), type);
return static_cast<Object<MatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
} }
protected: protected:
/* Allow construction only from Object */ /* Allow construction only from Object */
explicit MatrixTransformation3D(); explicit BasicMatrixTransformation3D();
private: private:
void doResetTransformation() override final { resetTransformation(); } void doResetTransformation() override final { resetTransformation(); }
@ -220,7 +215,14 @@ class MatrixTransformation3D: public AbstractTranslationRotationScaling3D<T> {
Math::Matrix4<T> _transformation; Math::Matrix4<T> _transformation;
}; };
template<class T> inline MatrixTransformation3D<T>::MatrixTransformation3D() = default; template<class T> inline BasicMatrixTransformation3D<T>::BasicMatrixTransformation3D() = default;
/**
@brief Three-dimensional transformation for float scenes implemented using matrices
@see @ref MatrixTransformation2D
*/
typedef BasicMatrixTransformation3D<Float> MatrixTransformation3D;
}} }}

10
src/SceneGraph/Object.h

@ -59,8 +59,8 @@ for introduction.
Common usage is to typedef Object with desired transformation type to save Common usage is to typedef Object with desired transformation type to save
unnecessary typing later, along with Scene and possibly other types, e.g.: unnecessary typing later, along with Scene and possibly other types, e.g.:
@code @code
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D<>> Scene3D; typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D;
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D<>> Object3D; typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
@endcode @endcode
Uses Corrade::Containers::LinkedList for parent/children relationship. Uses Corrade::Containers::LinkedList for parent/children relationship.
@ -88,7 +88,7 @@ See @ref compilation-speedup-hpp for more information.
@see Scene, AbstractFeature, AbstractTransformation, DebugTools::ObjectRenderer @see Scene, AbstractFeature, AbstractTransformation, DebugTools::ObjectRenderer
*/ */
template<class Transformation> class MAGNUM_SCENEGRAPH_EXPORT Object: public AbstractObject<Transformation::Dimensions, typename Transformation::Type>, public Transformation template<class Transformation> class MAGNUM_SCENEGRAPH_EXPORT Object: public AbstractBasicObject<Transformation::Dimensions, typename Transformation::Type>, public Transformation
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
, private Containers::LinkedList<Object<Transformation>>, private Containers::LinkedListItem<Object<Transformation>, Object<Transformation>> , private Containers::LinkedList<Object<Transformation>>, private Containers::LinkedListItem<Object<Transformation>, Object<Transformation>>
#endif #endif
@ -305,14 +305,14 @@ template<class Transformation> class MAGNUM_SCENEGRAPH_EXPORT Object: public Abs
return absoluteTransformationMatrix(); return absoluteTransformationMatrix();
} }
std::vector<MatrixType> doTransformationMatrices(const std::vector<AbstractObject<Transformation::Dimensions, typename Transformation::Type>*>& objects, const MatrixType& initialTransformationMatrix) const override final; std::vector<MatrixType> doTransformationMatrices(const std::vector<AbstractBasicObject<Transformation::Dimensions, typename Transformation::Type>*>& objects, const MatrixType& initialTransformationMatrix) const override final;
typename Transformation::DataType MAGNUM_SCENEGRAPH_LOCAL computeJointTransformation(const std::vector<Object<Transformation>*>& jointObjects, std::vector<typename Transformation::DataType>& jointTransformations, const std::size_t joint, const typename Transformation::DataType& initialTransformation) const; typename Transformation::DataType MAGNUM_SCENEGRAPH_LOCAL computeJointTransformation(const std::vector<Object<Transformation>*>& jointObjects, std::vector<typename Transformation::DataType>& jointTransformations, const std::size_t joint, const typename Transformation::DataType& initialTransformation) const;
bool MAGNUM_SCENEGRAPH_LOCAL doIsDirty() const override final { return isDirty(); } bool MAGNUM_SCENEGRAPH_LOCAL doIsDirty() const override final { return isDirty(); }
void MAGNUM_SCENEGRAPH_LOCAL doSetDirty() override final { setDirty(); } void MAGNUM_SCENEGRAPH_LOCAL doSetDirty() override final { setDirty(); }
void MAGNUM_SCENEGRAPH_LOCAL doSetClean() override final { setClean(); } void MAGNUM_SCENEGRAPH_LOCAL doSetClean() override final { setClean(); }
void doSetClean(const std::vector<AbstractObject<Transformation::Dimensions, typename Transformation::Type>*>& objects) override final; void doSetClean(const std::vector<AbstractBasicObject<Transformation::Dimensions, typename Transformation::Type>*>& objects) override final;
void MAGNUM_SCENEGRAPH_LOCAL setClean(const typename Transformation::DataType& absoluteTransformation); void MAGNUM_SCENEGRAPH_LOCAL setClean(const typename Transformation::DataType& absoluteTransformation);

16
src/SceneGraph/Object.hpp

@ -38,11 +38,11 @@
namespace Magnum { namespace SceneGraph { namespace Magnum { namespace SceneGraph {
template<UnsignedInt dimensions, class T> AbstractObject<dimensions, T>::AbstractObject() {} template<UnsignedInt dimensions, class T> AbstractBasicObject<dimensions, T>::AbstractBasicObject() {}
template<UnsignedInt dimensions, class T> AbstractObject<dimensions, T>::~AbstractObject() {} template<UnsignedInt dimensions, class T> AbstractBasicObject<dimensions, T>::~AbstractBasicObject() {}
template<UnsignedInt dimensions, class T> AbstractTransformation<dimensions, T>::AbstractTransformation() {} template<UnsignedInt dimensions, class T> AbstractBasicTransformation<dimensions, T>::AbstractBasicTransformation() {}
template<UnsignedInt dimensions, class T> AbstractTransformation<dimensions, T>::~AbstractTransformation() {} template<UnsignedInt dimensions, class T> AbstractBasicTransformation<dimensions, T>::~AbstractBasicTransformation() {}
/* `= default` causes linker errors in GCC 4.4 */ /* `= default` causes linker errors in GCC 4.4 */
template<class Transformation> Object<Transformation>::~Object() {} template<class Transformation> Object<Transformation>::~Object() {}
@ -114,7 +114,7 @@ template<class Transformation> void Object<Transformation>::setDirty() {
Object<Transformation>* self = static_cast<Object<Transformation>*>(this); Object<Transformation>* self = static_cast<Object<Transformation>*>(this);
/* Make all features dirty */ /* Make all features dirty */
for(AbstractFeature<Transformation::Dimensions, typename Transformation::Type>* i = self->firstFeature(); i; i = i->nextFeature()) for(AbstractBasicFeature<Transformation::Dimensions, typename Transformation::Type>* i = self->firstFeature(); i; i = i->nextFeature())
i->markDirty(); i->markDirty();
/* Make all children dirty */ /* Make all children dirty */
@ -162,7 +162,7 @@ template<class Transformation> void Object<Transformation>::setClean() {
} }
} }
template<class Transformation> auto Object<Transformation>::doTransformationMatrices(const std::vector<AbstractObject<Transformation::Dimensions, typename Transformation::Type>*>& objects, const MatrixType& initialTransformationMatrix) const -> std::vector<MatrixType> { template<class Transformation> auto Object<Transformation>::doTransformationMatrices(const std::vector<AbstractBasicObject<Transformation::Dimensions, typename Transformation::Type>*>& objects, const MatrixType& initialTransformationMatrix) const -> std::vector<MatrixType> {
std::vector<Object<Transformation>*> castObjects(objects.size()); std::vector<Object<Transformation>*> castObjects(objects.size());
for(std::size_t i = 0; i != objects.size(); ++i) for(std::size_t i = 0; i != objects.size(); ++i)
/** @todo Ensure this doesn't crash, somehow */ /** @todo Ensure this doesn't crash, somehow */
@ -324,7 +324,7 @@ template<class Transformation> typename Transformation::DataType Object<Transfor
} }
} }
template<class Transformation> void Object<Transformation>::doSetClean(const std::vector<AbstractObject<Transformation::Dimensions, typename Transformation::Type>*>& objects) { template<class Transformation> void Object<Transformation>::doSetClean(const std::vector<AbstractBasicObject<Transformation::Dimensions, typename Transformation::Type>*>& objects) {
std::vector<Object<Transformation>*> castObjects(objects.size()); std::vector<Object<Transformation>*> castObjects(objects.size());
for(std::size_t i = 0; i != objects.size(); ++i) for(std::size_t i = 0; i != objects.size(); ++i)
/** @todo Ensure this doesn't crash, somehow */ /** @todo Ensure this doesn't crash, somehow */
@ -379,7 +379,7 @@ template<class Transformation> void Object<Transformation>::setClean(const typen
MatrixType matrix, invertedMatrix; MatrixType matrix, invertedMatrix;
/* Clean all features */ /* Clean all features */
for(AbstractFeature<Transformation::Dimensions, typename Transformation::Type>* i = this->firstFeature(); i; i = i->nextFeature()) { for(AbstractBasicFeature<Transformation::Dimensions, typename Transformation::Type>* i = this->firstFeature(); i; i = i->nextFeature()) {
/* Cached absolute transformation, compute it if it wasn't /* Cached absolute transformation, compute it if it wasn't
computed already */ computed already */
if(i->cachedTransformations() & CachedTransformation::Absolute) { if(i->cachedTransformations() & CachedTransformation::Absolute) {

64
src/SceneGraph/RigidMatrixTransformation2D.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::RigidMatrixTransformation2D * @brief Class Magnum::SceneGraph::BasicRigidMatrixTransformation2D, typedef Magnum::SceneGraph::RigidMatrixTransformation2D
*/ */
#include "Math/Matrix3.h" #include "Math/Matrix3.h"
@ -38,17 +38,13 @@ namespace Magnum { namespace SceneGraph {
/** /**
@brief Two-dimensional rigid transformation implemented using matrices @brief Two-dimensional rigid transformation implemented using matrices
Unlike MatrixTransformation2D this class allows only rotation, reflection and Unlike BasicMatrixTransformation2D this class allows only rotation, reflection
translation (no scaling or setting arbitrary transformations). This allows to and translation (no scaling or setting arbitrary transformations). This allows
use Matrix3::invertedRigid() for faster computation of inverse transformations. to use Matrix3::invertedRigid() for faster computation of inverse
@see @ref scenegraph, RigidMatrixTransformation3D transformations.
@see @ref RigidMatrixTransformation2D, @ref scenegraph, @ref BasicRigidMatrixTransformation3D
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<class T> class BasicRigidMatrixTransformation2D: public AbstractBasicTranslationRotation2D<T> {
template<class T>
#else
template<class T = Float>
#endif
class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
public: public:
/** @brief Underlying transformation type */ /** @brief Underlying transformation type */
typedef Math::Matrix3<T> DataType; typedef Math::Matrix3<T> DataType;
@ -84,11 +80,11 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
* Normalizes the rotation part using Math::Algorithms::gramSchmidt() * Normalizes the rotation part using Math::Algorithms::gramSchmidt()
* to prevent rounding errors when rotating the object subsequently. * to prevent rounding errors when rotating the object subsequently.
*/ */
Object<RigidMatrixTransformation2D<T>>* normalizeRotation() { Object<BasicRigidMatrixTransformation2D<T>>* normalizeRotation() {
setTransformationInternal(Math::Matrix3<T>::from( setTransformationInternal(Math::Matrix3<T>::from(
Math::Algorithms::gramSchmidtOrthonormalize(_transformation.rotationScaling()), Math::Algorithms::gramSchmidtOrthonormalize(_transformation.rotationScaling()),
_transformation.translation())); _transformation.translation()));
return static_cast<Object<RigidMatrixTransformation2D<T>>*>(this); return static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this);
} }
/** /**
@ -98,18 +94,18 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
* Expects that the matrix represents rigid transformation. * Expects that the matrix represents rigid transformation.
* @see Matrix3::isRigidTransformation() * @see Matrix3::isRigidTransformation()
*/ */
Object<RigidMatrixTransformation2D<T>>* setTransformation(const Math::Matrix3<T>& transformation) { Object<BasicRigidMatrixTransformation2D<T>>* setTransformation(const Math::Matrix3<T>& transformation) {
CORRADE_ASSERT(transformation.isRigidTransformation(), CORRADE_ASSERT(transformation.isRigidTransformation(),
"SceneGraph::RigidMatrixTransformation2D::setTransformation(): the matrix doesn't represent rigid transformation", "SceneGraph::RigidMatrixTransformation2D::setTransformation(): the matrix doesn't represent rigid transformation",
static_cast<Object<RigidMatrixTransformation2D<T>>*>(this)); static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this));
setTransformationInternal(transformation); setTransformationInternal(transformation);
return static_cast<Object<RigidMatrixTransformation2D<T>>*>(this); return static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this);
} }
/** @copydoc AbstractTranslationRotationScaling2D::resetTransformation() */ /** @copydoc AbstractTranslationRotationScaling2D::resetTransformation() */
Object<RigidMatrixTransformation2D<T>>* resetTransformation() { Object<BasicRigidMatrixTransformation2D<T>>* resetTransformation() {
setTransformationInternal({}); setTransformationInternal({});
return static_cast<Object<RigidMatrixTransformation2D<T>>*>(this); return static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this);
} }
/** /**
@ -121,21 +117,21 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
* Expects that the matrix represents rigid transformation. * Expects that the matrix represents rigid transformation.
* @see Matrix3::isRigidTransformation() * @see Matrix3::isRigidTransformation()
*/ */
Object<RigidMatrixTransformation2D<T>>* transform(const Math::Matrix3<T>& transformation, TransformationType type = TransformationType::Global) { Object<BasicRigidMatrixTransformation2D<T>>* transform(const Math::Matrix3<T>& transformation, TransformationType type = TransformationType::Global) {
CORRADE_ASSERT(transformation.isRigidTransformation(), CORRADE_ASSERT(transformation.isRigidTransformation(),
"SceneGraph::RigidMatrixTransformation2D::transform(): the matrix doesn't represent rigid transformation", "SceneGraph::RigidMatrixTransformation2D::transform(): the matrix doesn't represent rigid transformation",
static_cast<Object<RigidMatrixTransformation2D<T>>*>(this)); static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this));
transformInternal(transformation, type); transformInternal(transformation, type);
return static_cast<Object<RigidMatrixTransformation2D<T>>*>(this); return static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this);
} }
/** /**
* @copydoc AbstractTranslationRotationScaling2D::translate() * @copydoc AbstractTranslationRotationScaling2D::translate()
* Same as calling transform() with Matrix3::translation(). * Same as calling transform() with Matrix3::translation().
*/ */
Object<RigidMatrixTransformation2D<T>>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) { Object<BasicRigidMatrixTransformation2D<T>>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix3<T>::translation(vector), type); transformInternal(Math::Matrix3<T>::translation(vector), type);
return static_cast<Object<RigidMatrixTransformation2D<T>>*>(this); return static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this);
} }
/** /**
@ -147,9 +143,9 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
* Same as calling transform() with Matrix3::rotation(). * Same as calling transform() with Matrix3::rotation().
* @see normalizeRotation() * @see normalizeRotation()
*/ */
Object<RigidMatrixTransformation2D<T>>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { Object<BasicRigidMatrixTransformation2D<T>>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix3<T>::rotation(angle), type); transformInternal(Math::Matrix3<T>::rotation(angle), type);
return static_cast<Object<RigidMatrixTransformation2D<T>>*>(this); return static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this);
} }
/** /**
@ -161,9 +157,9 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
* *
* Same as calling transform() with Matrix3::reflection(). * Same as calling transform() with Matrix3::reflection().
*/ */
Object<RigidMatrixTransformation2D<T>>* reflect(const Math::Vector2<T>& normal, TransformationType type = TransformationType::Global) { Object<BasicRigidMatrixTransformation2D<T>>* reflect(const Math::Vector2<T>& normal, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix3<T>::reflection(normal), type); transformInternal(Math::Matrix3<T>::reflection(normal), type);
return static_cast<Object<RigidMatrixTransformation2D<T>>*>(this); return static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this);
} }
/** /**
@ -172,14 +168,14 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
* if you want to move it above all. * if you want to move it above all.
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
*/ */
Object<RigidMatrixTransformation2D<T>>* move(Object<RigidMatrixTransformation2D<T>>* under) { Object<BasicRigidMatrixTransformation2D<T>>* move(Object<BasicRigidMatrixTransformation2D<T>>* under) {
static_cast<Object<RigidMatrixTransformation2D>*>(this)->Containers::template LinkedList<Object<RigidMatrixTransformation2D<T>>>::move(this, under); static_cast<Object<BasicRigidMatrixTransformation2D>*>(this)->Containers::template LinkedList<Object<BasicRigidMatrixTransformation2D<T>>>::move(this, under);
return static_cast<Object<RigidMatrixTransformation2D<T>>*>(this); return static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this);
} }
protected: protected:
/* Allow construction only from Object */ /* Allow construction only from Object */
explicit RigidMatrixTransformation2D(); explicit BasicRigidMatrixTransformation2D();
private: private:
void doResetTransformation() override final { resetTransformation(); } void doResetTransformation() override final { resetTransformation(); }
@ -197,9 +193,9 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
/* Setting transformation is forbidden for the scene */ /* Setting transformation is forbidden for the scene */
/** @todo Assert for this? */ /** @todo Assert for this? */
/** @todo Do this in some common code so we don't need to include Object? */ /** @todo Do this in some common code so we don't need to include Object? */
if(!static_cast<Object<RigidMatrixTransformation2D<T>>*>(this)->isScene()) { if(!static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this)->isScene()) {
_transformation = transformation; _transformation = transformation;
static_cast<Object<RigidMatrixTransformation2D<T>>*>(this)->setDirty(); static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this)->setDirty();
} }
} }
@ -212,7 +208,7 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
Math::Matrix3<T> _transformation; Math::Matrix3<T> _transformation;
}; };
template<class T> inline RigidMatrixTransformation2D<T>::RigidMatrixTransformation2D() = default; template<class T> inline BasicRigidMatrixTransformation2D<T>::BasicRigidMatrixTransformation2D() = default;
}} }}

77
src/SceneGraph/RigidMatrixTransformation3D.h

@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::SceneGraph::RigidMatrixTransformation3D * @brief Class Magnum::SceneGraph::BasicRigidMatrixTransformation3D, typedef Magnum::SceneGraph::RigidMatrixTransformation3D
*/ */
#include "Math/Matrix4.h" #include "Math/Matrix4.h"
@ -38,17 +38,13 @@ namespace Magnum { namespace SceneGraph {
/** /**
@brief Three-dimensional rigid transformation implemented using matrices @brief Three-dimensional rigid transformation implemented using matrices
Unlike MatrixTransformation3D this class allows only rotation, reflection and Unlike BasicMatrixTransformation3D this class allows only rotation, reflection
translation (no scaling or setting arbitrary transformations). This allows to and translation (no scaling or setting arbitrary transformations). This allows
use Matrix4::invertedRigid() for faster computation of inverse transformations. to use Matrix4::invertedRigid() for faster computation of inverse
@see @ref scenegraph, RigidMatrixTransformation2D transformations.
@see @ref RigidMatrixTransformation3D, @ref scenegraph, @ref BasicRigidMatrixTransformation2D
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT template<class T> class BasicRigidMatrixTransformation3D: public AbstractBasicTranslationRotation3D<T> {
template<class T>
#else
template<class T = Float>
#endif
class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
public: public:
/** @brief Underlying transformation type */ /** @brief Underlying transformation type */
typedef Math::Matrix4<T> DataType; typedef Math::Matrix4<T> DataType;
@ -84,11 +80,11 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* Normalizes the rotation part using Math::Algorithms::gramSchmidt() * Normalizes the rotation part using Math::Algorithms::gramSchmidt()
* to prevent rounding errors when rotating the object subsequently. * to prevent rounding errors when rotating the object subsequently.
*/ */
Object<RigidMatrixTransformation3D<T>>* normalizeRotation() { Object<BasicRigidMatrixTransformation3D<T>>* normalizeRotation() {
setTransformation(Math::Matrix4<T>::from( setTransformation(Math::Matrix4<T>::from(
Math::Algorithms::gramSchmidtOrthonormalize(_transformation.rotationScaling()), Math::Algorithms::gramSchmidtOrthonormalize(_transformation.rotationScaling()),
_transformation.translation())); _transformation.translation()));
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
} }
/** /**
@ -98,18 +94,18 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* Expects that the matrix represents rigid transformation. * Expects that the matrix represents rigid transformation.
* @see Matrix4::isRigidTransformation() * @see Matrix4::isRigidTransformation()
*/ */
Object<RigidMatrixTransformation3D<T>>* setTransformation(const Math::Matrix4<T>& transformation) { Object<BasicRigidMatrixTransformation3D<T>>* setTransformation(const Math::Matrix4<T>& transformation) {
CORRADE_ASSERT(transformation.isRigidTransformation(), CORRADE_ASSERT(transformation.isRigidTransformation(),
"SceneGraph::RigidMatrixTransformation3D::setTransformation(): the matrix doesn't represent rigid transformation", "SceneGraph::RigidMatrixTransformation3D::setTransformation(): the matrix doesn't represent rigid transformation",
static_cast<Object<RigidMatrixTransformation3D<T>>*>(this)); static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this));
setTransformationInternal(transformation); setTransformationInternal(transformation);
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
} }
/** @copydoc AbstractTranslationRotationScaling3D::resetTransformation() */ /** @copydoc AbstractTranslationRotationScaling3D::resetTransformation() */
Object<RigidMatrixTransformation3D<T>>* resetTransformation() { Object<BasicRigidMatrixTransformation3D<T>>* resetTransformation() {
setTransformation({}); setTransformation({});
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
} }
/** /**
@ -121,21 +117,21 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* Expects that the matrix represents rigid transformation. * Expects that the matrix represents rigid transformation.
* @see Matrix4::isRigidTransformation() * @see Matrix4::isRigidTransformation()
*/ */
Object<RigidMatrixTransformation3D<T>>* transform(const Math::Matrix4<T>& transformation, TransformationType type = TransformationType::Global) { Object<BasicRigidMatrixTransformation3D<T>>* transform(const Math::Matrix4<T>& transformation, TransformationType type = TransformationType::Global) {
CORRADE_ASSERT(transformation.isRigidTransformation(), CORRADE_ASSERT(transformation.isRigidTransformation(),
"SceneGraph::RigidMatrixTransformation3D::transform(): the matrix doesn't represent rigid transformation", "SceneGraph::RigidMatrixTransformation3D::transform(): the matrix doesn't represent rigid transformation",
static_cast<Object<RigidMatrixTransformation3D<T>>*>(this)); static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this));
transformInternal(transformation, type); transformInternal(transformation, type);
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
} }
/** /**
* @copydoc AbstractTranslationRotationScaling3D::translate() * @copydoc AbstractTranslationRotationScaling3D::translate()
* Same as calling transform() with Matrix4::translation(). * Same as calling transform() with Matrix4::translation().
*/ */
Object<RigidMatrixTransformation3D<T>>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) { Object<BasicRigidMatrixTransformation3D<T>>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix4<T>::translation(vector), type); transformInternal(Math::Matrix4<T>::translation(vector), type);
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
} }
/** /**
@ -149,9 +145,9 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* @see rotateX(), rotateY(), rotateZ(), Vector3::xAxis(), * @see rotateX(), rotateY(), rotateZ(), Vector3::xAxis(),
* Vector3::yAxis(), Vector3::zAxis(), normalizeRotation() * Vector3::yAxis(), Vector3::zAxis(), normalizeRotation()
*/ */
Object<RigidMatrixTransformation3D<T>>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) { Object<BasicRigidMatrixTransformation3D<T>>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix4<T>::rotation(angle, normalizedAxis), type); transformInternal(Math::Matrix4<T>::rotation(angle, normalizedAxis), type);
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
} }
/** /**
@ -163,9 +159,9 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* Same as calling transform() with Matrix4::rotationX(). * Same as calling transform() with Matrix4::rotationX().
* @see normalizeRotation() * @see normalizeRotation()
*/ */
Object<RigidMatrixTransformation3D<T>>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { Object<BasicRigidMatrixTransformation3D<T>>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix4<T>::rotationX(angle), type); transformInternal(Math::Matrix4<T>::rotationX(angle), type);
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
} }
/** /**
@ -177,9 +173,9 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* Same as calling transform() with Matrix4::rotationY(). * Same as calling transform() with Matrix4::rotationY().
* @see normalizeRotation() * @see normalizeRotation()
*/ */
Object<RigidMatrixTransformation3D<T>>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { Object<BasicRigidMatrixTransformation3D<T>>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix4<T>::rotationY(angle), type); transformInternal(Math::Matrix4<T>::rotationY(angle), type);
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
} }
/** /**
@ -191,9 +187,9 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* Same as calling transform() with Matrix4::rotationZ(). * Same as calling transform() with Matrix4::rotationZ().
* @see normalizeRotation() * @see normalizeRotation()
*/ */
Object<RigidMatrixTransformation3D<T>>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) { Object<BasicRigidMatrixTransformation3D<T>>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix4<T>::rotationZ(angle), type); transformInternal(Math::Matrix4<T>::rotationZ(angle), type);
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
} }
/** /**
@ -205,14 +201,14 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* *
* Same as calling transform() with Matrix4::reflection(). * Same as calling transform() with Matrix4::reflection().
*/ */
Object<RigidMatrixTransformation3D<T>>* reflect(const Math::Vector3<T>& normal, TransformationType type = TransformationType::Global) { Object<BasicRigidMatrixTransformation3D<T>>* reflect(const Math::Vector3<T>& normal, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix4<T>::reflection(normal), type); transformInternal(Math::Matrix4<T>::reflection(normal), type);
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this); return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
} }
protected: protected:
/* Allow construction only from Object */ /* Allow construction only from Object */
explicit RigidMatrixTransformation3D(); explicit BasicRigidMatrixTransformation3D();
private: private:
void doResetTransformation() override final { resetTransformation(); } void doResetTransformation() override final { resetTransformation(); }
@ -242,9 +238,9 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
/* Setting transformation is forbidden for the scene */ /* Setting transformation is forbidden for the scene */
/** @todo Assert for this? */ /** @todo Assert for this? */
/** @todo Do this in some common code so we don't need to include Object? */ /** @todo Do this in some common code so we don't need to include Object? */
if(!static_cast<Object<RigidMatrixTransformation3D<T>>*>(this)->isScene()) { if(!static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this)->isScene()) {
_transformation = transformation; _transformation = transformation;
static_cast<Object<RigidMatrixTransformation3D<T>>*>(this)->setDirty(); static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this)->setDirty();
} }
} }
@ -257,7 +253,14 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
Math::Matrix4<T> _transformation; Math::Matrix4<T> _transformation;
}; };
template<class T> inline RigidMatrixTransformation3D<T>::RigidMatrixTransformation3D() = default; template<class T> inline BasicRigidMatrixTransformation3D<T>::BasicRigidMatrixTransformation3D() = default;
/**
@brief Three-dimensional rigid transformation for float scenes implemented using matrices
@see @ref RigidMatrixTransformation2D
*/
typedef BasicRigidMatrixTransformation3D<Float> RigidMatrixTransformation3D;
}} }}

121
src/SceneGraph/SceneGraph.h

@ -40,102 +40,99 @@ namespace Magnum { namespace SceneGraph {
enum class AspectRatioPolicy: UnsignedByte; enum class AspectRatioPolicy: UnsignedByte;
#endif #endif
template<UnsignedInt dimensions, class T = Float> class AbstractCamera; template<UnsignedInt, class> class AbstractBasicCamera;
#ifndef CORRADE_GCC46_COMPATIBILITY typedef AbstractBasicCamera<2, Float> AbstractCamera2D;
template<class T = Float> using AbstractCamera2D = AbstractCamera<2, T>; typedef AbstractBasicCamera<3, Float> AbstractCamera3D;
template<class T = Float> using AbstractCamera3D = AbstractCamera<3, T>;
#endif
/* Enum CachedTransformation and CachedTransformations used only directly */ /* Enum CachedTransformation and CachedTransformations used only directly */
template<UnsignedInt dimensions, class T = Float> class AbstractFeature; template<UnsignedInt, class> class AbstractBasicFeature;
#ifndef CORRADE_GCC46_COMPATIBILITY typedef AbstractBasicFeature<2, Float> AbstractFeature2D;
template<class T = Float> using AbstractFeature2D = AbstractFeature<2, T>; typedef AbstractBasicFeature<3, Float> AbstractFeature3D;
template<class T = Float> using AbstractFeature3D = AbstractFeature<3, T>;
#endif
template<UnsignedInt dimensions, class T = Float> class AbstractFeatureGroup; template<UnsignedInt, class> class AbstractBasicFeatureGroup;
#ifndef CORRADE_GCC46_COMPATIBILITY typedef AbstractBasicFeatureGroup<2, Float> AbstractFeatureGroup2D;
template<class T = Float> using AbstractFeatureGroup2D = AbstractFeatureGroup<2, T>; typedef AbstractBasicFeatureGroup<3, Float> AbstractFeatureGroup3D;
template<class T = Float> using AbstractFeatureGroup3D = AbstractFeatureGroup<3, T>;
#endif
template<UnsignedInt dimensions, class Derived, class T = Float> class AbstractGroupedFeature; template<UnsignedInt dimensions, class Derived, class T> class AbstractBasicGroupedFeature;
#ifndef CORRADE_GCC46_COMPATIBILITY #ifndef CORRADE_GCC46_COMPATIBILITY
template<class Derived, class T = Float> using AbstractGroupedFeature2D = AbstractGroupedFeature<2, Derived, T>; template<class Derived> using AbstractGroupedFeature2D = AbstractBasicGroupedFeature<2, Derived, Float>;
template<class Derived, class T = Float> using AbstractGroupedFeature3D = AbstractGroupedFeature<3, Derived, T>; template<class Derived> using AbstractGroupedFeature3D = AbstractBasicGroupedFeature<3, Derived, Float>;
#endif #endif
template<UnsignedInt dimensions, class T = Float> class AbstractObject; template<UnsignedInt dimensions, class> class AbstractBasicObject;
#ifndef CORRADE_GCC46_COMPATIBILITY typedef AbstractBasicObject<2, Float> AbstractObject2D;
template<class T = Float> using AbstractObject2D = AbstractObject<2, T>; typedef AbstractBasicObject<3, Float> AbstractObject3D;
template<class T = Float> using AbstractObject3D = AbstractObject<3, T>;
#endif
#ifndef CORRADE_GCC45_COMPATIBILITY #ifndef CORRADE_GCC45_COMPATIBILITY
enum class TransformationType: UnsignedByte; enum class TransformationType: UnsignedByte;
#endif #endif
template<UnsignedInt dimensions, class T = Float> class AbstractTransformation; template<UnsignedInt dimensions, class> class AbstractBasicTransformation;
#ifndef CORRADE_GCC46_COMPATIBILITY typedef AbstractBasicTransformation<2, Float> AbstractTransformation2D;
template<class T = Float> using AbstractTransformation2D = AbstractTransformation<2, T>; typedef AbstractBasicTransformation<3, Float> AbstractTransformation3D;
template<class T = Float> using AbstractTransformation3D = AbstractTransformation<3, T>;
#endif
template<class T = Float> class AbstractTranslationRotation2D; template<class> class AbstractBasicTranslationRotation2D;
template<class T = Float> class AbstractTranslationRotation3D; template<class> class AbstractBasicTranslationRotation3D;
template<class T = Float> class AbstractTranslationRotationScaling2D; typedef AbstractBasicTranslationRotation2D<Float> AbstractTranslationRotation2D;
template<class T = Float> class AbstractTranslationRotationScaling3D; typedef AbstractBasicTranslationRotation3D<Float> AbstractTranslationRotation3D;
template<UnsignedInt dimensions, class T = Float> class Animable; template<class> class AbstractBasicTranslationRotationScaling2D;
#ifndef CORRADE_GCC46_COMPATIBILITY template<class> class AbstractBasicTranslationRotationScaling3D;
template<class T = Float> using Animable2D = Animable<2, T>; typedef AbstractBasicTranslationRotationScaling2D<Float> AbstractTranslationRotationScaling2D;
template<class T = Float> using Animable3D = Animable<3, T>; typedef AbstractBasicTranslationRotationScaling3D<Float> AbstractTranslationRotationScaling3D;
#endif
template<UnsignedInt, class> class BasicAnimable;
typedef BasicAnimable<2, Float> Animable2D;
typedef BasicAnimable<3, Float> Animable3D;
#ifndef CORRADE_GCC45_COMPATIBILITY #ifndef CORRADE_GCC45_COMPATIBILITY
enum class AnimationState: UnsignedByte; enum class AnimationState: UnsignedByte;
#endif #endif
template<UnsignedInt dimensions, class T = Float> class AnimableGroup; template<UnsignedInt, class> class BasicAnimableGroup;
#ifndef CORRADE_GCC46_COMPATIBILITY typedef BasicAnimableGroup<2, Float> AnimableGroup2D;
template<class T = Float> using AnimableGroup2D = AnimableGroup<2, T>; typedef BasicAnimableGroup<3, Float> AnimableGroup3D;
template<class T = Float> using AnimableGroup3D = AnimableGroup<3, T>;
#endif
template<class T = Float> class Camera2D; template<class> class BasicCamera2D;
template<class T = Float> class Camera3D; template<class> class BasicCamera3D;
typedef BasicCamera2D<Float> Camera2D;
typedef BasicCamera3D<Float> Camera3D;
template<UnsignedInt dimensions, class T = Float> class Drawable; template<UnsignedInt, class> class BasicDrawable;
#ifndef CORRADE_GCC46_COMPATIBILITY typedef BasicDrawable<2, Float> Drawable2D;
template<class T = Float> using Drawable2D = Drawable<2, T>; typedef BasicDrawable<3, Float> Drawable3D;
template<class T = Float> using Drawable3D = Drawable<3, T>;
#endif
template<class T = Float> class DualComplexTransformation; template<class> class BasicDualComplexTransformation;
template<class T = Float> class DualQuaternionTransformation; template<class> class BasicDualQuaternionTransformation;
typedef BasicDualComplexTransformation<Float> DualComplexTransformation;
typedef BasicDualQuaternionTransformation<Float> DualQuaternionTransformation;
template<UnsignedInt dimensions, class Feature, class T = Float> class FeatureGroup; template<UnsignedInt dimensions, class Feature, class T> class BasicFeatureGroup;
#ifndef CORRADE_GCC46_COMPATIBILITY #ifndef CORRADE_GCC46_COMPATIBILITY
template<class Feature, class T = Float> using FeatureGroup2D = FeatureGroup<2, Feature, T>; template<class Feature> using BasicFeatureGroup2D = BasicFeatureGroup<2, Feature, Float>;
template<class Feature, class T = Float> using FeatureGroup3D = FeatureGroup<3, Feature, T>; template<class Feature> using BasicFeatureGroup3D = BasicFeatureGroup<3, Feature, Float>;
#endif #endif
#ifndef CORRADE_GCC46_COMPATIBILITY #ifndef CORRADE_GCC46_COMPATIBILITY
template<UnsignedInt dimensions, class T = Float> using DrawableGroup = FeatureGroup<dimensions, Drawable<dimensions, T>, T>; template<UnsignedInt dimensions, class T> using BasicDrawableGroup = BasicFeatureGroup<dimensions, BasicDrawable<dimensions, T>, T>;
template<class T = Float> using DrawableGroup2D = DrawableGroup<2, T>;
template<class T = Float> using DrawableGroup3D = DrawableGroup<3, T>;
#else #else
template<UnsignedInt dimensions, class T = Float> class DrawableGroup; template<UnsignedInt, class> class BasicDrawableGroup;
#endif #endif
typedef BasicDrawableGroup<2, Float> DrawableGroup2D;
typedef BasicDrawableGroup<3, Float> DrawableGroup3D;
template<class T = Float> class MatrixTransformation2D; template<class> class BasicMatrixTransformation2D;
template<class T = Float> class MatrixTransformation3D; template<class> class BasicMatrixTransformation3D;
typedef BasicMatrixTransformation2D<Float> MatrixTransformation2D;
typedef BasicMatrixTransformation3D<Float> MatrixTransformation3D;
template<class Transformation> class Object; template<class Transformation> class Object;
template<class T = Float> class RigidMatrixTransformation2D; template<class> class BasicRigidMatrixTransformation2D;
template<class T = Float> class RigidMatrixTransformation3D; template<class> class BasicRigidMatrixTransformation3D;
typedef BasicRigidMatrixTransformation2D<Float> RigidMatrixTransformation2D;
typedef BasicRigidMatrixTransformation3D<Float> RigidMatrixTransformation3D;
template<class Transformation> class Scene; template<class Transformation> class Scene;
#endif #endif

30
src/SceneGraph/Test/AnimableTest.cpp

@ -45,7 +45,7 @@ class AnimableTest: public TestSuite::Tester {
void debug(); void debug();
}; };
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D<>> Object3D; typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
AnimableTest::AnimableTest() { AnimableTest::AnimableTest() {
addTests({&AnimableTest::state, addTests({&AnimableTest::state,
@ -59,9 +59,9 @@ AnimableTest::AnimableTest() {
} }
void AnimableTest::state() { void AnimableTest::state() {
class StateTrackingAnimable: public SceneGraph::Animable<3> { class StateTrackingAnimable: public SceneGraph::Animable3D {
public: public:
StateTrackingAnimable(AbstractObject<3>* object, AnimableGroup<3>* group = nullptr): SceneGraph::Animable<3>(object, group) { StateTrackingAnimable(AbstractObject3D* object, AnimableGroup3D* group = nullptr): SceneGraph::Animable3D(object, group) {
setDuration(1.0f); setDuration(1.0f);
} }
@ -77,7 +77,7 @@ void AnimableTest::state() {
}; };
Object3D object; Object3D object;
AnimableGroup<3> group; AnimableGroup3D group;
CORRADE_COMPARE(group.runningCount(), 0); CORRADE_COMPARE(group.runningCount(), 0);
/* Verify initial state */ /* Verify initial state */
@ -149,9 +149,9 @@ void AnimableTest::state() {
CORRADE_COMPARE(group.runningCount(), 2); CORRADE_COMPARE(group.runningCount(), 2);
} }
class OneShotAnimable: public SceneGraph::Animable<3> { class OneShotAnimable: public SceneGraph::Animable3D {
public: public:
OneShotAnimable(AbstractObject<3>* object, AnimableGroup<3>* group = nullptr): SceneGraph::Animable<3>(object, group), time(-1.0f) { OneShotAnimable(AbstractObject3D* object, AnimableGroup3D* group = nullptr): SceneGraph::Animable3D(object, group), time(-1.0f) {
setDuration(10.0f); setDuration(10.0f);
setState(AnimationState::Running); setState(AnimationState::Running);
} }
@ -174,9 +174,9 @@ class OneShotAnimable: public SceneGraph::Animable<3> {
}; };
void AnimableTest::step() { void AnimableTest::step() {
class InifiniteAnimable: public SceneGraph::Animable<3> { class InifiniteAnimable: public SceneGraph::Animable3D {
public: public:
InifiniteAnimable(AbstractObject<3>* object, AnimableGroup<3>* group = nullptr): SceneGraph::Animable<3>(object, group), time(-1.0f), delta(0.0f) {} InifiniteAnimable(AbstractObject3D* object, AnimableGroup3D* group = nullptr): SceneGraph::Animable3D(object, group), time(-1.0f), delta(0.0f) {}
Float time, delta; Float time, delta;
@ -188,7 +188,7 @@ void AnimableTest::step() {
}; };
Object3D object; Object3D object;
AnimableGroup<3> group; AnimableGroup3D group;
InifiniteAnimable animable(&object, &group); InifiniteAnimable animable(&object, &group);
/* Calling step() if no object is running should do nothing */ /* Calling step() if no object is running should do nothing */
@ -213,7 +213,7 @@ void AnimableTest::step() {
void AnimableTest::duration() { void AnimableTest::duration() {
Object3D object; Object3D object;
AnimableGroup<3> group; AnimableGroup3D group;
OneShotAnimable animable(&object, &group); OneShotAnimable animable(&object, &group);
CORRADE_VERIFY(!animable.isRepeated()); CORRADE_VERIFY(!animable.isRepeated());
@ -233,9 +233,9 @@ void AnimableTest::duration() {
} }
void AnimableTest::repeat() { void AnimableTest::repeat() {
class RepeatingAnimable: public SceneGraph::Animable<3> { class RepeatingAnimable: public SceneGraph::Animable3D {
public: public:
RepeatingAnimable(AbstractObject<3>* object, AnimableGroup<3>* group = nullptr): SceneGraph::Animable<3>(object, group), time(-1.0f) { RepeatingAnimable(AbstractObject3D* object, AnimableGroup3D* group = nullptr): SceneGraph::Animable3D(object, group), time(-1.0f) {
setDuration(10.0f); setDuration(10.0f);
setState(AnimationState::Running); setState(AnimationState::Running);
setRepeated(true); setRepeated(true);
@ -250,7 +250,7 @@ void AnimableTest::repeat() {
}; };
Object3D object; Object3D object;
AnimableGroup<3> group; AnimableGroup3D group;
RepeatingAnimable animable(&object, &group); RepeatingAnimable animable(&object, &group);
CORRADE_COMPARE(animable.repeatCount(), 0); CORRADE_COMPARE(animable.repeatCount(), 0);
@ -295,7 +295,7 @@ void AnimableTest::repeat() {
void AnimableTest::stop() { void AnimableTest::stop() {
Object3D object; Object3D object;
AnimableGroup<3> group; AnimableGroup3D group;
OneShotAnimable animable(&object, &group); OneShotAnimable animable(&object, &group);
CORRADE_COMPARE(animable.repeatCount(), 0); CORRADE_COMPARE(animable.repeatCount(), 0);
@ -320,7 +320,7 @@ void AnimableTest::stop() {
void AnimableTest::pause() { void AnimableTest::pause() {
Object3D object; Object3D object;
AnimableGroup<3> group; AnimableGroup3D group;
OneShotAnimable animable(&object, &group); OneShotAnimable animable(&object, &group);
/* First two steps, animation is running */ /* First two steps, animation is running */

16
src/SceneGraph/Test/CameraTest.cpp

@ -48,11 +48,9 @@ class CameraTest: public TestSuite::Tester {
void draw(); void draw();
}; };
typedef SceneGraph::Object<SceneGraph::MatrixTransformation2D<>> Object2D; typedef SceneGraph::Object<SceneGraph::MatrixTransformation2D> Object2D;
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D<>> Object3D; typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D<>> Scene3D; typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D;
typedef SceneGraph::Camera2D<> Camera2D;
typedef SceneGraph::Camera3D<> Camera3D;
CameraTest::CameraTest() { CameraTest::CameraTest() {
addTests({&CameraTest::fixAspectRatio, addTests({&CameraTest::fixAspectRatio,
@ -158,12 +156,12 @@ void CameraTest::projectionSizeViewport() {
} }
void CameraTest::draw() { void CameraTest::draw() {
class Drawable: public SceneGraph::Drawable<3> { class Drawable: public SceneGraph::Drawable3D {
public: public:
Drawable(AbstractObject<3>* object, DrawableGroup<3>* group, Matrix4& result): SceneGraph::Drawable<3>(object, group), result(result) {} Drawable(AbstractObject3D* object, DrawableGroup3D* group, Matrix4& result): SceneGraph::Drawable3D(object, group), result(result) {}
protected: protected:
void draw(const Matrix4& transformationMatrix, AbstractCamera<3>*) { void draw(const Matrix4& transformationMatrix, AbstractCamera3D*) {
result = transformationMatrix; result = transformationMatrix;
} }
@ -171,7 +169,7 @@ void CameraTest::draw() {
Matrix4& result; Matrix4& result;
}; };
DrawableGroup<3> group; DrawableGroup3D group;
Scene3D scene; Scene3D scene;
Object3D first(&scene); Object3D first(&scene);

12
src/SceneGraph/Test/DualComplexTransformationTest.cpp

@ -30,8 +30,8 @@
namespace Magnum { namespace SceneGraph { namespace Test { namespace Magnum { namespace SceneGraph { namespace Test {
typedef Object<DualComplexTransformation<>> Object2D; typedef Object<DualComplexTransformation> Object2D;
typedef Scene<DualComplexTransformation<>> Scene2D; typedef Scene<DualComplexTransformation> Scene2D;
class DualComplexTransformationTest: public TestSuite::Tester { class DualComplexTransformationTest: public TestSuite::Tester {
public: public:
@ -67,24 +67,24 @@ DualComplexTransformationTest::DualComplexTransformationTest() {
void DualComplexTransformationTest::fromMatrix() { void DualComplexTransformationTest::fromMatrix() {
Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f}); Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f});
DualComplex c = DualComplex::rotation(Deg(17.0f))*DualComplex::translation({1.0f, -0.3f}); DualComplex c = DualComplex::rotation(Deg(17.0f))*DualComplex::translation({1.0f, -0.3f});
CORRADE_COMPARE(DualComplexTransformation<>::fromMatrix(m), c); CORRADE_COMPARE(DualComplexTransformation::fromMatrix(m), c);
} }
void DualComplexTransformationTest::toMatrix() { void DualComplexTransformationTest::toMatrix() {
DualComplex c = DualComplex::rotation(Deg(17.0f))*DualComplex::translation({1.0f, -0.3f}); DualComplex c = DualComplex::rotation(Deg(17.0f))*DualComplex::translation({1.0f, -0.3f});
Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f}); Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(DualComplexTransformation<>::toMatrix(c), m); CORRADE_COMPARE(DualComplexTransformation::toMatrix(c), m);
} }
void DualComplexTransformationTest::compose() { void DualComplexTransformationTest::compose() {
DualComplex parent = DualComplex::rotation(Deg(17.0f)); DualComplex parent = DualComplex::rotation(Deg(17.0f));
DualComplex child = DualComplex::translation({1.0f, -0.3f}); DualComplex child = DualComplex::translation({1.0f, -0.3f});
CORRADE_COMPARE(DualComplexTransformation<>::compose(parent, child), parent*child); CORRADE_COMPARE(DualComplexTransformation::compose(parent, child), parent*child);
} }
void DualComplexTransformationTest::inverted() { void DualComplexTransformationTest::inverted() {
DualComplex c = DualComplex::rotation(Deg(17.0f))*DualComplex::translation({1.0f, -0.3f}); DualComplex c = DualComplex::rotation(Deg(17.0f))*DualComplex::translation({1.0f, -0.3f});
CORRADE_COMPARE(DualComplexTransformation<>::inverted(c)*c, DualComplex()); CORRADE_COMPARE(DualComplexTransformation::inverted(c)*c, DualComplex());
} }
void DualComplexTransformationTest::setTransformation() { void DualComplexTransformationTest::setTransformation() {

12
src/SceneGraph/Test/DualQuaternionTransformationTest.cpp

@ -30,8 +30,8 @@
namespace Magnum { namespace SceneGraph { namespace Test { namespace Magnum { namespace SceneGraph { namespace Test {
typedef Object<DualQuaternionTransformation<>> Object3D; typedef Object<DualQuaternionTransformation> Object3D;
typedef Scene<DualQuaternionTransformation<>> Scene3D; typedef Scene<DualQuaternionTransformation> Scene3D;
class DualQuaternionTransformationTest: public TestSuite::Tester { class DualQuaternionTransformationTest: public TestSuite::Tester {
public: public:
@ -67,24 +67,24 @@ DualQuaternionTransformationTest::DualQuaternionTransformationTest() {
void DualQuaternionTransformationTest::fromMatrix() { void DualQuaternionTransformationTest::fromMatrix() {
Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f}); Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f});
DualQuaternion q = DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis())*DualQuaternion::translation({1.0f, -0.3f, 2.3f}); DualQuaternion q = DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis())*DualQuaternion::translation({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(DualQuaternionTransformation<>::fromMatrix(m), q); CORRADE_COMPARE(DualQuaternionTransformation::fromMatrix(m), q);
} }
void DualQuaternionTransformationTest::toMatrix() { void DualQuaternionTransformationTest::toMatrix() {
DualQuaternion q = DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis())*DualQuaternion::translation({1.0f, -0.3f, 2.3f}); DualQuaternion q = DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis())*DualQuaternion::translation({1.0f, -0.3f, 2.3f});
Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f}); Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(DualQuaternionTransformation<>::toMatrix(q), m); CORRADE_COMPARE(DualQuaternionTransformation::toMatrix(q), m);
} }
void DualQuaternionTransformationTest::compose() { void DualQuaternionTransformationTest::compose() {
DualQuaternion parent = DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis()); DualQuaternion parent = DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis());
DualQuaternion child = DualQuaternion::translation({1.0f, -0.3f, 2.3f}); DualQuaternion child = DualQuaternion::translation({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(DualQuaternionTransformation<>::compose(parent, child), parent*child); CORRADE_COMPARE(DualQuaternionTransformation::compose(parent, child), parent*child);
} }
void DualQuaternionTransformationTest::inverted() { void DualQuaternionTransformationTest::inverted() {
DualQuaternion q = DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis())*DualQuaternion::translation({1.0f, -0.3f, 2.3f}); DualQuaternion q = DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis())*DualQuaternion::translation({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(DualQuaternionTransformation<>::inverted(q)*q, DualQuaternion()); CORRADE_COMPARE(DualQuaternionTransformation::inverted(q)*q, DualQuaternion());
} }
void DualQuaternionTransformationTest::setTransformation() { void DualQuaternionTransformationTest::setTransformation() {

12
src/SceneGraph/Test/MatrixTransformation2DTest.cpp

@ -29,8 +29,8 @@
namespace Magnum { namespace SceneGraph { namespace Test { namespace Magnum { namespace SceneGraph { namespace Test {
typedef Object<MatrixTransformation2D<>> Object2D; typedef Object<MatrixTransformation2D> Object2D;
typedef Scene<MatrixTransformation2D<>> Scene2D; typedef Scene<MatrixTransformation2D> Scene2D;
class MatrixTransformation2DTest: public TestSuite::Tester { class MatrixTransformation2DTest: public TestSuite::Tester {
public: public:
@ -67,23 +67,23 @@ MatrixTransformation2DTest::MatrixTransformation2DTest() {
void MatrixTransformation2DTest::fromMatrix() { void MatrixTransformation2DTest::fromMatrix() {
Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f}); Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(MatrixTransformation2D<>::fromMatrix(m), m); CORRADE_COMPARE(MatrixTransformation2D::fromMatrix(m), m);
} }
void MatrixTransformation2DTest::toMatrix() { void MatrixTransformation2DTest::toMatrix() {
Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f}); Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(MatrixTransformation2D<>::toMatrix(m), m); CORRADE_COMPARE(MatrixTransformation2D::toMatrix(m), m);
} }
void MatrixTransformation2DTest::compose() { void MatrixTransformation2DTest::compose() {
Matrix3 parent = Matrix3::rotation(Deg(17.0f)); Matrix3 parent = Matrix3::rotation(Deg(17.0f));
Matrix3 child = Matrix3::translation({1.0f, -0.3f}); Matrix3 child = Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(MatrixTransformation2D<>::compose(parent, child), parent*child); CORRADE_COMPARE(MatrixTransformation2D::compose(parent, child), parent*child);
} }
void MatrixTransformation2DTest::inverted() { void MatrixTransformation2DTest::inverted() {
Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f}); Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(MatrixTransformation2D<>::inverted(m)*m, Matrix3()); CORRADE_COMPARE(MatrixTransformation2D::inverted(m)*m, Matrix3());
} }
void MatrixTransformation2DTest::setTransformation() { void MatrixTransformation2DTest::setTransformation() {

12
src/SceneGraph/Test/MatrixTransformation3DTest.cpp

@ -29,8 +29,8 @@
namespace Magnum { namespace SceneGraph { namespace Test { namespace Magnum { namespace SceneGraph { namespace Test {
typedef Object<MatrixTransformation3D<>> Object3D; typedef Object<MatrixTransformation3D> Object3D;
typedef Scene<MatrixTransformation3D<>> Scene3D; typedef Scene<MatrixTransformation3D> Scene3D;
class MatrixTransformation3DTest: public TestSuite::Tester { class MatrixTransformation3DTest: public TestSuite::Tester {
public: public:
@ -67,23 +67,23 @@ MatrixTransformation3DTest::MatrixTransformation3DTest() {
void MatrixTransformation3DTest::fromMatrix() { void MatrixTransformation3DTest::fromMatrix() {
Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f})*Matrix4::scaling({2.0f, 1.4f, -2.1f}); Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f})*Matrix4::scaling({2.0f, 1.4f, -2.1f});
CORRADE_COMPARE(MatrixTransformation3D<>::fromMatrix(m), m); CORRADE_COMPARE(MatrixTransformation3D::fromMatrix(m), m);
} }
void MatrixTransformation3DTest::toMatrix() { void MatrixTransformation3DTest::toMatrix() {
Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f})*Matrix4::scaling({2.0f, 1.4f, -2.1f}); Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f})*Matrix4::scaling({2.0f, 1.4f, -2.1f});
CORRADE_COMPARE(MatrixTransformation3D<>::toMatrix(m), m); CORRADE_COMPARE(MatrixTransformation3D::toMatrix(m), m);
} }
void MatrixTransformation3DTest::compose() { void MatrixTransformation3DTest::compose() {
Matrix4 parent = Matrix4::rotationX(Deg(17.0f)); Matrix4 parent = Matrix4::rotationX(Deg(17.0f));
Matrix4 child = Matrix4::translation({1.0f, -0.3f, 2.3f}); Matrix4 child = Matrix4::translation({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(MatrixTransformation3D<>::compose(parent, child), parent*child); CORRADE_COMPARE(MatrixTransformation3D::compose(parent, child), parent*child);
} }
void MatrixTransformation3DTest::inverted() { void MatrixTransformation3DTest::inverted() {
Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f})*Matrix4::scaling({2.0f, 1.4f, -2.1f}); Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f})*Matrix4::scaling({2.0f, 1.4f, -2.1f});
CORRADE_COMPARE(MatrixTransformation3D<>::inverted(m)*m, Matrix4()); CORRADE_COMPARE(MatrixTransformation3D::inverted(m)*m, Matrix4());
} }
void MatrixTransformation3DTest::setTransformation() { void MatrixTransformation3DTest::setTransformation() {

20
src/SceneGraph/Test/ObjectTest.cpp

@ -47,12 +47,12 @@ class ObjectTest: public TestSuite::Tester {
void setCleanListBulk(); void setCleanListBulk();
}; };
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 CachingObject: public Object3D, AbstractFeature<3> { class CachingObject: public Object3D, AbstractFeature3D {
public: public:
CachingObject(Object3D* parent = nullptr): Object3D(parent), AbstractFeature<3>(this) { CachingObject(Object3D* parent = nullptr): Object3D(parent), AbstractFeature3D(this) {
setCachedTransformations(CachedTransformation::Absolute); setCachedTransformations(CachedTransformation::Absolute);
} }
@ -269,9 +269,9 @@ void ObjectTest::transformationsDuplicate() {
void ObjectTest::setClean() { void ObjectTest::setClean() {
Scene3D scene; Scene3D scene;
class CachingFeature: public AbstractFeature<3> { class CachingFeature: public AbstractFeature3D {
public: public:
CachingFeature(AbstractObject<3>* object): AbstractFeature<3>(object) { CachingFeature(AbstractObject3D* object): AbstractFeature3D(object) {
setCachedTransformations(CachedTransformation::Absolute); setCachedTransformations(CachedTransformation::Absolute);
} }
@ -282,9 +282,9 @@ void ObjectTest::setClean() {
} }
}; };
class CachingInvertedFeature: public AbstractFeature<3> { class CachingInvertedFeature: public AbstractFeature3D {
public: public:
CachingInvertedFeature(AbstractObject<3>* object): AbstractFeature<3>(object) { CachingInvertedFeature(AbstractObject3D* object): AbstractFeature3D(object) {
setCachedTransformations(CachedTransformation::InvertedAbsolute); setCachedTransformations(CachedTransformation::InvertedAbsolute);
} }
@ -367,9 +367,9 @@ void ObjectTest::setClean() {
void ObjectTest::setCleanListHierarchy() { void ObjectTest::setCleanListHierarchy() {
Scene3D scene; Scene3D scene;
class CachingFeature: public AbstractFeature<3> { class CachingFeature: public AbstractFeature3D {
public: public:
CachingFeature(AbstractObject<3>* object): AbstractFeature<3>(object) { CachingFeature(AbstractObject3D* object): AbstractFeature3D(object) {
setCachedTransformations(CachedTransformation::Absolute); setCachedTransformations(CachedTransformation::Absolute);
} }

14
src/SceneGraph/Test/RigidMatrixTransformation2DTest.cpp

@ -30,8 +30,8 @@
namespace Magnum { namespace SceneGraph { namespace Test { namespace Magnum { namespace SceneGraph { namespace Test {
typedef Object<RigidMatrixTransformation2D<>> Object2D; typedef Object<RigidMatrixTransformation2D> Object2D;
typedef Scene<RigidMatrixTransformation2D<>> Scene2D; typedef Scene<RigidMatrixTransformation2D> Scene2D;
class RigidMatrixTransformation2DTest: public TestSuite::Tester { class RigidMatrixTransformation2DTest: public TestSuite::Tester {
public: public:
@ -69,27 +69,27 @@ RigidMatrixTransformation2DTest::RigidMatrixTransformation2DTest() {
void RigidMatrixTransformation2DTest::fromMatrix() { void RigidMatrixTransformation2DTest::fromMatrix() {
std::ostringstream o; std::ostringstream o;
Error::setOutput(&o); Error::setOutput(&o);
RigidMatrixTransformation2D<>::fromMatrix(Matrix3::scaling(Vector2(4.0f))); RigidMatrixTransformation2D::fromMatrix(Matrix3::scaling(Vector2(4.0f)));
CORRADE_COMPARE(o.str(), "SceneGraph::RigidMatrixTransformation2D::fromMatrix(): the matrix doesn't represent rigid transformation\n"); CORRADE_COMPARE(o.str(), "SceneGraph::RigidMatrixTransformation2D::fromMatrix(): the matrix doesn't represent rigid transformation\n");
Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f}); Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(RigidMatrixTransformation2D<>::fromMatrix(m), m); CORRADE_COMPARE(RigidMatrixTransformation2D::fromMatrix(m), m);
} }
void RigidMatrixTransformation2DTest::toMatrix() { void RigidMatrixTransformation2DTest::toMatrix() {
Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f}); Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(RigidMatrixTransformation2D<>::toMatrix(m), m); CORRADE_COMPARE(RigidMatrixTransformation2D::toMatrix(m), m);
} }
void RigidMatrixTransformation2DTest::compose() { void RigidMatrixTransformation2DTest::compose() {
Matrix3 parent = Matrix3::rotation(Deg(17.0f)); Matrix3 parent = Matrix3::rotation(Deg(17.0f));
Matrix3 child = Matrix3::translation({1.0f, -0.3f}); Matrix3 child = Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(RigidMatrixTransformation2D<>::compose(parent, child), parent*child); CORRADE_COMPARE(RigidMatrixTransformation2D::compose(parent, child), parent*child);
} }
void RigidMatrixTransformation2DTest::inverted() { void RigidMatrixTransformation2DTest::inverted() {
Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f}); Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(RigidMatrixTransformation2D<>::inverted(m)*m, Matrix3()); CORRADE_COMPARE(RigidMatrixTransformation2D::inverted(m)*m, Matrix3());
} }
void RigidMatrixTransformation2DTest::setTransformation() { void RigidMatrixTransformation2DTest::setTransformation() {

14
src/SceneGraph/Test/RigidMatrixTransformation3DTest.cpp

@ -30,8 +30,8 @@
namespace Magnum { namespace SceneGraph { namespace Test { namespace Magnum { namespace SceneGraph { namespace Test {
typedef Object<RigidMatrixTransformation3D<>> Object3D; typedef Object<RigidMatrixTransformation3D> Object3D;
typedef Scene<RigidMatrixTransformation3D<>> Scene3D; typedef Scene<RigidMatrixTransformation3D> Scene3D;
class RigidMatrixTransformation3DTest: public TestSuite::Tester { class RigidMatrixTransformation3DTest: public TestSuite::Tester {
public: public:
@ -69,27 +69,27 @@ RigidMatrixTransformation3DTest::RigidMatrixTransformation3DTest() {
void RigidMatrixTransformation3DTest::fromMatrix() { void RigidMatrixTransformation3DTest::fromMatrix() {
std::ostringstream o; std::ostringstream o;
Error::setOutput(&o); Error::setOutput(&o);
RigidMatrixTransformation3D<>::fromMatrix(Matrix4::scaling(Vector3(4.0f))); RigidMatrixTransformation3D::fromMatrix(Matrix4::scaling(Vector3(4.0f)));
CORRADE_COMPARE(o.str(), "SceneGraph::RigidMatrixTransformation3D::fromMatrix(): the matrix doesn't represent rigid transformation\n"); CORRADE_COMPARE(o.str(), "SceneGraph::RigidMatrixTransformation3D::fromMatrix(): the matrix doesn't represent rigid transformation\n");
Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f}); Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(RigidMatrixTransformation3D<>::fromMatrix(m), m); CORRADE_COMPARE(RigidMatrixTransformation3D::fromMatrix(m), m);
} }
void RigidMatrixTransformation3DTest::toMatrix() { void RigidMatrixTransformation3DTest::toMatrix() {
Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f}); Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(RigidMatrixTransformation3D<>::toMatrix(m), m); CORRADE_COMPARE(RigidMatrixTransformation3D::toMatrix(m), m);
} }
void RigidMatrixTransformation3DTest::compose() { void RigidMatrixTransformation3DTest::compose() {
Matrix4 parent = Matrix4::rotationX(Deg(17.0f)); Matrix4 parent = Matrix4::rotationX(Deg(17.0f));
Matrix4 child = Matrix4::translation({1.0f, -0.3f, 2.3f}); Matrix4 child = Matrix4::translation({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(RigidMatrixTransformation3D<>::compose(parent, child), parent*child); CORRADE_COMPARE(RigidMatrixTransformation3D::compose(parent, child), parent*child);
} }
void RigidMatrixTransformation3DTest::inverted() { void RigidMatrixTransformation3DTest::inverted() {
Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f}); Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(RigidMatrixTransformation3D<>::inverted(m)*m, Matrix4()); CORRADE_COMPARE(RigidMatrixTransformation3D::inverted(m)*m, Matrix4());
} }
void RigidMatrixTransformation3DTest::setTransformation() { void RigidMatrixTransformation3DTest::setTransformation() {

4
src/SceneGraph/Test/SceneTest.cpp

@ -37,8 +37,8 @@ class SceneTest: public TestSuite::Tester {
void parent(); void parent();
}; };
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D<Float>> Scene3D; typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D;
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D<Float>> Object3D; typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
SceneTest::SceneTest() { SceneTest::SceneTest() {
addTests({&SceneTest::transformation, addTests({&SceneTest::transformation,

42
src/SceneGraph/instantiation.cpp

@ -37,27 +37,27 @@
namespace Magnum { namespace SceneGraph { namespace Magnum { namespace SceneGraph {
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
template class AbstractObject<2, Float>; template class AbstractBasicObject<2, Float>;
template class AbstractObject<3, Float>; template class AbstractBasicObject<3, Float>;
template class AbstractTransformation<2, Float>; template class AbstractBasicTransformation<2, Float>;
template class AbstractTransformation<3, Float>; template class AbstractBasicTransformation<3, Float>;
template class MAGNUM_SCENEGRAPH_EXPORT AbstractFeature<2, Float>; template class MAGNUM_SCENEGRAPH_EXPORT AbstractBasicFeature<2, Float>;
template class MAGNUM_SCENEGRAPH_EXPORT AbstractFeature<3, Float>; template class MAGNUM_SCENEGRAPH_EXPORT AbstractBasicFeature<3, Float>;
template class AbstractFeatureGroup<2, Float>; template class AbstractBasicFeatureGroup<2, Float>;
template class AbstractFeatureGroup<3, Float>; template class AbstractBasicFeatureGroup<3, Float>;
template class AbstractCamera<2, Float>; template class AbstractBasicCamera<2, Float>;
template class AbstractCamera<3, Float>; template class AbstractBasicCamera<3, Float>;
template class Camera2D<Float>; template class BasicCamera2D<Float>;
template class Camera3D<Float>; template class BasicCamera3D<Float>;
template class MAGNUM_SCENEGRAPH_EXPORT Object<DualComplexTransformation<Float>>; template class MAGNUM_SCENEGRAPH_EXPORT Object<BasicDualComplexTransformation<Float>>;
template class MAGNUM_SCENEGRAPH_EXPORT Object<DualQuaternionTransformation<Float>>; template class MAGNUM_SCENEGRAPH_EXPORT Object<BasicDualQuaternionTransformation<Float>>;
template class MAGNUM_SCENEGRAPH_EXPORT Object<MatrixTransformation2D<Float>>; template class MAGNUM_SCENEGRAPH_EXPORT Object<BasicMatrixTransformation2D<Float>>;
template class MAGNUM_SCENEGRAPH_EXPORT Object<MatrixTransformation3D<Float>>; template class MAGNUM_SCENEGRAPH_EXPORT Object<BasicMatrixTransformation3D<Float>>;
template class MAGNUM_SCENEGRAPH_EXPORT Object<RigidMatrixTransformation2D<Float>>; template class MAGNUM_SCENEGRAPH_EXPORT Object<BasicRigidMatrixTransformation2D<Float>>;
template class MAGNUM_SCENEGRAPH_EXPORT Object<RigidMatrixTransformation3D<Float>>; template class MAGNUM_SCENEGRAPH_EXPORT Object<BasicRigidMatrixTransformation3D<Float>>;
#endif #endif
}} }}

4
src/Shaders/DistanceFieldVector.h

@ -63,7 +63,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
* *
* @see setOutlineColor() * @see setOutlineColor()
*/ */
DistanceFieldVector* setColor(const Color4<>& color) { DistanceFieldVector* setColor(const Color4& color) {
AbstractShaderProgram::setUniform(colorUniform, color); AbstractShaderProgram::setUniform(colorUniform, color);
return this; return this;
} }
@ -74,7 +74,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
* *
* @see setOutlineRange(), setColor() * @see setOutlineRange(), setColor()
*/ */
DistanceFieldVector* setOutlineColor(const Color4<>& color) { DistanceFieldVector* setOutlineColor(const Color4& color) {
AbstractShaderProgram::setUniform(outlineColorUniform, color); AbstractShaderProgram::setUniform(outlineColorUniform, color);
return this; return this;
} }

2
src/Shaders/Flat.h

@ -64,7 +64,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Flat: public Abstra
* @brief Set color * @brief Set color
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
*/ */
Flat<dimensions>* setColor(const Color4<>& color) { Flat<dimensions>* setColor(const Color4& color) {
setUniform(colorUniform, color); setUniform(colorUniform, color);
return this; return this;
} }

4
src/Shaders/MeshVisualizer.cpp

@ -115,9 +115,9 @@ MeshVisualizer::MeshVisualizer(const Flags flags): flags(flags), transformationP
/* Set defaults in OpenGL ES (for desktop they are set in shader code itself) */ /* Set defaults in OpenGL ES (for desktop they are set in shader code itself) */
#ifdef MAGNUM_TARGET_GLES #ifdef MAGNUM_TARGET_GLES
setColor(Color3<>(1.0f)); setColor(Color3(1.0f));
if(flags & Flag::Wireframe) { if(flags & Flag::Wireframe) {
setWireframeColor(Color3<>(0.0f)); setWireframeColor(Color3(0.0f));
setWireframeWidth(1.0f); setWireframeWidth(1.0f);
setSmoothness(2.0f); setSmoothness(2.0f);
} }

4
src/Shaders/MeshVisualizer.h

@ -138,7 +138,7 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizer: public AbstractShaderProgram {
* *
* Initial value is fully opaque white. * Initial value is fully opaque white.
*/ */
MeshVisualizer* setColor(const Color4<>& color) { MeshVisualizer* setColor(const Color4& color) {
setUniform(colorUniform, color); setUniform(colorUniform, color);
return this; return this;
} }
@ -150,7 +150,7 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizer: public AbstractShaderProgram {
* Initial value is fully opaque black. Has effect only if * Initial value is fully opaque black. Has effect only if
* @ref Flag "Flag::Wireframe" is enabled. * @ref Flag "Flag::Wireframe" is enabled.
*/ */
MeshVisualizer* setWireframeColor(const Color4<>& color) { MeshVisualizer* setWireframeColor(const Color4& color) {
if(flags & Flag::Wireframe) setUniform(wireframeColorUniform, color); if(flags & Flag::Wireframe) setUniform(wireframeColorUniform, color);
return this; return this;
} }

8
src/Shaders/Phong.h

@ -55,7 +55,7 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram {
* *
* If not set, default value is `(0.0f, 0.0f, 0.0f)`. * If not set, default value is `(0.0f, 0.0f, 0.0f)`.
*/ */
Phong* setAmbientColor(const Color3<>& color) { Phong* setAmbientColor(const Color3& color) {
setUniform(ambientColorUniform, color); setUniform(ambientColorUniform, color);
return this; return this;
} }
@ -64,7 +64,7 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram {
* @brief Set diffuse color * @brief Set diffuse color
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
*/ */
Phong* setDiffuseColor(const Color3<>& color) { Phong* setDiffuseColor(const Color3& color) {
setUniform(diffuseColorUniform, color); setUniform(diffuseColorUniform, color);
return this; return this;
} }
@ -75,7 +75,7 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram {
* *
* If not set, default value is `(1.0f, 1.0f, 1.0f)`. * If not set, default value is `(1.0f, 1.0f, 1.0f)`.
*/ */
Phong* setSpecularColor(const Color3<>& color) { Phong* setSpecularColor(const Color3& color) {
setUniform(specularColorUniform, color); setUniform(specularColorUniform, color);
return this; return this;
} }
@ -126,7 +126,7 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram {
* *
* If not set, default value is `(1.0f, 1.0f, 1.0f)`. * If not set, default value is `(1.0f, 1.0f, 1.0f)`.
*/ */
Phong* setLightColor(const Color3<>& color) { Phong* setLightColor(const Color3& color) {
setUniform(lightColorUniform, color); setUniform(lightColorUniform, color);
return this; return this;
} }

2
src/Shaders/Vector.h

@ -60,7 +60,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Vector: public Abst
* @brief Set fill color * @brief Set fill color
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
*/ */
Vector* setColor(const Color4<>& color) { Vector* setColor(const Color4& color) {
AbstractShaderProgram::setUniform(colorUniform, color); AbstractShaderProgram::setUniform(colorUniform, color);
return this; return this;
} }

2
src/Shaders/VertexColor.h

@ -50,7 +50,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VertexColor: public
typedef Attribute<0, typename DimensionTraits<dimensions>::VectorType> Position; typedef Attribute<0, typename DimensionTraits<dimensions>::VectorType> Position;
/** @brief Vertex color */ /** @brief Vertex color */
typedef Attribute<1, Color3<>> Color; typedef Attribute<1, Color3> Color;
explicit VertexColor(); explicit VertexColor();

6
src/Shapes/AbstractShape.cpp

@ -31,16 +31,16 @@
namespace Magnum { namespace Shapes { namespace Magnum { namespace Shapes {
template<UnsignedInt dimensions> AbstractShape<dimensions>::AbstractShape(SceneGraph::AbstractObject<dimensions>* object, ShapeGroup<dimensions>* group): SceneGraph::AbstractGroupedFeature<dimensions, AbstractShape<dimensions>>(object, group) { template<UnsignedInt dimensions> AbstractShape<dimensions>::AbstractShape(SceneGraph::AbstractBasicObject<dimensions, Float>* object, ShapeGroup<dimensions>* group): SceneGraph::AbstractBasicGroupedFeature<dimensions, AbstractShape<dimensions>, Float>(object, group) {
this->setCachedTransformations(SceneGraph::CachedTransformation::Absolute); this->setCachedTransformations(SceneGraph::CachedTransformation::Absolute);
} }
template<UnsignedInt dimensions> ShapeGroup<dimensions>* AbstractShape<dimensions>::group() { template<UnsignedInt dimensions> ShapeGroup<dimensions>* AbstractShape<dimensions>::group() {
return static_cast<ShapeGroup<dimensions>*>(SceneGraph::AbstractGroupedFeature<dimensions, AbstractShape<dimensions>>::group()); return static_cast<ShapeGroup<dimensions>*>(SceneGraph::AbstractBasicGroupedFeature<dimensions, AbstractShape<dimensions>, Float>::group());
} }
template<UnsignedInt dimensions> const ShapeGroup<dimensions>* AbstractShape<dimensions>::group() const { template<UnsignedInt dimensions> const ShapeGroup<dimensions>* AbstractShape<dimensions>::group() const {
return static_cast<const ShapeGroup<dimensions>*>(SceneGraph::AbstractGroupedFeature<dimensions, AbstractShape<dimensions>>::group()); return static_cast<const ShapeGroup<dimensions>*>(SceneGraph::AbstractBasicGroupedFeature<dimensions, AbstractShape<dimensions>, Float>::group());
} }
template<UnsignedInt dimensions> auto AbstractShape<dimensions>::type() const -> Type { template<UnsignedInt dimensions> auto AbstractShape<dimensions>::type() const -> Type {

4
src/Shapes/AbstractShape.h

@ -49,7 +49,7 @@ This class is not directly instantiable, see Shape instead. See @ref shapes for
brief introduction. brief introduction.
@see AbstractShape2D, AbstractShape3D @see AbstractShape2D, AbstractShape3D
*/ */
template<UnsignedInt dimensions> class MAGNUM_SHAPES_EXPORT AbstractShape: public SceneGraph::AbstractGroupedFeature<dimensions, AbstractShape<dimensions>> { template<UnsignedInt dimensions> class MAGNUM_SHAPES_EXPORT AbstractShape: public SceneGraph::AbstractBasicGroupedFeature<dimensions, AbstractShape<dimensions>, Float> {
friend const Implementation::AbstractShape<dimensions>* Implementation::getAbstractShape<>(const AbstractShape<dimensions>*); friend const Implementation::AbstractShape<dimensions>* Implementation::getAbstractShape<>(const AbstractShape<dimensions>*);
public: public:
@ -79,7 +79,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHAPES_EXPORT AbstractShape: publi
* @param object Object holding this feature * @param object Object holding this feature
* @param group Group this shape belongs to * @param group Group this shape belongs to
*/ */
explicit AbstractShape(SceneGraph::AbstractObject<dimensions>* object, ShapeGroup<dimensions>* group = nullptr); explicit AbstractShape(SceneGraph::AbstractBasicObject<dimensions, Float>* object, ShapeGroup<dimensions>* group = nullptr);
/** /**
* @brief Shape group containing this shape * @brief Shape group containing this shape

6
src/Shapes/Shape.h

@ -75,17 +75,17 @@ template<class T> class MAGNUM_SHAPES_EXPORT Shape: public AbstractShape<T::Dime
* @param shape Shape * @param shape Shape
* @param group Group this shape belongs to * @param group Group this shape belongs to
*/ */
template<class ...U> explicit Shape(SceneGraph::AbstractObject<T::Dimensions>* object, const T& shape, ShapeGroup<T::Dimensions>* group = nullptr): AbstractShape<T::Dimensions>(object, group) { template<class ...U> explicit Shape(SceneGraph::AbstractBasicObject<T::Dimensions, Float>* object, const T& shape, ShapeGroup<T::Dimensions>* group = nullptr): AbstractShape<T::Dimensions>(object, group) {
Implementation::ShapeHelper<T>::set(*this, shape); Implementation::ShapeHelper<T>::set(*this, shape);
} }
/** @overload */ /** @overload */
template<class ...U> explicit Shape(SceneGraph::AbstractObject<T::Dimensions>* object, T&& shape, ShapeGroup<T::Dimensions>* group = nullptr): AbstractShape<T::Dimensions>(object, group) { template<class ...U> explicit Shape(SceneGraph::AbstractBasicObject<T::Dimensions, Float>* object, T&& shape, ShapeGroup<T::Dimensions>* group = nullptr): AbstractShape<T::Dimensions>(object, group) {
Implementation::ShapeHelper<T>::set(*this, std::move(shape)); Implementation::ShapeHelper<T>::set(*this, std::move(shape));
} }
/** @overload */ /** @overload */
template<class ...U> explicit Shape(SceneGraph::AbstractObject<T::Dimensions>* object, ShapeGroup<T::Dimensions>* group = nullptr): AbstractShape<T::Dimensions>(object, group) {} template<class ...U> explicit Shape(SceneGraph::AbstractBasicObject<T::Dimensions, Float>* object, ShapeGroup<T::Dimensions>* group = nullptr): AbstractShape<T::Dimensions>(object, group) {}
/** @brief Shape */ /** @brief Shape */
const T& shape() const { return _shape.shape; } const T& shape() const { return _shape.shape; }

4
src/Shapes/ShapeGroup.cpp

@ -31,11 +31,11 @@ namespace Magnum { namespace Shapes {
template<UnsignedInt dimensions> void ShapeGroup<dimensions>::setClean() { template<UnsignedInt dimensions> void ShapeGroup<dimensions>::setClean() {
/* Clean all objects */ /* Clean all objects */
if(!this->isEmpty()) { if(!this->isEmpty()) {
std::vector<SceneGraph::AbstractObject<dimensions>*> objects(this->size()); std::vector<SceneGraph::AbstractBasicObject<dimensions, Float>*> objects(this->size());
for(std::size_t i = 0; i != this->size(); ++i) for(std::size_t i = 0; i != this->size(); ++i)
objects[i] = (*this)[i]->object(); objects[i] = (*this)[i]->object();
SceneGraph::AbstractObject<dimensions>::setClean(objects); SceneGraph::AbstractBasicObject<dimensions, Float>::setClean(objects);
} }
dirty = false; dirty = false;

2
src/Shapes/ShapeGroup.h

@ -43,7 +43,7 @@ namespace Magnum { namespace Shapes {
See Shape for more information. See @ref shapes for brief introduction. See Shape for more information. See @ref shapes for brief introduction.
@see @ref scenegraph, ShapeGroup2D, ShapeGroup3D @see @ref scenegraph, ShapeGroup2D, ShapeGroup3D
*/ */
template<UnsignedInt dimensions> class MAGNUM_SHAPES_EXPORT ShapeGroup: public SceneGraph::FeatureGroup<dimensions, AbstractShape<dimensions>> { template<UnsignedInt dimensions> class MAGNUM_SHAPES_EXPORT ShapeGroup: public SceneGraph::BasicFeatureGroup<dimensions, AbstractShape<dimensions>, Float> {
friend class AbstractShape<dimensions>; friend class AbstractShape<dimensions>;
public: public:

8
src/Shapes/Test/ShapeTest.cpp

@ -44,10 +44,10 @@ class ShapeTest: public TestSuite::Tester {
void shapeGroup(); void shapeGroup();
}; };
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation2D<>> Scene2D; typedef SceneGraph::Scene<SceneGraph::MatrixTransformation2D> Scene2D;
typedef SceneGraph::Object<SceneGraph::MatrixTransformation2D<>> Object2D; typedef SceneGraph::Object<SceneGraph::MatrixTransformation2D> Object2D;
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D<>> Scene3D; typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D;
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D<>> Object3D; typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
ShapeTest::ShapeTest() { ShapeTest::ShapeTest() {
addTests({&ShapeTest::clean, addTests({&ShapeTest::clean,

8
src/Swizzle.h

@ -47,10 +47,10 @@ namespace Implementation {
template<class T> struct TypeForSize<2, T> { typedef Math::Vector2<typename T::Type> Type; }; template<class T> struct TypeForSize<2, T> { typedef Math::Vector2<typename T::Type> Type; };
template<class T> struct TypeForSize<3, T> { typedef Math::Vector3<typename T::Type> Type; }; template<class T> struct TypeForSize<3, T> { typedef Math::Vector3<typename T::Type> Type; };
template<class T> struct TypeForSize<4, T> { typedef Math::Vector4<typename T::Type> Type; }; template<class T> struct TypeForSize<4, T> { typedef Math::Vector4<typename T::Type> Type; };
template<class T> struct TypeForSize<3, Color3<T>> { typedef Color3<T> Type; }; template<class T> struct TypeForSize<3, BasicColor3<T>> { typedef BasicColor3<T> Type; };
template<class T> struct TypeForSize<3, Color4<T>> { typedef Color3<T> Type; }; template<class T> struct TypeForSize<3, BasicColor4<T>> { typedef BasicColor3<T> Type; };
template<class T> struct TypeForSize<4, Color3<T>> { typedef Color4<T> Type; }; template<class T> struct TypeForSize<4, BasicColor3<T>> { typedef BasicColor4<T> Type; };
template<class T> struct TypeForSize<4, Color4<T>> { typedef Color4<T> Type; }; template<class T> struct TypeForSize<4, BasicColor4<T>> { typedef BasicColor4<T> Type; };
} }
/** /**

94
src/Test/ColorTest.cpp

@ -52,10 +52,8 @@ class ColorTest: public TestSuite::Tester {
void configuration(); void configuration();
}; };
typedef Magnum::Color3<UnsignedByte> Color3; typedef Magnum::BasicColor3<UnsignedByte> Color3ub;
typedef Magnum::Color4<UnsignedByte> Color4; typedef Magnum::BasicColor4<UnsignedByte> Color4ub;
typedef Magnum::Color3<Float> Color3f;
typedef Magnum::Color4<Float> Color4f;
ColorTest::ColorTest() { ColorTest::ColorTest() {
addTests({&ColorTest::access, addTests({&ColorTest::access,
@ -77,8 +75,8 @@ ColorTest::ColorTest() {
} }
void ColorTest::access() { void ColorTest::access() {
Color3f c3(15, 255, 10); Color3ub c3(15, 255, 10);
const Color3f cc3(15, 255, 10); const Color3ub cc3(15, 255, 10);
CORRADE_COMPARE(c3.r(), 15); CORRADE_COMPARE(c3.r(), 15);
CORRADE_COMPARE(c3.g(), 255); CORRADE_COMPARE(c3.g(), 255);
@ -87,8 +85,8 @@ void ColorTest::access() {
CORRADE_COMPARE(cc3.g(), 255); CORRADE_COMPARE(cc3.g(), 255);
CORRADE_COMPARE(cc3.b(), 10); CORRADE_COMPARE(cc3.b(), 10);
Color4 c4(125, 98, 51, 22); Color4ub c4(125, 98, 51, 22);
const Color4f cc4(125, 98, 51, 22); const Color4ub cc4(125, 98, 51, 22);
CORRADE_COMPARE(c4.r(), 125); CORRADE_COMPARE(c4.r(), 125);
CORRADE_COMPARE(c4.g(), 98); CORRADE_COMPARE(c4.g(), 98);
@ -101,98 +99,98 @@ void ColorTest::access() {
} }
void ColorTest::fromHue() { void ColorTest::fromHue() {
CORRADE_COMPARE(Color3::fromHSV(Deg(27.0f), 1.0f, 1.0f), Color3(255, 114, 0)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(27.0f), 1.0f, 1.0f), Color3ub(255, 114, 0));
CORRADE_COMPARE(Color3::fromHSV(Deg(86.0f), 1.0f, 1.0f), Color3(144, 255, 0)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(86.0f), 1.0f, 1.0f), Color3ub(144, 255, 0));
CORRADE_COMPARE(Color3::fromHSV(Deg(134.0f), 1.0f, 1.0f), Color3(0, 255, 59)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(134.0f), 1.0f, 1.0f), Color3ub(0, 255, 59));
CORRADE_COMPARE(Color3::fromHSV(Deg(191.0f), 1.0f, 1.0f), Color3(0, 208, 255)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(191.0f), 1.0f, 1.0f), Color3ub(0, 208, 255));
CORRADE_COMPARE(Color3::fromHSV(Deg(269.0f), 1.0f, 1.0f), Color3(123, 0, 255)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(269.0f), 1.0f, 1.0f), Color3ub(123, 0, 255));
CORRADE_COMPARE(Color3::fromHSV(Deg(317.0f), 1.0f, 1.0f), Color3(255, 0, 182)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(317.0f), 1.0f, 1.0f), Color3ub(255, 0, 182));
} }
void ColorTest::hue() { void ColorTest::hue() {
CORRADE_COMPARE(Color3(255, 115, 0).hue(), Deg(27.058824f)); CORRADE_COMPARE(Color3ub(255, 115, 0).hue(), Deg(27.058824f));
CORRADE_COMPARE(Color3(145, 255, 0).hue(), Deg(85.882353f)); CORRADE_COMPARE(Color3ub(145, 255, 0).hue(), Deg(85.882353f));
CORRADE_COMPARE(Color3(0, 255, 60).hue(), Deg(134.11765f)); CORRADE_COMPARE(Color3ub(0, 255, 60).hue(), Deg(134.11765f));
CORRADE_COMPARE(Color3(0, 208, 255).hue(), Deg(191.05882f)); CORRADE_COMPARE(Color3ub(0, 208, 255).hue(), Deg(191.05882f));
CORRADE_COMPARE(Color3(123, 0, 255).hue(), Deg(268.94117f)); CORRADE_COMPARE(Color3ub(123, 0, 255).hue(), Deg(268.94117f));
CORRADE_COMPARE(Color3(255, 0, 183).hue(), Deg(316.94117f)); CORRADE_COMPARE(Color3ub(255, 0, 183).hue(), Deg(316.94117f));
} }
void ColorTest::fromSaturation() { void ColorTest::fromSaturation() {
CORRADE_COMPARE(Color3::fromHSV(Deg(0.0f), 0.702f, 1.0f), Color3(255, 75, 75)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(0.0f), 0.702f, 1.0f), Color3ub(255, 75, 75));
} }
void ColorTest::saturation() { void ColorTest::saturation() {
CORRADE_COMPARE(Color3(255, 76, 76).saturation(), 0.701961f); CORRADE_COMPARE(Color3ub(255, 76, 76).saturation(), 0.701961f);
CORRADE_COMPARE(Color3().saturation(), 0.0f); CORRADE_COMPARE(Color3ub().saturation(), 0.0f);
} }
void ColorTest::fromValue() { void ColorTest::fromValue() {
CORRADE_COMPARE(Color3::fromHSV(Deg(0.0f), 1.0f, 0.522f), Color3(133, 0, 0)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(0.0f), 1.0f, 0.522f), Color3ub(133, 0, 0));
} }
void ColorTest::value() { void ColorTest::value() {
CORRADE_COMPARE(Color3(133, 0, 0).value(), 0.521569f); CORRADE_COMPARE(Color3ub(133, 0, 0).value(), 0.521569f);
} }
void ColorTest::hsv() { void ColorTest::hsv() {
CORRADE_COMPARE(Color3::fromHSV(Deg(230.0f), 0.749f, 0.427f), Color3(27, 40, 108)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(230.0f), 0.749f, 0.427f), Color3ub(27, 40, 108));
Deg hue; Deg hue;
Float saturation, value; Float saturation, value;
std::tie(hue, saturation, value) = Color3(27, 41, 109).toHSV(); std::tie(hue, saturation, value) = Color3ub(27, 41, 109).toHSV();
CORRADE_COMPARE(hue, Deg(229.756106f)); CORRADE_COMPARE(hue, Deg(229.756106f));
CORRADE_COMPARE(saturation, 0.752294f); CORRADE_COMPARE(saturation, 0.752294f);
CORRADE_COMPARE(value, 0.427451f); CORRADE_COMPARE(value, 0.427451f);
} }
void ColorTest::hsvOverflow() { void ColorTest::hsvOverflow() {
CORRADE_COMPARE(Color3::fromHSV(Deg(27.0f-360.0f), 1.0f, 1.0f), Color3(255, 114, 0)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(27.0f-360.0f), 1.0f, 1.0f), Color3ub(255, 114, 0));
CORRADE_COMPARE(Color3::fromHSV(Deg(86.0f-360.0f), 1.0f, 1.0f), Color3(144, 255, 0)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(86.0f-360.0f), 1.0f, 1.0f), Color3ub(144, 255, 0));
CORRADE_COMPARE(Color3::fromHSV(Deg(134.0f-360.0f), 1.0f, 1.0f), Color3(0, 255, 59)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(134.0f-360.0f), 1.0f, 1.0f), Color3ub(0, 255, 59));
CORRADE_COMPARE(Color3::fromHSV(Deg(191.0f-360.0f), 1.0f, 1.0f), Color3(0, 208, 255)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(191.0f-360.0f), 1.0f, 1.0f), Color3ub(0, 208, 255));
CORRADE_COMPARE(Color3::fromHSV(Deg(269.0f-360.0f), 1.0f, 1.0f), Color3(123, 0, 255)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(269.0f-360.0f), 1.0f, 1.0f), Color3ub(123, 0, 255));
CORRADE_COMPARE(Color3::fromHSV(Deg(317.0f-360.0f), 1.0f, 1.0f), Color3(255, 0, 182)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(317.0f-360.0f), 1.0f, 1.0f), Color3ub(255, 0, 182));
CORRADE_COMPARE(Color3::fromHSV(Deg(360.0f+27.0f), 1.0f, 1.0f), Color3(255, 114, 0)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(360.0f+27.0f), 1.0f, 1.0f), Color3ub(255, 114, 0));
CORRADE_COMPARE(Color3::fromHSV(Deg(360.0f+86.0f), 1.0f, 1.0f), Color3(144, 255, 0)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(360.0f+86.0f), 1.0f, 1.0f), Color3ub(144, 255, 0));
CORRADE_COMPARE(Color3::fromHSV(Deg(360.0f+134.0f), 1.0f, 1.0f), Color3(0, 255, 59)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(360.0f+134.0f), 1.0f, 1.0f), Color3ub(0, 255, 59));
CORRADE_COMPARE(Color3::fromHSV(Deg(360.0f+191.0f), 1.0f, 1.0f), Color3(0, 208, 255)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(360.0f+191.0f), 1.0f, 1.0f), Color3ub(0, 208, 255));
CORRADE_COMPARE(Color3::fromHSV(Deg(360.0f+269.0f), 1.0f, 1.0f), Color3(123, 0, 255)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(360.0f+269.0f), 1.0f, 1.0f), Color3ub(123, 0, 255));
CORRADE_COMPARE(Color3::fromHSV(Deg(360.0f+317.0f), 1.0f, 1.0f), Color3(255, 0, 182)); CORRADE_COMPARE(Color3ub::fromHSV(Deg(360.0f+317.0f), 1.0f, 1.0f), Color3ub(255, 0, 182));
} }
void ColorTest::hsvAlpha() { void ColorTest::hsvAlpha() {
CORRADE_COMPARE(Color4::fromHSV(std::make_tuple(Deg(230.0f), 0.749f, 0.427f), 23), Color4(27, 40, 108, 23)); CORRADE_COMPARE(Color4ub::fromHSV(std::make_tuple(Deg(230.0f), 0.749f, 0.427f), 23), Color4ub(27, 40, 108, 23));
CORRADE_COMPARE(Color4::fromHSV(Deg(230.0f), 0.749f, 0.427f, 23), Color4(27, 40, 108, 23)); CORRADE_COMPARE(Color4ub::fromHSV(Deg(230.0f), 0.749f, 0.427f, 23), Color4ub(27, 40, 108, 23));
} }
void ColorTest::debug() { void ColorTest::debug() {
std::ostringstream o; std::ostringstream o;
Debug(&o) << Color3f(0.5f, 0.75f, 1.0f); Debug(&o) << Color3(0.5f, 0.75f, 1.0f);
CORRADE_COMPARE(o.str(), "Vector(0.5, 0.75, 1)\n"); CORRADE_COMPARE(o.str(), "Vector(0.5, 0.75, 1)\n");
o.str({}); o.str({});
Debug(&o) << Color4f(0.5f, 0.75f, 0.0f, 1.0f); Debug(&o) << Color4(0.5f, 0.75f, 0.0f, 1.0f);
CORRADE_COMPARE(o.str(), "Vector(0.5, 0.75, 0, 1)\n"); CORRADE_COMPARE(o.str(), "Vector(0.5, 0.75, 0, 1)\n");
} }
void ColorTest::configuration() { void ColorTest::configuration() {
Utility::Configuration c; Utility::Configuration c;
Color3f color3(0.5f, 0.75f, 1.0f); Color3 color3(0.5f, 0.75f, 1.0f);
std::string value3("0.5 0.75 1"); std::string value3("0.5 0.75 1");
c.setValue("color3", color3); c.setValue("color3", color3);
CORRADE_COMPARE(c.value("color3"), value3); CORRADE_COMPARE(c.value("color3"), value3);
CORRADE_COMPARE(c.value<Color3f>("color3"), color3); CORRADE_COMPARE(c.value<Color3>("color3"), color3);
Color4f color4(0.5f, 0.75f, 0.0f, 1.0f); Color4 color4(0.5f, 0.75f, 0.0f, 1.0f);
std::string value4("0.5 0.75 0 1"); std::string value4("0.5 0.75 0 1");
c.setValue("color4", color4); c.setValue("color4", color4);
CORRADE_COMPARE(c.value("color4"), value4); CORRADE_COMPARE(c.value("color4"), value4);
CORRADE_COMPARE(c.value<Color4f>("color4"), color4); CORRADE_COMPARE(c.value<Color4>("color4"), color4);
} }
}} }}

12
src/Test/SwizzleTest.cpp

@ -50,8 +50,8 @@ void SwizzleTest::rgba() {
void SwizzleTest::type() { void SwizzleTest::type() {
constexpr Vector4i orig; constexpr Vector4i orig;
constexpr Color3<Float> origColor3; constexpr Color3 origColor3;
constexpr Color4<UnsignedByte> origColor4; constexpr BasicColor4<UnsignedByte> origColor4;
/* decltype(a) is not const because a is not constexpr under GCC <= 4.5 */ /* decltype(a) is not const because a is not constexpr under GCC <= 4.5 */
#ifdef CORRADE_GCC45_COMPATIBILITY #ifdef CORRADE_GCC45_COMPATIBILITY
@ -68,16 +68,16 @@ void SwizzleTest::type() {
CORRADE_VERIFY((std::is_same<decltype(c), const Vector4i>::value)); CORRADE_VERIFY((std::is_same<decltype(c), const Vector4i>::value));
constexpr auto d = swizzle<'y', 'z', 'r'>(origColor3); constexpr auto d = swizzle<'y', 'z', 'r'>(origColor3);
CORRADE_VERIFY((std::is_same<decltype(d), const Color3<Float>>::value)); CORRADE_VERIFY((std::is_same<decltype(d), const Color3>::value));
constexpr auto e = swizzle<'y', 'z', 'a'>(origColor4); constexpr auto e = swizzle<'y', 'z', 'a'>(origColor4);
CORRADE_VERIFY((std::is_same<decltype(e), const Color3<UnsignedByte>>::value)); CORRADE_VERIFY((std::is_same<decltype(e), const BasicColor3<UnsignedByte>>::value));
constexpr auto f = swizzle<'y', 'z', 'y', 'x'>(origColor3); constexpr auto f = swizzle<'y', 'z', 'y', 'x'>(origColor3);
CORRADE_VERIFY((std::is_same<decltype(f), const Color4<Float>>::value)); CORRADE_VERIFY((std::is_same<decltype(f), const Color4>::value));
constexpr auto g = swizzle<'y', 'a', 'y', 'x'>(origColor4); constexpr auto g = swizzle<'y', 'a', 'y', 'x'>(origColor4);
CORRADE_VERIFY((std::is_same<decltype(g), const Color4<UnsignedByte>>::value)); CORRADE_VERIFY((std::is_same<decltype(g), const BasicColor4<UnsignedByte>>::value));
#ifdef CORRADE_GCC45_COMPATIBILITY #ifdef CORRADE_GCC45_COMPATIBILITY
#undef const #undef const

4
src/Text/TextRenderer.h

@ -163,7 +163,7 @@ std::tie(mesh, rectangle) = Text::TextRenderer2D::render(font, cache, 0.15f,
// Draw white text centered on the screen // Draw white text centered on the screen
shader->setTransformationProjectionMatrix(projection*Matrix3::translation(-rectangle.width()/2.0f)) shader->setTransformationProjectionMatrix(projection*Matrix3::translation(-rectangle.width()/2.0f))
->setColor(Color3<>(1.0f)); ->setColor(Color3(1.0f));
->use(); ->use();
glyphCache->texture()->bind(Shaders::VectorShader2D::FontTextureLayer); glyphCache->texture()->bind(Shaders::VectorShader2D::FontTextureLayer);
mesh.draw(); mesh.draw();
@ -189,7 +189,7 @@ renderer.render("Hello World Countdown: 10");
// Draw the text centered on the screen // Draw the text centered on the screen
shader->setTransformationProjectionMatrix(projection*Matrix3::translation(-renderer.rectangle().width()/2.0f)) shader->setTransformationProjectionMatrix(projection*Matrix3::translation(-renderer.rectangle().width()/2.0f))
->setColor(Color3<>(1.0f)); ->setColor(Color3(1.0f));
->use(); ->use();
glyphCache->texture()->bind(Shaders::VectorShader2D::FontTextureLayer); glyphCache->texture()->bind(Shaders::VectorShader2D::FontTextureLayer);
renderer.mesh().draw(); renderer.mesh().draw();

2
src/Texture.h

@ -427,7 +427,7 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
return this; return this;
} }
#ifndef MAGNUM_TARGET_GLES3 #ifndef MAGNUM_TARGET_GLES3
Texture<Dimensions>* setBorderColor(const Color4<>& color) { Texture<Dimensions>* setBorderColor(const Color4& color) {
AbstractTexture::setBorderColor(color); AbstractTexture::setBorderColor(color);
return this; return this;
} }

Loading…
Cancel
Save