Browse Source

Merge branch 'master' into compatibility

Conflicts:
	src/CMakeLists.txt
	src/Math/Test/CMakeLists.txt
	src/Physics/ObjectShapeGroup.cpp
	src/Physics/ObjectShapeGroup.h
	src/ResourceManager.h
Vladimír Vondruš 14 years ago
parent
commit
1e393245e6
  1. 26
      doc/compilation-speedup.dox
  2. 5
      doc/scenegraph.dox
  3. 2
      src/AbstractShaderProgram.h
  4. 18
      src/CMakeLists.txt
  5. 4
      src/Color.h
  6. 2
      src/Math/Algorithms/Test/CMakeLists.txt
  7. 106
      src/Math/RectangularMatrix.cpp
  8. 91
      src/Math/RectangularMatrix.h
  9. 27
      src/Math/Test/CMakeLists.txt
  10. 37
      src/Math/Vector.cpp
  11. 18
      src/Math/Vector.h
  12. 1
      src/Physics/Box.h
  13. 12
      src/Physics/CMakeLists.txt
  14. 32
      src/Physics/DebugDrawResourceManager.cpp
  15. 47
      src/Physics/DebugDrawResourceManager.h
  16. 4
      src/Physics/Implementation/AbstractDebugRenderer.cpp
  17. 16
      src/Physics/Implementation/AbstractDebugRenderer.h
  18. 17
      src/Physics/Implementation/BoxRenderer.cpp
  19. 9
      src/Physics/Implementation/BoxRenderer.h
  20. 58
      src/Physics/Implementation/DebugRenderer.h
  21. 46
      src/Physics/ObjectShape.cpp
  22. 98
      src/Physics/ObjectShape.h
  23. 20
      src/Physics/ObjectShapeGroup.cpp
  24. 39
      src/Physics/ObjectShapeGroup.h
  25. 51
      src/Physics/ShapedObject.cpp
  26. 97
      src/Physics/ShapedObject.h
  27. 2
      src/Physics/Test/CMakeLists.txt
  28. 35
      src/Physics/Test/ObjectShapeTest.cpp
  29. 8
      src/Physics/Test/ObjectShapeTest.h
  30. 11
      src/ResourceManager.h
  31. 21
      src/SceneGraph/AbstractCamera.h
  32. 10
      src/SceneGraph/AbstractFeature.h
  33. 13
      src/SceneGraph/AbstractGroupedFeature.h
  34. 27
      src/SceneGraph/AbstractObject.h
  35. 18
      src/SceneGraph/AbstractTransformation.h
  36. 7
      src/SceneGraph/AbstractTranslationRotation2D.h
  37. 7
      src/SceneGraph/AbstractTranslationRotation3D.h
  38. 7
      src/SceneGraph/AbstractTranslationRotationScaling2D.h
  39. 7
      src/SceneGraph/AbstractTranslationRotationScaling3D.h
  40. 1
      src/SceneGraph/CMakeLists.txt
  41. 7
      src/SceneGraph/Camera2D.h
  42. 7
      src/SceneGraph/Camera3D.h
  43. 28
      src/SceneGraph/Drawable.h
  44. 12
      src/SceneGraph/FeatureGroup.h
  45. 9
      src/SceneGraph/MatrixTransformation2D.h
  46. 9
      src/SceneGraph/MatrixTransformation3D.h
  47. 21
      src/SceneGraph/Object.h
  48. 101
      src/SceneGraph/Object.hpp
  49. 94
      src/SceneGraph/SceneGraph.h
  50. 68
      src/SceneGraph/Test/ObjectTest.cpp
  51. 3
      src/SceneGraph/Test/ObjectTest.h
  52. 2
      src/Shaders/FlatShader2D.frag
  53. 4
      src/Test/CMakeLists.txt

26
doc/compilation-speedup.dox

@ -14,6 +14,11 @@ floating-point vectors and matrices like @ref Vector3 and @ref Matrix4, but to
actually use any of them, you have to include the respective header, e.g.
Math/Vector3.h.
You are encouraged to use forward declarations also in your code. However, for
some types it can be too cumbersome -- e.g. too many template parameters,
typedefs etc. In this case a header with forward declarations is usually
available: see SceneGraph/SceneGraph.h for example.
@section compilation-speedup-templates Templates
Many things in %Magnum are templated to allow handling of various types and
@ -33,17 +38,18 @@ Template implementation files have `*.hpp` extension (hinting that they are
something between `*.h` and `*.cpp` files).
Template implementation file can be included along the header itself and it
will just work, but it doesn't positively affect compilation time. If you are
using one template specialization on many places, template implementation
files give you the ability to explicitly instantiate the template in some
source file. Then you can include only the header everywhere else and leave
the rest on the linker.
will just work, but it will negatively affect compilation time. If you are
using one template specialization in many places, the compiler performs
compilation of the same template specialization many times. Template
implementation files give you the ability to explicitly instantiate the
template only once in some dedicated source file. Then you can include just
the header everywhere else and leave the rest on the linker.
Templated classes which have implementation files state in their documentation
all common specializations that are already compiled in the libraries. So,
unless the templated class is too generic (ResourceManager for example) or you
need something special, you don't have to mess with Object implementation
files at all. See Color3 or SceneGraph::Object for an example.
unless the templated class is too generic or you need something special, you
don't have to mess with template implementation files at all. See
SceneGraph::Object or SceneGraph::AbstractCamera for an example.
Sometimes you however need to use your own specialization and that's why
template implementation files are included in the library. For example we want
@ -61,8 +67,8 @@ using namespace Magnum::SceneGraph;
template class Object<MatrixTransformation3D<GLdouble>>;
@endcode
All other files using the same object specialization now need to include only
SceneGraph/Object.h header and if we compile our `Object.cpp` together with
the rest, the Object specialization will be compiled only once.
SceneGraph/Object.h header. Thus the Object specialization will be compiled
only once in our `Object.cpp` file, saving precious compilation time.
@subsection compilation-speedup-extern-templates Extern templates

5
doc/scenegraph.dox

@ -24,6 +24,11 @@ Transformation handles object position, rotation etc. and its basic property
is dimension count (2D or 3D) and underlying floating-point type (by default
`float`s are used everywhere, but you can use `double`s too).
@note All classes in SceneGraph have `GLfloat` as default underlying
floating-point type, which means that you can omit that template parameter
and write just <tt>%AbstractObject<2></tt> or <tt>%MatrixTransformation3D<></tt>
instead of <tt>%AbstractObject<2, GLfloat></tt> and <tt>%MatrixTransformation3D&lt;GLfloat&gt;</tt>.
%Scene graph has implementation of transformations in both 2D and 3D, using
either matrices or combination of position and rotation. Each implementation
has its own advantages and disadvantages -- for example when using matrices

2
src/AbstractShaderProgram.h

@ -28,6 +28,8 @@
#include "magnumVisibility.h"
/** @todo early asserts (no bool returns?) */
namespace Magnum {
namespace Math {

18
src/CMakeLists.txt

@ -98,7 +98,9 @@ endif()
# Files shared between main library and math unit test library
set(MagnumMath_SRCS
Math/Math.cpp)
Math/Math.cpp
Math/RectangularMatrix.cpp
Math/Vector.cpp)
if(NOT CMAKE_NO_OBJECT_TARGET)
add_library(MagnumMathObjects OBJECT ${MagnumMath_SRCS})
endif()
@ -167,13 +169,21 @@ if(BUILD_TESTS)
# Library with graceful assert for testing
if(NOT CMAKE_NO_OBJECT_TARGET)
add_library(MagnumMathTestLib SHARED
$<TARGET_OBJECTS:MagnumMathObjects>)
add_library(MagnumTestLib SHARED
$<TARGET_OBJECTS:MagnumObjects>)
$<TARGET_OBJECTS:MagnumObjects>
$<TARGET_OBJECTS:MagnumMathObjects>)
else()
add_library(MagnumMathTestLib SHARED
${MagnumMath_SRCS})
add_library(MagnumTestLib SHARED
${Magnum_SRCS})
${Magnum_SRCS}
${MagnumMath_SRCS})
endif()
set_target_properties(MagnumTestLib PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT)
set_target_properties(MagnumTestLib MagnumMathTestLib PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT)
target_link_libraries(MagnumTestLib ${Magnum_LIBS})
add_subdirectory(Test)

4
src/Color.h

@ -143,6 +143,8 @@ range @f$ [0.0, 1.0] @f$.
@todo Signed normalization to [-1.0, 1.0] like in OpenGL?
*/
/* Not using template specialization because some internal functions are
impossible to explicitly instantiate */
template<class T> class Color3: public Math::Vector3<T> {
public:
/** @brief Corresponding floating-point type for HSV computation */
@ -287,6 +289,8 @@ MAGNUM_VECTOR_SUBCLASS_OPERATOR_IMPLEMENTATION(Color3, 3)
See Color3 for more information.
*/
/* Not using template specialization because some internal functions are
impossible to explicitly instantiate */
template<class T> class Color4: public Math::Vector4<T> {
public:
/** @copydoc Color3::FloatingPointType */

2
src/Math/Algorithms/Test/CMakeLists.txt

@ -1 +1 @@
corrade_add_test2(MathAlgorithmsGaussJordanTest GaussJordanTest.cpp)
corrade_add_test2(MathAlgorithmsGaussJordanTest GaussJordanTest.cpp LIBRARIES MagnumMathTestLib)

106
src/Math/RectangularMatrix.cpp

@ -0,0 +1,106 @@
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#include "RectangularMatrix.h"
namespace Magnum { namespace Math {
#ifndef DOXYGEN_GENERATING_OUTPUT
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<1, 2, float>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<1, 3, float>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<1, 4, float>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<1, 2, int>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<1, 3, int>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<1, 4, int>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<1, 2, unsigned int>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<1, 3, unsigned int>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<1, 4, unsigned int>&);
#ifndef MAGNUM_TARGET_GLES
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<1, 2, double>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<1, 3, double>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<1, 4, double>&);
#endif
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<2, 2, float>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<3, 3, float>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<4, 4, float>&);
#ifndef MAGNUM_TARGET_GLES
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<2, 2, double>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<3, 3, double>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<4, 4, double>&);
#endif
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<2, 3, float>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<3, 2, float>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<2, 4, float>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<4, 2, float>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<3, 4, float>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<4, 3, float>&);
#ifndef MAGNUM_TARGET_GLES
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<2, 3, double>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<3, 2, double>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<2, 4, double>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<4, 2, double>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<3, 4, double>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::RectangularMatrix<4, 3, double>&);
#endif
#endif
}}
namespace Corrade { namespace Utility {
#ifndef DOXYGEN_GENERATING_OUTPUT
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<1, 2, float>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<1, 3, float>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<1, 4, float>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<1, 2, int>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<1, 3, int>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<1, 4, int>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<1, 2, unsigned int>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<1, 3, unsigned int>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<1, 4, unsigned int>>;
#ifndef MAGNUM_TARGET_GLES
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<1, 2, double>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<1, 3, double>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<1, 4, double>>;
#endif
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<2, 2, float>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<3, 3, float>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<4, 4, float>>;
#ifndef MAGNUM_TARGET_GLES
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<2, 2, double>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<3, 3, double>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<4, 4, double>>;
#endif
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<2, 3, float>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<3, 2, float>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<2, 4, float>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<4, 2, float>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<3, 4, float>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<4, 3, float>>;
#ifndef MAGNUM_TARGET_GLES
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<2, 3, double>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<3, 2, double>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<2, 4, double>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<4, 2, double>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<3, 4, double>>;
template struct ConfigurationValue<Magnum::Math::RectangularMatrix<4, 3, double>>;
#endif
#endif
}}

