Browse Source

SceneGraph: generalized camera implementation.

The camera now accepts generic projection matrix instead of providing
functions for setting orthographic/perspective projection. This allowed
to completely get rid of the AbstractCamera->Camera*D inheritance
hierarchy and everything is now done through one templated Camera class.

The Camera2D::setProjection(), Camera3D::setOrthographic() and
Camera3D::setPerspective() are deprecated, use
Camera*D::setProjectionMatrix() in combination with
Matrix3::projection(), Matrix4::orthographicProjection() and
Matrix4::perspectiveProjection() instead.

The Camera3D::near() and Camera3D::far() getters are removed. The user
is advised to cache the values on application side if they are really
needed. More general queries for all six clipping planes (*not*
distance) might be implemented later.

The AbstractCamera, AbstractBasicCamera2D, AbstractBaseicCamera3D,
AbstractCamera2D and AbstractCamera3D types are deprecated as there is
no such type anymore, use Camera, BasicCamera2D, BasicCamera3D, Camera2D
and Camera3D instead.

The AbstractCamera.h, AbstractCamera.hpp, Camera2D.h, Camera2D.hpp,
Camera3D.h and Camera3D.hpp headers are deprecated, use Camera.h and
Camera.hpp instead.

As always, all deprecated features will be removed in some future
release.
pull/107/head
Vladimír Vondruš 11 years ago
parent
commit
73419be9e6
  1. 4
      src/Magnum/DebugTools/ForceRenderer.cpp
  2. 2
      src/Magnum/DebugTools/ForceRenderer.h
  3. 4
      src/Magnum/DebugTools/ObjectRenderer.cpp
  4. 2
      src/Magnum/DebugTools/ObjectRenderer.h
  5. 4
      src/Magnum/DebugTools/ShapeRenderer.cpp
  6. 2
      src/Magnum/DebugTools/ShapeRenderer.h
  7. 4
      src/Magnum/Platform/Sdl2Application.h
  8. 188
      src/Magnum/SceneGraph/AbstractCamera.h
  9. 76
      src/Magnum/SceneGraph/AbstractCamera.hpp
  10. 18
      src/Magnum/SceneGraph/CMakeLists.txt
  11. 284
      src/Magnum/SceneGraph/Camera.h
  12. 107
      src/Magnum/SceneGraph/Camera.hpp
  13. 84
      src/Magnum/SceneGraph/Camera2D.h
  14. 23
      src/Magnum/SceneGraph/Camera2D.hpp
  15. 120
      src/Magnum/SceneGraph/Camera3D.h
  16. 46
      src/Magnum/SceneGraph/Camera3D.hpp
  17. 10
      src/Magnum/SceneGraph/Drawable.h
  18. 23
      src/Magnum/SceneGraph/SceneGraph.h
  19. 15
      src/Magnum/SceneGraph/Test/CameraTest.cpp
  20. 9
      src/Magnum/SceneGraph/instantiation.cpp

4
src/Magnum/DebugTools/ForceRenderer.cpp

