Browse Source

Merge branch 'master' into compatibility

Conflicts:
	src/Magnum.h
	src/Physics/Test/ShapeTestBase.h
	src/ResourceManager.h
Vladimír Vondruš 14 years ago
parent
commit
8a287cebfa
  1. 137
      src/AbstractResourceLoader.h
  2. 12
      src/AbstractShaderProgram.h
  3. 10
      src/AbstractTexture.h
  4. 3
      src/CMakeLists.txt
  5. 1
      src/Context.cpp
  6. 7
      src/Magnum.h
  7. 6
      src/Math/RectangularMatrix.h
  8. 10
      src/Math/Test/Matrix3Test.cpp
  9. 10
      src/Math/Test/Matrix4Test.cpp
  10. 10
      src/Math/Test/MatrixTest.cpp
  11. 10
      src/Math/Test/Point2DTest.cpp
  12. 10
      src/Math/Test/Point3DTest.cpp
  13. 10
      src/Math/Test/RectangularMatrixTest.cpp
  14. 10
      src/Math/Test/Vector2Test.cpp
  15. 10
      src/Math/Test/Vector3Test.cpp
  16. 10
      src/Math/Test/Vector4Test.cpp
  17. 10
      src/Math/Test/VectorTest.cpp
  18. 51
      src/Mesh.cpp
  19. 28
      src/Mesh.h
  20. 2
      src/MeshTools/CompressIndices.h
  21. 4
      src/MeshTools/FlipNormals.h
  22. 2
      src/MeshTools/GenerateFlatNormals.h
  23. 2
      src/MeshTools/Tipsify.h
  24. 6
      src/MeshTools/magnumMeshToolsVisibility.h
  25. 14
      src/Physics/AbstractShape.h
  26. 6
      src/Physics/AxisAlignedBox.cpp
  27. 4
      src/Physics/AxisAlignedBox.h
  28. 4
      src/Physics/Box.cpp
  29. 4
      src/Physics/Box.h
  30. 8
      src/Physics/Capsule.cpp
  31. 4
      src/Physics/Capsule.h
  32. 4
      src/Physics/DebugDrawResourceManager.cpp
  33. 4
      src/Physics/DebugDrawResourceManager.h
  34. 2
      src/Physics/Implementation/AxisAlignedBoxRenderer.cpp
  35. 2
      src/Physics/Implementation/BoxRenderer.cpp
  36. 6
      src/Physics/Line.cpp
  37. 4
      src/Physics/Line.h
  38. 4
      src/Physics/ObjectShape.cpp
  39. 4
      src/Physics/ObjectShape.h
  40. 2
      src/Physics/ObjectShapeGroup.h
  41. 6
      src/Physics/Plane.cpp
  42. 6
      src/Physics/Plane.h
  43. 4
      src/Physics/Point.cpp
  44. 4
      src/Physics/Point.h
  45. 6
      src/Physics/ShapeGroup.cpp
  46. 4
      src/Physics/ShapeGroup.h
  47. 6
      src/Physics/Sphere.cpp
  48. 4
      src/Physics/Sphere.h
  49. 4
      src/Physics/Test/AxisAlignedBoxTest.cpp
  50. 2
      src/Physics/Test/BoxTest.cpp
  51. 4
      src/Physics/Test/CapsuleTest.cpp
  52. 2
      src/Physics/Test/LineTest.cpp
  53. 4
      src/Physics/Test/PlaneTest.cpp
  54. 2
      src/Physics/Test/PointTest.cpp
  55. 4
      src/Physics/Test/ShapeGroupTest.cpp
  56. 2
      src/Physics/Test/ShapeTestBase.h
  57. 6
      src/Physics/Test/SphereTest.cpp
  58. 6
      src/Physics/magnumPhysicsVisibility.h
  59. 2
      src/Platform/AbstractXApplication.cpp
  60. 2
      src/Platform/Sdl2Application.cpp
  61. 39
      src/Resource.cpp
  62. 266
      src/Resource.h
  63. 383
      src/ResourceManager.h
  64. 6
      src/SceneGraph/AbstractCamera.h
  65. 8
      src/SceneGraph/AbstractFeature.h
  66. 8
      src/SceneGraph/Camera.cpp
  67. 2
      src/SceneGraph/Camera2D.h
  68. 2
      src/SceneGraph/Camera3D.h
  69. 2
      src/SceneGraph/MatrixTransformation2D.cpp
  70. 2
      src/SceneGraph/MatrixTransformation3D.cpp
  71. 6
      src/SceneGraph/magnumSceneGraphVisibility.h
  72. 2
      src/Shaders/FlatShader.cpp
  73. 8
      src/Shaders/FlatShader.h
  74. 4
      src/Shaders/FlatShader2D.vert
  75. 8
      src/Shaders/PhongShader.h
  76. 2
      src/Shaders/VertexColorShader.cpp
  77. 10
      src/Shaders/VertexColorShader.h
  78. 4
      src/Shaders/VertexColorShader2D.vert
  79. 6
      src/Shaders/magnumShadersVisibility.h
  80. 4
      src/Test/CMakeLists.txt
  81. 16
      src/Test/ColorTest.cpp
  82. 47
      src/Test/MeshTest.cpp
  83. 32
      src/Test/MeshTest.h
  84. 203
      src/Test/ResourceManagerTest.cpp
  85. 25
      src/Test/ResourceManagerTest.h
  86. 47
      src/Test/TypeTraitsTest.cpp
  87. 32
      src/Test/TypeTraitsTest.h
  88. 61
      src/TypeTraits.cpp
  89. 26
      src/TypeTraits.h

137
src/AbstractResourceLoader.h

@ -0,0 +1,137 @@
#ifndef Magnum_AbstractResourceLoader_h
#define Magnum_AbstractResourceLoader_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::AbstractResourceLoader
*/
#include "Magnum.h"
#include <string>
#include "ResourceManager.h"
namespace Magnum {
/**
@brief Base for resource loaders
Provides asynchronous resource loading for ResourceManager.
*/
template<class T> class AbstractResourceLoader {
friend class Implementation::ResourceManagerData<T>;
public:
inline AbstractResourceLoader(): manager(nullptr), _requestedCount(0), _loadedCount(0), _notFoundCount(0) {}
inline virtual ~AbstractResourceLoader() {
if(manager) manager->_loader = nullptr;
}
/**
* @brief Count of requested resources
*
* Count of resources requested by calling load().
*/
inline std::size_t requestedCount() const { return _requestedCount; }
/**
* @brief Count of not found resources
*
* Count of resources requested by calling load(), but not found by
* the loader.
*/
inline std::size_t notFountCount() const { return _notFoundCount; }
/**
* @brief Count of loaded resources
*
* Count of resources requested by calling load(), but not found by
* the loader.
*/
inline std::size_t loadedCount() const { return _loadedCount; }
/**
* @brief %Resource name corresponding to given key
*
* If no such resource exists or the resource name is not available,
* returns empty string. Default implementation returns empty string.
*/
virtual std::string name(ResourceKey key) const;
/**
* @brief Request resource to be loaded
*
* If the resource isn't yet loaded or loading, state of the resource
* is set to @ref Resource::ResourceState "ResourceState::Loading" and count of
* requested features is incremented.
*
* The resource might be loaded asynchronously and added to
* ResourceManager when loading is done.
* @see ResourceManager::state(), requestedCount(), notFountCount(),
* loadedCount()
*/
virtual void load(ResourceKey key) = 0;
protected:
/**
* @brief Set loaded resource to resource manager
*
* Also increments count of loaded resources. Parameter @p state
* must be either @ref ResourceManager::ResourceDataState "ResourceDataState::Mutable"
* or @ref ResourceManager::ResourceDataState "ResourceDataState::Final". See
* ResourceManager::set() for more information.
* @see loadedCount()
*/
inline void set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy) {
CORRADE_ASSERT(state == ResourceDataState::Mutable || state == ResourceDataState::Final,
"AbstractResourceLoader::set(): state must be either Mutable or Final", );
++_loadedCount;
manager->set(key, data, state, policy);
}
/**
* @brief Mark resource as not found
*
* Also increments count of not found resources. See
* ResourceManager::setNotFound() for more information.
* @see notFountCount()
*/
inline void setNotFound(ResourceKey key) {
++_notFoundCount;
/** @todo What policy for notfound resources? */
manager->set(key, nullptr, ResourceDataState::NotFound, ResourcePolicy::Resident);
}
private:
Implementation::ResourceManagerData<T>* manager;
std::size_t _requestedCount;
std::size_t _loadedCount;
std::size_t _notFoundCount;
};
template<class T> inline std::string AbstractResourceLoader<T>::name(ResourceKey) const { return {}; }
template<class T> inline void AbstractResourceLoader<T>::load(ResourceKey key) {
++_requestedCount;
/** @todo What policy for loading resources? */
manager->set(key, nullptr, ResourceDataState::Loading, ResourcePolicy::Resident);
}
}
#endif

12
src/AbstractShaderProgram.h

@ -53,9 +53,9 @@ functions and properties:
- <strong>%Attribute definitions</strong> with location and type for
configuring meshes, for example:
@code
static const Attribute<0, Point3D> Position;
static const Attribute<1, Vector3> Normal;
static const Attribute<2, Vector2> TextureCoordinates;
typedef Attribute<0, Point3D> Position;
typedef Attribute<1, Vector3> Normal;
typedef Attribute<2, Vector2> TextureCoordinates;
@endcode
@todoc Output attribute location (for bindFragmentDataLocationIndexed(),
referenced also from Framebuffer::mapDefaultForDraw() / Framebuffer::mapForDraw())
@ -127,9 +127,9 @@ the program:
@code
// Shaders attached...
bindAttributeLocation(Position.Location, "position");
bindAttributeLocation(Normal.Location, "normal");
bindAttributeLocation(TextureCoords.Location, "textureCoordinates");
bindAttributeLocation(Position::Location, "position");
bindAttributeLocation(Normal::Location, "normal");
bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates");
bindFragmentDataLocationIndexed(0, 0, "color");
bindFragmentDataLocationIndexed(1, 1, "ambient");

10
src/AbstractTexture.h