91
src/Math/RectangularMatrix.h

@ -26,6 +26,8 @@
#include "MathTypeTraits.h"
#include "magnumVisibility.h"
namespace Magnum { namespace Math {
/** @todo Properly test all constexpr */
@ -400,6 +402,51 @@ template<std::size_t cols, std::size_t rows, class T> Corrade::Utility::Debug op
return debug;
}
/* Explicit instantiation for types used in OpenGL */
#ifndef DOXYGEN_GENERATING_OUTPUT
/* Vectors */
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<1, 2, float>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<1, 3, float>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<1, 4, float>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<1, 2, int>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<1, 3, int>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<1, 4, int>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<1, 2, unsigned int>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<1, 3, unsigned int>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<1, 4, unsigned int>&);
#ifndef MAGNUM_TARGET_GLES
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<1, 2, double>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<1, 3, double>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<1, 4, double>&);
#endif
/* Square matrices */
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<2, 2, float>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<3, 3, float>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<4, 4, float>&);
#ifndef MAGNUM_TARGET_GLES
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<2, 2, double>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<3, 3, double>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<4, 4, double>&);
#endif
/* Rectangular matrices */
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<2, 3, float>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<3, 2, float>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<2, 4, float>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<4, 2, float>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<3, 4, float>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<4, 3, float>&);
#ifndef MAGNUM_TARGET_GLES
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<2, 3, double>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<3, 2, double>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<2, 4, double>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<4, 2, double>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<3, 4, double>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const RectangularMatrix<4, 3, double>&);
#endif
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
#define MAGNUM_RECTANGULARMATRIX_SUBCLASS_IMPLEMENTATION(cols, rows, ...) \
inline constexpr static __VA_ARGS__& from(T* data) { \
@ -491,6 +538,50 @@ template<std::size_t cols, std::size_t rows, class T> struct ConfigurationValue<
}
};
#ifndef DOXYGEN_GENERATING_OUTPUT
/* Vectors */
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<1, 2, float>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<1, 3, float>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<1, 4, float>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<1, 2, int>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<1, 3, int>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<1, 4, int>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<1, 2, unsigned int>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<1, 3, unsigned int>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<1, 4, unsigned int>>;
#ifndef MAGNUM_TARGET_GLES
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<1, 2, double>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<1, 3, double>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<1, 4, double>>;
#endif
/* Square matrices */
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<2, 2, float>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<3, 3, float>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<4, 4, float>>;
#ifndef MAGNUM_TARGET_GLES
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<2, 2, double>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<3, 3, double>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<4, 4, double>>;
#endif
/* Rectangular matrices */
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<2, 3, float>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<3, 2, float>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<2, 4, float>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<4, 2, float>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<3, 4, float>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<4, 3, float>>;
#ifndef MAGNUM_TARGET_GLES
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<2, 3, double>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<3, 2, double>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<2, 4, double>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<4, 2, double>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<3, 4, double>>;
extern template struct MAGNUM_EXPORT ConfigurationValue<Magnum::Math::RectangularMatrix<4, 3, double>>;
#endif
#endif
}}
/* Include also Vector, so the definition is complete */

27
src/Math/Test/CMakeLists.txt