@ -28,7 +28,7 @@
#include "Magnum/Buffer.h" #include "Magnum/Buffer.h"
#include "Magnum/Mesh.h" #include "Magnum/Mesh.h"
#include "Magnum/DebugTools/ResourceManager.h" #include "Magnum/DebugTools/ResourceManager.h"
#include "Magnum/SceneGraph/AbstractCamera.h" #include "Magnum/SceneGraph/Camera.h"
#include "Magnum/Shaders/Flat.h" #include "Magnum/Shaders/Flat.h"
#include "Implementation/ForceRendererTransformation.h" #include "Implementation/ForceRendererTransformation.h"
@ -89,7 +89,7 @@ template<UnsignedInt dimensions> ForceRenderer<dimensions>::ForceRenderer(SceneG
/* To avoid deleting pointers to incomplete type on destruction of Resource members */ /* To avoid deleting pointers to incomplete type on destruction of Resource members */
template<UnsignedInt dimensions> ForceRenderer<dimensions>::~ForceRenderer() = default; template<UnsignedInt dimensions> ForceRenderer<dimensions>::~ForceRenderer() = default;
template<UnsignedInt dimensions> void ForceRenderer<dimensions>::draw(const MatrixTypeFor<dimensions, Float>& transformationMatrix, SceneGraph::AbstractCamera<dimensions, Float>& camera) { template<UnsignedInt dimensions> void ForceRenderer<dimensions>::draw(const MatrixTypeFor<dimensions, Float>& transformationMatrix, SceneGraph::Camera<dimensions, Float>& camera) {
shader->setTransformationProjectionMatrix(camera.projectionMatrix()*Implementation::forceRendererTransformation<dimensions>(transformationMatrix.transformPoint(forcePosition), force)*MatrixTypeFor<dimensions, Float>::scaling(VectorTypeFor<dimensions, Float>{options->scale()})) shader->setTransformationProjectionMatrix(camera.projectionMatrix()*Implementation::forceRendererTransformation<dimensions>(transformationMatrix.transformPoint(forcePosition), force)*MatrixTypeFor<dimensions, Float>::scaling(VectorTypeFor<dimensions, Float>{options->scale()}))
.setColor(options->color()); .setColor(options->color());
mesh->draw(*shader); mesh->draw(*shader);

2
src/Magnum/DebugTools/ForceRenderer.h

@ -129,7 +129,7 @@ template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ForceRenderer: p
~ForceRenderer(); ~ForceRenderer();
private: private:
void draw(const MatrixTypeFor<dimensions, Float>& transformationMatrix, SceneGraph::AbstractCamera<dimensions, Float>& camera) override; void draw(const MatrixTypeFor<dimensions, Float>& transformationMatrix, SceneGraph::Camera<dimensions, Float>& camera) override;
const VectorTypeFor<dimensions, Float> forcePosition; const VectorTypeFor<dimensions, Float> forcePosition;
const VectorTypeFor<dimensions, Float>& force; const VectorTypeFor<dimensions, Float>& force;

4
src/Magnum/DebugTools/ObjectRenderer.cpp

@ -29,7 +29,7 @@
#include "Magnum/Mesh.h" #include "Magnum/Mesh.h"
#include "Magnum/DebugTools/ResourceManager.h" #include "Magnum/DebugTools/ResourceManager.h"
#include "Magnum/MeshTools/Interleave.h" #include "Magnum/MeshTools/Interleave.h"
#include "Magnum/SceneGraph/AbstractCamera.h" #include "Magnum/SceneGraph/Camera.h"
#include "Magnum/Shaders/VertexColor.h" #include "Magnum/Shaders/VertexColor.h"
namespace Magnum { namespace DebugTools { namespace Magnum { namespace DebugTools {
@ -178,7 +178,7 @@ template<UnsignedInt dimensions> ObjectRenderer<dimensions>::ObjectRenderer(Scen
/* To avoid deleting pointers to incomplete type on destruction of Resource members */ /* To avoid deleting pointers to incomplete type on destruction of Resource members */
template<UnsignedInt dimensions> ObjectRenderer<dimensions>::~ObjectRenderer() = default; template<UnsignedInt dimensions> ObjectRenderer<dimensions>::~ObjectRenderer() = default;
template<UnsignedInt dimensions> void ObjectRenderer<dimensions>::draw(const MatrixTypeFor<dimensions, Float>& transformationMatrix, SceneGraph::AbstractCamera<dimensions, Float>& camera) { template<UnsignedInt dimensions> void ObjectRenderer<dimensions>::draw(const MatrixTypeFor<dimensions, Float>& transformationMatrix, SceneGraph::Camera<dimensions, Float>& camera) {
shader->setTransformationProjectionMatrix(camera.projectionMatrix()*transformationMatrix*MatrixTypeFor<dimensions, Float>::scaling(VectorTypeFor<dimensions, Float>{options->size()})); shader->setTransformationProjectionMatrix(camera.projectionMatrix()*transformationMatrix*MatrixTypeFor<dimensions, Float>::scaling(VectorTypeFor<dimensions, Float>{options->size()}));
mesh->draw(*shader); mesh->draw(*shader);
} }

2
src/Magnum/DebugTools/ObjectRenderer.h

@ -101,7 +101,7 @@ template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ObjectRenderer:
~ObjectRenderer(); ~ObjectRenderer();
private: private:
void draw(const MatrixTypeFor<dimensions, Float>& transformationMatrix, SceneGraph::AbstractCamera<dimensions, Float>& camera) override; void draw(const MatrixTypeFor<dimensions, Float>& transformationMatrix, SceneGraph::Camera<dimensions, Float>& camera) override;
Resource<ObjectRendererOptions> options; Resource<ObjectRendererOptions> options;
Resource<AbstractShaderProgram, Shaders::VertexColor<dimensions>> shader; Resource<AbstractShaderProgram, Shaders::VertexColor<dimensions>> shader;

4
src/Magnum/DebugTools/ShapeRenderer.cpp

@ -28,7 +28,7 @@
#include "Magnum/DebugTools/ResourceManager.h" #include "Magnum/DebugTools/ResourceManager.h"
#include "Magnum/Shapes/Composition.h" #include "Magnum/Shapes/Composition.h"
#include "Magnum/Shapes/Shape.h" #include "Magnum/Shapes/Shape.h"
#include "Magnum/SceneGraph/AbstractCamera.h" #include "Magnum/SceneGraph/Camera.h"
#include "Implementation/AxisAlignedBoxRenderer.h" #include "Implementation/AxisAlignedBoxRenderer.h"
#include "Implementation/BoxRenderer.h" #include "Implementation/BoxRenderer.h"
@ -122,7 +122,7 @@ template<UnsignedInt dimensions> ShapeRenderer<dimensions>::~ShapeRenderer() {
for(auto i: renderers) delete i; for(auto i: renderers) delete i;
} }
template<UnsignedInt dimensions> void ShapeRenderer<dimensions>::draw(const MatrixTypeFor<dimensions, Float>&, SceneGraph::AbstractCamera<dimensions, Float>& camera) { template<UnsignedInt dimensions> void ShapeRenderer<dimensions>::draw(const MatrixTypeFor<dimensions, Float>&, SceneGraph::Camera<dimensions, Float>& camera) {
const MatrixTypeFor<dimensions, Float> projectionMatrix = camera.projectionMatrix()*camera.cameraMatrix(); const MatrixTypeFor<dimensions, Float> projectionMatrix = camera.projectionMatrix()*camera.cameraMatrix();
for(auto i: renderers) i->draw(options, projectionMatrix); for(auto i: renderers) i->draw(options, projectionMatrix);
} }

2
src/Magnum/DebugTools/ShapeRenderer.h

@ -161,7 +161,7 @@ template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ShapeRenderer: p
~ShapeRenderer(); ~ShapeRenderer();
private: private:
void draw(const MatrixTypeFor<dimensions, Float>& transformationMatrix, SceneGraph::AbstractCamera<dimensions, Float>& camera) override; void draw(const MatrixTypeFor<dimensions, Float>& transformationMatrix, SceneGraph::Camera<dimensions, Float>& camera) override;
Resource<ShapeRendererOptions> options; Resource<ShapeRendererOptions> options;
std::vector<Implementation::AbstractShapeRenderer<dimensions>*> renderers; std::vector<Implementation::AbstractShapeRenderer<dimensions>*> renderers;

4
src/Magnum/Platform/Sdl2Application.h

@ -345,8 +345,8 @@ class Sdl2Application {
* Called when window size changes. The default implementation does * Called when window size changes. The default implementation does
* nothing, if you want to respond to size changes, you should pass the * nothing, if you want to respond to size changes, you should pass the
* new size to @ref DefaultFramebuffer::setViewport() and possibly * new size to @ref DefaultFramebuffer::setViewport() and possibly
* elsewhere (to @ref SceneGraph::AbstractCamera::setViewport() "SceneGraph::Camera*D::setViewport()", * elsewhere (to @ref SceneGraph::Camera::setViewport(), other
* other framebuffers...). * framebuffers...).
* *
* Note that this function might not get called at all if the window * Note that this function might not get called at all if the window
* size doesn't change. You should configure the initial state of your * size doesn't change. You should configure the initial state of your

188
src/Magnum/SceneGraph/AbstractCamera.h

@ -26,180 +26,50 @@
*/ */
/** @file /** @file
* @brief Class @ref Magnum::SceneGraph::AbstractCamera, enum @ref Magnum::SceneGraph::AspectRatioPolicy, alias @ref Magnum::SceneGraph::AbstractBasicCamera2D, @ref Magnum::SceneGraph::AbstractBasicCamera3D, typedef @ref Magnum::SceneGraph::AbstractCamera2D, @ref Magnum::SceneGraph::AbstractCamera3D * @brief Use @ref Magnum/SceneGraph/Camera.h instead.
*/ */
#include "Magnum/Math/Matrix3.h" #include "Magnum/configure.h"
#include "Magnum/Math/Matrix4.h"
#include "Magnum/SceneGraph/AbstractFeature.h"
#include "Magnum/SceneGraph/visibility.h"
namespace Magnum { namespace SceneGraph { #ifdef MAGNUM_BUILD_DEPRECATED
#include "Magnum/SceneGraph/Camera.h"
/** CORRADE_DEPRECATED_FILE("use Magnum/SceneGraph/Camera.h instead")
@brief Camera aspect ratio policy
@see @ref AbstractCamera::setAspectRatioPolicy() namespace Magnum { namespace SceneGraph {
*/
enum class AspectRatioPolicy: UnsignedByte {
NotPreserved, /**< Don't preserve aspect ratio (default) */
Extend, /**< Extend on larger side of view */
Clip /**< Clip on smaller side of view */
};
namespace Implementation {
template<UnsignedInt dimensions, class T> MatrixTypeFor<dimensions, T> aspectRatioFix(AspectRatioPolicy aspectRatioPolicy, const Math::Vector2<T>& projectionScale, const Vector2i& viewport);
}
/** /**
@brief Base for cameras * @copybrief Camera
* @deprecated Use @ref Camera instead.
See Drawable documentation for more information. This class is not directly */
instantiatable, use @ref BasicCamera2D or @ref BasicCamera3D subclasses template<UnsignedInt dimensions, class T> using AbstractCamera CORRADE_DEPRECATED("use Camera instead") = Camera<dimensions, T>;
instead.
@anchor SceneGraph-AbstractCamera-explicit-specializations
## Explicit template specializations
The following specializations are explicitly compiled into @ref SceneGraph
library. For other specializations (e.g. using @ref Magnum::Double "Double"
type) you have to use @ref AbstractCamera.hpp implementation file to avoid
linker errors. See also relevant sections in @ref SceneGraph-Camera2D-explicit-specializations "Camera2D"
and @ref SceneGraph-Camera3D-explicit-specializations "Camera3D" class documentation or
@ref compilation-speedup-hpp for more information.
- @ref AbstractCamera2D
- @ref AbstractCamera3D
@see @ref scenegraph, @ref AbstractBasicCamera2D, @ref AbstractBasicCamera3D,
@ref Drawable, @ref DrawableGroup
*/
template<UnsignedInt dimensions, class T> class AbstractCamera: public AbstractFeature<dimensions, T> {
public:
/** @brief Aspect ratio policy */
AspectRatioPolicy aspectRatioPolicy() const { return _aspectRatioPolicy; }
/**
* @brief Set aspect ratio policy
* @return Reference to self (for method chaining)
*/
AbstractCamera<dimensions, T>& setAspectRatioPolicy(AspectRatioPolicy policy);
/**
* @brief Camera matrix
*
* Camera matrix describes world position relative to the camera and is
* applied after object transformation matrix and before projection
* matrix.
*/
MatrixTypeFor<dimensions, T> cameraMatrix() {
AbstractFeature<dimensions, T>::object().setClean();
return _cameraMatrix;
}
/**
* @brief Projection matrix
*
* Projection matrix handles e.g. perspective distortion and is applied
* as last, after @ref cameraMatrix() and object transformation matrix.
* @see @ref projectionSize()
*/
MatrixTypeFor<dimensions, T> projectionMatrix() const { return _projectionMatrix; }
/**
* @brief Size of (near) XY plane in current projection
*
* Returns size of near XY plane computed from projection matrix.
* @see @ref projectionMatrix()
*/
Math::Vector2<T> projectionSize() const {
return {T(2.0)/_projectionMatrix[0].x(), T(2.0)/_projectionMatrix[1].y()};
}
/** @brief Viewport size */
Vector2i viewport() const { return _viewport; }
/**
* @brief Set viewport size
*
* Stores viewport size internally and recalculates projection matrix
* according to aspect ratio policy.
* @see @ref setAspectRatioPolicy()
*/
virtual void setViewport(const Vector2i& size);
/**
* @brief Draw
*
* Draws given group of drawables.
*/
virtual void draw(DrawableGroup<dimensions, T>& group);
protected:
/**
* @brief Constructor
* @param object Object holding the camera
*/
explicit AbstractCamera(AbstractObject<dimensions, T>& object);
~AbstractCamera();
/** Recalculates camera matrix */
void cleanInverted(const MatrixTypeFor<dimensions, T>& invertedAbsoluteTransformationMatrix) override {
_cameraMatrix = invertedAbsoluteTransformationMatrix;
}
#ifndef DOXYGEN_GENERATING_OUTPUT
void fixAspectRatio();
MatrixTypeFor<dimensions, T> rawProjectionMatrix;
AspectRatioPolicy _aspectRatioPolicy;
#endif
private:
MatrixTypeFor<dimensions, T> _projectionMatrix;
MatrixTypeFor<dimensions, T> _cameraMatrix;
Vector2i _viewport;
};
/** /**
@brief Base camera for two-dimensional scenes * @copybrief BasicCamera2D
* @deprecated Use @ref BasicCamera2D instead.
Convenience alternative to `AbstractCamera<2, T>`. See */
@ref AbstractCamera for more information. template<class T> using AbstractBasicCamera2D CORRADE_DEPRECATED("use BasicCamera2D instead") = BasicCamera2D<T>;
@see @ref AbstractCamera2D, @ref AbstractBasicCamera3D
*/
template<class T> using AbstractBasicCamera2D = AbstractCamera<2, T>;
/** /**
@brief Base camera for two-dimensional float scenes * @copybrief Camera2D
* @deprecated Use @ref Camera2D instead.
@see @ref AbstractCamera3D */
*/ CORRADE_DEPRECATED("use Camera2D instead") typedef Camera2D AbstractCamera2D;
typedef AbstractBasicCamera2D<Float> AbstractCamera2D;
/** /**
@brief Base camera for three-dimensional scenes * @copybrief BasicCamera3D
* @deprecated Use @ref BasicCamera3D instead.
Convenience alternative to `AbstractCamera<3, T>`. See */
@ref AbstractCamera for more information. template<class T> using AbstractBasicCamera3D CORRADE_DEPRECATED("use BasicCamera3D instead") = BasicCamera3D<T>;
@see @ref AbstractCamera3D, @ref AbstractBasicCamera2D
*/
template<class T> using AbstractBasicCamera3D = AbstractCamera<3, T>;
/** /**
@brief Base camera for three-dimensional float scenes * @copybrief Camera3D
* @deprecated Use @ref Camera3D instead.
@see @ref AbstractCamera2D */
*/ CORRADE_DEPRECATED("use Camera3D instead") typedef Camera3D AbstractCamera3D;
typedef AbstractBasicCamera3D<Float> AbstractCamera3D;
#if defined(CORRADE_TARGET_WINDOWS) && !defined(__MINGW32__)
extern template class MAGNUM_SCENEGRAPH_EXPORT AbstractCamera<2, Float>;
extern template class MAGNUM_SCENEGRAPH_EXPORT AbstractCamera<3, Float>;
#endif
}} }}
#else
#error use Magnum/SceneGraph/Camera.h instead
#endif
#endif #endif

76
src/Magnum/SceneGraph/AbstractCamera.hpp

@ -26,76 +26,16 @@
*/ */
/** @file /** @file
* @brief @ref compilation-speedup-hpp "Template implementation" for @ref AbstractCamera.h * @deprecated Use @ref Magnum/SceneGraph/Camera.hpp instead.
*/ */
#include "Magnum/Math/Functions.h" #include "Magnum/configure.h"
#include "Magnum/SceneGraph/AbstractCamera.h"
#include "Magnum/SceneGraph/Drawable.h"
namespace Magnum { namespace SceneGraph { #ifdef MAGNUM_BUILD_DEPRECATED
#include "Magnum/SceneGraph/Camera.hpp"
namespace Implementation { CORRADE_DEPRECATED_FILE("use Magnum/SceneGraph/Camera.hpp instead")
#else
template<UnsignedInt dimensions, class T> MatrixTypeFor<dimensions, T> aspectRatioFix(AspectRatioPolicy aspectRatioPolicy, const Math::Vector2<T>& projectionScale, const Vector2i& viewport) { #error use Magnum/SceneGraph/Camera.hpp instead
/* Don't divide by zero / don't preserve anything */ #endif
if(projectionScale.x() == 0 || projectionScale.y() == 0 || viewport.x() == 0 || viewport.y() == 0 || aspectRatioPolicy == AspectRatioPolicy::NotPreserved)
return {};
CORRADE_INTERNAL_ASSERT((projectionScale > Math::Vector2<T>(0)).all() && (viewport > Vector2i(0)).all());
Math::Vector2<T> relativeAspectRatio = Math::Vector2<T>(viewport)*projectionScale;
/* Extend on larger side = scale larger side down
Clip on smaller side = scale smaller side up */
return MatrixTypeFor<dimensions, T>::scaling(Math::Vector<dimensions, T>::pad(
(relativeAspectRatio.x() > relativeAspectRatio.y()) == (aspectRatioPolicy == AspectRatioPolicy::Extend) ?
Vector2(relativeAspectRatio.y()/relativeAspectRatio.x(), T(1)) :
Vector2(T(1), relativeAspectRatio.x()/relativeAspectRatio.y()), T(1)));
}
}
template<UnsignedInt dimensions, class T> AbstractCamera<dimensions, T>::AbstractCamera(AbstractObject<dimensions, T>& object): AbstractFeature<dimensions, T>(object), _aspectRatioPolicy(AspectRatioPolicy::NotPreserved) {
AbstractFeature<dimensions, T>::setCachedTransformations(CachedTransformation::InvertedAbsolute);
}
template<UnsignedInt dimensions, class T> AbstractCamera<dimensions, T>::~AbstractCamera() = default;
template<UnsignedInt dimensions, class T> void AbstractCamera<dimensions, T>::fixAspectRatio() {
_projectionMatrix = Implementation::aspectRatioFix<dimensions, T>(_aspectRatioPolicy, {Math::abs(rawProjectionMatrix[0].x()), Math::abs(rawProjectionMatrix[1].y())}, _viewport)*rawProjectionMatrix;
}
template<UnsignedInt dimensions, class T> AbstractCamera<dimensions, T>& AbstractCamera<dimensions, T>::setAspectRatioPolicy(AspectRatioPolicy policy) {
_aspectRatioPolicy = policy;
fixAspectRatio();
return *this;
}
template<UnsignedInt dimensions, class T> void AbstractCamera<dimensions, T>::setViewport(const Vector2i& size) {
_viewport = size;
fixAspectRatio();
}
template<UnsignedInt dimensions, class T> void AbstractCamera<dimensions, T>::draw(DrawableGroup<dimensions, T>& group) {
AbstractObject<dimensions, T>* scene = AbstractFeature<dimensions, T>::object().scene();
CORRADE_ASSERT(scene, "Camera::draw(): cannot draw when camera is not part of any scene", );
/* Compute camera matrix */
AbstractFeature<dimensions, T>::object().setClean();
/* Compute transformations of all objects in the group relative to the camera */
std::vector<std::reference_wrapper<AbstractObject<dimensions, T>>> objects;
objects.reserve(group.size());
for(std::size_t i = 0; i != group.size(); ++i)
objects.push_back(group[i].object());
std::vector<MatrixTypeFor<dimensions, T>> transformations =
scene->transformationMatrices(objects, _cameraMatrix);
/* Perform the drawing */
for(std::size_t i = 0; i != transformations.size(); ++i)
group[i].draw(transformations[i], *this);
}
}}
#endif #endif

18
src/Magnum/SceneGraph/CMakeLists.txt

@ -32,8 +32,6 @@ set(MagnumSceneGraph_GracefulAssert_SRCS
instantiation.cpp) instantiation.cpp)
set(MagnumSceneGraph_HEADERS set(MagnumSceneGraph_HEADERS
AbstractCamera.h
AbstractCamera.hpp
AbstractFeature.h AbstractFeature.h
AbstractFeature.hpp AbstractFeature.hpp
AbstractGroupedFeature.h AbstractGroupedFeature.h
@ -47,10 +45,8 @@ set(MagnumSceneGraph_HEADERS
Animable.h Animable.h
Animable.hpp Animable.hpp
AnimableGroup.h AnimableGroup.h
Camera2D.h Camera.h
Camera2D.hpp Camera.hpp
Camera3D.h
Camera3D.hpp
Drawable.h Drawable.h
Drawable.hpp Drawable.hpp
DualComplexTransformation.h DualComplexTransformation.h
@ -69,6 +65,16 @@ set(MagnumSceneGraph_HEADERS
visibility.h) visibility.h)
if(MAGNUM_BUILD_DEPRECATED)
list(APPEND MagnumSceneGraph_HEADERS
AbstractCamera.h
AbstractCamera.hpp
Camera2D.h
Camera2D.hpp
Camera3D.h
Camera3D.hpp)
endif()
# Objects shared between main and test library # Objects shared between main and test library
add_library(MagnumSceneGraphObjects OBJECT add_library(MagnumSceneGraphObjects OBJECT
${MagnumSceneGraph_SRCS} ${MagnumSceneGraph_SRCS}

284
src/Magnum/SceneGraph/Camera.h

@ -0,0 +1,284 @@
#ifndef Magnum_SceneGraph_Camera_h
#define Magnum_SceneGraph_Camera_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
/** @file
* @brief Class @ref Magnum::SceneGraph::Camera, enum @ref Magnum::SceneGraph::AspectRatioPolicy, alias @ref Magnum::SceneGraph::BasicCamera2D, @ref Magnum::SceneGraph::BasicCamera3D, typedef @ref Magnum::SceneGraph::Camera2D, @ref Magnum::SceneGraph::Camera3D
*/
#include "Magnum/Math/Matrix3.h"
#include "Magnum/Math/Matrix4.h"
#include "Magnum/SceneGraph/AbstractFeature.h"
#include "Magnum/SceneGraph/visibility.h"
#ifdef CORRADE_TARGET_WINDOWS /* I so HATE windef.h */
#undef near
#undef far
#endif
namespace Magnum { namespace SceneGraph {
/**
@brief Camera aspect ratio policy
@see @ref Camera::setAspectRatioPolicy()
*/
enum class AspectRatioPolicy: UnsignedByte {
NotPreserved, /**< Don't preserve aspect ratio (default) */
Extend, /**< Extend on larger side of view */
Clip /**< Clip on smaller side of view */
};
namespace Implementation {
template<UnsignedInt dimensions, class T> MatrixTypeFor<dimensions, T> aspectRatioFix(AspectRatioPolicy aspectRatioPolicy, const Math::Vector2<T>& projectionScale, const Vector2i& viewport);
}
/**
@brief Camera
See @ref Drawable documentation for more information. The camera by default
displays OpenGL unit cube `[(-1, -1, -1); (1, 1, 1)]` and doesn't do any aspect
ratio correction.
Common setup example for 2D scenes:
@code
SceneGraph::Camera2D camera{&cameraObject};
camera.setProjectionMatrix(Matrix3::projection({4.0f/3.0f, 1.0f}))
.setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend);
@endcode
Common setup example for 3D scenes:
@code
SceneGraph::Camera3D camera{&cameraObject};
camera.setProjectionMatrix(Matrix3::perspectiveProjection(35.0_degf, 1.0f, 0.001f, 100.0f))
.setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend);
@endcode
@anchor SceneGraph-Camera-explicit-specializations
## Explicit template specializations
The following specializations are explicitly compiled into @ref SceneGraph
library. For other specializations (e.g. using @ref Magnum::Double "Double"
type) you have to use @ref Camera.hpp implementation file to avoid linker
errors. See also @ref compilation-speedup-hpp for more information.
- @ref Camera2D
- @ref Camera3D
@see @ref scenegraph, @ref BasicCamera2D, @ref BasicCamera3D, @ref Camera2D,
@ref Camera3D, @ref Drawable, @ref DrawableGroup
*/
template<UnsignedInt dimensions, class T> class Camera: public AbstractFeature<dimensions, T> {
public:
/**
* @brief Constructor
* @param object Object holding the camera
*
* Sets orthographic projection to the default OpenGL cube (range
* @f$ [-1; 1] @f$ in all directions).
* @see @ref setProjectionMatrix()
*/
explicit Camera(AbstractObject<dimensions, T>& object);
#ifndef MAGNUM_BUILD_DEPRECATED
/* This is here to avoid ambiguity with deleted copy constructor when
passing `*this` from class subclassing both BasicCamera3D and
AbstractObject */
template<class U, class = typename std::enable_if<std::is_base_of<AbstractObject<dimensions, T>, U>::value>::type> Camera(U& object): Camera<dimensions, T>{static_cast<AbstractObject<dimensions, T>&>(object)} {}
#endif
~Camera();
/** @brief Aspect ratio policy */
AspectRatioPolicy aspectRatioPolicy() const { return _aspectRatioPolicy; }
/**
* @brief Set aspect ratio policy
* @return Reference to self (for method chaining)
*
* @attention Aspect ratio correction might not work properly with some
* specific cases of projection matrices. Projection matrices
* generated with @ref Matrix3::projection(),
* @ref Matrix4::orthographicProjection() or
* @ref Matrix4::perspectiveProjection() are known to be working.
*/
Camera<dimensions, T>& setAspectRatioPolicy(AspectRatioPolicy policy);
/**
* @brief Camera matrix
*
* Camera matrix describes world position relative to the camera and is
* applied after object transformation matrix and before projection
* matrix.
*/
MatrixTypeFor<dimensions, T> cameraMatrix() {
AbstractFeature<dimensions, T>::object().setClean();
return _cameraMatrix;
}
/**
* @brief Projection matrix
*
* Projection matrix handles e.g. perspective distortion and is applied
* as last, after @ref cameraMatrix() and object transformation matrix.
* @see @ref projectionSize()
*/
MatrixTypeFor<dimensions, T> projectionMatrix() const { return _projectionMatrix; }
/**
* @brief Set projection matrix
* @return Reference to self (for method chaining)
*
* @see @ref Matrix3::projection(), @ref Matrix4::orthographicProjection(),
* @ref Matrix4::perspectiveProjection()
*/
Camera<dimensions, T>& setProjectionMatrix(const MatrixTypeFor<dimensions, T>& matrix);
#ifdef MAGNUM_BUILD_DEPRECATED
/**
* @brief Set projection
* @deprecated Use @ref setProjectionMatrix() with @ref Matrix3::projection() instead.
*/
template<UnsignedInt d = dimensions, class = typename std::enable_if<d == 2>::type> CORRADE_DEPRECATED("use setProjectionMatrix() with Matrix3::projection() instead") BasicCamera2D<T>& setProjection(const Math::Vector2<T>& size) {
return setProjectionMatrix(Math::Matrix3<T>::projection(size));
}
/**
* @brief Set orthographic projection
* @deprecated Use @ref setProjectionMatrix() with
* @ref Matrix4::orthographicProjection() instead.
*/
template<UnsignedInt d = dimensions, class = typename std::enable_if<d == 3>::type> CORRADE_DEPRECATED("use setProjectionMatrix() with Matrix4::orthographicProjection() instead") BasicCamera3D<T>& setOrthographic(const Math::Vector2<T>& size, T near, T far) {
return setProjectionMatrix(Math::Matrix4<T>::orthographicProjection(size, near, far));
}
/**
* @brief Set perspective projection
* @deprecated Use @ref setProjectionMatrix() with
* @ref Matrix4::perspectiveProjection() instead.
*/
template<UnsignedInt d = dimensions, class = typename std::enable_if<d == 3>::type> CORRADE_DEPRECATED("use setProjectionMatrix() with Matrix4::orthographicProjection() instead") BasicCamera3D<T>& setPerspective(const Math::Vector2<T>& size, T near, T far) {
return setProjectionMatrix(Math::Matrix4<T>::perspectiveProjection(size, near, far));
}
/**
* @brief Set perspective projection
* @deprecated Use @ref setProjectionMatrix() with
* @ref Matrix4::perspectiveProjection() instead.
*/
template<UnsignedInt d = dimensions, class = typename std::enable_if<d == 3>::type> CORRADE_DEPRECATED("use setProjectionMatrix() with Matrix4::orthographicProjection() instead") BasicCamera3D<T>& setPerspective(Math::Rad<T> fov, T aspectRatio, T near, T far) {
return setProjectionMatrix(Math::Matrix4<T>::perspectiveProjection(fov, aspectRatio, near, far));
}
#endif
/**
* @brief Size of (near) XY plane in current projection
*
* Returns size of near XY plane computed from projection matrix.
* @see @ref projectionMatrix()
*/
Math::Vector2<T> projectionSize() const {
return {T(2.0)/_projectionMatrix[0].x(), T(2.0)/_projectionMatrix[1].y()};
}
/** @brief Viewport size */
Vector2i viewport() const { return _viewport; }
/**
* @brief Set viewport size
*
* Stores viewport size internally and recalculates projection matrix
* according to aspect ratio policy.
* @see @ref setAspectRatioPolicy()
*/
virtual void setViewport(const Vector2i& size);
/**
* @brief Draw
*
* Draws given group of drawables.
*/
virtual void draw(DrawableGroup<dimensions, T>& group);
private:
/** Recalculates camera matrix */
void cleanInverted(const MatrixTypeFor<dimensions, T>& invertedAbsoluteTransformationMatrix) override {
_cameraMatrix = invertedAbsoluteTransformationMatrix;
}
#ifndef DOXYGEN_GENERATING_OUTPUT
void fixAspectRatio();
MatrixTypeFor<dimensions, T> _rawProjectionMatrix;
AspectRatioPolicy _aspectRatioPolicy;
#endif
MatrixTypeFor<dimensions, T> _projectionMatrix;
MatrixTypeFor<dimensions, T> _cameraMatrix;
Vector2i _viewport;
};
/**
@brief Camera for two-dimensional scenes
Convenience alternative to `Camera<2, T>`. See @ref Camera for more
information.
@see @ref Camera2D, @ref BasicCamera3D
*/
template<class T> using BasicCamera2D = Camera<2, T>;
/**
@brief Camera for two-dimensional float scenes
@see @ref Camera3D
*/
typedef BasicCamera2D<Float> Camera2D;
/**
@brief Camera for three-dimensional scenes
Convenience alternative to `Camera<3, T>`. See @ref Camera for more
information.
@see @ref Camera3D, @ref BasicCamera2D
*/
template<class T> using BasicCamera3D = Camera<3, T>;
/**
@brief Camera for three-dimensional float scenes
@see @ref Camera2D
*/
typedef BasicCamera3D<Float> Camera3D;
#if defined(CORRADE_TARGET_WINDOWS) && !defined(__MINGW32__)
extern template class MAGNUM_SCENEGRAPH_EXPORT Camera<2, Float>;
extern template class MAGNUM_SCENEGRAPH_EXPORT Camera<3, Float>;
#endif
}}
#endif

107
src/Magnum/SceneGraph/Camera.hpp

@ -0,0 +1,107 @@
#ifndef Magnum_SceneGraph_Camera_hpp
#define Magnum_SceneGraph_Camera_hpp
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
/** @file
* @brief @ref compilation-speedup-hpp "Template implementation" for @ref Camera.h
*/
#include "Magnum/Math/Functions.h"
#include "Magnum/SceneGraph/Camera.h"
#include "Magnum/SceneGraph/Drawable.h"
namespace Magnum { namespace SceneGraph {
namespace Implementation {
template<UnsignedInt dimensions, class T> MatrixTypeFor<dimensions, T> aspectRatioFix(AspectRatioPolicy aspectRatioPolicy, const Math::Vector2<T>& projectionScale, const Vector2i& viewport) {
/* Don't divide by zero / don't preserve anything */
if(projectionScale.x() == 0 || projectionScale.y() == 0 || viewport.x() == 0 || viewport.y() == 0 || aspectRatioPolicy == AspectRatioPolicy::NotPreserved)
return {};
CORRADE_INTERNAL_ASSERT((projectionScale > Math::Vector2<T>(0)).all() && (viewport > Vector2i(0)).all());
Math::Vector2<T> relativeAspectRatio = Math::Vector2<T>(viewport)*projectionScale;
/* Extend on larger side = scale larger side down
Clip on smaller side = scale smaller side up */
return MatrixTypeFor<dimensions, T>::scaling(Math::Vector<dimensions, T>::pad(
(relativeAspectRatio.x() > relativeAspectRatio.y()) == (aspectRatioPolicy == AspectRatioPolicy::Extend) ?
Vector2(relativeAspectRatio.y()/relativeAspectRatio.x(), T(1)) :
Vector2(T(1), relativeAspectRatio.x()/relativeAspectRatio.y()), T(1)));
}
}
template<UnsignedInt dimensions, class T> Camera<dimensions, T>::Camera(AbstractObject<dimensions, T>& object): AbstractFeature<dimensions, T>(object), _aspectRatioPolicy(AspectRatioPolicy::NotPreserved) {
AbstractFeature<dimensions, T>::setCachedTransformations(CachedTransformation::InvertedAbsolute);
}
template<UnsignedInt dimensions, class T> Camera<dimensions, T>::~Camera() = default;
template<UnsignedInt dimensions, class T> void Camera<dimensions, T>::fixAspectRatio() {
_projectionMatrix = Implementation::aspectRatioFix<dimensions, T>(_aspectRatioPolicy, {Math::abs(_rawProjectionMatrix[0].x()), Math::abs(_rawProjectionMatrix[1].y())}, _viewport)*_rawProjectionMatrix;
}
template<UnsignedInt dimensions, class T> Camera<dimensions, T>& Camera<dimensions, T>::setAspectRatioPolicy(AspectRatioPolicy policy) {
_aspectRatioPolicy = policy;
fixAspectRatio();
return *this;
}
template<UnsignedInt dimensions, class T> Camera<dimensions, T>& Camera<dimensions, T>::setProjectionMatrix(const MatrixTypeFor<dimensions, T>& matrix) {
_rawProjectionMatrix = matrix;
fixAspectRatio();
return *this;
}
template<UnsignedInt dimensions, class T> void Camera<dimensions, T>::setViewport(const Vector2i& size) {
_viewport = size;
fixAspectRatio();
}
template<UnsignedInt dimensions, class T> void Camera<dimensions, T>::draw(DrawableGroup<dimensions, T>& group) {
AbstractObject<dimensions, T>* scene = AbstractFeature<dimensions, T>::object().scene();
CORRADE_ASSERT(scene, "Camera::draw(): cannot draw when camera is not part of any scene", );
/* Compute camera matrix */
AbstractFeature<dimensions, T>::object().setClean();
/* Compute transformations of all objects in the group relative to the camera */
std::vector<std::reference_wrapper<AbstractObject<dimensions, T>>> objects;
objects.reserve(group.size());
for(std::size_t i = 0; i != group.size(); ++i)
objects.push_back(group[i].object());
std::vector<MatrixTypeFor<dimensions, T>> transformations =
scene->transformationMatrices(objects, _cameraMatrix);
/* Perform the drawing */
for(std::size_t i = 0; i != transformations.size(); ++i)
group[i].draw(transformations[i], *this);
}
}}
#endif

84
src/Magnum/SceneGraph/Camera2D.h

@ -26,86 +26,16 @@
*/ */
/** @file /** @file
* @brief Class @ref Magnum::SceneGraph::BasicCamera2D, typedef @ref Magnum::SceneGraph::Camera2D * @deprecated Use @ref Magnum/SceneGraph/Camera.h instead.
*/ */
#include "Magnum/SceneGraph/AbstractCamera.h" #include "Magnum/configure.h"
namespace Magnum { namespace SceneGraph { #ifdef MAGNUM_BUILD_DEPRECATED
#include "Magnum/SceneGraph/Camera.h"
/** CORRADE_DEPRECATED_FILE("use Magnum/SceneGraph/Camera.h instead")
@brief Camera for two-dimensional scenes #else
#error use Magnum/SceneGraph/Camera.h instead
See @ref Drawable documentation for complete introduction. The camera by
default displays OpenGL unit cube `[(-1, -1, -1); (1, 1, 1)]` and doesn't do
any aspect ratio correction. Common setup example:
@code
SceneGraph::Camera2D camera{&cameraObject};
camera.setProjection({4.0f/3.0f, 1.0f})
.setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend);
@endcode
@anchor SceneGraph-Camera2D-explicit-specializations
## Explicit template specializations
The following specialization is explicitly compiled into @ref SceneGraph
library. For other specializations (e.g. using @ref Magnum::Double "Double"
type) you have to use @ref Camera2D.hpp implementation file to avoid linker
errors. See also relevant section in @ref SceneGraph-AbstractCamera-explicit-specializations "AbstractCamera"
class documentation or @ref compilation-speedup-hpp for more information.
- @ref Camera2D
@see @ref scenegraph, @ref Camera2D, @ref BasicCamera3D, @ref Drawable,
@ref DrawableGroup
*/
template<class T> class BasicCamera2D: public AbstractBasicCamera2D<T> {
public:
/**
* @brief Constructor
* @param object Object holding this feature
*
* Sets orthographic projection to the default OpenGL cube (range @f$ [-1; 1] @f$ in all directions).
* @see @ref setProjection()
*/
explicit BasicCamera2D(AbstractBasicObject2D<T>& object);
#ifndef DOXYGEN_GENERATING_OUTPUT
/* This is here to avoid ambiguity with deleted copy constructor when
passing `*this` from class subclassing both BasicCamera2D and
AbstractObject */
template<class U, class = typename std::enable_if<std::is_base_of<AbstractBasicObject2D<T>, U>::value>::type> BasicCamera2D(U& object): BasicCamera2D(static_cast<AbstractBasicObject2D<T>&>(object)) {}
#endif
/**
* @brief Set projection
* @param size Size of the view
* @return Reference to self (for method chaining)
*
* @see @ref Matrix3::projection()
*/
BasicCamera2D<T>& setProjection(const Math::Vector2<T>& size);
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
BasicCamera2D<T>& setAspectRatioPolicy(AspectRatioPolicy policy) {
AbstractBasicCamera2D<T>::setAspectRatioPolicy(policy);
return *this;
}
#endif
};
/**
@brief Camera for two-dimensional float scenes
@see @ref Camera3D
*/
typedef BasicCamera2D<Float> Camera2D;
#if defined(CORRADE_TARGET_WINDOWS) && !defined(__MINGW32__)
extern template class MAGNUM_SCENEGRAPH_EXPORT BasicCamera2D<Float>;
#endif #endif
}}
#endif #endif

23
src/Magnum/SceneGraph/Camera2D.hpp

@ -26,23 +26,16 @@
*/ */
/** @file /** @file
* @brief @ref compilation-speedup-hpp "Template implementation" for @ref Camera2D.h * @deprecated Use @ref Magnum/SceneGraph/Camera.hpp instead.
*/ */
#include "Magnum/SceneGraph/AbstractCamera.hpp" #include "Magnum/configure.h"
#include "Magnum/SceneGraph/Camera2D.h"
namespace Magnum { namespace SceneGraph { #ifdef MAGNUM_BUILD_DEPRECATED
#include "Magnum/SceneGraph/Camera.hpp"
template<class T> BasicCamera2D<T>::BasicCamera2D(AbstractBasicObject2D<T>& object): AbstractBasicCamera2D<T>(object) {} CORRADE_DEPRECATED_FILE("use Magnum/SceneGraph/Camera.hpp instead")
#else
template<class T> BasicCamera2D<T>& BasicCamera2D<T>::setProjection(const Math::Vector2<T>& size) { #error use Magnum/SceneGraph/Camera.hpp instead
AbstractBasicCamera2D<T>::rawProjectionMatrix = Math::Matrix3<T>::projection(size); #endif
AbstractBasicCamera2D<T>::fixAspectRatio();
return *this;
}
}}
#endif #endif

120
src/Magnum/SceneGraph/Camera3D.h

@ -26,122 +26,16 @@
*/ */
/** @file /** @file
* @brief Class @ref Magnum::SceneGraph::BasicCamera3D, typedef @ref Magnum::SceneGraph::Camera3D * @deprecated Use @ref Magnum/SceneGraph/Camera.h instead.
*/ */
#include "Magnum/SceneGraph/AbstractCamera.h" #include "Magnum/configure.h"
#ifdef CORRADE_TARGET_WINDOWS /* I so HATE windef.h */ #ifdef MAGNUM_BUILD_DEPRECATED
#undef near #include "Magnum/SceneGraph/Camera.h"
#undef far CORRADE_DEPRECATED_FILE("use Magnum/SceneGraph/Camera.h instead")
#else
#error use Magnum/SceneGraph/Camera.h instead
#endif #endif
namespace Magnum { namespace SceneGraph {
/**
@brief Camera for three-dimensional scenes
See @ref Drawable documentation for complete introduction. The camera by
default displays OpenGL unit cube `[(-1, -1, -1); (1, 1, 1)]` with orthographic
projection and doesn't do any aspect ratio correction. Common setup example:
@code
SceneGraph::Camera3D camera{&cameraObject};
camera.setPerspective(35.0_degf, 1.0f, 0.001f, 100.0f)
.setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend);
@endcode
@anchor SceneGraph-Camera3D-explicit-specializations
## Explicit template specializations
The following specialization is explicitly compiled into @ref SceneGraph
library. For other specializations (e.g. using @ref Magnum::Double "Double"
type) you have to use @ref Camera3D.hpp implementation file to avoid linker
errors. See also relevant section in @ref SceneGraph-AbstractCamera-explicit-specializations "AbstractCamera"
class documentation or @ref compilation-speedup-hpp for more information.
- @ref Camera3D
@see @ref scenegraph, @ref Camera3D, @ref BasicCamera2D, @ref Drawable,
@ref DrawableGroup
*/
template<class T> class BasicCamera3D: public AbstractBasicCamera3D<T> {
public:
/**
* @brief Constructor
* @param object Object holding this feature
*/
explicit BasicCamera3D(AbstractBasicObject3D<T>& object);
#ifndef DOXYGEN_GENERATING_OUTPUT
/* This is here to avoid ambiguity with deleted copy constructor when
passing `*this` from class subclassing both BasicCamera3D and
AbstractObject */
template<class U, class = typename std::enable_if<std::is_base_of<AbstractBasicObject3D<T>, U>::value>::type> BasicCamera3D(U& object): BasicCamera3D(static_cast<AbstractBasicObject3D<T>&>(object)) {}
#endif
/**
* @brief Set orthographic projection
* @param size Size of the view
* @param near Near clipping plane
* @param far Far clipping plane
* @return Reference to self (for method chaining)
*
* @see @ref setPerspective(), @ref Matrix4::orthographicProjection()
*/
BasicCamera3D<T>& setOrthographic(const Math::Vector2<T>& size, T near, T far);
/**
* @brief Set perspective projection
* @param size Size of near clipping plane
* @param near Near clipping plane
* @param far Far clipping plane
* @return Reference to self (for method chaining)
*
* @see @ref setOrthographic(), @ref Matrix4::perspectiveProjection()
*/
BasicCamera3D<T>& setPerspective(const Math::Vector2<T>& size, T near, T far);
/**
* @brief Set perspective projection
* @param fov Field of view angle (horizontal)
* @param aspectRatio Aspect ratio
* @param near Near clipping plane
* @param far Far clipping plane
* @return Reference to self (for method chaining)
*
* @see @ref setOrthographic(), @ref Matrix4::perspectiveProjection()
*/
BasicCamera3D<T>& setPerspective(Math::Rad<T> fov, T aspectRatio, T near, T far);
/** @brief Near clipping plane */
T near() const { return _near; }
/** @brief Far clipping plane */
T far() const { return _far; }
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
BasicCamera3D<T>& setAspectRatioPolicy(AspectRatioPolicy policy) {
AbstractBasicCamera3D<T>::setAspectRatioPolicy(policy);
return *this;
}
#endif
private:
T _near, _far;
};
/**
@brief Camera for three-dimensional float scenes
@see @ref Camera2D
*/
typedef BasicCamera3D<Float> Camera3D;
#if defined(CORRADE_TARGET_WINDOWS) && !defined(__MINGW32__)
extern template class MAGNUM_SCENEGRAPH_EXPORT BasicCamera3D<Float>;
#endif
}}
#endif #endif

46
src/Magnum/SceneGraph/Camera3D.hpp

@ -26,46 +26,16 @@
*/ */
/** @file /** @file
* @brief @ref compilation-speedup-hpp "Template implementation" for @ref Camera3D.h * @deprecated Use @ref Magnum/SceneGraph/Camera.hpp instead.
*/ */
#include "Magnum/SceneGraph/AbstractCamera.hpp" #include "Magnum/configure.h"
#include "Magnum/SceneGraph/Camera3D.h"
namespace Magnum { namespace SceneGraph { #ifdef MAGNUM_BUILD_DEPRECATED
#include "Magnum/SceneGraph/Camera.hpp"
template<class T> BasicCamera3D<T>::BasicCamera3D(AbstractBasicObject3D<T>& object): AbstractBasicCamera3D<T>(object), _near(T(0)), _far(T(0)) {} CORRADE_DEPRECATED_FILE("use Magnum/SceneGraph/Camera.hpp instead")
#else
template<class T> BasicCamera3D<T>& BasicCamera3D<T>::setOrthographic(const Math::Vector2<T>& size, T near, T far) { #error use Magnum/SceneGraph/Camera.hpp instead
/** @todo Get near/far from the matrix */ #endif
_near = near;
_far = far;
AbstractBasicCamera3D<T>::rawProjectionMatrix = Math::Matrix4<T>::orthographicProjection(size, near, far);
AbstractBasicCamera3D<T>::fixAspectRatio();
return *this;
}
template<class T> BasicCamera3D<T>& BasicCamera3D<T>::setPerspective(const Math::Vector2<T>& size, T near, T far) {
/** @todo Get near/far from the matrix */
_near = near;
_far = far;
AbstractBasicCamera3D<T>::rawProjectionMatrix = Math::Matrix4<T>::perspectiveProjection(size, near, far);
AbstractBasicCamera3D<T>::fixAspectRatio();
return *this;
}
template<class T> BasicCamera3D<T>& BasicCamera3D<T>::setPerspective(Math::Rad<T> fov, T aspectRatio, T near, T far) {
/** @todo Get near/far from the matrix */
_near = near;
_far = far;
AbstractBasicCamera3D<T>::rawProjectionMatrix = Math::Matrix4<T>::perspectiveProjection(fov, aspectRatio, near, far);
AbstractBasicCamera3D<T>::fixAspectRatio();
return *this;
}
}}
#endif #endif

10
src/Magnum/SceneGraph/Drawable.h

@ -38,7 +38,7 @@ namespace Magnum { namespace SceneGraph {
Adds drawing functionality to the object. Each Drawable is part of some Adds drawing functionality to the object. Each Drawable is part of some
@ref DrawableGroup and the whole group can be drawn with particular camera @ref DrawableGroup and the whole group can be drawn with particular camera
using @ref AbstractCamera::draw(). using @ref Camera::draw().
## Usage ## Usage
@ -57,7 +57,7 @@ class RedCube: public Object3D, public SceneGraph::Drawable3D {
} }
private: private:
void draw(const Matrix4& transformationMatrix, AbstractCamera3D& camera) override { void draw(const Matrix4& transformationMatrix, Camera3D& camera) override {
_shader.setDiffuseColor(Color3::fromHSV(216.0_degf, 0.85f, 1.0f)) _shader.setDiffuseColor(Color3::fromHSV(216.0_degf, 0.85f, 1.0f))
.setLightPosition(camera.cameraMatrix().transformPoint({5.0f, 5.0f, 7.0f})) .setLightPosition(camera.cameraMatrix().transformPoint({5.0f, 5.0f, 7.0f}))
.setTransformationMatrix(transformationMatrix) .setTransformationMatrix(transformationMatrix)
@ -110,7 +110,7 @@ information.
auto cameraObject = new Object3D(&scene); auto cameraObject = new Object3D(&scene);
cameraObject->translate(Vector3::zAxis(5.0f)); cameraObject->translate(Vector3::zAxis(5.0f));
auto camera = new SceneGraph::Camera3D(&cameraObject); auto camera = new SceneGraph::Camera3D(&cameraObject);
camera->setPerspective(35.0_degf, 1.0f, 0.001f, 100.0f); camera->setProjectionMatrix(Matrix4::perspectiveProjection(35.0_degf, 1.0f, 0.001f, 100.0f));
// ... // ...
@ -200,9 +200,9 @@ template<UnsignedInt dimensions, class T> class Drawable: public AbstractGrouped
* @param camera Camera * @param camera Camera
* *
* Projection matrix can be retrieved from * Projection matrix can be retrieved from
* @ref SceneGraph::AbstractCamera::projectionMatrix() "AbstractCamera::projectionMatrix()". * @ref SceneGraph::Camera::projectionMatrix() "Camera::projectionMatrix()".
*/ */
virtual void draw(const MatrixTypeFor<dimensions, T>& transformationMatrix, AbstractCamera<dimensions, T>& camera) = 0; virtual void draw(const MatrixTypeFor<dimensions, T>& transformationMatrix, Camera<dimensions, T>& camera) = 0;
}; };
/** /**

23
src/Magnum/SceneGraph/SceneGraph.h

@ -31,17 +31,15 @@
#include "Magnum/Types.h" #include "Magnum/Types.h"
#ifdef MAGNUM_BUILD_DEPRECATED
#include <Corrade/Utility/Macros.h>
#endif
namespace Magnum { namespace SceneGraph { namespace Magnum { namespace SceneGraph {
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
enum class AspectRatioPolicy: UnsignedByte; enum class AspectRatioPolicy: UnsignedByte;
template<UnsignedInt, class> class AbstractCamera;
template<class T> using AbstractBasicCamera2D = AbstractCamera<2, T>;
template<class T> using AbstractBasicCamera3D = AbstractCamera<3, T>;
typedef AbstractBasicCamera2D<Float> AbstractCamera2D;
typedef AbstractBasicCamera3D<Float> AbstractCamera3D;
/* Enum CachedTransformation and CachedTransformations used only directly */ /* Enum CachedTransformation and CachedTransformations used only directly */
template<UnsignedInt, class> class AbstractFeature; template<UnsignedInt, class> class AbstractFeature;
@ -100,11 +98,20 @@ template<class T> using BasicAnimableGroup3D = AnimableGroup<3, T>;
typedef BasicAnimableGroup2D<Float> AnimableGroup2D; typedef BasicAnimableGroup2D<Float> AnimableGroup2D;
typedef BasicAnimableGroup3D<Float> AnimableGroup3D; typedef BasicAnimableGroup3D<Float> AnimableGroup3D;
template<class> class BasicCamera2D; template<UnsignedInt, class> class Camera;
template<class> class BasicCamera3D; template<class T> using BasicCamera2D = Camera<2, T>;
template<class T> using BasicCamera3D = Camera<3, T>;
typedef BasicCamera2D<Float> Camera2D; typedef BasicCamera2D<Float> Camera2D;
typedef BasicCamera3D<Float> Camera3D; typedef BasicCamera3D<Float> Camera3D;
#ifdef MAGNUM_BUILD_DEPRECATED
template<UnsignedInt dimensions, class T> using AbstractCamera CORRADE_DEPRECATED("use BasicCamera2D instead") = Camera<dimensions, T>;
template<class T> using AbstractBasicCamera2D CORRADE_DEPRECATED("use BasicCamera2D instead") = BasicCamera2D<T>;
CORRADE_DEPRECATED("use Camera2D instead") typedef Camera2D AbstractCamera2D;
template<class T> using AbstractBasicCamera3D CORRADE_DEPRECATED("use BasicCamera3D instead") = BasicCamera3D<T>;
CORRADE_DEPRECATED("use Camera3D instead") typedef Camera3D AbstractCamera3D;
#endif
template<UnsignedInt, class> class Drawable; template<UnsignedInt, class> class Drawable;
template<class T> using BasicDrawable2D = Drawable<2, T>; template<class T> using BasicDrawable2D = Drawable<2, T>;
template<class T> using BasicDrawable3D = Drawable<3, T>; template<class T> using BasicDrawable3D = Drawable<3, T>;

15
src/Magnum/SceneGraph/Test/CameraTest.cpp

@ -25,9 +25,8 @@
#include <Corrade/TestSuite/Tester.h> #include <Corrade/TestSuite/Tester.h>
#include "Magnum/SceneGraph/AbstractCamera.hpp" /* only for aspectRatioFix(), so it doesn't have to be exported */ #include "Magnum/SceneGraph/Camera.hpp" /* only for aspectRatioFix(), so it doesn't have to be exported */
#include "Magnum/SceneGraph/Camera2D.h" #include "Magnum/SceneGraph/Camera.h"
#include "Magnum/SceneGraph/Camera3D.h"
#include "Magnum/SceneGraph/Drawable.h" #include "Magnum/SceneGraph/Drawable.h"
#include "Magnum/SceneGraph/MatrixTransformation2D.h" #include "Magnum/SceneGraph/MatrixTransformation2D.h"
#include "Magnum/SceneGraph/MatrixTransformation3D.h" #include "Magnum/SceneGraph/MatrixTransformation3D.h"
@ -124,7 +123,7 @@ void CameraTest::defaultProjection3D() {
void CameraTest::projectionCorrectedInvertedY() { void CameraTest::projectionCorrectedInvertedY() {
Object2D o; Object2D o;
Camera2D camera(o); Camera2D camera(o);
camera.setProjection({4.0f, -2.0f}) camera.setProjectionMatrix(Matrix3::projection({4.0f, -2.0f}))
.setAspectRatioPolicy(AspectRatioPolicy::Extend) .setAspectRatioPolicy(AspectRatioPolicy::Extend)
.setViewport({4, 4}); .setViewport({4, 4});
@ -139,7 +138,7 @@ void CameraTest::projectionSize2D() {
Vector2 projectionSize(4.0f, 3.0f); Vector2 projectionSize(4.0f, 3.0f);
Object2D o; Object2D o;
Camera2D camera(o); Camera2D camera(o);
camera.setProjection(projectionSize); camera.setProjectionMatrix(Matrix3::projection(projectionSize));
CORRADE_COMPARE(camera.projectionSize(), projectionSize); CORRADE_COMPARE(camera.projectionSize(), projectionSize);
} }
@ -147,14 +146,14 @@ void CameraTest::projectionSizeOrthographic() {
Vector2 projectionSizeRectangle(5.0f, 4.0f); Vector2 projectionSizeRectangle(5.0f, 4.0f);
Object3D o; Object3D o;
Camera3D camera(o); Camera3D camera(o);
camera.setOrthographic(projectionSizeRectangle, 1, 9); camera.setProjectionMatrix(Matrix4::orthographicProjection(projectionSizeRectangle, 1, 9));
CORRADE_COMPARE(camera.projectionSize(), projectionSizeRectangle); CORRADE_COMPARE(camera.projectionSize(), projectionSizeRectangle);
} }
void CameraTest::projectionSizePerspective() { void CameraTest::projectionSizePerspective() {
Object3D o; Object3D o;
Camera3D camera(o); Camera3D camera(o);
camera.setPerspective(Deg(27.0f), 2.35f, 32.0f, 100); camera.setProjectionMatrix(Matrix4::perspectiveProjection(Deg(27.0f), 2.35f, 32.0f, 100));
CORRADE_COMPARE(camera.projectionSize(), Vector2(0.48015756f, 0.204322f)); CORRADE_COMPARE(camera.projectionSize(), Vector2(0.48015756f, 0.204322f));
} }
@ -177,7 +176,7 @@ void CameraTest::draw() {
Drawable(AbstractObject3D& object, DrawableGroup3D* group, Matrix4& result): SceneGraph::Drawable3D(object, group), result(result) {} Drawable(AbstractObject3D& object, DrawableGroup3D* group, Matrix4& result): SceneGraph::Drawable3D(object, group), result(result) {}
protected: protected:
void draw(const Matrix4& transformationMatrix, AbstractCamera3D&) override { void draw(const Matrix4& transformationMatrix, Camera3D&) override {
result = transformationMatrix; result = transformationMatrix;
} }

9
src/Magnum/SceneGraph/instantiation.cpp

@ -25,8 +25,7 @@
#include "Magnum/SceneGraph/AbstractFeature.hpp" #include "Magnum/SceneGraph/AbstractFeature.hpp"
#include "Magnum/SceneGraph/Animable.hpp" #include "Magnum/SceneGraph/Animable.hpp"
#include "Magnum/SceneGraph/Camera2D.hpp" #include "Magnum/SceneGraph/Camera.hpp"
#include "Magnum/SceneGraph/Camera3D.hpp"
#include "Magnum/SceneGraph/Drawable.hpp" #include "Magnum/SceneGraph/Drawable.hpp"
#include "Magnum/SceneGraph/DualComplexTransformation.h" #include "Magnum/SceneGraph/DualComplexTransformation.h"
#include "Magnum/SceneGraph/DualQuaternionTransformation.h" #include "Magnum/SceneGraph/DualQuaternionTransformation.h"
@ -64,10 +63,8 @@ template class MAGNUM_SCENEGRAPH_EXPORT_HPP Animable<3, Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP AnimableGroup<2, Float>; template class MAGNUM_SCENEGRAPH_EXPORT_HPP AnimableGroup<2, Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP AnimableGroup<3, Float>; template class MAGNUM_SCENEGRAPH_EXPORT_HPP AnimableGroup<3, Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP AbstractCamera<2, Float>; template class MAGNUM_SCENEGRAPH_EXPORT_HPP Camera<2, Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP AbstractCamera<3, Float>; template class MAGNUM_SCENEGRAPH_EXPORT_HPP Camera<3, Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP BasicCamera2D<Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP BasicCamera3D<Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP Drawable<2, Float>; template class MAGNUM_SCENEGRAPH_EXPORT_HPP Drawable<2, Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP Drawable<3, Float>; template class MAGNUM_SCENEGRAPH_EXPORT_HPP Drawable<3, Float>;

Loading…
Cancel
Save