@ -29,10 +29,12 @@ namespace Magnum {
@brief Base for textures
@attention Don't forget to call @ref Texture::setWrapping() "setWrapping()",
setMinificationFilter() and setMagnificationFilter() after creating the
texture, otherwise the texture will be incomplete. If you specified mipmap
filtering in setMinificationFilter(), be sure to also either explicitly set
all mip levels or call generateMipmap().
setMinificationFilter() and setMagnificationFilter() after creating the
texture, otherwise the texture will be incomplete. If you specified
@ref Wrapping "Wrapping::ClampToBorder" in @ref Texture::setWrapping() "setWrapping()",
be sure to also call setBorderColor(). If you specified mipmap filtering
in setMinificationFilter(), be sure to also either explicitly set all mip
levels or call generateMipmap().
The texture is bound to shader via bind(). Texture uniform on the shader must
also be set to particular texture layer using

3
src/CMakeLists.txt

@ -32,6 +32,7 @@ set(Magnum_SRCS
Profiler.cpp
Query.cpp
Renderbuffer.cpp
Resource.cpp
Shader.cpp
SizeTraits.cpp
Timeline.cpp
@ -58,6 +59,7 @@ endif()
set(Magnum_HEADERS
AbstractImage.h
AbstractResourceLoader.h
AbstractShaderProgram.h
AbstractTexture.h
Buffer.h
@ -76,6 +78,7 @@ set(Magnum_HEADERS
Profiler.h
Query.h
Renderbuffer.h
Resource.h
ResourceManager.h
Shader.h
SizeTraits.h

1
src/Context.cpp

@ -18,6 +18,7 @@
#include <string>
#include <unordered_map>
#include <Utility/Debug.h>
#include <Utility/utilities.h>
#include "AbstractShaderProgram.h"
#include "AbstractTexture.h"

7
src/Magnum.h

@ -120,8 +120,8 @@ typedef BufferedImage<3> BufferedImage3D;
class BufferedTexture;
#endif
template<class = GLfloat> class Color3;
template<class = GLfloat> class Color4;
template<class T = GLfloat> class Color3;
template<class T = GLfloat> class Color4;
#ifndef CORRADE_GCC45_COMPATIBILITY
enum class Version: GLint;
@ -160,7 +160,8 @@ enum class ResourceState: std::uint8_t;
enum class ResourceDataState: std::uint8_t;
enum class ResourcePolicy: std::uint8_t;
#endif
template<class, class> class Resource;
template<class T, class U = T> class Resource;
class ResourceKey;
template<class...> class ResourceManager;
class Shader;

6
src/Math/RectangularMatrix.h

@ -22,7 +22,7 @@
#include <cmath>
#include <limits>
#include <Utility/Debug.h>
#include <Utility/Configuration.h>
#include <Utility/ConfigurationValue.h>
#include "MathTypeTraits.h"
@ -508,7 +508,7 @@ namespace Corrade { namespace Utility {
/** @configurationvalue{Magnum::Math::RectangularMatrix} */
template<std::size_t cols, std::size_t rows, class T> struct ConfigurationValue<Magnum::Math::RectangularMatrix<cols, rows, T>> {
/** @brief Writes elements separated with spaces */
static std::string toString(const Magnum::Math::RectangularMatrix<cols, rows, T>& value, int flags = 0) {
static std::string toString(const Magnum::Math::RectangularMatrix<cols, rows, T>& value, ConfigurationValueFlags flags) {
std::string output;
for(std::size_t row = 0; row != rows; ++row) {
@ -522,7 +522,7 @@ template<std::size_t cols, std::size_t rows, class T> struct ConfigurationValue<
}
/** @brief Reads elements separated with whitespace */
static Magnum::Math::RectangularMatrix<cols, rows, T> fromString(const std::string& stringValue, int flags = 0) {
static Magnum::Math::RectangularMatrix<cols, rows, T> fromString(const std::string& stringValue, ConfigurationValueFlags flags) {
Magnum::Math::RectangularMatrix<cols, rows, T> result;
std::istringstream in(stringValue);

10
src/Math/Test/Matrix3Test.cpp

@ -15,7 +15,7 @@
#include "Matrix3Test.h"
#include <sstream>
#include <Utility/Configuration.h>
#include "Constants.h"
#include "Matrix3.h"
@ -148,14 +148,18 @@ void Matrix3Test::debug() {
}
void Matrix3Test::configuration() {
Configuration c;
Matrix3 m(
5.0f, 8.0f, 4.0f,
4.0f, 7.0f, 3.125f,
4.0f, 5.0f, 9.55f
);
string value("5 4 4 8 7 5 4 3.125 9.55");
CORRADE_COMPARE(ConfigurationValue<Matrix3>::toString(m), value);
CORRADE_COMPARE(ConfigurationValue<Matrix3>::fromString(value), m);
c.setValue("matrix", m);
CORRADE_COMPARE(c.value<std::string>("matrix"), value);
CORRADE_COMPARE(c.value<Matrix3>("matrix"), m);
}
}}}

10
src/Math/Test/Matrix4Test.cpp

@ -15,7 +15,7 @@
#include "Matrix4Test.h"
#include <sstream>
#include <Utility/Configuration.h>
#include "Constants.h"
#include "Matrix4.h"
@ -195,6 +195,8 @@ void Matrix4Test::debug() {
}
void Matrix4Test::configuration() {
Configuration c;
Matrix4 m(
3.0f, 5.0f, 8.0f, 4.0f,
4.0f, 4.0f, 7.0f, 3.125f,
@ -202,8 +204,10 @@ void Matrix4Test::configuration() {
9.0f, 4.0f, 5.0f, 9.55f
);
string value("3 4 7 9 5 4 -1 4 8 7 8 5 4 3.125 0 9.55");
CORRADE_COMPARE(ConfigurationValue<Matrix4>::toString(m), value);
CORRADE_COMPARE(ConfigurationValue<Matrix4>::fromString(value), m);
c.setValue("matrix", m);
CORRADE_COMPARE(c.value<std::string>("matrix"), value);
CORRADE_COMPARE(c.value<Matrix4>("matrix"), m);
}
}}}

10
src/Math/Test/MatrixTest.cpp

@ -15,7 +15,7 @@
#include "MatrixTest.h"
#include <sstream>
#include <Utility/Configuration.h>
#include "Matrix.h"
@ -186,6 +186,8 @@ void MatrixTest::debug() {
}
void MatrixTest::configuration() {
Configuration c;
Matrix4 m(
3.0f, 5.0f, 8.0f, 4.0f,
4.0f, 4.0f, 7.0f, 3.125f,
@ -193,8 +195,10 @@ void MatrixTest::configuration() {
9.0f, 4.0f, 5.0f, 9.55f
);
string value("3 4 7 9 5 4 -1 4 8 7 8 5 4 3.125 0 9.55");
CORRADE_COMPARE(ConfigurationValue<Matrix4>::toString(m), value);
CORRADE_COMPARE(ConfigurationValue<Matrix4>::fromString(value), m);
c.setValue("matrix", m);
CORRADE_COMPARE(c.value<std::string>("matrix"), value);
CORRADE_COMPARE(c.value<Matrix4>("matrix"), m);
}
}}}

10
src/Math/Test/Point2DTest.cpp

@ -15,7 +15,7 @@
#include "Point2DTest.h"
#include <sstream>
#include <Utility/Configuration.h>
#include "Point2D.h"
@ -47,10 +47,14 @@ void Point2DTest::debug() {
}
void Point2DTest::configuration() {
Configuration c;
Point2D vec(3.0f, 3.125f, 9.55f);
string value("3 3.125 9.55");
CORRADE_COMPARE(ConfigurationValue<Point2D>::toString(vec), value);
CORRADE_COMPARE(ConfigurationValue<Point2D>::fromString(value), vec);
c.setValue("point", vec);
CORRADE_COMPARE(c.value<std::string>("point"), value);
CORRADE_COMPARE(c.value<Point2D>("point"), vec);
}
}}}

10
src/Math/Test/Point3DTest.cpp

@ -15,7 +15,7 @@
#include "Point3DTest.h"
#include <sstream>
#include <Utility/Configuration.h>
#include "Point3D.h"
@ -47,10 +47,14 @@ void Point3DTest::debug() {
}
void Point3DTest::configuration() {
Configuration c;
Point3D vec(3.0f, 3.125f, 9.0f, 9.55f);
string value("3 3.125 9 9.55");
CORRADE_COMPARE(ConfigurationValue<Point3D>::toString(vec), value);
CORRADE_COMPARE(ConfigurationValue<Point3D>::fromString(value), vec);
c.setValue("point", vec);
CORRADE_COMPARE(c.value<std::string>("point"), value);
CORRADE_COMPARE(c.value<Point3D>("point"), vec);
}
}}}

10
src/Math/Test/RectangularMatrixTest.cpp

@ -15,7 +15,7 @@
#include "RectangularMatrixTest.h"
#include <sstream>
#include <Utility/Configuration.h>
#include "RectangularMatrix.h"
@ -242,8 +242,12 @@ void RectangularMatrixTest::configuration() {
7.0f, -1.0f, 8.0f, 9.55f
);
string value("3 4 7 5 4 -1 8 7 8 4 3.125 9.55");
CORRADE_COMPARE(ConfigurationValue<Matrix3x4>::toString(m), value);
CORRADE_COMPARE(ConfigurationValue<Matrix3x4>::fromString(value), m);
Configuration c;
c.setValue<Matrix3x4>("matrix", m);
CORRADE_COMPARE(c.value<std::string>("matrix"), value);
CORRADE_COMPARE(c.value<Matrix3x4>("matrix"), m);
}
}}}

10
src/Math/Test/Vector2Test.cpp

@ -15,7 +15,7 @@
#include "Vector2Test.h"
#include <sstream>
#include <Utility/Configuration.h>
#include "Vector2.h"
@ -57,10 +57,14 @@ void Vector2Test::debug() {
}
void Vector2Test::configuration() {
Configuration c;
Vector2 vec(3.125f, 9.0f);
string value("3.125 9");
CORRADE_COMPARE(ConfigurationValue<Vector2>::toString(vec), value);
CORRADE_COMPARE(ConfigurationValue<Vector2>::fromString(value), vec);
c.setValue("vector", vec);
CORRADE_COMPARE(c.value<std::string>("vector"), value);
CORRADE_COMPARE(c.value<Vector2>("vector"), vec);
}
}}}

10
src/Math/Test/Vector3Test.cpp

@ -15,7 +15,7 @@
#include "Vector3Test.h"
#include <sstream>
#include <Utility/Configuration.h>
#include "Vector3.h"
@ -75,10 +75,14 @@ void Vector3Test::debug() {
}
void Vector3Test::configuration() {
Configuration c;
Vector3 vec(3.0f, 3.125f, 9.55f);
string value("3 3.125 9.55");
CORRADE_COMPARE(ConfigurationValue<Vector3>::toString(vec), value);
CORRADE_COMPARE(ConfigurationValue<Vector3>::fromString(value), vec);
c.setValue("vector", vec);
CORRADE_COMPARE(c.value<std::string>("vector"), value);
CORRADE_COMPARE(c.value<Vector3>("vector"), vec);
}
}}}

10
src/Math/Test/Vector4Test.cpp

@ -15,7 +15,7 @@
#include "Vector4Test.h"
#include <sstream>
#include <Utility/Configuration.h>
#include "Vector4.h"
@ -59,10 +59,14 @@ void Vector4Test::debug() {
}
void Vector4Test::configuration() {
Configuration c;
Vector4 vec(3.0f, 3.125f, 9.0f, 9.55f);
string value("3 3.125 9 9.55");
CORRADE_COMPARE(ConfigurationValue<Vector4>::toString(vec), value);
CORRADE_COMPARE(ConfigurationValue<Vector4>::fromString(value), vec);
c.setValue("vector", vec);
CORRADE_COMPARE(c.value<std::string>("vector"), value);
CORRADE_COMPARE(c.value<Vector4>("vector"), vec);
}
}}}

10
src/Math/Test/VectorTest.cpp

@ -15,7 +15,7 @@
#include "VectorTest.h"
#include <sstream>
#include <Utility/Configuration.h>
#include "Constants.h"
#include "Vector.h"
@ -116,10 +116,14 @@ void VectorTest::debug() {
}
void VectorTest::configuration() {
Configuration c;
Vector4 vec(3.0f, 3.125f, 9.0f, 9.55f);
string value("3 3.125 9 9.55");
CORRADE_COMPARE(ConfigurationValue<Vector4>::toString(vec), value);
CORRADE_COMPARE(ConfigurationValue<Vector4>::fromString(value), vec);
c.setValue("vector", vec);
CORRADE_COMPARE(c.value<std::string>("vector"), value);
CORRADE_COMPARE(c.value<Vector4>("vector"), vec);
}
}}}

51
src/Mesh.cpp

@ -265,4 +265,55 @@ void Mesh::unbindImplementationDefault() {
void Mesh::unbindImplementationVAO() {}
#ifndef DOXYGEN_GENERATING_OUTPUT
Debug operator<<(Debug debug, Mesh::Primitive value) {
switch(value) {
#define _c(value) case Mesh::Primitive::value: return debug << "Mesh::Primitive::" #value;
_c(Points)
_c(Lines)
_c(LineStrip)
_c(LineLoop)
_c(Triangles)
_c(TriangleStrip)
_c(TriangleFan)
#undef _c
}
return debug << "Mesh::Primitive::(invalid)";
}
#endif
}
namespace Corrade { namespace Utility {
std::string ConfigurationValue<Magnum::Mesh::Primitive>::toString(Magnum::Mesh::Primitive value, ConfigurationValueFlags) {
switch(value) {
#define _c(value) case Magnum::Mesh::Primitive::value: return #value;
_c(Points)
_c(Lines)
_c(LineStrip)
_c(LineLoop)
_c(Triangles)
_c(TriangleStrip)
_c(TriangleFan)
#undef _c
}
return "";
}
Magnum::Mesh::Primitive ConfigurationValue<Magnum::Mesh::Primitive>::fromString(const std::string& stringValue, ConfigurationValueFlags) {
#define _c(value) if(stringValue == #value) return Magnum::Mesh::Primitive::value;
_c(Lines)
_c(LineStrip)
_c(LineLoop)
_c(Triangles)
_c(TriangleStrip)
_c(TriangleFan)
#undef _c
return Magnum::Mesh::Primitive::Points;
}
}}

28
src/Mesh.h

@ -33,8 +33,8 @@ namespace Magnum {
@section Mesh-configuration Mesh configuration
To properly configure mesh, you have to set primitive either in constructor or
using setPrimitive() and call setVertexCount(). Then create vertex buffers,
and them with vertex data. You can also use MeshTools::interleave() to
using setPrimitive() and call setVertexCount(). Then create vertex buffers and
fill them with vertex data. You can also use MeshTools::interleave() to
conveniently set vertex count and buffer data. At last assign them to mesh and
@ref AbstractShaderProgram::Attribute "shader attributes" using
addVertexBuffer(), addInterleavedVertexBuffer() or addVertexBufferStride().
@ -742,6 +742,30 @@ class MAGNUM_EXPORT Mesh {
#endif
};
/** @debugoperator{Magnum::Mesh} */
Debug MAGNUM_EXPORT operator<<(Debug debug, Mesh::Primitive value);
}
namespace Corrade { namespace Utility {
/** @configurationvalue{Magnum::Mesh} */
template<> struct MAGNUM_EXPORT ConfigurationValue<Magnum::Mesh::Primitive> {
/**
* @brief Writes enum value as string
*
* If the value is invalid, returns empty string.
*/
static std::string toString(Magnum::Mesh::Primitive value, ConfigurationValueFlags);
/**
* @brief Reads enum value as string
*
* If the value is invalid, returns @ref Magnum::Mesh::Primitive "Mesh::Primitive::Points".
*/
static Magnum::Mesh::Primitive fromString(const std::string& stringValue, ConfigurationValueFlags);
};
}}
#endif

2
src/MeshTools/CompressIndices.h