@ -1,24 +1,19 @@
corrade_add_test2(MathConstantsTest ConstantsTest.cpp)
if(NOT CMAKE_NO_OBJECT_TARGET)
set(MathTest_SRCS MathTest.cpp $<TARGET_OBJECTS:MagnumMathObjects>)
else()
set(MathTest_SRCS MathTest.cpp ${MagnumMath_SRCS})
endif()
corrade_add_test2(MathTest ${MathTest_SRCS})
corrade_add_test2(MathTest MathTest.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test2(MathMathTypeTraitsTest MathTypeTraitsTest.cpp)
corrade_add_test2(MathRectangularMatrixTest RectangularMatrixTest.cpp)
corrade_add_test2(MathRectangularMatrixTest RectangularMatrixTest.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test2(MathVectorTest VectorTest.cpp)
corrade_add_test2(MathVector2Test Vector2Test.cpp)
corrade_add_test2(MathVector3Test Vector3Test.cpp)
corrade_add_test2(MathVector4Test Vector4Test.cpp)
corrade_add_test2(MathVectorTest VectorTest.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test2(MathVector2Test Vector2Test.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test2(MathVector3Test Vector3Test.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test2(MathVector4Test Vector4Test.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test2(MathPoint2DTest Point2DTest.cpp)
corrade_add_test2(MathPoint3DTest Point3DTest.cpp)
corrade_add_test2(MathPoint2DTest Point2DTest.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test2(MathPoint3DTest Point3DTest.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test2(MathMatrixTest MatrixTest.cpp)
corrade_add_test2(MathMatrix3Test Matrix3Test.cpp)
corrade_add_test2(MathMatrix4Test Matrix4Test.cpp)
corrade_add_test2(MathMatrixTest MatrixTest.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test2(MathMatrix3Test Matrix3Test.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test2(MathMatrix4Test Matrix4Test.cpp LIBRARIES MagnumMathTestLib)
set_target_properties(MathVectorTest MathMatrix4Test PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT)

37
src/Math/Vector.cpp

@ -0,0 +1,37 @@
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#include "Vector.h"
namespace Magnum { namespace Math {
#ifndef DOXYGEN_GENERATING_OUTPUT
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::Vector<2, float>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::Vector<3, float>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::Vector<4, float>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::Vector<2, int>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::Vector<3, int>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::Vector<4, int>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::Vector<2, unsigned int>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::Vector<3, unsigned int>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::Vector<4, unsigned int>&);
#ifndef MAGNUM_TARGET_GLES
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::Vector<2, double>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::Vector<3, double>&);
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Magnum::Math::Vector<4, double>&);
#endif
#endif
}}

18
src/Math/Vector.h

@ -254,6 +254,24 @@ template<std::size_t size, class T> Corrade::Utility::Debug operator<<(Corrade::
return debug;
}
/* Explicit instantiation for types used in OpenGL */
#ifndef DOXYGEN_GENERATING_OUTPUT
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Vector<2, float>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Vector<3, float>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Vector<4, float>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Vector<2, int>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Vector<3, int>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Vector<4, int>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Vector<2, unsigned int>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Vector<3, unsigned int>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Vector<4, unsigned int>&);
#ifndef MAGNUM_TARGET_GLES
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Vector<2, double>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Vector<3, double>&);
extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utility::Debug, const Vector<4, double>&);
#endif
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
#define MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(Type, size) \
inline constexpr static Type<T>& from(T* data) { \

1
src/Physics/Box.h

@ -30,6 +30,7 @@ namespace Magnum { namespace Physics {
/**
@brief Unit-size box with assigned transformation matrix
@todo Use quat + position + size instead?
@see Box2D, Box3D
*/
template<std::uint8_t dimensions> class PHYSICS_EXPORT Box: public AbstractShape<dimensions> {

12
src/Physics/CMakeLists.txt

@ -3,20 +3,30 @@ set(MagnumPhysics_SRCS
AxisAlignedBox.cpp
Box.cpp
Capsule.cpp
DebugDrawResourceManager.cpp
Line.cpp
Plane.cpp
Point.cpp
ObjectShape.cpp
ObjectShapeGroup.cpp
ShapeGroup.cpp
Sphere.cpp)
Sphere.cpp
Implementation/AbstractDebugRenderer.cpp
Implementation/BoxRenderer.cpp)
set(MagnumPhysics_HEADERS
AbstractShape.h
AxisAlignedBox.h
Box.h
Capsule.h
DebugDrawResourceManager.h
Line.h
LineSegment.h
Plane.h
Point.h
ObjectShape.h
ObjectShapeGroup.h
ShapeGroup.h
Sphere.h

32
src/Physics/DebugDrawResourceManager.cpp

@ -18,13 +18,14 @@
#include "AbstractShaderProgram.h"
#include "Buffer.h"
#include "Mesh.h"
#include "ResourceManager.h"
#include "Shaders/FlatShader.h"
#include "AbstractShape.h"
#include "Box.h"
#include "ShapedObject.h"
#include "ObjectShape.h"
#include "ShapeGroup.h"
#include "Implementation/AbstractDebugRenderer.h"
#include "Implementation/BoxRenderer.h"
#include "Implementation/DebugRenderer.h"
namespace Magnum {
@ -32,24 +33,33 @@ template class ResourceManager<AbstractShaderProgram, Buffer, Mesh, Physics::Imp
namespace Physics {
SceneGraph::Object2D* DebugDrawResourceManager::createDebugRenderer(AbstractShape2D* shape, ResourceKey options) {
return createDebugMesh(nullptr, shape, options);
template<std::uint8_t dimensions> SceneGraph::Drawable<dimensions>* DebugDrawResourceManager::createDebugRenderer(ObjectShape<dimensions>* shape, ResourceKey options) {
Implementation::DebugRenderer<dimensions>* renderer = new Implementation::DebugRenderer<dimensions>(shape->object(), instance()->get<Options>(options));
createDebugMesh(renderer, shape->shape());
return renderer;
}
SceneGraph::Object2D* DebugDrawResourceManager::createDebugMesh(SceneGraph::Object2D* parent, AbstractShape2D* shape, ResourceKey options) {
template SceneGraph::Drawable<2>* DebugDrawResourceManager::createDebugRenderer(ObjectShape<2>* shape, ResourceKey options);
template SceneGraph::Drawable<3>* DebugDrawResourceManager::createDebugRenderer(ObjectShape<3>* shape, ResourceKey options);
void DebugDrawResourceManager::createDebugMesh(Implementation::DebugRenderer<2>* renderer, AbstractShape2D* shape) {
switch(shape->type()) {
case AbstractShape2D::Type::Box:
return new Implementation::BoxRenderer<2>(*static_cast<Box2D*>(shape), options, parent);
renderer->addRenderer(new Implementation::BoxRenderer<2>(*static_cast<Box2D*>(shape)));
break;
case AbstractShape2D::Type::ShapeGroup: {
if(!parent) parent = new SceneGraph::Object2D;
ShapeGroup2D* group = static_cast<ShapeGroup2D*>(shape);
if(group->first()) createDebugMesh(parent, group->first(), options);
if(group->second()) createDebugMesh(parent, group->second(), options);
return parent;
} default: return nullptr;
if(group->first()) createDebugMesh(renderer, group->first());
if(group->second()) createDebugMesh(renderer, group->second());
break;
}
default:
Warning() << "Physics::DebugDrawResourceManager::createDebugRenderer(): type" << shape->type() << "not implemented";
}
}
void DebugDrawResourceManager::createDebugMesh(Implementation::DebugRenderer<3>*, AbstractShape3D*) {}
DebugDrawResourceManager::DebugDrawResourceManager() {
setFallback<Options>(new Options);
set<AbstractShaderProgram>("shader2d", new Shaders::FlatShader<2>, ResourceDataState::Final, ResourcePolicy::Resident);

47
src/Physics/DebugDrawResourceManager.h

@ -22,6 +22,7 @@
#include "Magnum.h"
#include "Color.h"
#include "ResourceManager.h"
#include "SceneGraph/SceneGraph.h"
#include "magnumPhysicsVisibility.h"
@ -36,27 +37,20 @@ namespace Physics { namespace Implementation {
struct Options {
Color3<GLfloat> color;
};
template<std::uint8_t> class AbstractDebugRenderer;
template<std::uint8_t> class DebugRenderer;
}}
#ifndef WIN32
extern template class PHYSICS_EXPORT ResourceManager<AbstractShaderProgram, Buffer, Mesh, Physics::Implementation::Options>;
#endif
#endif
/** @todo fix extern template multiple definition linker errors in mingw32-gcc */
namespace SceneGraph {
class Object2D;
class Object3D;
}
namespace Physics {
template<std::uint8_t> class AbstractShape;
typedef AbstractShape<2> AbstractShape2D;
typedef AbstractShape<3> AbstractShape3D;
template<std::uint8_t> class ObjectShape;
typedef ObjectShape<2> ObjectShape2D;
typedef ObjectShape<3> ObjectShape3D;
/**
@brief %Resource manager for physics debug draw
@ -64,14 +58,18 @@ Can create objects which draw object collision shape for debugging purposes.
@section DebugDrawResourceManager-usage Basic usage
The manager must be instanced for the whole lifetime of debug draw objects.
To create debug draw objects, call createDebugRenderer() and add the resulting
object to the scene. You can specify options via Options struct - add it to
To create debug renderers, call createDebugRenderer() and add the resulting
drawable to some group. You can specify options via Options struct - add it to
the manager and then create debug renderer with the same options key. This way
you can easily share the same options with more objects. If no options for
you can easily share the same options with more renderers. If no options for
given key exist, default is used.
Example code:
@code
// Group of drawables,preferrably dedicated for debug renderers, so you can
// easily enable or disable debug draw
DrawableGroup2D group;
// Instance the manager at first
DebugDrawResourceManager manager;
@ -81,11 +79,10 @@ auto o = new DebugDrawResourceManager::Options {
};
manager->set<DebugDrawResourceManager::Options>("red", o, ResourceDataState::Final, ResourcePolicy::Persistent);
// Add debug draw object for given shape, use "red" options for it, don't
// forget to add it to the scene
ShapedObject2D* object;
DebugDrawResourceManager::createDebugRenderer(object->shape(), "red")
->setParent(object);
// Create debug renderer for given shape, use "red" options for it. Don't
// forget to add it to some drawable group.
ObjectShape2D* shape;
group.add(DebugDrawResourceManager::createDebugRenderer(shape, "red"));
@endcode
*/
class PHYSICS_EXPORT DebugDrawResourceManager: public ResourceManager<AbstractShaderProgram, Buffer, Mesh, Physics::Implementation::Options> {
@ -106,17 +103,17 @@ class PHYSICS_EXPORT DebugDrawResourceManager: public ResourceManager<AbstractSh
* @ref DebugDrawResourceManager-usage "class documentation" for
* more information.
*
* Returned object is not parented to anything, you have to add it to
* desired scene yourself.
* Returned drawable is not part of any group, you have to add it to
* one yourself.
*/
static SceneGraph::Object2D* createDebugRenderer(AbstractShape2D* shape, ResourceKey options = ResourceKey());
template<std::uint8_t dimensions> static SceneGraph::Drawable<dimensions>* createDebugRenderer(ObjectShape<dimensions>* shape, ResourceKey options = ResourceKey());
DebugDrawResourceManager();
~DebugDrawResourceManager();
private:
static SceneGraph::Object2D* createDebugMesh(SceneGraph::Object2D* parent, AbstractShape2D* shape, ResourceKey options);
static void createDebugMesh(Implementation::DebugRenderer<2>* renderer, AbstractShape2D* shape);
static void createDebugMesh(Implementation::DebugRenderer<3>* renderer, AbstractShape3D* shape);
};
}}

4
src/Physics/Implementation/AbstractDebugRenderer.cpp

@ -22,7 +22,9 @@
namespace Magnum { namespace Physics { namespace Implementation {
template<std::uint8_t dimensions> AbstractDebugRenderer<dimensions>::AbstractDebugRenderer(ResourceKey shader, ResourceKey mesh, ResourceKey options, typename SceneGraph::AbstractObject<dimensions>::ObjectType* parent): SceneGraph::AbstractObject<dimensions>::ObjectType(parent), shader(DebugDrawResourceManager::instance()->get<AbstractShaderProgram, Shaders::FlatShader<dimensions>>(shader)), mesh(DebugDrawResourceManager::instance()->get<Mesh>(mesh)), options(DebugDrawResourceManager::instance()->get<Options>(options)) {}
template<std::uint8_t dimensions> AbstractDebugRenderer<dimensions>::AbstractDebugRenderer(ResourceKey shader, ResourceKey mesh): shader(DebugDrawResourceManager::instance()->get<AbstractShaderProgram, Shaders::FlatShader<dimensions>>(shader)), mesh(DebugDrawResourceManager::instance()->get<Mesh>(mesh)) {}
template<std::uint8_t dimensions> AbstractDebugRenderer<dimensions>::~AbstractDebugRenderer() {}
template class AbstractDebugRenderer<2>;
template class AbstractDebugRenderer<3>;

16
src/Physics/Implementation/AbstractDebugRenderer.h

@ -15,9 +15,9 @@
GNU Lesser General Public License version 3 for more details.
*/
#include "Color.h"
#include "DimensionTraits.h"
#include "ResourceManager.h"
#include "SceneGraph/Camera.h"
#include "SceneGraph/SceneGraph.h"
namespace Magnum {
@ -32,19 +32,19 @@ namespace Physics { namespace Implementation {
struct Options;
template<std::uint8_t dimensions> class AbstractDebugRenderer: public SceneGraph::AbstractObject<dimensions>::ObjectType {
template<std::uint8_t dimensions> class AbstractDebugRenderer {
public:
AbstractDebugRenderer(ResourceKey shader, ResourceKey mesh, ResourceKey options, typename SceneGraph::AbstractObject<dimensions>::ObjectType* parent);
AbstractDebugRenderer(ResourceKey shader, ResourceKey mesh);
virtual ~AbstractDebugRenderer();
virtual void draw(Resource<Options>& options, const typename DimensionTraits<dimensions>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions, GLfloat>* camera) = 0;
protected:
Resource<AbstractShaderProgram, Shaders::FlatShader<dimensions>> shader;
Resource<Mesh> mesh;
Resource<Options> options;
};
extern template class AbstractDebugRenderer<2>;
extern template class AbstractDebugRenderer<3>;
}}}
#endif

17
src/Physics/Implementation/BoxRenderer.cpp

@ -20,6 +20,7 @@
#include "Physics/DebugDrawResourceManager.h"
#include "Primitives/Cube.h"
#include "Primitives/Square.h"
#include "SceneGraph/AbstractCamera.h"
#include "Shaders/FlatShader.h"
namespace Magnum { namespace Physics { namespace Implementation {
@ -28,8 +29,8 @@ namespace {
template<std::uint8_t> struct BoxMesh {};
template<> struct BoxMesh<2> {
constexpr static ResourceKey shader() { return {"shader2d"}; }
constexpr static ResourceKey key() { return {"box2d"}; }
static ResourceKey shader() { return {"shader2d"}; }
static ResourceKey key() { return {"box2d"}; }
static Mesh* mesh(Buffer* buffer) {
Primitives::Square square;
@ -42,8 +43,8 @@ namespace {
};
template<> struct BoxMesh<3> {
constexpr static ResourceKey shader() { return {"shader3d"}; }
constexpr static ResourceKey key() { return {"box3d"}; }
static ResourceKey shader() { return {"shader3d"}; }
static ResourceKey key() { return {"box3d"}; }
static Mesh* mesh(Buffer* buffer) {
Primitives::Cube cube;
@ -56,16 +57,16 @@ namespace {
};
}
template<std::uint8_t dimensions> BoxRenderer<dimensions>::BoxRenderer(Box<dimensions>& box, ResourceKey options, typename SceneGraph::AbstractObject<dimensions>::ObjectType* parent): AbstractDebugRenderer<dimensions>(BoxMesh<dimensions>::shader(), BoxMesh<dimensions>::key(), options, parent), buffer(DebugDrawResourceManager::instance()->get<Buffer>(BoxMesh<dimensions>::key())), box(box) {
template<std::uint8_t dimensions> BoxRenderer<dimensions>::BoxRenderer(Box<dimensions>& box): AbstractDebugRenderer<dimensions>(BoxMesh<dimensions>::shader(), BoxMesh<dimensions>::key()), buffer(DebugDrawResourceManager::instance()->get<Buffer>(BoxMesh<dimensions>::key())), box(box) {
if(!this->mesh) {
DebugDrawResourceManager::instance()->set(this->buffer.key(), new Buffer, ResourceDataState::Final, ResourcePolicy::Manual);
DebugDrawResourceManager::instance()->set<Mesh>(this->mesh.key(), BoxMesh<dimensions>::mesh(buffer), ResourceDataState::Final, ResourcePolicy::Manual);
}
}
template<std::uint8_t dimensions> void BoxRenderer<dimensions>::draw(const typename DimensionTraits<dimensions, GLfloat>::MatrixType&, typename SceneGraph::AbstractObject<dimensions>::CameraType* camera) {
this->shader->setTransformationProjection(camera->projectionMatrix()*box.transformedTransformation())
->setColor(this->options->color)
template<std::uint8_t dimensions> void BoxRenderer<dimensions>::draw(Resource<Options>& options, const typename DimensionTraits<dimensions, GLfloat>::MatrixType&, typename SceneGraph::AbstractCamera<dimensions>* camera) {
this->shader->setTransformationProjection(camera->projectionMatrix()*camera->cameraMatrix()*box.transformedTransformation())
->setColor(options->color)
->use();
this->mesh->draw();
}

9
src/Physics/Implementation/BoxRenderer.h

@ -17,6 +17,8 @@
#include "AbstractDebugRenderer.h"
#include "magnumCompatibility.h"
namespace Magnum {
class Buffer;
@ -29,18 +31,15 @@ namespace Implementation {
template<std::uint8_t dimensions> class BoxRenderer: public AbstractDebugRenderer<dimensions> {
public:
BoxRenderer(Box<dimensions>& box, ResourceKey options, typename SceneGraph::AbstractObject<dimensions>::ObjectType* parent);
BoxRenderer(Box<dimensions>& box);
void draw(const typename DimensionTraits<dimensions, GLfloat>::MatrixType& transformation, typename SceneGraph::AbstractObject<dimensions>::CameraType* camera);
void draw(Resource<Options>& options, const typename DimensionTraits<dimensions>::MatrixType& transformation, typename SceneGraph::AbstractCamera<dimensions, GLfloat>* camera) override;
private:
Resource<Buffer> buffer;
Box<dimensions>& box;
};
extern template class BoxRenderer<2>;
extern template class BoxRenderer<3>;
}}}
#endif

58
src/Physics/Implementation/DebugRenderer.h

@ -0,0 +1,58 @@
#ifndef Magnum_Physics_Implementation_DebugRenderer_h
#define Magnum_Physics_Implementation_DebugRenderer_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#include "ResourceManager.h"
#include "SceneGraph/Drawable.h"
#include "AbstractDebugRenderer.h"
namespace Magnum {
class AbstractShaderProgram;
class Mesh;
namespace Shaders {
template<std::uint8_t> class FlatShader;
}
namespace Physics { namespace Implementation {
struct Options;
template<std::uint8_t dimensions> class DebugRenderer: public SceneGraph::Drawable<dimensions> {
public:
DebugRenderer(SceneGraph::AbstractObject<dimensions>* object, Resource<Options>&& options): SceneGraph::Drawable<dimensions>(object), options(options) {}
inline ~DebugRenderer() {
for(auto i: renderers) delete i;
}
inline void addRenderer(AbstractDebugRenderer<dimensions>* renderer) {
renderers.push_back(renderer);
}
inline void draw(const typename DimensionTraits<dimensions>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions, GLfloat>* camera) override {
for(auto i: renderers) i->draw(options, transformationMatrix, camera);
}
private:
Resource<Options> options;
std::vector<AbstractDebugRenderer<dimensions>*> renderers;
};
}}}
#endif

46
src/Physics/ObjectShape.cpp

@ -0,0 +1,46 @@
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#include "ObjectShape.h"
#include <algorithm>
#include "AbstractShape.h"
#include "ObjectShapeGroup.h"
using namespace std;
namespace Magnum { namespace Physics {
template<uint8_t dimensions> ObjectShape<dimensions>::ObjectShape(SceneGraph::AbstractObject<dimensions>* object, ObjectShapeGroup<dimensions>* group): SceneGraph::AbstractGroupedFeature<dimensions, ObjectShape<dimensions>>(object, group), _shape(nullptr) {
this->setCachedTransformations(SceneGraph::AbstractFeature<dimensions>::CachedTransformation::Absolute);
}
template<uint8_t dimensions> ObjectShape<dimensions>::~ObjectShape() {
delete _shape;
}
template<uint8_t dimensions> void ObjectShape<dimensions>::markDirty() {
group()->setDirty();
}
template<uint8_t dimensions> void ObjectShape<dimensions>::clean(const typename DimensionTraits<dimensions, GLfloat>::MatrixType& absoluteTransformation) {
if(_shape) _shape->applyTransformation(absoluteTransformation);
}
template class ObjectShape<2>;
template class ObjectShape<3>;
}}

98
src/Physics/ObjectShape.h

@ -0,0 +1,98 @@
#ifndef Magnum_Physics_ObjectShape_h
#define Magnum_Physics_ObjectShape_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
/** @file
* @brief Class Magnum::Physics::ObjectShape
*/
#include "SceneGraph/AbstractGroupedFeature.h"
#include "ObjectShapeGroup.h"
#include "magnumPhysicsVisibility.h"
namespace Magnum { namespace Physics {
template<std::uint8_t> class ObjectShapeGroup;
template<std::uint8_t> class AbstractShape;
/**
@brief Object shape
Adds shape for collision detection to object.
@see ObjectShape2D, ObjectShape3D
*/
template<std::uint8_t dimensions> class PHYSICS_EXPORT ObjectShape: public SceneGraph::AbstractGroupedFeature<dimensions, ObjectShape<dimensions>> {
public:
/**
* @brief Constructor
* @param object Object holding this feature
* @param group Group this shape belongs to
*
* Creates empty object shape.
* @see setShape()
*/
ObjectShape(SceneGraph::AbstractObject<dimensions>* object, ObjectShapeGroup<dimensions>* group = nullptr);
/**
* @brief Destructor
*
* Deletes associated shape.
*/
~ObjectShape();
/** @brief Shape */
inline AbstractShape<dimensions>* shape() { return _shape; }
inline const AbstractShape<dimensions>* shape() const { return _shape; } /**< @overload */
/**
* @brief Set shape
* @return Pointer to self (for method chaining)
*/
inline ObjectShape<dimensions>* setShape(AbstractShape<dimensions>* shape) {
_shape = shape;
this->object()->setDirty();
return this;
}
inline ObjectShapeGroup<dimensions>* group() {
return static_cast<ObjectShapeGroup<dimensions>*>(SceneGraph::AbstractGroupedFeature<dimensions, ObjectShape<dimensions>>::group());
}
inline const ObjectShapeGroup<dimensions>* group() const {
return static_cast<const ObjectShapeGroup<dimensions>*>(SceneGraph::AbstractGroupedFeature<dimensions, ObjectShape<dimensions>>::group());
}
protected:
/** Marks also the group as dirty */
void markDirty() override;
/** Applies transformation to associated shape. */
void clean(const typename DimensionTraits<dimensions>::MatrixType& absoluteTransformation) override;
private:
AbstractShape<dimensions>* _shape;
};
/** @brief Two-dimensional object shape */
typedef ObjectShape<2> ObjectShape2D;
/** @brief Three-dimensional object shape */
typedef ObjectShape<3> ObjectShape3D;
}}
#endif

20
src/Physics/ShapedObjectGroup.cpp → src/Physics/ObjectShapeGroup.cpp

@ -13,20 +13,26 @@
GNU Lesser General Public License version 3 for more details.
*/
#include "ShapedObjectGroup.h"
#include "ObjectShapeGroup.h"
#include "ShapedObject.h"
#include "ObjectShape.h"
namespace Magnum { namespace Physics {
template<std::uint8_t dimensions> void ShapedObjectGroup<dimensions>::setClean() {
for(auto it = objects.begin(); it != objects.end(); ++it)
if((*it)->isDirty()) (*it)->setClean();
template<std::uint8_t dimensions> void ObjectShapeGroup<dimensions>::setClean() {
/* Clean all objects */
if(!this->isEmpty()) {
std::vector<SceneGraph::AbstractObject<dimensions>*> objects(this->size());
for(std::size_t i = 0; i != this->size(); ++i)
objects[i] = (*this)[i]->object();
objects[0]->setClean(objects);
}
dirty = false;
}
template class ShapedObjectGroup<2>;
template class ShapedObjectGroup<3>;
template class ObjectShapeGroup<2>;
template class ObjectShapeGroup<3>;
}}

39
src/Physics/ShapedObjectGroup.h → src/Physics/ObjectShapeGroup.h

@ -1,5 +1,5 @@
#ifndef Magnum_Physics_ShapedObjectGroup_h
#define Magnum_Physics_ShapedObjectGroup_h
#ifndef Magnum_Physics_ObjectShapeGroup_h
#define Magnum_Physics_ObjectShapeGroup_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
@ -16,28 +16,28 @@
*/
/** @file
* @brief Class Magnum::Physics::ShapedObjectGroup
* @brief Class Magnum::Physics::ObjectShapeGroup
*/
#include <cstdint>
#include <vector>
#include "SceneGraph/FeatureGroup.h"
#include "magnumPhysicsVisibility.h"
namespace Magnum { namespace Physics {
template<std::uint8_t> class ShapedObject;
template<std::uint8_t> class ObjectShape;
/**
@brief Group of shaped objects
@brief Group of object shapes
@ref ShapedObject "ShapedObject*D" instances are added to the group by
specifying it in the constructor. When the group is deleted, all objects
belogning to it are deleted too.
@see ShapedObjectGroup2D, ShapedObjectGroup3D
@see ObjectShapeGroup2D, ObjectShapeGroup3D
*/
template<std::uint8_t dimensions> class PHYSICS_EXPORT ShapedObjectGroup {
friend class ShapedObject<dimensions>;
template<std::uint8_t dimensions> class PHYSICS_EXPORT ObjectShapeGroup: public SceneGraph::FeatureGroup<dimensions, ObjectShape<dimensions>> {
friend class ObjectShape<dimensions>;
public:
/**
@ -45,17 +45,7 @@ template<std::uint8_t dimensions> class PHYSICS_EXPORT ShapedObjectGroup {
*
* Marks the group as dirty.
*/
inline ShapedObjectGroup(): dirty(true) {}
/**
* @brief Destructor
*
* Deletes all objects belogning to the group.
*/
inline virtual ~ShapedObjectGroup() {
for(auto it = objects.begin(); it != objects.end(); ++it)
delete *it;
}
inline ObjectShapeGroup(): dirty(true) {}
/**
* @brief Whether the group is dirty
@ -83,15 +73,14 @@ template<std::uint8_t dimensions> class PHYSICS_EXPORT ShapedObjectGroup {
void setClean();
private:
std::vector<ShapedObject<dimensions>*> objects;
bool dirty;
};
/** @brief Group of two-dimensional shaped objects */
typedef ShapedObjectGroup<2> ShapedObjectGroup2D;
typedef ObjectShapeGroup<2> ObjectShapeGroup2D;
/** @brief Group of three-dimensional shaped objects */
typedef ShapedObjectGroup<3> ShapedObjectGroup3D;
typedef ObjectShapeGroup<3> ObjectShapeGroup3D;
}}

51
src/Physics/ShapedObject.cpp

@ -1,51 +0,0 @@
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#include "ShapedObject.h"
#include <algorithm>
#include "AbstractShape.h"
#include "ShapedObjectGroup.h"
using namespace std;
namespace Magnum { namespace Physics {
template<uint8_t dimensions> ShapedObject<dimensions>::ShapedObject(ShapedObjectGroup<dimensions>* group, typename SceneGraph::AbstractObject<dimensions>::ObjectType* parent): SceneGraph::AbstractObject<dimensions>::ObjectType(parent), group(group), _shape(nullptr) {
group->objects.push_back(this);
}
template<uint8_t dimensions> ShapedObject<dimensions>::~ShapedObject() {
group->objects.erase(find(group->objects.begin(), group->objects.end(), this));
delete _shape;
}
template<uint8_t dimensions> void ShapedObject<dimensions>::setDirty() {
SceneGraph::AbstractObject<dimensions>::ObjectType::setDirty();
group->setDirty();
}
template<uint8_t dimensions> void ShapedObject<dimensions>::clean(const typename DimensionTraits<dimensions, GLfloat>::MatrixType& absoluteTransformation) {
SceneGraph::AbstractObject<dimensions>::ObjectType::clean(absoluteTransformation);
if(_shape) _shape->applyTransformation(absoluteTransformation);
}
template class ShapedObject<2>;
template class ShapedObject<3>;
}}

97
src/Physics/ShapedObject.h

@ -1,97 +0,0 @@
#ifndef Magnum_Physics_ShapedObject_h
#define Magnum_Physics_ShapedObject_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
/** @file
* @brief Class Magnum::Physics::ShapedObject
*/
#include "SceneGraph/Object.h"
#include "magnumPhysicsVisibility.h"
namespace Magnum { namespace Physics {
template<std::uint8_t> class ShapedObjectGroup;
template<std::uint8_t> class AbstractShape;
/**
@brief Object with assigned shape
@see ShapedObject2D, ShapedObject3D
*/
template<std::uint8_t dimensions> class PHYSICS_EXPORT ShapedObject: public SceneGraph::AbstractObject<dimensions>::ObjectType {
public:
/**
* @brief Constructor
* @param group Group this shaped object belongs to
* @param parent Parent object
*
* Creates object with no shape.
* @see setShape()
*/
ShapedObject(ShapedObjectGroup<dimensions>* group, typename SceneGraph::AbstractObject<dimensions>::ObjectType* parent = nullptr);
/**
* @brief Destructor
*
* Deletes associated shape.
*/
~ShapedObject();
/** @brief Object shape */
inline AbstractShape<dimensions>* shape() { return _shape; }
inline const AbstractShape<dimensions>* shape() const { return _shape; } /**< @overload */
/**
* @brief Set object shape
* @return Pointer to self (for method chaining)
*/
inline ShapedObject<dimensions>* setShape(AbstractShape<dimensions>* shape) {
_shape = shape;
setDirty();
return this;
}
/**
* @copybrief SceneGraph::AbstractObject::setDirty()
*
* Marks shaped object group as dirty.
*/
void setDirty();
protected:
/**
* @copybrief SceneGraph::AbstractObject::clean()
*
* Applies transformation to associated shape.
*/
void clean(const typename DimensionTraits<dimensions, GLfloat>::MatrixType& absoluteTransformation);
private:
ShapedObjectGroup<dimensions>* group;
AbstractShape<dimensions>* _shape;
};
/** @brief Two-dimensional shaped object */
typedef ShapedObject<2> ShapedObject2D;
/** @brief Three-dimensional shaped object */
typedef ShapedObject<3> ShapedObject3D;
}}
#endif

2
src/Physics/Test/CMakeLists.txt

@ -7,3 +7,5 @@ corrade_add_test2(PhysicsPlaneTest PlaneTest.cpp LIBRARIES MagnumPhysics)
corrade_add_test2(PhysicsPointTest PointTest.cpp LIBRARIES MagnumPhysics)
corrade_add_test2(PhysicsShapeGroupTest ShapeGroupTest.cpp LIBRARIES MagnumPhysics)
corrade_add_test2(PhysicsSphereTest SphereTest.cpp LIBRARIES MagnumPhysics)
corrade_add_test2(PhysicsObjectShapeTest ObjectShapeTest.cpp LIBRARIES MagnumPhysics)

35
src/Physics/Test/ShapedObjectTest.cpp → src/Physics/Test/ObjectShapeTest.cpp

@ -13,23 +13,36 @@
GNU Lesser General Public License version 3 for more details.
*/
#include "ShapedObjectTest.h"
#include "ObjectShapeTest.h"
#include "Physics/ShapedObjectGroup.h"
#include "Physics/ShapedObject.h"
#include "Physics/ObjectShapeGroup.h"
#include "Physics/ObjectShape.h"
#include "Physics/Point.h"
#include "SceneGraph/MatrixTransformation3D.h"
#include "SceneGraph/Scene.h"
CORRADE_TEST_MAIN(Magnum::Physics::Test::ShapedObjectTest)
CORRADE_TEST_MAIN(Magnum::Physics::Test::ObjectShapeTest)
namespace Magnum { namespace Physics { namespace Test {
ShapedObjectTest::ShapedObjectTest() {
addTests(&ShapedObjectTest::clean);
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D<>> Scene3D;
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D<>> Object3D;
ObjectShapeTest::ObjectShapeTest() {
addTests(&ObjectShapeTest::clean);
}
void ShapedObjectTest::clean() {
ShapedObjectGroup3D group;
void ObjectShapeTest::clean() {
Scene3D scene;
ObjectShapeGroup3D group;
Object3D a(&scene);
ObjectShape3D* shape = new ObjectShape3D(&a, &group);
shape->setShape(new Physics::Point3D({1.0f, -2.0f, 3.0f}));
a.scale(Vector3(-2.0f));
ShapedObject3D a(&group), b(&group);
Object3D b(&scene);
new ObjectShape3D(&b, &group);
/* Everything is dirty at the beginning */
CORRADE_VERIFY(group.isDirty());
@ -42,6 +55,10 @@ void ShapedObjectTest::clean() {
CORRADE_VERIFY(!a.isDirty());
CORRADE_VERIFY(b.isDirty());
/* Verify that the feature was actually cleaned */
CORRADE_COMPARE(static_cast<const Physics::Point3D*>(shape->shape())->transformedPosition(),
Vector3(-2.0f, 4.0f, -6.0f));
/* Setting group clean will clean whole group */
a.setDirty();
group.setClean();

8
src/Physics/Test/ShapedObjectTest.h → src/Physics/Test/ObjectShapeTest.h

@ -1,5 +1,5 @@
#ifndef Magnum_Physics_Test_ShapedObjectTest_h
#define Magnum_Physics_Test_ShapedObjectTest_h
#ifndef Magnum_Physics_Test_ObjectShapeTest_h
#define Magnum_Physics_Test_ObjectShapeTest_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
@ -19,9 +19,9 @@
namespace Magnum { namespace Physics { namespace Test {
class ShapedObjectTest: public Corrade::TestSuite::Tester<ShapedObjectTest> {
class ObjectShapeTest: public Corrade::TestSuite::Tester<ObjectShapeTest> {
public:
ShapedObjectTest();
ObjectShapeTest();
void clean();
};

11
src/ResourceManager.h

@ -142,12 +142,12 @@ namespace Implementation {
}
#endif
Data(Data&& other): data(other.data), state(other.state), policy(other.policy), referenceCount(other.referenceCount) {
inline Data(Data&& other): data(other.data), state(other.state), policy(other.policy), referenceCount(other.referenceCount) {
other.data = nullptr;
other.referenceCount = 0;
}
~Data() {
inline ~Data() {
CORRADE_ASSERT(referenceCount == 0, "ResourceManager: cannot destruct it while data are still referenced", );
delete data;
}
@ -398,6 +398,8 @@ template<class T, class U = T> class Resource {
Provides storage for arbitrary set of types, accessible globally using
instance().
@section ResourceManager-usage Usage
Each resource is referenced from Resource class. For optimizing performance,
each resource can be set as mutable or final. Mutable resources can be
modified by the manager and thus each %Resource instance asks the manager for
@ -453,6 +455,9 @@ cube->draw();
- Destroying resource references and deleting manager instance when nothing
references the resources anymore.
*/
/* Due to too much work involved with explicit template instantiation (all
Resource combinations, all ResourceManagerData...), this class doesn't have
template implementation file. */
template<class... Types> class ResourceManager: protected Implementation::ResourceManagerData<Types>... {
public:
/** @brief Global instance */
@ -566,7 +571,7 @@ template<class... Types> class ResourceManager: protected Implementation::Resour
};
/** @debugoperator{Magnum::ResourceKey} */
template<class T> Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const ResourceKey& value) {
template<class T> inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const ResourceKey& value) {
return debug << static_cast<const Corrade::Utility::HashDigest<sizeof(std::size_t)>&>(value);
}

21
src/SceneGraph/AbstractCamera.h

@ -27,14 +27,6 @@
namespace Magnum { namespace SceneGraph {
template<std::uint8_t, class> class Drawable;
template<std::uint8_t, class, class> class FeatureGroup;
#ifndef MAGNUM_GCC46_COMPATIBILITY
template<std::uint8_t dimensions, class T = GLfloat> using DrawableGroup = FeatureGroup<dimensions, Drawable<dimensions, T>, T>;
#else
template<std::uint8_t, class> class DrawableGroup;
#endif
/** @relates AbstractCamera
@brief Camera aspect ratio policy
@ -72,7 +64,12 @@ file to avoid linker errors. See also relevant sections in
@see Drawable, DrawableGroup, AbstractCamera2D, AbstractCamera3D
*/
template<std::uint8_t dimensions, class T = GLfloat> class SCENEGRAPH_EXPORT AbstractCamera: public AbstractFeature<dimensions, T> {
#ifndef DOXYGEN_GENERATING_OUTPUT
template<std::uint8_t dimensions, class T>
#else
template<std::uint8_t dimensions, class T = GLfloat>
#endif
class SCENEGRAPH_EXPORT AbstractCamera: public AbstractFeature<dimensions, T> {
public:
/**
* @brief Constructor
@ -200,12 +197,6 @@ template<class T = GLfloat> using AbstractCamera3D = AbstractCamera<3, T>;
typedef AbstractCamera<3, T = GLfloat> AbstractCamera3D;
#endif
/* Make implementers' life easier */
#ifndef MAGNUM_GCC46_COMPATIBILITY
template<class T = GLfloat> using DrawableGroup2D = DrawableGroup<2, T>;
template<class T = GLfloat> using DrawableGroup3D = DrawableGroup<3, T>;
#endif
}}
#endif

10
src/SceneGraph/AbstractFeature.h

@ -45,6 +45,9 @@ namespace Implementation {
Contained in Object, takes care of transformation caching. See @ref scenegraph
for introduction.
Uses Corrade::Containers::LinkedList for accessing holder object and sibling
features.
@section AbstractFeature-subclassing Subclassing
Feature is templated on dimension count and underlying transformation type, so
@ -114,10 +117,11 @@ which is automatically extracted from the pointer in our constructor.
@see AbstractFeature2D, AbstractFeature3D
*/
#ifndef DOXYGEN_GENERATING_OUTPUT
template<std::uint8_t dimensions, class T> class AbstractFeature: private Corrade::Containers::LinkedListItem<AbstractFeature<dimensions, T>, AbstractObject<dimensions, T>>
#else
template<std::uint8_t dimensions, class T = GLfloat> class AbstractFeature
#ifndef DOXYGEN_GENERATING_OUTPUT
: private Corrade::Containers::LinkedListItem<AbstractFeature<dimensions, T>, AbstractObject<dimensions, T>>
#endif
#endif
{
friend class Corrade::Containers::LinkedList<AbstractFeature<dimensions, T>>;
friend class Corrade::Containers::LinkedListItem<AbstractFeature<dimensions, T>, AbstractObject<dimensions, T>>;

13
src/SceneGraph/AbstractGroupedFeature.h

@ -47,7 +47,12 @@ typedef SceneGraph::FeatureGroup3D<Drawable> DrawableGroup;
@see AbstractGroupedFeature2D, AbstractGroupedFeature3D, FeatureGroup,
FeatureGroup2D, FeatureGroup3D
*/
template<std::uint8_t dimensions, class Derived, class T = GLfloat> class AbstractGroupedFeature: public AbstractFeature<dimensions, T> {
#ifndef DOXYGEN_GENERATING_OUTPUT
template<std::uint8_t dimensions, class Derived, class T>
#else
template<std::uint8_t dimensions, class Derived, class T = GLfloat>
#endif
class AbstractGroupedFeature: public AbstractFeature<dimensions, T> {
friend class FeatureGroup<dimensions, Derived, T>;
public:
@ -123,12 +128,6 @@ template<class Derived, class T = GLfloat> using AbstractGroupedFeature3D = Abst
typedef AbstractGroupedFeature<3, Derived, T = GLfloat> AbstractGroupedFeature3D;
#endif
/* Make implementers' life easier */
#ifndef MAGNUM_GCC46_COMPATIBILITY
template<class Feature, class T = GLfloat> using FeatureGroup2D = FeatureGroup<2, Feature, T>;
template<class Feature, class T = GLfloat> using FeatureGroup3D = FeatureGroup<3, Feature, T>;
#endif
}}
#endif

27
src/SceneGraph/AbstractObject.h

@ -22,14 +22,12 @@
#include <Containers/LinkedList.h>
#include "DimensionTraits.h"
#include "Magnum.h"
#include "SceneGraph.h"
#include "magnumCompatibility.h"
namespace Magnum { namespace SceneGraph {
template<std::uint8_t, class> class AbstractFeature;
/**
@brief Base for objects
@ -37,12 +35,15 @@ Provides minimal interface for features, not depending on object transformation
implementation. This class is not directly instantiatable, use Object subclass
instead. See also @ref scenegraph for more information.
Uses Corrade::Containers::LinkedList for storing features.
@see AbstractObject2D, AbstractObject3D
*/
#ifndef DOXYGEN_GENERATING_OUTPUT
template<std::uint8_t dimensions, class T> class AbstractObject: private Corrade::Containers::LinkedList<AbstractFeature<dimensions, T>>
#else
template<std::uint8_t dimensions, class T = GLfloat> class AbstractObject
#ifndef DOXYGEN_GENERATING_OUTPUT
: private Corrade::Containers::LinkedList<AbstractFeature<dimensions, T>>
#endif
#endif
{
friend class Corrade::Containers::LinkedList<AbstractFeature<dimensions, T>>;
friend class Corrade::Containers::LinkedListItem<AbstractFeature<dimensions, T>, AbstractObject<dimensions, T>>;
@ -150,10 +151,24 @@ template<std::uint8_t dimensions, class T = GLfloat> class AbstractObject
* on all object features which have caching enabled and recursively
* calls setClean() on every parent which is not already clean. If the
* object is already clean, the function does nothing.
*
* See also setClean(const std::vector& objects), which cleans given
* set of objects more efficiently than when calling setClean() on
* each object individually.
* @see @ref scenegraph-caching, setDirty(), isDirty()
*/
virtual void setClean() = 0;
/**
* @brief Clean absolute transformations of given set of objects
*
* Only dirty objects in the list are cleaned.
* @warning This function cannot check if all objects are of the same
* Object type, use typesafe Object::setClean(const std::vector& objects) when
* possible.
*/
virtual void setClean(const std::vector<AbstractObject<dimensions, T>*>& objects) const = 0;
/*@}*/
};

18
src/SceneGraph/AbstractTransformation.h

@ -21,13 +21,11 @@
#include <vector>
#include "Magnum.h"
#include "DimensionTraits.h"
#include "SceneGraph.h"
namespace Magnum { namespace SceneGraph {
template<class> class Object;
/**
@brief Base for transformations
@ -43,7 +41,12 @@ When sublassing, you have to:
@see AbstractTransformation2D, AbstractTransformation3D
*/
template<std::uint8_t dimensions, class T = GLfloat> class AbstractTransformation {
#ifndef DOXYGEN_GENERATING_OUTPUT
template<std::uint8_t dimensions, class T>
#else
template<std::uint8_t dimensions, class T = GLfloat>
#endif
class AbstractTransformation {
public:
/** @brief Underlying floating-point type */
typedef T Type;
@ -60,6 +63,13 @@ template<std::uint8_t dimensions, class T = GLfloat> class AbstractTransformatio
* These members must be defined by the implementation.
*/
/**
* @todo Common way to call setClean() on the object after setting
* transformation & disallowing transformation setting on scene,
* so the implementer doesn't forget to do it? It could also
* allow to hide Object::isScene() from unwanted publicity.
*/
/**
* @brief Transformation data type
*

7
src/SceneGraph/AbstractTranslationRotation2D.h

@ -28,7 +28,12 @@ namespace Magnum { namespace SceneGraph {
@see AbstractTranslationRotation3D
*/
template<class T = GLfloat> class AbstractTranslationRotation2D: public AbstractTransformation<2, T> {
#ifndef DOXYGEN_GENERATING_OUTPUT
template<class T>
#else
template<class T = GLfloat>
#endif
class AbstractTranslationRotation2D: public AbstractTransformation<2, T> {
public:
/**
* @brief Translate object

7
src/SceneGraph/AbstractTranslationRotation3D.h

@ -29,7 +29,12 @@ namespace Magnum { namespace SceneGraph {
@see AbstractTranslationRotation2D
*/
template<class T = GLfloat> class AbstractTranslationRotation3D: public AbstractTransformation<3, T> {
#ifndef DOXYGEN_GENERATING_OUTPUT
template<class T>
#else
template<class T = GLfloat>
#endif
class AbstractTranslationRotation3D: public AbstractTransformation<3, T> {
public:
/**
* @brief Translate object

7
src/SceneGraph/AbstractTranslationRotationScaling2D.h

@ -28,7 +28,12 @@ namespace Magnum { namespace SceneGraph {
@see AbstractTranslationRotationScaling2D
*/
template<class T = GLfloat> class AbstractTranslationRotationScaling2D: public AbstractTranslationRotation2D<T> {
#ifndef DOXYGEN_GENERATING_OUTPUT
template<class T>
#else
template<class T = GLfloat>
#endif
class AbstractTranslationRotationScaling2D: public AbstractTranslationRotation2D<T> {
public:
/**
* @brief Scale object

7
src/SceneGraph/AbstractTranslationRotationScaling3D.h

@ -28,7 +28,12 @@ namespace Magnum { namespace SceneGraph {
@see AbstractTranslationRotationScaling2D
*/
template<class T = GLfloat> class AbstractTranslationRotationScaling3D: public AbstractTranslationRotation3D<T> {
#ifndef DOXYGEN_GENERATING_OUTPUT
template<class T>
#else
template<class T = GLfloat>
#endif
class AbstractTranslationRotationScaling3D: public AbstractTranslationRotation3D<T> {
public:
/**
* @brief Scale object

1
src/SceneGraph/CMakeLists.txt

@ -22,6 +22,7 @@ set(MagnumSceneGraph_HEADERS
Object.h
Object.hpp
Scene.h
SceneGraph.h
magnumSceneGraphVisibility.h)
add_library(MagnumSceneGraphObjects OBJECT ${MagnumSceneGraph_SRCS})

7
src/SceneGraph/Camera2D.h

@ -38,7 +38,12 @@ avoid linker errors. See @ref compilation-speedup-hpp for more information.
@see Camera3D, Drawable, DrawableGroup
*/
template<class T = GLfloat> class SCENEGRAPH_EXPORT Camera2D: public AbstractCamera<2, T> {
#ifndef DOXYGEN_GENERATING_OUTPUT
template<class T>
#else
template<class T = GLfloat>
#endif
class SCENEGRAPH_EXPORT Camera2D: public AbstractCamera<2, T> {
public:
/**
* @brief Constructor

7
src/SceneGraph/Camera3D.h

@ -43,7 +43,12 @@ avoid linker errors. See @ref compilation-speedup-hpp for more information.
@see Camera2D, Drawable, DrawableGroup
*/
template<class T = GLfloat> class SCENEGRAPH_EXPORT Camera3D: public AbstractCamera<3, T> {
#ifndef DOXYGEN_GENERATING_OUTPUT
template<class T>
#else
template<class T = GLfloat>
#endif
class SCENEGRAPH_EXPORT Camera3D: public AbstractCamera<3, T> {
public:
/**
* @brief Constructor

28
src/SceneGraph/Drawable.h

@ -23,14 +23,6 @@
namespace Magnum { namespace SceneGraph {
template<std::uint8_t, class> class AbstractCamera;
template<std::uint8_t, class> class Drawable;
#ifndef MAGNUM_GCC46_COMPATIBILITY
template<std::uint8_t dimensions, class T = GLfloat> using DrawableGroup = FeatureGroup<dimensions, Drawable<dimensions, T>, T>;
#else
template<std::uint8_t, class> class DrawableGroup;
#endif
/**
@brief %Drawable
@ -85,7 +77,12 @@ void MyApplication::drawEvent() {
@see Drawable2D, Drawable3D, DrawableGroup2D, DrawableGroup3D
*/
template<std::uint8_t dimensions, class T = GLfloat> class Drawable: public AbstractGroupedFeature<dimensions, Drawable<dimensions, T>, T> {
#ifndef DOXYGEN_GENERATING_OUTPUT
template<std::uint8_t dimensions, class T>
#else
template<std::uint8_t dimensions, class T = GLfloat>
#endif
class Drawable: public AbstractGroupedFeature<dimensions, Drawable<dimensions, T>, T> {
public:
/** @copydoc AbstractGroupedFeature::AbstractGroupedFeature() */
inline Drawable(AbstractObject<dimensions, T>* object, DrawableGroup<dimensions, T>* group = nullptr): AbstractGroupedFeature<dimensions, Drawable<dimensions, T>, T>(object, group) {}
@ -145,7 +142,12 @@ See Drawable for more information.
#if !defined(MAGNUM_GCC46_COMPATIBILITY) && !defined(DOXYGEN_GENERATING_OUTPUT)
template<std::uint8_t dimensions, class T = GLfloat> using DrawableGroup = FeatureGroup<dimensions, Drawable<dimensions, T>, T>;
#else
template<std::uint8_t dimensions, class T = GLfloat> class DrawableGroup: public FeatureGroup<dimensions, Drawable<dimensions, T>, T> {};
#ifndef DOXYGEN_GENERATING_OUTPUT
template<std::uint8_t dimensions, class T>
#else
template<std::uint8_t dimensions, class T = GLfloat>
#endif
class DrawableGroup: public FeatureGroup<dimensions, Drawable<dimensions, T>, T> {};
#endif
/**
@ -182,12 +184,6 @@ template<class T = GLfloat> using DrawableGroup3D = DrawableGroup<3, T>;
typedef DrawableGroup<3, T = GLfloat> DrawableGroup3D;
#endif
/* Make implementers' life easier */
#ifndef MAGNUM_GCC46_COMPATIBILITY
template<class T = GLfloat> using AbstractCamera2D = AbstractCamera<2, T>;
template<class T = GLfloat> using AbstractCamera3D = AbstractCamera<3, T>;
#endif
}}
#endif

12
src/SceneGraph/FeatureGroup.h

@ -19,24 +19,26 @@
* @brief Class Magnum::SceneGraph::FeatureGroup, alias Magnum::SceneGraph::FeatureGroup2D, Magnum::SceneGraph::FeatureGroup3D
*/
#include <cstdint>
#include <algorithm>
#include <vector>
#include <Utility/Debug.h>
#include "Magnum.h"
#include "SceneGraph.h"
namespace Magnum { namespace SceneGraph {
template<std::uint8_t, class, class T> class AbstractGroupedFeature;
/**
@brief Group of features
See AbstractGroupedFeature for more information.
@see FeatureGroup2D, FeatureGroup3D
*/
template<std::uint8_t dimensions, class Feature, class T = GLfloat> class FeatureGroup {
#ifndef DOXYGEN_GENERATING_OUTPUT
template<std::uint8_t dimensions, class Feature, class T>
#else
template<std::uint8_t dimensions, class Feature, class T = GLfloat>
#endif
class FeatureGroup {
friend class AbstractGroupedFeature<dimensions, Feature, T>;
public:

9
src/SceneGraph/MatrixTransformation2D.h

@ -30,7 +30,12 @@ namespace Magnum { namespace SceneGraph {
@see MatrixTransformation3D
*/
template<class T = GLfloat> class MatrixTransformation2D: public AbstractTranslationRotationScaling2D<T> {
#ifndef DOXYGEN_GENERATING_OUTPUT
template<class T>
#else
template<class T = GLfloat>
#endif
class MatrixTransformation2D: public AbstractTranslationRotationScaling2D<T> {
public:
/** @brief Transformation matrix type */
typedef typename DimensionTraits<2, T>::MatrixType DataType;
@ -64,7 +69,7 @@ template<class T = GLfloat> class MatrixTransformation2D: public AbstractTransla
MatrixTransformation2D<T>* setTransformation(const Math::Matrix3<T>& transformation) {
/* Setting transformation is forbidden for the scene */
/** @todo Assert for this? */
/** @todo Do this in some common code? */
/** @todo Do this in some common code so we don't need to include Object? */
if(!static_cast<Object<MatrixTransformation2D<T>>*>(this)->isScene()) {
_transformation = transformation;
static_cast<Object<MatrixTransformation2D<T>>*>(this)->setDirty();

9
src/SceneGraph/MatrixTransformation3D.h

@ -30,7 +30,12 @@ namespace Magnum { namespace SceneGraph {
@see MatrixTransformation2D
*/
template<class T = GLfloat> class MatrixTransformation3D: public AbstractTranslationRotationScaling3D<T> {
#ifndef DOXYGEN_GENERATING_OUTPUT
template<class T>
#else
template<class T = GLfloat>
#endif
class MatrixTransformation3D: public AbstractTranslationRotationScaling3D<T> {
public:
/** @brief Transformation matrix type */
typedef typename DimensionTraits<3, T>::MatrixType DataType;
@ -64,7 +69,7 @@ template<class T = GLfloat> class MatrixTransformation3D: public AbstractTransla
MatrixTransformation3D<T>* setTransformation(const Math::Matrix4<T>& transformation) {
/* Setting transformation is forbidden for the scene */
/** @todo Assert for this? */
/** @todo Do this in some common code? */
/** @todo Do this in some common code so we don't need to include Object? */
if(!static_cast<Object<MatrixTransformation3D<T>>*>(this)->isScene()) {
_transformation = transformation;
static_cast<Object<MatrixTransformation3D<T>>*>(this)->setDirty();

21
src/SceneGraph/Object.h

@ -28,8 +28,6 @@
namespace Magnum { namespace SceneGraph {
template<class Transformation> class Scene;
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
enum class ObjectFlag: std::uint8_t {
@ -48,8 +46,10 @@ namespace Implementation {
@brief %Object
Base of scene graph. Contains specific transformation implementation, takes
care of parent/children relationships and contains features. See
@ref scenegraph for introduction.
care of parent/children relationship and contains features. See @ref scenegraph
for introduction.
Uses Corrade::Containers::LinkedList for parent/children relationship.
@section Object-explicit-specializations Explicit template specializations
@ -78,6 +78,15 @@ template<class Transformation> class Object: public AbstractObject<Transformatio
#endif
public:
/**
* @brief Clean absolute transformations of given set of objects
*
* Only dirty objects in the list are cleaned.
* @see setClean(), AbstractObject::setClean()
*/
/* `objects` passed by copy intentionally (to avoid copy internally) */
static void setClean(std::vector<Object<Transformation>*> objects);
/**
* @brief Constructor
* @param parent Parent object
@ -213,6 +222,10 @@ template<class Transformation> class Object: public AbstractObject<Transformatio
typename Transformation::DataType computeJointTransformation(const std::vector<Object<Transformation>*>& jointObjects, std::vector<typename Transformation::DataType>& jointTransformations, const std::size_t joint, const typename Transformation::DataType& initialTransformation) const;
void setClean(const std::vector<AbstractObject<Transformation::Dimensions, typename Transformation::Type>*>& objects) const override;
void setClean(const typename Transformation::DataType& absoluteTransformation);
typedef Implementation::ObjectFlag Flag;
typedef Implementation::ObjectFlags Flags;
std::uint16_t counter;

101
src/SceneGraph/Object.hpp

@ -21,6 +21,7 @@
#include "Object.h"
#include <algorithm>
#include <stack>
#include "Scene.h"
@ -123,42 +124,9 @@ template<class Transformation> void Object<Transformation>::setClean() {
Object<Transformation>* o = objects.top();
objects.pop();
/* Compose transformations */
/* Compose transformation and clean object */
absoluteTransformation = Transformation::compose(absoluteTransformation, o->transformation());
/* "Lazy storage" for transformation matrix and inverted transformation matrix */
typedef typename AbstractFeature<Transformation::Dimensions, typename Transformation::Type>::CachedTransformation CachedTransformation;
typename AbstractFeature<Transformation::Dimensions, typename Transformation::Type>::CachedTransformations cached;
typename DimensionTraits<Transformation::Dimensions, typename Transformation::Type>::MatrixType
matrix, invertedMatrix;
/* Clean all features */
for(AbstractFeature<Transformation::Dimensions, typename Transformation::Type>* i = o->firstFeature(); i; i = i->nextFeature()) {
/* Cached absolute transformation, compute it if it wasn't
computed already */
if(i->cachedTransformations() & CachedTransformation::Absolute) {
if(!(cached & CachedTransformation::Absolute)) {
cached |= CachedTransformation::Absolute;
matrix = Transformation::toMatrix(absoluteTransformation);
}
i->clean(matrix);
}
/* Cached inverse absolute transformation, compute it if it wasn't
computed already */
if(i->cachedTransformations() & CachedTransformation::InvertedAbsolute) {
if(!(cached & CachedTransformation::InvertedAbsolute)) {
cached |= CachedTransformation::InvertedAbsolute;
invertedMatrix = Transformation::toMatrix(Transformation::inverted(absoluteTransformation));
}
i->cleanInverted(invertedMatrix);
}
}
/* Mark object as clean */
o->flags &= ~Flag::Dirty;
o->setClean(absoluteTransformation);
}
}
@ -286,6 +254,69 @@ template<class Transformation> typename Transformation::DataType Object<Transfor
}
}
template<class Transformation> void Object<Transformation>::setClean(const std::vector<AbstractObject<Transformation::Dimensions, typename Transformation::Type>*>& objects) const {
std::vector<Object<Transformation>*> castObjects(objects.size());
for(std::size_t i = 0; i != objects.size(); ++i)
/** @todo Ensure this doesn't crash, somehow */
castObjects[i] = static_cast<Object<Transformation>*>(objects[i]);
setClean(std::move(castObjects));
}
template<class Transformation> void Object<Transformation>::setClean(std::vector<Object<Transformation>*> objects) {
/* Remove all clean objects from the list */
auto firstClean = std::remove_if(objects.begin(), objects.end(), [](Object<Transformation>* o) { return !o->isDirty(); });
objects.erase(firstClean, objects.end());
/* No dirty objects left, done */
if(objects.empty()) return;
/* Compute absolute transformations */
Scene<Transformation>* scene = objects[0]->scene();
CORRADE_ASSERT(scene, "Object::setClean(): objects must be part of some scene", );
std::vector<typename Transformation::DataType> transformations(scene->transformations(objects));
/* Go through all objects and clean them */
for(std::size_t i = 0; i != objects.size(); ++i)
objects[i]->setClean(transformations[i]);
}
template<class Transformation> void Object<Transformation>::setClean(const typename Transformation::DataType& absoluteTransformation) {
/* "Lazy storage" for transformation matrix and inverted transformation matrix */
typedef typename AbstractFeature<Transformation::Dimensions, typename Transformation::Type>::CachedTransformation CachedTransformation;
typename AbstractFeature<Transformation::Dimensions, typename Transformation::Type>::CachedTransformations cached;
typename DimensionTraits<Transformation::Dimensions, typename Transformation::Type>::MatrixType
matrix, invertedMatrix;
/* Clean all features */
for(AbstractFeature<Transformation::Dimensions, typename Transformation::Type>* i = this->firstFeature(); i; i = i->nextFeature()) {
/* Cached absolute transformation, compute it if it wasn't
computed already */
if(i->cachedTransformations() & CachedTransformation::Absolute) {
if(!(cached & CachedTransformation::Absolute)) {
cached |= CachedTransformation::Absolute;
matrix = Transformation::toMatrix(absoluteTransformation);
}
i->clean(matrix);
}
/* Cached inverse absolute transformation, compute it if it wasn't
computed already */
if(i->cachedTransformations() & CachedTransformation::InvertedAbsolute) {
if(!(cached & CachedTransformation::InvertedAbsolute)) {
cached |= CachedTransformation::InvertedAbsolute;
invertedMatrix = Transformation::toMatrix(Transformation::inverted(absoluteTransformation));
}
i->cleanInverted(invertedMatrix);
}
}
/* Mark object as clean */
flags &= ~Flag::Dirty;
}
}}
#endif

94
src/SceneGraph/SceneGraph.h

@ -0,0 +1,94 @@
#ifndef Magnum_SceneGraph_SceneGraph_h
#define Magnum_SceneGraph_SceneGraph_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
/** @file
* @brief Forward declarations for Magnum::SceneGraph namespace
*/
#include <cstdint>
#include "Magnum.h"
namespace Magnum { namespace SceneGraph {
template<std::uint8_t dimensions, class T = GLfloat> class AbstractCamera;
#ifndef MAGNUM_GCC46_COMPATIBILITY
template<class T = GLfloat> using AbstractCamera2D = AbstractCamera<2, T>;
template<class T = GLfloat> using AbstractCamera3D = AbstractCamera<3, T>;
#endif
template<std::uint8_t dimensions, class T = GLfloat> class AbstractFeature;
#ifndef MAGNUM_GCC46_COMPATIBILITY
template<class T = GLfloat> using AbstractFeature2D = AbstractFeature<2, T>;
template<class T = GLfloat> using AbstractFeature3D = AbstractFeature<3, T>;
#endif
template<std::uint8_t dimensions, class Derived, class T = GLfloat> class AbstractGroupedFeature;
#ifndef MAGNUM_GCC46_COMPATIBILITY
template<class Derived, class T = GLfloat> using AbstractGroupedFeature2D = AbstractGroupedFeature<2, Derived, T>;
template<class Derived, class T = GLfloat> using AbstractGroupedFeature3D = AbstractGroupedFeature<3, Derived, T>;
#endif
template<std::uint8_t dimensions, class T = GLfloat> class AbstractObject;
#ifndef MAGNUM_GCC46_COMPATIBILITY
template<class T = GLfloat> using AbstractObject2D = AbstractObject<2, T>;
template<class T = GLfloat> using AbstractObject3D = AbstractObject<3, T>;
#endif
template<std::uint8_t dimensions, class T = GLfloat> class AbstractTransformation;
#ifndef MAGNUM_GCC46_COMPATIBILITY
template<class T = GLfloat> using AbstractTransformation2D = AbstractTransformation<2, T>;
template<class T = GLfloat> using AbstractTransformation3D = AbstractTransformation<3, T>;
#endif
template<class T = GLfloat> class AbstractTranslationRotation2D;
template<class T = GLfloat> class AbstractTranslationRotation3D;
template<class T = GLfloat> class AbstractTranslationRotationScaling2D;
template<class T = GLfloat> class AbstractTranslationRotationScaling3D;
template<class T = GLfloat> class Camera2D;
template<class T = GLfloat> class Camera3D;
template<std::uint8_t dimensions, class T = GLfloat> class Drawable;
#ifndef MAGNUM_GCC46_COMPATIBILITY
template<class T = GLfloat> using Drawable2D = Drawable<2, T>;
template<class T = GLfloat> using Drawable3D = Drawable<3, T>;
#endif
template<std::uint8_t dimensions, class Feature, class T = GLfloat> class FeatureGroup;
#ifndef MAGNUM_GCC46_COMPATIBILITY
template<class Feature, class T = GLfloat> using FeatureGroup2D = FeatureGroup<2, Feature, T>;
template<class Feature, class T = GLfloat> using FeatureGroup3D = FeatureGroup<3, Feature, T>;
#endif
#ifndef MAGNUM_GCC46_COMPATIBILITY
template<std::uint8_t dimensions, class T = GLfloat> using DrawableGroup = FeatureGroup<dimensions, Drawable<dimensions, T>, T>;
template<class T = GLfloat> using DrawableGroup2D = DrawableGroup<2, T>;
template<class T = GLfloat> using DrawableGroup3D = DrawableGroup<3, T>;
#else
template<std::uint8_t dimensions, class T = GLfloat> class DrawableGroup;
#endif
template<class T = GLfloat> class MatrixTransformation2D;
template<class T = GLfloat> class MatrixTransformation3D;
template<class Transformation> class Object;
template<class Transformation> class Scene;
}}
#endif

68
src/SceneGraph/Test/ObjectTest.cpp

@ -30,12 +30,27 @@ namespace Magnum { namespace SceneGraph { namespace Test {
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D<GLfloat>> Object3D;
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D<GLfloat>> Scene3D;
class CachingObject: public Object3D, AbstractFeature<3, GLfloat> {
public:
inline CachingObject(Object3D* parent = nullptr): Object3D(parent), AbstractFeature<3, GLfloat>(this) {
setCachedTransformations(CachedTransformation::Absolute);
}
Matrix4 cleanedAbsoluteTransformation;
protected:
void clean(const Matrix4& absoluteTransformation) override {
cleanedAbsoluteTransformation = absoluteTransformation;
}
};
ObjectTest::ObjectTest() {
addTests(&ObjectTest::parenting,
&ObjectTest::scene,
&ObjectTest::absoluteTransformation,
&ObjectTest::transformations,
&ObjectTest::caching);
&ObjectTest::setClean,
&ObjectTest::bulkSetClean);
}
void ObjectTest::parenting() {
@ -105,6 +120,9 @@ void ObjectTest::transformations() {
Matrix4 initial = Matrix4::rotationX(deg(90.0f)).inverted();
/* Empty list */
CORRADE_COMPARE(s.transformations(vector<Object3D*>(), initial), vector<Matrix4>());
/* Scene alone */
CORRADE_COMPARE(s.transformations({&s}, initial), vector<Matrix4>{initial});
@ -168,7 +186,7 @@ void ObjectTest::transformations() {
CORRADE_COMPARE(o.str(), "SceneGraph::Object::transformations(): the objects are not part of the same tree\n");
}
void ObjectTest::caching() {
void ObjectTest::setClean() {
Scene3D scene;
class CachingFeature: public AbstractFeature<3, GLfloat> {
@ -197,20 +215,6 @@ void ObjectTest::caching() {
}
};
class CachingObject: public Object3D, AbstractFeature<3, GLfloat> {
public:
inline CachingObject(Object3D* parent = nullptr): Object3D(parent), AbstractFeature<3, GLfloat>(this) {
setCachedTransformations(CachedTransformation::Absolute);
}
Matrix4 cleanedAbsoluteTransformation;
protected:
void clean(const Matrix4& absoluteTransformation) override {
cleanedAbsoluteTransformation = absoluteTransformation;
}
};
CachingObject* childOne = new CachingObject(&scene);
childOne->scale(Vector3(2.0f));
@ -277,4 +281,36 @@ void ObjectTest::caching() {
CORRADE_VERIFY(childThree->isDirty());
}
void ObjectTest::bulkSetClean() {
/* Verify it doesn't crash when passed empty list */
Object3D::setClean(vector<Object3D*>());
Scene3D scene;
Object3D a(&scene);
Object3D b(&scene);
b.setClean();
Object3D c(&scene);
c.translate(Vector3::zAxis(3.0f));
CachingObject d(&c);
d.scale(Vector3(-2.0f));
Object3D e(&scene);
vector<Object3D*> cleanAll{&a, &b, &c, &d, &e};
/* All objects should be cleaned */
CORRADE_VERIFY(a.isDirty());
CORRADE_VERIFY(!b.isDirty());
CORRADE_VERIFY(c.isDirty());
CORRADE_VERIFY(d.isDirty());
CORRADE_VERIFY(e.isDirty());
Object3D::setClean(cleanAll);
CORRADE_VERIFY(!a.isDirty());
CORRADE_VERIFY(!b.isDirty());
CORRADE_VERIFY(!c.isDirty());
CORRADE_VERIFY(!d.isDirty());
CORRADE_VERIFY(!e.isDirty());
/* Verify that right transformation was passed */
CORRADE_COMPARE(d.cleanedAbsoluteTransformation, Matrix4::translation(Vector3::zAxis(3.0f))*Matrix4::scaling(Vector3(-2.0f)));
}
}}}

3
src/SceneGraph/Test/ObjectTest.h

@ -27,7 +27,8 @@ class ObjectTest: public Corrade::TestSuite::Tester<ObjectTest> {
void scene();
void absoluteTransformation();
void transformations();
void caching();
void setClean();
void bulkSetClean();
};
}}}

2
src/Shaders/FlatShader2D.frag

@ -4,7 +4,7 @@
uniform lowp vec3 color;
#ifndef NEW_GLSL
#ifdef NEW_GLSL
out lowp vec4 fragmentColor;
#endif

4
src/Test/CMakeLists.txt

@ -1,5 +1,5 @@
corrade_add_test2(ColorTest ColorTest.cpp)
corrade_add_test2(ColorTest ColorTest.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test2(ResourceManagerTest ResourceManagerTest.cpp)
corrade_add_test2(SwizzleTest SwizzleTest.cpp)
corrade_add_test2(SwizzleTest SwizzleTest.cpp LIBRARIES MagnumMathTestLib)
set_target_properties(ResourceManagerTest PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT)

Loading…
Cancel
Save