@ -31,7 +31,7 @@ namespace Magnum { namespace MeshTools {
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
class MESHTOOLS_EXPORT CompressIndices {
class MAGNUM_MESHTOOLS_EXPORT CompressIndices {
public:
CompressIndices(const std::vector<std::uint32_t>& indices): indices(indices) {}

4
src/MeshTools/FlipNormals.h

@ -34,7 +34,7 @@ namespace Magnum { namespace MeshTools {
The same as flipNormals(std::vector<std::uint32_t>&, std::vector<Vector3>&),
but flips only face winding.
*/
void MESHTOOLS_EXPORT flipFaceWinding(std::vector<std::uint32_t>& indices);
void MAGNUM_MESHTOOLS_EXPORT flipFaceWinding(std::vector<std::uint32_t>& indices);
/**
@brief Flip mesh normals
@ -42,7 +42,7 @@ void MESHTOOLS_EXPORT flipFaceWinding(std::vector<std::uint32_t>& indices);
The same as flipNormals(std::vector<std::uint32_t>&, std::vector<Vector3>&),
but flips only normals, not face winding.
*/
void MESHTOOLS_EXPORT flipNormals(std::vector<Vector3>& normals);
void MAGNUM_MESHTOOLS_EXPORT flipNormals(std::vector<Vector3>& normals);
/**
@brief Flip mesh normals and face winding

2
src/MeshTools/GenerateFlatNormals.h

@ -51,7 +51,7 @@ use the same indices.
@attention Index count must be divisible by 3, otherwise zero length result
is generated.
*/
std::tuple<std::vector<std::uint32_t>, std::vector<Vector3>> MESHTOOLS_EXPORT generateFlatNormals(const std::vector<std::uint32_t>& indices, const std::vector<Point3D>& positions);
std::tuple<std::vector<std::uint32_t>, std::vector<Vector3>> MAGNUM_MESHTOOLS_EXPORT generateFlatNormals(const std::vector<std::uint32_t>& indices, const std::vector<Point3D>& positions);
}}

2
src/MeshTools/Tipsify.h

@ -29,7 +29,7 @@ namespace Magnum { namespace MeshTools {
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
class MESHTOOLS_EXPORT Tipsify {
class MAGNUM_MESHTOOLS_EXPORT Tipsify {
public:
inline Tipsify(std::vector<std::uint32_t>& indices, std::uint32_t vertexCount): indices(indices), vertexCount(vertexCount) {}

6
src/MeshTools/magnumMeshToolsVisibility.h

@ -17,12 +17,12 @@
#ifdef _WIN32
#if defined(MagnumMeshTools_EXPORTS) || defined(MagnumMeshToolsObjects_EXPORTS)
#define MESHTOOLS_EXPORT __declspec(dllexport)
#define MAGNUM_MESHTOOLS_EXPORT __declspec(dllexport)
#else
#define MESHTOOLS_EXPORT __declspec(dllimport)
#define MAGNUM_MESHTOOLS_EXPORT __declspec(dllimport)
#endif
#else
#define MESHTOOLS_EXPORT __attribute__ ((visibility ("default")))
#define MAGNUM_MESHTOOLS_EXPORT __attribute__ ((visibility ("default")))
#endif
#endif

14
src/Physics/AbstractShape.h

@ -65,7 +65,7 @@ namespace Implementation {
See @ref collision-detection for brief introduction.
@see AbstractShape2D, AbstractShape3D
*/
template<std::uint8_t dimensions> class PHYSICS_EXPORT AbstractShape {
template<std::uint8_t dimensions> class MAGNUM_PHYSICS_EXPORT AbstractShape {
public:
/** @brief Dimension count */
static const std::uint8_t Dimensions = dimensions;
@ -100,12 +100,12 @@ template<std::uint8_t dimensions> class PHYSICS_EXPORT AbstractShape {
virtual Type type() const = 0;
/**
* @brief Apply transformation
* @brief Apply transformation matrix
*
* Applies transformation to user-defined shape properties and caches
* them for later usage in collision detection.
* Applies transformation matrix to user-defined shape properties and
* caches them for later usage in collision detection.
*/
virtual void applyTransformation(const typename DimensionTraits<dimensions>::MatrixType& transformation) = 0;
virtual void applyTransformationMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) = 0;
/**
* @brief Detect collision with other shape
@ -126,8 +126,8 @@ typedef AbstractShape<3> AbstractShape3D;
/** @debugoperator{Magnum::Physics::AbstractShape} */
#ifndef DOXYGEN_GENERATING_OUTPUT
Debug PHYSICS_EXPORT operator<<(Debug debug, AbstractShape2D::Type value);
Debug PHYSICS_EXPORT operator<<(Debug debug, AbstractShape3D::Type value);
Debug MAGNUM_PHYSICS_EXPORT operator<<(Debug debug, AbstractShape2D::Type value);
Debug MAGNUM_PHYSICS_EXPORT operator<<(Debug debug, AbstractShape3D::Type value);
#else
template<std::uint8_t dimensions> Debug operator<<(Debug debug, typename AbstractShape<dimensions>::Type value);
#endif

6
src/Physics/AxisAlignedBox.cpp

@ -20,9 +20,9 @@
namespace Magnum { namespace Physics {
template<std::uint8_t dimensions> void AxisAlignedBox<dimensions>::applyTransformation(const typename DimensionTraits<dimensions>::MatrixType& transformation) {
_transformedPosition = (transformation*typename DimensionTraits<dimensions>::PointType(_position)).vector();
_transformedSize = transformation.rotationScaling()*_size;
template<std::uint8_t dimensions> void AxisAlignedBox<dimensions>::applyTransformationMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) {
_transformedPosition = (matrix*typename DimensionTraits<dimensions>::PointType(_position)).vector();
_transformedSize = matrix.rotationScaling()*_size;
}
template class AxisAlignedBox<2>;

4
src/Physics/AxisAlignedBox.h

@ -31,7 +31,7 @@ namespace Magnum { namespace Physics {
@see AxisAlignedBox2D, AxisAlignedBox3D
*/
template<std::uint8_t dimensions> class PHYSICS_EXPORT AxisAlignedBox: public AbstractShape<dimensions> {
template<std::uint8_t dimensions> class MAGNUM_PHYSICS_EXPORT AxisAlignedBox: public AbstractShape<dimensions> {
public:
/** @brief Constructor */
inline AxisAlignedBox(const typename DimensionTraits<dimensions>::VectorType& position, const typename DimensionTraits<dimensions>::VectorType& size): _position(position), _transformedPosition(position), _size(size), _transformedSize(size) {}
@ -40,7 +40,7 @@ template<std::uint8_t dimensions> class PHYSICS_EXPORT AxisAlignedBox: public Ab
return AbstractShape<dimensions>::Type::AxisAlignedBox;
}
void applyTransformation(const typename DimensionTraits<dimensions>::MatrixType& transformation) override;
void applyTransformationMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) override;
/** @brief Position */
inline typename DimensionTraits<dimensions>::VectorType position() const {

4
src/Physics/Box.cpp

@ -20,8 +20,8 @@
namespace Magnum { namespace Physics {
template<std::uint8_t dimensions> void Box<dimensions>::applyTransformation(const typename DimensionTraits<dimensions>::MatrixType& transformation) {
_transformedTransformation = (transformation*_transformation);
template<std::uint8_t dimensions> void Box<dimensions>::applyTransformationMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) {
_transformedTransformation = matrix*_transformation;
}
template class Box<2>;

4
src/Physics/Box.h

@ -33,7 +33,7 @@ namespace Magnum { namespace Physics {
@todo Use quat + position + size instead?
@see Box2D, Box3D
*/
template<std::uint8_t dimensions> class PHYSICS_EXPORT Box: public AbstractShape<dimensions> {
template<std::uint8_t dimensions> class MAGNUM_PHYSICS_EXPORT Box: public AbstractShape<dimensions> {
public:
/** @brief Constructor */
inline Box(const typename DimensionTraits<dimensions>::MatrixType& transformation): _transformation(transformation), _transformedTransformation(transformation) {}
@ -42,7 +42,7 @@ template<std::uint8_t dimensions> class PHYSICS_EXPORT Box: public AbstractShape
return AbstractShape<dimensions>::Type::Box;
}
void applyTransformation(const typename DimensionTraits<dimensions>::MatrixType& transformation) override;
void applyTransformationMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) override;
/** @brief Transformation */
inline typename DimensionTraits<dimensions>::MatrixType transformation() const {

8
src/Physics/Capsule.cpp

@ -27,10 +27,10 @@ using namespace Magnum::Math::Geometry;
namespace Magnum { namespace Physics {
template<std::uint8_t dimensions> void Capsule<dimensions>::applyTransformation(const typename DimensionTraits<dimensions>::MatrixType& transformation) {
_transformedA = (transformation*typename DimensionTraits<dimensions>::PointType(_a)).vector();
_transformedB = (transformation*typename DimensionTraits<dimensions>::PointType(_b)).vector();
float scaling = (transformation.rotationScaling()*typename DimensionTraits<dimensions>::VectorType(1/Constants::sqrt3())).length();
template<std::uint8_t dimensions> void Capsule<dimensions>::applyTransformationMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) {
_transformedA = (matrix*typename DimensionTraits<dimensions>::PointType(_a)).vector();
_transformedB = (matrix*typename DimensionTraits<dimensions>::PointType(_b)).vector();
float scaling = (matrix.rotationScaling()*typename DimensionTraits<dimensions>::VectorType(1/Constants::sqrt3())).length();
_transformedRadius = scaling*_radius;
}

4
src/Physics/Capsule.h

@ -34,7 +34,7 @@ Unlike other elements the capsule doesn't support asymmetric scaling. When
applying transformation, the scale factor is averaged from all axes.
@see Capsule2D, Capsule3D
*/
template<std::uint8_t dimensions> class PHYSICS_EXPORT Capsule: public AbstractShape<dimensions> {
template<std::uint8_t dimensions> class MAGNUM_PHYSICS_EXPORT Capsule: public AbstractShape<dimensions> {
public:
/** @brief Constructor */
inline Capsule(const typename DimensionTraits<dimensions>::VectorType& a, const typename DimensionTraits<dimensions>::VectorType& b, float radius): _a(a), _transformedA(a), _b(b), _transformedB(b), _radius(radius), _transformedRadius(radius) {}
@ -43,7 +43,7 @@ template<std::uint8_t dimensions> class PHYSICS_EXPORT Capsule: public AbstractS
return AbstractShape<dimensions>::Type::Capsule;
}
void applyTransformation(const typename DimensionTraits<dimensions>::MatrixType& transformation) override;
void applyTransformationMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) override;
bool collides(const AbstractShape<dimensions>* other) const override;

4
src/Physics/DebugDrawResourceManager.cpp

@ -43,8 +43,8 @@ template<std::uint8_t dimensions> SceneGraph::Drawable<dimensions>* DebugDrawRes
return renderer;
}
template SceneGraph::Drawable<2> PHYSICS_EXPORT * DebugDrawResourceManager::createDebugRenderer(ObjectShape<2>* shape, ResourceKey options);
template SceneGraph::Drawable<3> PHYSICS_EXPORT * DebugDrawResourceManager::createDebugRenderer(ObjectShape<3>* shape, ResourceKey options);
template SceneGraph::Drawable<2> MAGNUM_PHYSICS_EXPORT * DebugDrawResourceManager::createDebugRenderer(ObjectShape<2>* shape, ResourceKey options);
template SceneGraph::Drawable<3> MAGNUM_PHYSICS_EXPORT * DebugDrawResourceManager::createDebugRenderer(ObjectShape<3>* shape, ResourceKey options);
void DebugDrawResourceManager::createDebugMesh(Implementation::DebugRenderer<2>* renderer, AbstractShape2D* shape) {
switch(shape->type()) {

4
src/Physics/DebugDrawResourceManager.h

@ -43,7 +43,7 @@ namespace Physics { namespace Implementation {
}}
#endif
extern template ResourceManager<AbstractShaderProgram, Buffer, Mesh, Physics::Implementation::Options> PHYSICS_EXPORT *& ResourceManager<AbstractShaderProgram, Buffer, Mesh, Physics::Implementation::Options>::internalInstance();
extern template ResourceManager<AbstractShaderProgram, Buffer, Mesh, Physics::Implementation::Options> MAGNUM_PHYSICS_EXPORT *& ResourceManager<AbstractShaderProgram, Buffer, Mesh, Physics::Implementation::Options>::internalInstance();
namespace Physics {
@ -81,7 +81,7 @@ ObjectShape2D* shape;
group.add(DebugDrawResourceManager::createDebugRenderer(shape, "red"));
@endcode
*/
class PHYSICS_EXPORT DebugDrawResourceManager: public ResourceManager<AbstractShaderProgram, Buffer, Mesh, Physics::Implementation::Options> {
class MAGNUM_PHYSICS_EXPORT DebugDrawResourceManager: public ResourceManager<AbstractShaderProgram, Buffer, Mesh, Physics::Implementation::Options> {
public:
#ifdef DOXYGEN_GENERATING_OUTPUT
/** @brief %Options */

2
src/Physics/Implementation/AxisAlignedBoxRenderer.cpp

@ -26,7 +26,7 @@ template<std::uint8_t dimensions> void AxisAlignedBoxRenderer<dimensions>::draw(
typename DimensionTraits<dimensions>::MatrixType transformation =
DimensionTraits<dimensions>::MatrixType::translation(axisAlignedBox.transformedPosition())*
DimensionTraits<dimensions>::MatrixType::scaling(axisAlignedBox.transformedSize());
this->shader->setTransformationProjection(camera->projectionMatrix()*camera->cameraMatrix()*transformation)
this->shader->setTransformationProjectionMatrix(camera->projectionMatrix()*camera->cameraMatrix()*transformation)
->setColor(options->color)
->use();
this->mesh->draw();

2
src/Physics/Implementation/BoxRenderer.cpp

@ -23,7 +23,7 @@
namespace Magnum { namespace Physics { namespace Implementation {
template<std::uint8_t dimensions> void BoxRenderer<dimensions>::draw(Resource<Options>& options, const typename DimensionTraits<dimensions>::MatrixType&, typename SceneGraph::AbstractCamera<dimensions>* camera) {
this->shader->setTransformationProjection(camera->projectionMatrix()*camera->cameraMatrix()*box.transformedTransformation())
this->shader->setTransformationProjectionMatrix(camera->projectionMatrix()*camera->cameraMatrix()*box.transformedTransformation())
->setColor(options->color)
->use();
this->mesh->draw();

6
src/Physics/Line.cpp

@ -20,9 +20,9 @@
namespace Magnum { namespace Physics {
template<std::uint8_t dimensions> void Line<dimensions>::applyTransformation(const typename DimensionTraits<dimensions>::MatrixType& transformation) {
_transformedA = (transformation*typename DimensionTraits<dimensions>::PointType(_a)).vector();
_transformedB = (transformation*typename DimensionTraits<dimensions>::PointType(_b)).vector();
template<std::uint8_t dimensions> void Line<dimensions>::applyTransformationMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) {
_transformedA = (matrix*typename DimensionTraits<dimensions>::PointType(_a)).vector();
_transformedB = (matrix*typename DimensionTraits<dimensions>::PointType(_b)).vector();
}
/* Explicitly instantiate the templates */

4
src/Physics/Line.h

@ -32,7 +32,7 @@ namespace Magnum { namespace Physics {
@see Line2D, Line3D
@todo collision detection of two Line2D
*/
template<std::uint8_t dimensions> class PHYSICS_EXPORT Line: public AbstractShape<dimensions> {
template<std::uint8_t dimensions> class MAGNUM_PHYSICS_EXPORT Line: public AbstractShape<dimensions> {
public:
/** @brief Constructor */
inline Line(const typename DimensionTraits<dimensions>::VectorType& a, const typename DimensionTraits<dimensions>::VectorType& b): _a(a), _transformedA(a), _b(b), _transformedB(b) {}
@ -41,7 +41,7 @@ template<std::uint8_t dimensions> class PHYSICS_EXPORT Line: public AbstractShap
return AbstractShape<dimensions>::Type::Line;
}
void applyTransformation(const typename DimensionTraits<dimensions>::MatrixType& transformation) override;
void applyTransformationMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) override;
/** @brief First point */
inline typename DimensionTraits<dimensions>::VectorType a() const {

4
src/Physics/ObjectShape.cpp

@ -36,8 +36,8 @@ template<uint8_t dimensions> void ObjectShape<dimensions>::markDirty() {
group()->setDirty();
}
template<uint8_t dimensions> void ObjectShape<dimensions>::clean(const typename DimensionTraits<dimensions>::MatrixType& absoluteTransformation) {
if(_shape) _shape->applyTransformation(absoluteTransformation);
template<uint8_t dimensions> void ObjectShape<dimensions>::clean(const typename DimensionTraits<dimensions>::MatrixType& absoluteTransformationMatrix) {
if(_shape) _shape->applyTransformationMatrix(absoluteTransformationMatrix);
}
template class ObjectShape<2>;

4
src/Physics/ObjectShape.h

@ -32,7 +32,7 @@ namespace Magnum { namespace Physics {
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>> {
template<std::uint8_t dimensions> class MAGNUM_PHYSICS_EXPORT ObjectShape: public SceneGraph::AbstractGroupedFeature<dimensions, ObjectShape<dimensions>> {
public:
/**
* @brief Constructor
@ -78,7 +78,7 @@ template<std::uint8_t dimensions> class PHYSICS_EXPORT ObjectShape: public Scene
void markDirty() override;
/** Applies transformation to associated shape. */
void clean(const typename DimensionTraits<dimensions>::MatrixType& absoluteTransformation) override;
void clean(const typename DimensionTraits<dimensions>::MatrixType& absoluteTransformationMatrix) override;
private:
AbstractShape<dimensions>* _shape;

2
src/Physics/ObjectShapeGroup.h

@ -34,7 +34,7 @@ namespace Magnum { namespace Physics {
@see ObjectShapeGroup2D, ObjectShapeGroup3D
*/
template<std::uint8_t dimensions> class PHYSICS_EXPORT ObjectShapeGroup: public SceneGraph::FeatureGroup<dimensions, ObjectShape<dimensions>> {
template<std::uint8_t dimensions> class MAGNUM_PHYSICS_EXPORT ObjectShapeGroup: public SceneGraph::FeatureGroup<dimensions, ObjectShape<dimensions>> {
friend class ObjectShape<dimensions>;
public:

6
src/Physics/Plane.cpp

@ -27,9 +27,9 @@ using namespace Magnum::Math::Geometry;
namespace Magnum { namespace Physics {
void Plane::applyTransformation(const Matrix4& transformation) {
_transformedPosition = (transformation*Magnum::Point3D(_position)).xyz();
_transformedNormal = transformation.rotation()*_normal;
void Plane::applyTransformationMatrix(const Matrix4& matrix) {
_transformedPosition = (matrix*Magnum::Point3D(_position)).xyz();
_transformedNormal = matrix.rotation()*_normal;
}
bool Plane::collides(const AbstractShape<3>* other) const {

6
src/Physics/Plane.h

@ -28,7 +28,7 @@
namespace Magnum { namespace Physics {
/** @brief Infinite plane, defined by position and normal (3D only) */
class PHYSICS_EXPORT Plane: public AbstractShape<3> {
class MAGNUM_PHYSICS_EXPORT Plane: public AbstractShape<3> {
public:
/** @brief Constructor */
inline Plane(const Vector3& position, const Vector3& normal): _position(position), _transformedPosition(position), _normal(normal), _transformedNormal(normal) {}
@ -36,10 +36,10 @@ class PHYSICS_EXPORT Plane: public AbstractShape<3> {
inline Type type() const override { return Type::Plane; }
#ifndef DOXYGEN_GENERATING_OUTPUT
void applyTransformation(const Matrix4& transformation) override;
void applyTransformationMatrix(const Matrix4& matrix) override;
bool collides(const AbstractShape<3>* other) const override;
#else
void applyTransformation(const typename DimensionTraits<dimensions>::MatrixType& transformation) override;
void applyTransformationMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) override;
bool collides(const AbstractShape* other) const override;
#endif

4
src/Physics/Point.cpp

@ -20,8 +20,8 @@
namespace Magnum { namespace Physics {
template<std::uint8_t dimensions> void Point<dimensions>::applyTransformation(const typename DimensionTraits<dimensions>::MatrixType& transformation) {
_transformedPosition = (transformation*typename DimensionTraits<dimensions>::PointType(_position)).vector();
template<std::uint8_t dimensions> void Point<dimensions>::applyTransformationMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) {
_transformedPosition = (matrix*typename DimensionTraits<dimensions>::PointType(_position)).vector();
}
template class Point<2>;

4
src/Physics/Point.h

@ -31,7 +31,7 @@ namespace Magnum { namespace Physics {
@see Point2D, Point3D
*/
template<std::uint8_t dimensions> class PHYSICS_EXPORT Point: public AbstractShape<dimensions> {
template<std::uint8_t dimensions> class MAGNUM_PHYSICS_EXPORT Point: public AbstractShape<dimensions> {
public:
/** @brief Constructor */
inline Point(const typename DimensionTraits<dimensions>::VectorType& position): _position(position), _transformedPosition(position) {}
@ -40,7 +40,7 @@ template<std::uint8_t dimensions> class PHYSICS_EXPORT Point: public AbstractSha
return AbstractShape<dimensions>::Type::Point;
}
void applyTransformation(const typename DimensionTraits<dimensions>::MatrixType& transformation) override;
void applyTransformationMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) override;
/** @brief Position */
inline typename DimensionTraits<dimensions>::VectorType position() const {

6
src/Physics/ShapeGroup.cpp

@ -43,9 +43,9 @@ template<std::uint8_t dimensions> ShapeGroup<dimensions>& ShapeGroup<dimensions>
return *this;
}
template<std::uint8_t dimensions> void ShapeGroup<dimensions>::applyTransformation(const typename DimensionTraits<dimensions>::MatrixType& transformation) {
if(a) a->applyTransformation(transformation);
if(b) b->applyTransformation(transformation);
template<std::uint8_t dimensions> void ShapeGroup<dimensions>::applyTransformationMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) {
if(a) a->applyTransformationMatrix(matrix);
if(b) b->applyTransformationMatrix(matrix);
}
template<std::uint8_t dimensions> bool ShapeGroup<dimensions>::collides(const AbstractShape<dimensions>* other) const {

4
src/Physics/ShapeGroup.h

@ -57,7 +57,7 @@ Result of logical operations on shapes.
See @ref collision-detection for brief introduction.
@see ShapeGroup2D, ShapeGroup3D
*/
template<std::uint8_t dimensions> class PHYSICS_EXPORT ShapeGroup: public AbstractShape<dimensions> {
template<std::uint8_t dimensions> class MAGNUM_PHYSICS_EXPORT ShapeGroup: public AbstractShape<dimensions> {
#ifndef DOXYGEN_GENERATING_OUTPUT
// template<class T> friend constexpr operator~(const T& a) -> enableIfIsBaseType;
// template<class T> friend constexpr operator~(T&& a) -> enableIfIsBaseType;
@ -105,7 +105,7 @@ template<std::uint8_t dimensions> class PHYSICS_EXPORT ShapeGroup: public Abstra
return AbstractShape<dimensions>::Type::ShapeGroup;
}
void applyTransformation(const typename DimensionTraits<dimensions>::MatrixType& transformation) override;
void applyTransformationMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) override;
bool collides(const AbstractShape<dimensions>* other) const override;

6
src/Physics/Sphere.cpp

@ -39,9 +39,9 @@ namespace {
}
}
template<std::uint8_t dimensions> void Sphere<dimensions>::applyTransformation(const typename DimensionTraits<dimensions>::MatrixType& transformation) {
_transformedPosition = (transformation*typename DimensionTraits<dimensions>::PointType(_position)).vector();
float scaling = (transformation.rotationScaling()*unitVector<dimensions>()).length();
template<std::uint8_t dimensions> void Sphere<dimensions>::applyTransformationMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) {
_transformedPosition = (matrix*typename DimensionTraits<dimensions>::PointType(_position)).vector();
float scaling = (matrix.rotationScaling()*unitVector<dimensions>()).length();
_transformedRadius = scaling*_radius;
}

4
src/Physics/Sphere.h

@ -34,7 +34,7 @@ Unlike other elements the sphere doesn't support asymmetric scaling. When
applying transformation, the scale factor is averaged from all axes.
@see Sphere2D, Sphere3D
*/
template<std::uint8_t dimensions> class PHYSICS_EXPORT Sphere: public AbstractShape<dimensions> {
template<std::uint8_t dimensions> class MAGNUM_PHYSICS_EXPORT Sphere: public AbstractShape<dimensions> {
public:
/** @brief Constructor */
inline Sphere(const typename DimensionTraits<dimensions>::VectorType& position, float radius): _position(position), _transformedPosition(position), _radius(radius), _transformedRadius(radius) {}
@ -43,7 +43,7 @@ template<std::uint8_t dimensions> class PHYSICS_EXPORT Sphere: public AbstractSh
return AbstractShape<dimensions>::Type::Sphere;
}
void applyTransformation(const typename DimensionTraits<dimensions>::MatrixType& transformation) override;
void applyTransformationMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) override;
bool collides(const AbstractShape<dimensions>* other) const override;

4
src/Physics/Test/AxisAlignedBoxTest.cpp

@ -30,11 +30,11 @@ AxisAlignedBoxTest::AxisAlignedBoxTest() {
void AxisAlignedBoxTest::applyTransformation() {
Physics::AxisAlignedBox3D box({-1.0f, -2.0f, -3.0f}, {1.0f, 2.0f, 3.0f});
box.applyTransformation(Matrix4::scaling({2.0f, -1.0f, 1.5f}));
box.applyTransformationMatrix(Matrix4::scaling({2.0f, -1.0f, 1.5f}));
CORRADE_COMPARE(box.transformedPosition(), Vector3(-2.0f, 2.0f, -4.5f));
CORRADE_COMPARE(box.transformedSize(), Vector3(2.0f, -2.0f, 4.5f));
box.applyTransformation(Matrix4::translation(Vector3(1.0f))*Matrix4::rotation(deg(90.0f), Vector3::xAxis()));
box.applyTransformationMatrix(Matrix4::translation(Vector3(1.0f))*Matrix4::rotation(deg(90.0f), Vector3::xAxis()));
CORRADE_COMPARE(box.transformedPosition(), Vector3(0.0f, 4.0f, -1.0f));
CORRADE_COMPARE(box.transformedSize(), Vector3(1.0f, -3.0f, 2.0f));
}

2
src/Physics/Test/BoxTest.cpp

@ -29,7 +29,7 @@ BoxTest::BoxTest() {
void BoxTest::applyTransformation() {
Physics::Box3D box(Matrix4::translation({1.0f, 2.0f, -3.0f}));
box.applyTransformation(Matrix4::scaling({2.0f, -1.0f, 1.5f}));
box.applyTransformationMatrix(Matrix4::scaling({2.0f, -1.0f, 1.5f}));
CORRADE_COMPARE(box.transformedTransformation(), Matrix4::scaling({2.0f, -1.0f, 1.5f})*Matrix4::translation({1.0f, 2.0f, -3.0f}));
}

4
src/Physics/Test/CapsuleTest.cpp

@ -32,13 +32,13 @@ CapsuleTest::CapsuleTest() {
void CapsuleTest::applyTransformation() {
Physics::Capsule3D capsule({1.0f, 2.0f, 3.0f}, {-1.0f, -2.0f, -3.0f}, 7.0f);
capsule.applyTransformation(Matrix4::rotation(deg(90.0f), Vector3::zAxis()));
capsule.applyTransformationMatrix(Matrix4::rotation(deg(90.0f), Vector3::zAxis()));
CORRADE_COMPARE(capsule.transformedA(), Vector3(-2.0f, 1.0f, 3.0f));
CORRADE_COMPARE(capsule.transformedB(), Vector3(2.0f, -1.0f, -3.0f));
CORRADE_COMPARE(capsule.radius(), 7.0f);
/* Apply average scaling to radius */
capsule.applyTransformation(Matrix4::scaling({Constants::sqrt3(), -Constants::sqrt2(), 2.0f}));
capsule.applyTransformationMatrix(Matrix4::scaling({Constants::sqrt3(), -Constants::sqrt2(), 2.0f}));
CORRADE_COMPARE(capsule.transformedRadius(), Constants::sqrt3()*7.0f);
}

2
src/Physics/Test/LineTest.cpp

@ -29,7 +29,7 @@ LineTest::LineTest() {
void LineTest::applyTransformation() {
Physics::Line3D line({1.0f, 2.0f, 3.0f}, {-1.0f, -2.0f, -3.0f});
line.applyTransformation(Matrix4::rotation(deg(90.0f), Vector3::zAxis()));
line.applyTransformationMatrix(Matrix4::rotation(deg(90.0f), Vector3::zAxis()));
CORRADE_COMPARE(line.transformedA(), Vector3(-2.0f, 1.0f, 3.0f));
CORRADE_COMPARE(line.transformedB(), Vector3(2.0f, -1.0f, -3.0f));
}

4
src/Physics/Test/PlaneTest.cpp

@ -33,12 +33,12 @@ PlaneTest::PlaneTest() {
void PlaneTest::applyTransformation() {
Physics::Plane plane({1.0f, 2.0f, 3.0f}, {Constants::sqrt2(), -Constants::sqrt2(), 0});
plane.applyTransformation(Matrix4::rotation(deg(90.0f), Vector3::xAxis()));
plane.applyTransformationMatrix(Matrix4::rotation(deg(90.0f), Vector3::xAxis()));
CORRADE_COMPARE(plane.transformedPosition(), Vector3(1.0f, -3.0f, 2.0f));
CORRADE_COMPARE(plane.transformedNormal(), Vector3(Constants::sqrt2(), 0, -Constants::sqrt2()));
/* The normal should stay normalized */
plane.applyTransformation(Matrix4::scaling({1.5f, 2.0f, 3.0f}));
plane.applyTransformationMatrix(Matrix4::scaling({1.5f, 2.0f, 3.0f}));
CORRADE_COMPARE(plane.transformedPosition(), Vector3(1.5f, 4.0f, 9.0f));
CORRADE_COMPARE(plane.transformedNormal(), Vector3(Constants::sqrt2(), -Constants::sqrt2(), 0));
}

2
src/Physics/Test/PointTest.cpp

@ -28,7 +28,7 @@ PointTest::PointTest() {
void PointTest::applyTransformation() {
Physics::Point3D point({1.0f, 2.0f, 3.0f});
point.applyTransformation(Matrix4::translation({5.0f, 6.0f, 7.0f}));
point.applyTransformationMatrix(Matrix4::translation({5.0f, 6.0f, 7.0f}));
CORRADE_COMPARE(point.transformedPosition(), Vector3(6.0f, 8.0f, 10.0f));
}

4
src/Physics/Test/ShapeGroupTest.cpp

@ -43,7 +43,7 @@ void ShapeGroupTest::copy() {
}
/* Just to test that it doesn't crash */
group.applyTransformation(Matrix4::translation(Vector3::xAxis(1.0f)));
group.applyTransformationMatrix(Matrix4::translation(Vector3::xAxis(1.0f)));
CORRADE_VERIFY(true);
}
@ -54,7 +54,7 @@ void ShapeGroupTest::reference() {
ShapeGroup3D group = !(ref(point) || ref(segment));
group.applyTransformation(Matrix4::translation(Vector3(1.0f)));
group.applyTransformationMatrix(Matrix4::translation(Vector3(1.0f)));
CORRADE_VERIFY((point.transformedPosition() == Vector3(2.0f, 3.0f, 4.0f)));
CORRADE_VERIFY((segment.transformedA() == Vector3(3.0f, 2.0f, 31.0f)));

2
src/Physics/Test/ShapeTestBase.h

@ -25,7 +25,7 @@ namespace Magnum { namespace Physics { namespace Test {
class ShapeTestBase {
protected:
template<class T> void randomTransformation(T& shape) {
shape.applyTransformation(Matrix4::translation(Vector3(7.0f, 8.0f, -9.0f)));
shape.applyTransformationMatrix(Matrix4::translation(Vector3(7.0f, 8.0f, -9.0f)));
}
};

6
src/Physics/Test/SphereTest.cpp

@ -35,17 +35,17 @@ SphereTest::SphereTest() {
void SphereTest::applyTransformation() {
Physics::Sphere3D sphere({1.0f, 2.0f, 3.0f}, 7.0f);
sphere.applyTransformation(Matrix4::rotation(deg(90.0f), Vector3::yAxis()));
sphere.applyTransformationMatrix(Matrix4::rotation(deg(90.0f), Vector3::yAxis()));
CORRADE_COMPARE(sphere.transformedPosition(), Vector3(3.0f, 2.0f, -1.0f));
CORRADE_COMPARE(sphere.transformedRadius(), 7.0f);
/* Symmetric scaling */
sphere.applyTransformation(Matrix4::scaling(Vector3(2.0f)));
sphere.applyTransformationMatrix(Matrix4::scaling(Vector3(2.0f)));
CORRADE_COMPARE(sphere.transformedPosition(), Vector3(2.0f, 4.0f, 6.0f));
CORRADE_COMPARE(sphere.transformedRadius(), 14.0f);
/* Apply average scaling to radius */
sphere.applyTransformation(Matrix4::scaling({Constants::sqrt3(), -Constants::sqrt2(), 2.0f}));
sphere.applyTransformationMatrix(Matrix4::scaling({Constants::sqrt3(), -Constants::sqrt2(), 2.0f}));
CORRADE_COMPARE(sphere.transformedRadius(), Constants::sqrt3()*7.0f);
}

6
src/Physics/magnumPhysicsVisibility.h

@ -17,12 +17,12 @@
#ifdef _WIN32
#ifdef MagnumPhysics_EXPORTS
#define PHYSICS_EXPORT __declspec(dllexport)
#define MAGNUM_PHYSICS_EXPORT __declspec(dllexport)
#else
#define PHYSICS_EXPORT __declspec(dllimport)
#define MAGNUM_PHYSICS_EXPORT __declspec(dllimport)
#endif
#else
#define PHYSICS_EXPORT __attribute__ ((visibility ("default")))
#define MAGNUM_PHYSICS_EXPORT __attribute__ ((visibility ("default")))
#endif
#endif

2
src/Platform/AbstractXApplication.cpp

@ -15,6 +15,8 @@
#include "AbstractXApplication.h"
#include <Utility/utilities.h>
#include "Context.h"
#include "ExtensionWrangler.h"

2
src/Platform/Sdl2Application.cpp

@ -15,6 +15,8 @@
#include "Sdl2Application.h"
#include <Utility/utilities.h>
#include "Context.h"
#include "ExtensionWrangler.h"

39
src/Resource.cpp

@ -0,0 +1,39 @@
/*
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 "Resource.h"
namespace Magnum {
#ifndef DOXYGEN_GENERATING_OUTPUT
Debug MAGNUM_EXPORT operator<<(Debug debug, ResourceState value) {
switch(value) {
#define _c(value) case ResourceState::value: return debug << "ResourceState::" #value;
_c(NotLoaded)
_c(NotLoadedFallback)
_c(Loading)
_c(LoadingFallback)
_c(NotFound)
_c(NotFoundFallback)
_c(Mutable)
_c(Final)
#undef _c
}
return debug << "ResourceState::(invalid)";
}
#endif
}

266
src/Resource.h

@ -0,0 +1,266 @@
#ifndef Magnum_Resource_h
#define Magnum_Resource_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 /Resource.h
* @brief Class Magnum::ResourceKey, Magnum::Resource, enum Magnum::ResourceState
*/
#include <Utility/MurmurHash2.h>
#include "Magnum.h"
#include "magnumVisibility.h"
namespace Magnum {
/** @relates Resource
* @brief %Resource state
*
* @see Resource::state(), ResourceManager::state()
*/
enum class ResourceState: std::uint8_t {
/** The resource is not yet loaded (and no fallback is available). */
NotLoaded,
/** The resource is not yet loaded and fallback resource is used instead. */
NotLoadedFallback,
/** The resource is currently loading (and no fallback is available). */
Loading,
/** The resource is currently loading and fallback resource is used instead. */
LoadingFallback,
/** The resource was not found (and no fallback is available). */
NotFound,
/** The resource was not found and fallback resource is used instead. */
NotFoundFallback,
/** The resource is loaded, but can be changed by the manager at any time. */
Mutable,
/** The resource is loaded and won't be changed by the manager anymore. */
Final
};
/** @debugoperator{Magnum::Resource} */
Debug MAGNUM_EXPORT operator<<(Debug debug, ResourceState value);
/**
@brief Key for accessing resource
@see ResourceManager::referenceCount(), ResourceManager::state(),
ResourceManager::get(), ResourceManager::set(), Resource::key()
*/
class ResourceKey: public Corrade::Utility::MurmurHash2::Digest {
public:
/**
* @brief Default constructor
*
* Creates zero key. Note that it is not the same as calling other
* constructors with empty string.
*/
inline constexpr ResourceKey() {}
/** @brief Constructor */
inline ResourceKey(const std::string& key): Corrade::Utility::MurmurHash2::Digest(Corrade::Utility::MurmurHash2()(key)) {}
/**
* @brief Constructor
* @todo constexpr
*/
template<std::size_t size> inline constexpr ResourceKey(const char(&key)[size]): Corrade::Utility::MurmurHash2::Digest(Corrade::Utility::MurmurHash2()(key)) {}
};
/** @debugoperator{Magnum::ResourceKey} */
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);
}
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<class> class ResourceManagerData;
}
#endif
/**
@brief %Resource reference
See ResourceManager for more information.
*/
#ifndef DOXYGEN_GENERATING_OUTPUT
template<class T, class U>
#else
template<class T, class U = T>
#endif
class Resource {
friend class Implementation::ResourceManagerData<T>;
public:
/**
* @brief Default constructor
*
* Creates empty resource. Resources are acquired from the manager by
* calling ResourceManager::get().
*/
inline Resource(): manager(nullptr), lastCheck(0), _state(ResourceState::Final), data(nullptr) {}
/** @brief Copy constructor */
inline Resource(const Resource<T, U>& other): manager(other.manager), _key(other._key), lastCheck(other.lastCheck), _state(other._state), data(other.data) {
if(manager) manager->incrementReferenceCount(_key);
}
/** @brief Move constructor */
inline Resource(Resource<T, U>&& other): manager(other.manager), _key(other._key), lastCheck(other.lastCheck), _state(other._state), data(other.data) {
other.manager = nullptr;
}
/** @brief Destructor */
inline ~Resource() {
if(manager) manager->decrementReferenceCount(_key);
}
/** @brief Assignment operator */
Resource<T, U>& operator=(const Resource<T, U>& other) {
if(manager) manager->decrementReferenceCount(_key);
manager = other.manager;
_key = other._key;
lastCheck = other.lastCheck;
_state = other._state;
data = other.data;
if(manager) manager->incrementReferenceCount(_key);
return *this;
}
/** @brief Assignment move operator */
Resource<T, U>& operator=(Resource<T, U>&& other) {
if(manager) manager->decrementReferenceCount(_key);
manager = other.manager;
_key = other._key;
lastCheck = other.lastCheck;
_state = other._state;
data = other.data;
other.manager = nullptr;
return *this;
}
/** @brief Resource key */
inline ResourceKey key() const { return _key; }
/**
* @brief %Resource state
*
* @see operator bool(), ResourceManager::state()
*/
inline ResourceState state() {
acquire();
return _state;
}
/**
* @brief Whether the resource is available
*
* Returns `false` when resource is not loaded and no fallback is
* available (i.e. state() is either @ref ResourceState "ResourceState::NotLoaded",
* @ref ResourceState "ResourceState::Loading" or
* @ref ResourceState "ResourceState::NotFound"), true otherwise.
*/
inline operator bool() {
acquire();
return data;
}
/**
* @brief %Resource data
*
* The resource must be loaded before accessing it. Use boolean
* conversion operator or state() for testing whether it is loaded.
*/
inline operator U*() {
acquire();
CORRADE_ASSERT(data, "Resource: accessing not loaded data with key" << key(), nullptr);
return static_cast<U*>(data);
}
/** @overload */
inline U* operator->() {
acquire();
CORRADE_ASSERT(data, "Resource: accessing not loaded data with key" << key(), nullptr);
return static_cast<U*>(data);
}
/** @overload */
inline U& operator*() {
acquire();
CORRADE_ASSERT(data, "Resource: accessing not loaded data with key" << key(), *static_cast<U*>(data));
return *static_cast<U*>(data);
}
private:
inline Resource(Implementation::ResourceManagerData<T>* manager, ResourceKey key): manager(manager), _key(key), lastCheck(0), _state(ResourceState::NotLoaded), data(nullptr) {
manager->incrementReferenceCount(key);
}
void acquire() {
/* The data are already final, nothing to do */
if(_state == ResourceState::Final) return;
/* Nothing changed since last check */
if(manager->lastChange() < lastCheck) return;
/* Acquire new data and save last check time */
const typename Implementation::ResourceManagerData<T>::Data& d = manager->data(_key);
lastCheck = manager->lastChange();
/* Try to get the data */
data = d.data;
_state = static_cast<ResourceState>(d.state);
/* Data are not available */
if(!data) {
/* Fallback found, add *Fallback to state */
if((data = manager->fallback())) {
if(_state == ResourceState::Loading)
_state = ResourceState::LoadingFallback;
else if(_state == ResourceState::NotFound)
_state = ResourceState::NotFoundFallback;
else _state = ResourceState::NotLoadedFallback;
/* Fallback not found and loading didn't start yet */
} else if(_state != ResourceState::Loading && _state != ResourceState::NotFound)
_state = ResourceState::NotLoaded;
}
}
Implementation::ResourceManagerData<T>* manager;
ResourceKey _key;
std::size_t lastCheck;
ResourceState _state;
T* data;
};
}
/* Make the definition complete */
#include "ResourceManager.h"
#endif

383
src/ResourceManager.h

@ -16,53 +16,47 @@
*/
/** @file
* @brief Class Magnum::ResourceManager, Magnum::ResourceKey, Magnum::Resource, enum Magnum::ResourceState, Magnum::ResourceDataState, Magnum::ResourcePolicy
* @brief Class Magnum::ResourceManager, enum Magnum::ResourceDataState, Magnum::ResourcePolicy
*/
#include <unordered_map>
#include <Utility/MurmurHash2.h>
namespace Magnum {
/** @relates ResourceManager
* @brief %Resource state
*
* @see Resource::state(), ResourceManager::state()
*/
enum class ResourceState: std::uint8_t {
/** The resource is not yet loaded. */
NotLoaded,
/** The resource is not yet loaded and fallback resource is used instead. */
Fallback,
#include "Resource.h"
/** The resource is loaded, but can be changed by the manager at any time. */
Mutable,
/** The resource is loaded and won't be changed by the manager anymore. */
Final
};
namespace Magnum {
/** @relates ResourceManager
* @brief %Resource data state
*
* @see ResourceManager::set()
* @see ResourceManager::set(), ResourceState
*/
enum class ResourceDataState: std::uint8_t {
/**
* The resource is currently loading. Parameter @p data in ResourceManager::set()
* should be set to `null`.
*/
Loading = int(ResourceState::Loading),
/**
* The resource was not found. Parameter @p data in ResourceManager::set()
* should be set to `null`.
*/
NotFound = int(ResourceState::NotFound),
/**
* The resource can be changed by the manager in the future. This is
* slower, as Resource needs to ask the manager for new version every time
* the data are accessed, but allows changing the data for e.g. debugging
* purposes.
*/
Mutable = int(ResourceState::Mutable),
Mutable = std::uint8_t(ResourceState::Mutable),
/**
* The resource cannot be changed by the manager in the future. This is
* faster, as Resource instances will ask for the data only one time, thus
* suitable for production code.
*/
Final = int(ResourceState::Final)
Final = std::uint8_t(ResourceState::Final)
};
/** @relates ResourceManager
@ -84,33 +78,7 @@ enum class ResourcePolicy: std::uint8_t {
ReferenceCounted
};
/**
@brief Key for accessing resource
@see ResourceManager::referenceCount(), ResourceManager::state(),
ResourceManager::get(), ResourceManager::set(), Resource::key()
*/
class ResourceKey: public Corrade::Utility::MurmurHash2::Digest {
public:
/**
* @brief Default constructor
*
* Creates zero key. Note that it is not the same as calling other
* constructors with empty string.
*/
inline constexpr ResourceKey() {}
/** @brief Constructor */
inline ResourceKey(const std::string& key): Corrade::Utility::MurmurHash2::Digest(Corrade::Utility::MurmurHash2()(key)) {}
/**
* @brief Constructor
* @todo constexpr
*/
template<std::size_t size> inline constexpr ResourceKey(const char(&key)[size]): Corrade::Utility::MurmurHash2::Digest(Corrade::Utility::MurmurHash2()(key)) {}
};
template<class T, class U> class Resource;
template<class> class AbstractResourceLoader;
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
@ -122,46 +90,22 @@ namespace Implementation {
};
template<class T> class ResourceManagerData {
template<class, class> friend class Resource;
friend class AbstractResourceLoader<T>;
ResourceManagerData(const ResourceManagerData<T>&) = delete;
ResourceManagerData(ResourceManagerData<T>&&) = delete;
ResourceManagerData<T>& operator=(const ResourceManagerData<T>&) = delete;
ResourceManagerData<T>& operator=(ResourceManagerData<T>&&) = delete;
public:
struct Data {
Data& operator=(const Data&) = delete;
Data& operator=(Data&&) = delete;
inline Data(): data(nullptr), state(ResourceDataState::Mutable), policy(ResourcePolicy::Manual), referenceCount(0) {}
/* Fugly hack for GCC 4.5, because std::pair doesn't have move constructor yet */
#ifndef CORRADE_GCC45_COMPATIBILITY
Data(const Data&) = delete;
#else
Data(const Data& other): data(other.data), state(other.state), policy(other.policy), referenceCount(other.referenceCount) {
const_cast<Data&>(other).data = nullptr;
const_cast<Data&>(other).referenceCount = 0;
}
#endif
inline Data(Data&& other): data(other.data), state(other.state), policy(other.policy), referenceCount(other.referenceCount) {
other.data = nullptr;
other.referenceCount = 0;
}
inline ~Data() {
CORRADE_ASSERT(referenceCount == 0, "ResourceManager: cannot destruct it while data are still referenced", );
delete data;
}
T* data;
ResourceDataState state;
ResourcePolicy policy;
std::size_t referenceCount;
};
inline virtual ~ResourceManagerData() {
delete _fallback;
if(_loader) {
_loader->manager = nullptr;
delete _loader;
}
}
inline std::size_t lastChange() const { return _lastChange; }
@ -176,21 +120,45 @@ namespace Implementation {
ResourceState state(ResourceKey key) const {
auto it = _data.find(key);
if(it == _data.end() || !it->second.data)
return _fallback ? ResourceState::Fallback : ResourceState::NotLoaded;
else
return static_cast<ResourceState>(it->second.state);
/* Resource not loaded */
if(it == _data.end() || !it->second.data) {
/* Fallback found, add *Fallback to state */
if(_fallback) {
if(it != _data.end() && it->second.state == ResourceDataState::Loading)
return ResourceState::LoadingFallback;
else if(it != _data.end() && it->second.state == ResourceDataState::NotFound)
return ResourceState::NotFoundFallback;
else return ResourceState::NotLoadedFallback;
}
/* Fallback not found, loading didn't start yet */
if(it == _data.end() || (it->second.state != ResourceDataState::Loading && it->second.state != ResourceDataState::NotFound))
return ResourceState::NotLoaded;
}
/* Loading / NotFound without fallback, Mutable / Final */
return static_cast<ResourceState>(it->second.state);
}
template<class U> inline Resource<T, U> get(ResourceKey key) {
/* Ask loader for the data, if they aren't there yet */
if(_loader && _data.find(key) == _data.end())
_loader->load(key);
return Resource<T, U>(this, key);
}
void set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy) {
auto it = _data.find(key);
/* NotFound / Loading state shouldn't have any data */
CORRADE_ASSERT((data == nullptr) == (state == ResourceDataState::NotFound || state == ResourceDataState::Loading),
"ResourceManager::set(): data should be null if and only if state is NotFound or Loading", );
/* Cannot change resource with already final state */
CORRADE_ASSERT(it == _data.end() || it->second.state != ResourceDataState::Final, "ResourceManager: cannot change already final resource", );
CORRADE_ASSERT(it == _data.end() || it->second.state != ResourceDataState::Final,
"ResourceManager::set(): cannot change already final resource", );
/* If nothing is referencing reference-counted resource, we're done */
if(policy == ResourcePolicy::ReferenceCounted && (it == _data.end() || it->second.referenceCount == 0)) {
@ -216,6 +184,9 @@ namespace Implementation {
++_lastChange;
}
inline T* fallback() { return _fallback; }
inline const T* fallback() const { return _fallback; }
inline void setFallback(T* data) {
delete _fallback;
_fallback = data;
@ -230,7 +201,53 @@ namespace Implementation {
}
}
inline T* fallback() const { return _fallback; }
inline AbstractResourceLoader<T>* loader() { return _loader; }
inline const AbstractResourceLoader<T>* loader() const { return _loader; }
inline void setLoader(AbstractResourceLoader<T>* loader) {
/* Delete previous loader */
delete _loader;
/* Add new loader */
_loader = loader;
if(_loader) _loader->manager = this;
}
protected:
inline ResourceManagerData(): _fallback(nullptr), _loader(nullptr), _lastChange(0) {}
private:
struct Data {
Data& operator=(const Data&) = delete;
Data& operator=(Data&&) = delete;
inline Data(): data(nullptr), state(ResourceDataState::Mutable), policy(ResourcePolicy::Manual), referenceCount(0) {}
/* Fugly hack for GCC 4.5, because std::pair doesn't have move constructor yet */
#ifndef CORRADE_GCC45_COMPATIBILITY
Data(const Data&) = delete;
#else
Data(const Data& other): data(other.data), state(other.state), policy(other.policy), referenceCount(other.referenceCount) {
const_cast<Data&>(other).data = nullptr;
const_cast<Data&>(other).referenceCount = 0;
}
#endif
inline Data(Data&& other): data(other.data), state(other.state), policy(other.policy), referenceCount(other.referenceCount) {
other.data = nullptr;
other.referenceCount = 0;
}
inline ~Data() {
CORRADE_ASSERT(referenceCount == 0, "ResourceManager: cannot destruct it while data are still referenced", );
delete data;
}
T* data;
ResourceDataState state;
ResourcePolicy policy;
std::size_t referenceCount;
};
inline const Data& data(ResourceKey key) {
return _data[key];
@ -248,160 +265,14 @@ namespace Implementation {
_data.erase(it);
}
protected:
inline ResourceManagerData(): _fallback(nullptr), _lastChange(0) {}
private:
std::unordered_map<ResourceKey, Data, ResourceKeyHash> _data;
T* _fallback;
AbstractResourceLoader<T>* _loader;
std::size_t _lastChange;
};
}
#endif
/**
@brief %Resource reference
See ResourceManager for more information.
*/
template<class T, class U = T> class Resource {
friend class Implementation::ResourceManagerData<T>;
public:
/**
* @brief Default constructor
*
* Creates empty resource. Resources are acquired from the manager by
* calling ResourceManager::get().
*/
inline Resource(): manager(nullptr), lastCheck(0), _state(ResourceState::Final), data(nullptr) {}
/** @brief Copy constructor */
inline Resource(const Resource<T, U>& other): manager(other.manager), _key(other._key), lastCheck(other.lastCheck), _state(other._state), data(other.data) {
if(manager) manager->incrementReferenceCount(_key);
}
/** @brief Move constructor */
inline Resource(Resource<T, U>&& other): manager(other.manager), _key(other._key), lastCheck(other.lastCheck), _state(other._state), data(other.data) {
other.manager = nullptr;
}
/** @brief Destructor */
inline ~Resource() {
if(manager) manager->decrementReferenceCount(_key);
}
/** @brief Assignment operator */
Resource<T, U>& operator=(const Resource<T, U>& other) {
if(manager) manager->decrementReferenceCount(_key);
manager = other.manager;
_key = other._key;
lastCheck = other.lastCheck;
_state = other._state;
data = other.data;
if(manager) manager->incrementReferenceCount(_key);
return *this;
}
/** @brief Assignment move operator */
Resource<T, U>& operator=(Resource<T, U>&& other) {
if(manager) manager->decrementReferenceCount(_key);
manager = other.manager;
_key = other._key;
lastCheck = other.lastCheck;
_state = other._state;
data = other.data;
other.manager = nullptr;
return *this;
}
/** @brief Resource key */
inline ResourceKey key() const { return _key; }
/**
* @brief %Resource state
*
* @see operator bool()
*/
inline ResourceState state() {
acquire();
return _state;
}
/**
* @brief Whether the resource is available
* @return False when resource is not loaded and no fallback is
* available, true otherwise.
*
* @see state()
*/
inline operator bool() {
acquire();
return data;
}
/**
* @brief %Resource data
*
* The resource must be loaded before accessing it. Use boolean
* conversion operator or state() for testing whether it is loaded.
*/
inline operator U*() {
acquire();
CORRADE_ASSERT(data, "Resource: accessing not loaded data with key" << key(), nullptr);
return static_cast<U*>(data);
}
/** @overload */
inline U* operator->() {
acquire();
CORRADE_ASSERT(data, "Resource: accessing not loaded data with key" << key(), nullptr);
return static_cast<U*>(data);
}
/** @overload */
inline U& operator*() {
acquire();
CORRADE_ASSERT(data, "Resource: accessing not loaded data with key" << key(), *static_cast<U*>(data));
return *static_cast<U*>(data);
}
private:
inline Resource(Implementation::ResourceManagerData<T>* manager, ResourceKey key): manager(manager), _key(key), lastCheck(0), _state(ResourceState::NotLoaded), data(nullptr) {
manager->incrementReferenceCount(key);
}
void acquire() {
/* The data are already final, nothing to do */
if(_state == ResourceState::Final) return;
/* Nothing changed since last check */
if(manager->lastChange() < lastCheck) return;
/* Acquire new data and save last check time */
const typename Implementation::ResourceManagerData<T>::Data& d = manager->data(_key);
lastCheck = manager->lastChange();
/* Try to get the data */
if((data = d.data))
_state = static_cast<ResourceState>(d.state);
else if((data = manager->fallback()))
_state = ResourceState::Fallback;
else
_state = ResourceState::NotLoaded;
}
Implementation::ResourceManagerData<T>* manager;
ResourceKey _key;
std::size_t lastCheck;
ResourceState _state;
T* data;
};
/**
@brief %Resource manager
@ -468,7 +339,7 @@ cube->draw();
/* 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>... {
template<class... Types> class ResourceManager: private Implementation::ResourceManagerData<Types>... {
public:
/** @brief Global instance */
inline static ResourceManager<Types...>* instance() {
@ -554,13 +425,23 @@ template<class... Types> class ResourceManager: protected Implementation::Resour
* }
* @endcode
* @attention If resource state is already `ResourceState::Final`,
* subsequent updates are not possible.
* subsequent updates are not possible.
* @see referenceCount(), state()
*/
template<class T> inline void set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy) {
this->Implementation::ResourceManagerData<T>::set(key, data, state, policy);
}
/** @brief Fallback for not found resources */
template<class T> inline T* fallback() {
return this->Implementation::ResourceManagerData<T>::fallback();
}
/** @overload */
template<class T> inline const T* fallback() const {
return this->Implementation::ResourceManagerData<T>::fallback();
}
/** @brief Set fallback for not found resources */
template<class T> inline void setFallback(T* data) {
return this->Implementation::ResourceManagerData<T>::setFallback(data);
@ -576,6 +457,26 @@ template<class... Types> class ResourceManager: protected Implementation::Resour
freeInternal(std::common_type<Types>()...);
}
/** @brief Loader for given type of resources */
template<class T> inline AbstractResourceLoader<T>* loader() {
return this->Implementation::ResourceManagerData<T>::loader();
}
/** @overload */
template<class T> inline const AbstractResourceLoader<T>* loader() const {
return this->Implementation::ResourceManagerData<T>::loader();
}
/**
* @brief Set loader for given type of resources
*
* The loader will affect only loading of resources requested after
* that.
*/
template<class T> inline void setLoader(AbstractResourceLoader<T>* loader) {
return this->Implementation::ResourceManagerData<T>::setLoader(loader);
}
private:
template<class FirstType, class ...NextTypes> inline void freeInternal(std::common_type<FirstType>, std::common_type<NextTypes>... t) {
free<FirstType>();
@ -593,11 +494,9 @@ template<class ...Types> ResourceManager<Types...>*& ResourceManager<Types...>::
}
#endif
/** @debugoperator{Magnum::ResourceKey} */
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);
}
}
/* Make the definition complete */
#include "AbstractResourceLoader.h"
#endif

6
src/SceneGraph/AbstractCamera.h

@ -69,7 +69,7 @@ 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> {
class MAGNUM_SCENEGRAPH_EXPORT AbstractCamera: public AbstractFeature<dimensions, T> {
public:
/**
* @brief Constructor
@ -141,8 +141,8 @@ class SCENEGRAPH_EXPORT AbstractCamera: public AbstractFeature<dimensions, T> {
protected:
/** Recalculates camera matrix */
inline void cleanInverted(const typename DimensionTraits<dimensions, T>::MatrixType& invertedAbsoluteTransformation) override {
_cameraMatrix = invertedAbsoluteTransformation;
inline void cleanInverted(const typename DimensionTraits<dimensions, T>::MatrixType& invertedAbsoluteTransformationMatrix) override {
_cameraMatrix = invertedAbsoluteTransformationMatrix;
}
#ifndef DOXYGEN_GENERATING_OUTPUT

8
src/SceneGraph/AbstractFeature.h

@ -72,8 +72,8 @@ class CachingFeature: public SceneGraph::AbstractFeature3D<> {
}
protected:
void clean(const Matrix4& absoluteTransformation) override {
absolutePosition = absoluteTransformation.translation();
void clean(const Matrix4& absoluteTransformationMatrix) override {
absolutePosition = absoluteTransformationMatrix.translation();
}
private:
@ -258,7 +258,7 @@ template<std::uint8_t dimensions, class T = GLfloat> class AbstractFeature
* Default implementation does nothing.
* @see @ref scenegraph-caching, cleanInverted()
*/
virtual void clean(const typename DimensionTraits<dimensions, T>::MatrixType& absoluteTransformation);
virtual void clean(const typename DimensionTraits<dimensions, T>::MatrixType& absoluteTransformationMatrix);
/**
* @brief Clean data based on inverted absolute transformation
@ -272,7 +272,7 @@ template<std::uint8_t dimensions, class T = GLfloat> class AbstractFeature
* Default implementation does nothing.
* @see @ref scenegraph-caching, clean()
*/
virtual void cleanInverted(const typename DimensionTraits<dimensions, T>::MatrixType& invertedAbsoluteTransformation);
virtual void cleanInverted(const typename DimensionTraits<dimensions, T>::MatrixType& invertedAbsoluteTransformationMatrix);
/*@}*/

8
src/SceneGraph/Camera.cpp

@ -19,10 +19,10 @@
namespace Magnum { namespace SceneGraph {
#ifndef DOXYGEN_GENERATING_OUTPUT
template class SCENEGRAPH_EXPORT AbstractCamera<2, GLfloat>;
template class SCENEGRAPH_EXPORT AbstractCamera<3, GLfloat>;
template class SCENEGRAPH_EXPORT Camera2D<GLfloat>;
template class SCENEGRAPH_EXPORT Camera3D<GLfloat>;
template class MAGNUM_SCENEGRAPH_EXPORT AbstractCamera<2, GLfloat>;
template class MAGNUM_SCENEGRAPH_EXPORT AbstractCamera<3, GLfloat>;
template class MAGNUM_SCENEGRAPH_EXPORT Camera2D<GLfloat>;
template class MAGNUM_SCENEGRAPH_EXPORT Camera3D<GLfloat>;
#endif
}}

2
src/SceneGraph/Camera2D.h

@ -43,7 +43,7 @@ template<class T>
#else
template<class T = GLfloat>
#endif
class SCENEGRAPH_EXPORT Camera2D: public AbstractCamera<2, T> {
class MAGNUM_SCENEGRAPH_EXPORT Camera2D: public AbstractCamera<2, T> {
public:
/**
* @brief Constructor

2
src/SceneGraph/Camera3D.h

@ -48,7 +48,7 @@ template<class T>
#else
template<class T = GLfloat>
#endif
class SCENEGRAPH_EXPORT Camera3D: public AbstractCamera<3, T> {
class MAGNUM_SCENEGRAPH_EXPORT Camera3D: public AbstractCamera<3, T> {
public:
/**
* @brief Constructor

2
src/SceneGraph/MatrixTransformation2D.cpp

@ -20,7 +20,7 @@
namespace Magnum { namespace SceneGraph {
#ifndef DOXYGEN_GENERATING_OUTPUT
template class SCENEGRAPH_EXPORT Object<MatrixTransformation2D<>>;
template class MAGNUM_SCENEGRAPH_EXPORT Object<MatrixTransformation2D<>>;
#endif
}}

2
src/SceneGraph/MatrixTransformation3D.cpp

@ -20,7 +20,7 @@
namespace Magnum { namespace SceneGraph {
#ifndef DOXYGEN_GENERATING_OUTPUT
template class SCENEGRAPH_EXPORT Object<MatrixTransformation3D<>>;
template class MAGNUM_SCENEGRAPH_EXPORT Object<MatrixTransformation3D<>>;
#endif
}}

6
src/SceneGraph/magnumSceneGraphVisibility.h

@ -17,13 +17,13 @@
#ifdef _WIN32
#if defined(MagnumSceneGraph_EXPORTS) || defined(MagnumSceneGraphObjects_EXPORTS)
#define SCENEGRAPH_EXPORT __declspec(dllexport)
#define MAGNUM_SCENEGRAPH_EXPORT __declspec(dllexport)
#else
#define SCENEGRAPH_EXPORT __declspec(dllimport)
#define MAGNUM_SCENEGRAPH_EXPORT __declspec(dllimport)
#endif
#define SCENEGRAPH_LOCAL
#else
#define SCENEGRAPH_EXPORT __attribute__ ((visibility ("default")))
#define MAGNUM_SCENEGRAPH_EXPORT __attribute__ ((visibility ("default")))
#define SCENEGRAPH_LOCAL __attribute__ ((visibility ("hidden")))
#endif

2
src/Shaders/FlatShader.cpp

@ -76,7 +76,7 @@ template<std::uint8_t dimensions> FlatShader<dimensions>::FlatShader() {
link();
transformationProjectionUniform = uniformLocation("transformationProjection");
transformationProjectionMatrixUniform = uniformLocation("transformationProjectionMatrix");
colorUniform = uniformLocation("color");
}

8
src/Shaders/FlatShader.h

@ -35,7 +35,7 @@ namespace Magnum { namespace Shaders {
Draws whole mesh with one color.
@see FlatShader2D, FlatShader3D
*/
template<std::uint8_t dimensions> class SHADERS_EXPORT FlatShader: public AbstractShaderProgram {
template<std::uint8_t dimensions> class MAGNUM_SHADERS_EXPORT FlatShader: public AbstractShaderProgram {
public:
/** @brief Vertex position */
typedef Attribute<0, typename DimensionTraits<dimensions>::PointType> Position;
@ -46,8 +46,8 @@ template<std::uint8_t dimensions> class SHADERS_EXPORT FlatShader: public Abstra
* @brief Set transformation and projection matrix
* @return Pointer to self (for method chaining)
*/
FlatShader<dimensions>* setTransformationProjection(const typename DimensionTraits<dimensions>::MatrixType& matrix) {
setUniform(transformationProjectionUniform, matrix);
FlatShader<dimensions>* setTransformationProjectionMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) {
setUniform(transformationProjectionMatrixUniform, matrix);
return this;
}
@ -61,7 +61,7 @@ template<std::uint8_t dimensions> class SHADERS_EXPORT FlatShader: public Abstra
}
private:
GLint transformationProjectionUniform,
GLint transformationProjectionMatrixUniform,
colorUniform;
};

4
src/Shaders/FlatShader2D.vert

@ -2,7 +2,7 @@
#define in attribute
#endif
uniform highp mat3 transformationProjection;
uniform highp mat3 transformationProjectionMatrix;
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = 0) in highp vec3 position;
@ -11,5 +11,5 @@ in highp vec3 position;
#endif
void main() {
gl_Position.xywz = vec4(transformationProjection*position, 0.0);
gl_Position.xywz = vec4(transformationProjectionMatrix*position, 0.0);
}

8
src/Shaders/PhongShader.h

@ -33,7 +33,7 @@ namespace Magnum { namespace Shaders {
If supported, uses GLSL 3.20 and @extension{ARB,explicit_attrib_location},
otherwise falls back to GLSL 1.20.
*/
class SHADERS_EXPORT PhongShader: public AbstractShaderProgram {
class MAGNUM_SHADERS_EXPORT PhongShader: public AbstractShaderProgram {
public:
typedef Attribute<0, Point3D> Position; /**< @brief Vertex position */
typedef Attribute<1, Vector3> Normal; /**< @brief Normal direction */
@ -84,10 +84,10 @@ class SHADERS_EXPORT PhongShader: public AbstractShaderProgram {
}
/**
* @brief Set transformation matrix and normal matrix
* @brief Set transformation and normal matrix
* @return Pointer to self (for method chaining)
*/
inline PhongShader* setTransformation(const Matrix4& matrix) {
inline PhongShader* setTransformationMatrix(const Matrix4& matrix) {
setUniform(transformationMatrixUniform, matrix);
setUniform(normalMatrixUniform, matrix.rotation());
return this;
@ -97,7 +97,7 @@ class SHADERS_EXPORT PhongShader: public AbstractShaderProgram {
* @brief Set projection matrix
* @return Pointer to self (for method chaining)
*/
inline PhongShader* setProjection(const Matrix4& matrix) {
inline PhongShader* setProjectionMatrix(const Matrix4& matrix) {
setUniform(projectionMatrixUniform, matrix);
return this;
}

2
src/Shaders/VertexColorShader.cpp

@ -77,7 +77,7 @@ template<std::uint8_t dimensions> VertexColorShader<dimensions>::VertexColorShad
link();
transformationProjectionUniform = uniformLocation("transformationProjection");
transformationProjectionMatrixUniform = uniformLocation("transformationProjectionMatrix");
}
template class VertexColorShader<2>;

10
src/Shaders/VertexColorShader.h

@ -35,7 +35,7 @@ namespace Magnum { namespace Shaders {
Draws vertex-colored mesh.
@see VertexColorShader2D, VertexColorShader3D
*/
template<std::uint8_t dimensions> class SHADERS_EXPORT VertexColorShader: public AbstractShaderProgram {
template<std::uint8_t dimensions> class MAGNUM_SHADERS_EXPORT VertexColorShader: public AbstractShaderProgram {
public:
/** @brief Vertex position */
typedef Attribute<0, typename DimensionTraits<dimensions>::PointType> Position;
@ -46,16 +46,16 @@ template<std::uint8_t dimensions> class SHADERS_EXPORT VertexColorShader: public
VertexColorShader();
/**
* @brief Set transformation and projection
* @brief Set transformation and projection matrix
* @return Pointer to self (for method chaining)
*/
inline VertexColorShader<dimensions>* setTransformationProjection(const typename DimensionTraits<dimensions>::MatrixType& matrix) {
setUniform(transformationProjectionUniform, matrix);
inline VertexColorShader<dimensions>* setTransformationProjectionMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) {
setUniform(transformationProjectionMatrixUniform, matrix);
return this;
}
private:
GLint transformationProjectionUniform;
GLint transformationProjectionMatrixUniform;
};
/** @brief 2D vertex color shader */

4
src/Shaders/VertexColorShader2D.vert

@ -3,7 +3,7 @@
#define out varying
#endif
uniform highp mat3 transformationProjection;
uniform highp mat3 transformationProjectionMatrix;
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = 0) in highp vec3 position;
@ -16,6 +16,6 @@ in lowp vec3 color;
out lowp vec3 interpolatedColor;
void main() {
gl_Position.xywz = vec4(transformationProjection*position, 0.0);
gl_Position.xywz = vec4(transformationProjectionMatrix*position, 0.0);
interpolatedColor = color;
}

6
src/Shaders/magnumShadersVisibility.h

@ -17,12 +17,12 @@
#ifdef _WIN32
#ifdef MagnumShaders_EXPORTS
#define SHADERS_EXPORT __declspec(dllexport)
#define MAGNUM_SHADERS_EXPORT __declspec(dllexport)
#else
#define SHADERS_EXPORT __declspec(dllimport)
#define MAGNUM_SHADERS_EXPORT __declspec(dllimport)
#endif
#else
#define SHADERS_EXPORT __attribute__ ((visibility ("default")))
#define MAGNUM_SHADERS_EXPORT __attribute__ ((visibility ("default")))
#endif
#endif

4
src/Test/CMakeLists.txt

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

16
src/Test/ColorTest.cpp

@ -15,6 +15,8 @@
#include "ColorTest.h"
#include <Utility/Configuration.h>
#include "Color.h"
using namespace std;
@ -135,15 +137,21 @@ void ColorTest::debug() {
}
void ColorTest::configuration() {
Configuration c;
Color3f color3(0.5f, 0.75f, 1.0f);
string value3("0.5 0.75 1");
CORRADE_COMPARE(ConfigurationValue<Color3f>::toString(color3), value3);
CORRADE_COMPARE(ConfigurationValue<Color3f>::fromString(value3), color3);
c.setValue("color3", color3);
CORRADE_COMPARE(c.value<std::string>("color3"), value3);
CORRADE_COMPARE(c.value<Color3f>("color3"), color3);
Color4f color4(0.5f, 0.75f, 0.0f, 1.0f);
string value4("0.5 0.75 0 1");
CORRADE_COMPARE(ConfigurationValue<Color4f>::toString(color4), value4);
CORRADE_COMPARE(ConfigurationValue<Color4f>::fromString(value4), color4);
c.setValue("color4", color4);
CORRADE_COMPARE(c.value<std::string>("color4"), value4);
CORRADE_COMPARE(c.value<Color4f>("color4"), color4);
}
}}

47
src/Test/MeshTest.cpp

@ -0,0 +1,47 @@
/*
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 "MeshTest.h"
#include <Utility/Configuration.h>
#include "Mesh.h"
CORRADE_TEST_MAIN(Magnum::Test::MeshTest)
using namespace Corrade::Utility;
namespace Magnum { namespace Test {
MeshTest::MeshTest() {
addTests(&MeshTest::debug,
&MeshTest::configuration);
}
void MeshTest::debug() {
std::ostringstream o;
Debug(&o) << Mesh::Primitive::TriangleFan;
CORRADE_COMPARE(o.str(), "Mesh::Primitive::TriangleFan\n");
}
void MeshTest::configuration() {
Configuration c;
c.setValue("primitive", Mesh::Primitive::LineStrip);
CORRADE_COMPARE(c.value<std::string>("primitive"), "LineStrip");
CORRADE_COMPARE(c.value<Mesh::Primitive>("primitive"), Mesh::Primitive::LineStrip);
}
}}

32
src/Test/MeshTest.h

@ -0,0 +1,32 @@
#ifndef Magnum_Test_MeshTest_h
#define Magnum_Test_MeshTest_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 <TestSuite/Tester.h>
namespace Magnum { namespace Test {
class MeshTest: public Corrade::TestSuite::Tester<MeshTest> {
public:
MeshTest();
void debug();
void configuration();
};
}}
#endif

203
src/Test/ResourceManagerTest.cpp

@ -17,6 +17,7 @@
#include <sstream>
#include "AbstractResourceLoader.h"
#include "ResourceManager.h"
using namespace std;
@ -26,94 +27,214 @@ CORRADE_TEST_MAIN(Magnum::Test::ResourceManagerTest)
namespace Magnum { namespace Test {
class Data {
public:
static std::size_t count;
inline Data() { ++count; }
inline ~Data() { --count; }
};
typedef Magnum::ResourceManager<int32_t, Data> ResourceManager;
class IntResourceLoader: public AbstractResourceLoader<std::int32_t> {
public:
void load(ResourceKey key) override {
AbstractResourceLoader::load(key);
}
void load() {
set("hello", new std::int32_t(773), ResourceDataState::Final, ResourcePolicy::Resident);
setNotFound("world");
}
};
size_t Data::count = 0;
ResourceManagerTest::ResourceManagerTest() {
rm = new ResourceManager;
addTests(&ResourceManagerTest::state,
&ResourceManagerTest::stateFallback,
&ResourceManagerTest::stateDisallowed,
&ResourceManagerTest::basic,
&ResourceManagerTest::residentPolicy,
&ResourceManagerTest::referenceCountedPolicy,
&ResourceManagerTest::manualPolicy,
&ResourceManagerTest::destroy);
&ResourceManagerTest::loader);
}
void ResourceManagerTest::state() {
ResourceKey questionKey("the-question");
rm->set(questionKey, new int32_t(10), ResourceDataState::Mutable, ResourcePolicy::Resident);
Resource<int32_t> theQuestion = rm->get<int32_t>(questionKey);
CORRADE_VERIFY(theQuestion.state() == ResourceState::Mutable);
CORRADE_COMPARE(*theQuestion, 10);
ResourceManager rm;
Resource<Data> data = rm.get<Data>("data");
CORRADE_VERIFY(!data);
CORRADE_COMPARE(data.state(), ResourceState::NotLoaded);
CORRADE_COMPARE(rm.state<Data>("data"), ResourceState::NotLoaded);
rm.set<Data>("data", nullptr, ResourceDataState::Loading, ResourcePolicy::Resident);
CORRADE_VERIFY(!data);
CORRADE_COMPARE(data.state(), ResourceState::Loading);
CORRADE_COMPARE(rm.state<Data>("data"), ResourceState::Loading);
rm.set<Data>("data", nullptr, ResourceDataState::NotFound, ResourcePolicy::Resident);
CORRADE_VERIFY(!data);
CORRADE_COMPARE(data.state(), ResourceState::NotFound);
CORRADE_COMPARE(rm.state<Data>("data"), ResourceState::NotFound);
/* Nothing happened at all */
CORRADE_COMPARE(Data::count, 0);
}
void ResourceManagerTest::stateFallback() {
{
ResourceManager rm;
rm.setFallback<Data>(new Data);
Resource<Data> data = rm.get<Data>("data");
CORRADE_VERIFY(data);
CORRADE_COMPARE(data.state(), ResourceState::NotLoadedFallback);
CORRADE_COMPARE(rm.state<Data>("data"), ResourceState::NotLoadedFallback);
rm.set<Data>("data", nullptr, ResourceDataState::Loading, ResourcePolicy::Resident);
CORRADE_VERIFY(data);
CORRADE_COMPARE(data.state(), ResourceState::LoadingFallback);
CORRADE_COMPARE(rm.state<Data>("data"), ResourceState::LoadingFallback);
rm.set<Data>("data", nullptr, ResourceDataState::NotFound, ResourcePolicy::Resident);
CORRADE_VERIFY(data);
CORRADE_COMPARE(data.state(), ResourceState::NotFoundFallback);
CORRADE_COMPARE(rm.state<Data>("data"), ResourceState::NotFoundFallback);
/* Only fallback is here */
CORRADE_COMPARE(Data::count, 1);
}
/* Fallback gets destroyed */
CORRADE_COMPARE(Data::count, 0);
}
void ResourceManagerTest::stateDisallowed() {
ResourceManager rm;
/* Check that hash function is working properly */
stringstream out;
Error::setOutput(&out);
Data d;
rm.set("data", &d, ResourceDataState::Loading, ResourcePolicy::Resident);
CORRADE_COMPARE(out.str(), "ResourceManager::set(): data should be null if and only if state is NotFound or Loading\n");
out.str("");
rm.set<Data>("data", nullptr, ResourceDataState::Final, ResourcePolicy::Resident);
CORRADE_COMPARE(out.str(), "ResourceManager::set(): data should be null if and only if state is NotFound or Loading\n");
}
void ResourceManagerTest::basic() {
ResourceManager rm;
/* One mutable, one final */
ResourceKey questionKey("the-question");
ResourceKey answerKey("the-answer");
rm->set(answerKey, new int32_t(42), ResourceDataState::Final, ResourcePolicy::Resident);
Resource<int32_t> theAnswer = rm->get<int32_t>(answerKey);
CORRADE_VERIFY(theAnswer.state() == ResourceState::Final);
rm.set(questionKey, new int32_t(10), ResourceDataState::Mutable, ResourcePolicy::Resident);
rm.set(answerKey, new int32_t(42), ResourceDataState::Final, ResourcePolicy::Resident);
Resource<int32_t> theQuestion = rm.get<int32_t>(questionKey);
Resource<int32_t> theAnswer = rm.get<int32_t>(answerKey);
/* Check basic functionality */
CORRADE_COMPARE(theQuestion.state(), ResourceState::Mutable);
CORRADE_COMPARE(theAnswer.state(), ResourceState::Final);
CORRADE_COMPARE(*theQuestion, 10);
CORRADE_COMPARE(*theAnswer, 42);
CORRADE_COMPARE(rm->count<int32_t>(), 2);
CORRADE_COMPARE(rm.count<int32_t>(), 2);
/* Cannot change already final resource */
stringstream out;
Error::setOutput(&out);
rm->set(answerKey, new int32_t(43), ResourceDataState::Mutable, ResourcePolicy::Resident);
rm.set(answerKey, new int32_t(43), ResourceDataState::Mutable, ResourcePolicy::Resident);
CORRADE_COMPARE(*theAnswer, 42);
CORRADE_COMPARE(out.str(), "ResourceManager: cannot change already final resource\n");
CORRADE_COMPARE(out.str(), "ResourceManager::set(): cannot change already final resource\n");
/* Check non-final resource changes */
rm->set(questionKey, new int32_t(20), ResourceDataState::Final, ResourcePolicy::Resident);
CORRADE_VERIFY(theQuestion.state() == ResourceState::Final);
/* But non-final can be changed */
rm.set(questionKey, new int32_t(20), ResourceDataState::Final, ResourcePolicy::Resident);
CORRADE_COMPARE(theQuestion.state(), ResourceState::Final);
CORRADE_COMPARE(*theQuestion, 20);
}
void ResourceManagerTest::residentPolicy() {
ResourceManager* rm = new ResourceManager;
rm->set("blah", new Data(), ResourceDataState::Mutable, ResourcePolicy::Resident);
CORRADE_COMPARE(Data::count, 1);
rm->free();
CORRADE_COMPARE(Data::count, 1);
delete rm;
CORRADE_COMPARE(Data::count, 0);
}
void ResourceManagerTest::referenceCountedPolicy() {
ResourceManager rm;
ResourceKey dataRefCountKey("dataRefCount");
/* Reference counted resources must be requested first */
{
rm->set(dataRefCountKey, new Data(), ResourceDataState::Final, ResourcePolicy::ReferenceCounted);
CORRADE_COMPARE(rm->count<Data>(), 0);
Resource<Data> data = rm->get<Data>(dataRefCountKey);
CORRADE_VERIFY(data.state() == ResourceState::NotLoaded);
rm.set(dataRefCountKey, new Data(), ResourceDataState::Final, ResourcePolicy::ReferenceCounted);
CORRADE_COMPARE(rm.count<Data>(), 0);
Resource<Data> data = rm.get<Data>(dataRefCountKey);
CORRADE_COMPARE(data.state(), ResourceState::NotLoaded);
CORRADE_COMPARE(Data::count, 0);
} {
Resource<Data> data = rm->get<Data>(dataRefCountKey);
CORRADE_COMPARE(rm->count<Data>(), 1);
CORRADE_VERIFY(data.state() == ResourceState::NotLoaded);
rm->set(dataRefCountKey, new Data(), ResourceDataState::Final, ResourcePolicy::ReferenceCounted);
CORRADE_VERIFY(data.state() == ResourceState::Final);
Resource<Data> data = rm.get<Data>(dataRefCountKey);
CORRADE_COMPARE(rm.count<Data>(), 1);
CORRADE_COMPARE(data.state(), ResourceState::NotLoaded);
rm.set(dataRefCountKey, new Data(), ResourceDataState::Final, ResourcePolicy::ReferenceCounted);
CORRADE_COMPARE(data.state(), ResourceState::Final);
CORRADE_COMPARE(Data::count, 1);
}
CORRADE_COMPARE(rm->count<Data>(), 0);
CORRADE_COMPARE(rm.count<Data>(), 0);
CORRADE_COMPARE(Data::count, 0);
}
void ResourceManagerTest::manualPolicy() {
ResourceManager rm;
ResourceKey dataKey("data");
/* Manual free */
{
rm->set(dataKey, new Data(), ResourceDataState::Mutable, ResourcePolicy::Manual);
Resource<Data> data = rm->get<Data>(dataKey);
rm->free();
rm.set(dataKey, new Data(), ResourceDataState::Mutable, ResourcePolicy::Manual);
Resource<Data> data = rm.get<Data>(dataKey);
rm.free();
}
CORRADE_COMPARE(rm->count<Data>(), 1);
CORRADE_COMPARE(rm.count<Data>(), 1);
CORRADE_COMPARE(Data::count, 1);
rm->free();
CORRADE_COMPARE(rm->count<Data>(), 0);
rm.free();
CORRADE_COMPARE(rm.count<Data>(), 0);
CORRADE_COMPARE(Data::count, 0);
rm->set(dataKey, new Data(), ResourceDataState::Mutable, ResourcePolicy::Manual);
CORRADE_COMPARE(rm->count<Data>(), 1);
rm.set(dataKey, new Data(), ResourceDataState::Mutable, ResourcePolicy::Manual);
CORRADE_COMPARE(rm.count<Data>(), 1);
CORRADE_COMPARE(Data::count, 1);
}
void ResourceManagerTest::destroy() {
delete rm;
rm = nullptr;
CORRADE_COMPARE(Data::count, 0);
void ResourceManagerTest::loader() {
ResourceManager rm;
IntResourceLoader loader;
rm.setLoader(&loader);
Resource<Data> data = rm.get<Data>("data");
Resource<std::int32_t> hello = rm.get<std::int32_t>("hello");
Resource<std::int32_t> world = rm.get<std::int32_t>("world");
CORRADE_COMPARE(data.state(), ResourceState::NotLoaded);
CORRADE_COMPARE(hello.state(), ResourceState::Loading);
CORRADE_COMPARE(world.state(), ResourceState::Loading);
loader.load();
CORRADE_COMPARE(hello.state(), ResourceState::Final);
CORRADE_COMPARE(*hello, 773);
CORRADE_COMPARE(world.state(), ResourceState::NotFound);
}
}}

25
src/Test/ResourceManagerTest.h

@ -17,33 +17,20 @@
#include <TestSuite/Tester.h>
namespace Magnum {
template<class...> class ResourceManager;
namespace Test {
class Data {
public:
static std::size_t count;
inline Data() { ++count; }
inline ~Data() { --count; }
};
typedef Magnum::ResourceManager<int32_t, Data> ResourceManager;
namespace Magnum { namespace Test {
class ResourceManagerTest: public Corrade::TestSuite::Tester<ResourceManagerTest> {
public:
ResourceManagerTest();
void state();
void stateFallback();
void stateDisallowed();
void basic();
void residentPolicy();
void referenceCountedPolicy();
void manualPolicy();
void destroy();
private:
ResourceManager* rm;
void loader();
};
}}

47
src/Test/TypeTraitsTest.cpp

@ -0,0 +1,47 @@
/*
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 "TypeTraitsTest.h"
#include <Utility/Configuration.h>
#include "TypeTraits.h"
CORRADE_TEST_MAIN(Magnum::Test::TypeTraitsTest)
using namespace Corrade::Utility;
namespace Magnum { namespace Test {
TypeTraitsTest::TypeTraitsTest() {
addTests(&TypeTraitsTest::debug,
&TypeTraitsTest::configuration);
}
void TypeTraitsTest::debug() {
std::ostringstream o;
Debug(&o) << Type::UnsignedShort;
CORRADE_COMPARE(o.str(), "Type::UnsignedShort\n");
}
void TypeTraitsTest::configuration() {
Configuration c;
c.setValue("type", Type::Byte);
CORRADE_COMPARE(c.value<std::string>("type"), "Byte");
CORRADE_COMPARE(c.value<Type>("type"), Type::Byte);
}
}}

32
src/Test/TypeTraitsTest.h

@ -0,0 +1,32 @@
#ifndef Magnum_Test_TypeTraitsTest_h
#define Magnum_Test_TypeTraitsTest_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 <TestSuite/Tester.h>
namespace Magnum { namespace Test {
class TypeTraitsTest: public Corrade::TestSuite::Tester<TypeTraitsTest> {
public:
TypeTraitsTest();
void debug();
void configuration();
};
}}
#endif

61
src/TypeTraits.cpp

@ -16,6 +16,7 @@
#include "TypeTraits.h"
#include <type_traits>
#include <Utility/Debug.h>
using namespace std;
@ -67,4 +68,64 @@ bool TypeInfo::isIntegral(Type type) {
}
}
#ifndef DOXYGEN_GENERATING_OUTPUT
Debug operator<<(Debug debug, Type value) {
switch(value) {
#define _c(value) case Type::value: return debug << "Type::" #value;
_c(UnsignedByte)
_c(Byte)
_c(UnsignedShort)
_c(Short)
_c(UnsignedInt)
_c(Int)
_c(Float)
#ifndef MAGNUM_TARGET_GLES
_c(Double)
#endif
#undef _c
}
return debug << "Type::(invalid)";
}
#endif
}
namespace Corrade { namespace Utility {
std::string ConfigurationValue<Magnum::Type>::toString(Magnum::Type value, ConfigurationValueFlags) {
switch(value) {
#define _c(value) case Magnum::Type::value: return #value;
_c(UnsignedByte)
_c(Byte)
_c(UnsignedShort)
_c(Short)
_c(UnsignedInt)
_c(Int)
_c(Float)
#ifndef MAGNUM_TARGET_GLES
_c(Double)
#endif
#undef _c
}
return "";
}
Magnum::Type ConfigurationValue<Magnum::Type>::fromString(const std::string& stringValue, ConfigurationValueFlags) {
#define _c(value) if(stringValue == #value) return Magnum::Type::value;
_c(UnsignedByte)
_c(Byte)
_c(UnsignedShort)
_c(Short)
_c(UnsignedInt)
_c(Int)
#ifndef MAGNUM_TARGET_GLES
_c(Double)
#endif
#undef _c
return Magnum::Type::Float;
}
}}

26
src/TypeTraits.h

@ -19,6 +19,8 @@
* @brief Enum Magnum::Type, class Magnum::TypeOf, Magnum::TypeInfo, Magnum::TypeTraits
*/
#include <Utility/ConfigurationValue.h>
#include "Math/MathTypeTraits.h"
#include "AbstractImage.h"
@ -114,6 +116,9 @@ enum class Type: GLenum {
#endif
};
/** @debugoperator{Magnum::TypeInfo} */
Debug MAGNUM_EXPORT operator<<(Debug debug, Type value);
/**
@brief Class for converting Type enum values to types
@ -340,4 +345,25 @@ template<class T> struct TypeTraits<Math::Matrix4<T>>: TypeTraits<Math::Matrix<4
}
namespace Corrade { namespace Utility {
/** @configurationvalue{Magnum::TypeInfo} */
template<> struct MAGNUM_EXPORT ConfigurationValue<Magnum::Type> {
/**
* @brief Writes enum value as string
*
* If the value is invalid, returns empty string.
*/
static std::string toString(Magnum::Type value, ConfigurationValueFlags);
/**
* @brief Reads enum value as string
*
* If the value is invalid, returns @ref Magnum::Type "Magnum::Type::Float".
*/
static Magnum::Type fromString(const std::string& stringValue, ConfigurationValueFlags);
};
}}
#endif

Loading…
Cancel
Save