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/Mesh.h"
#include "Magnum/DebugTools/ResourceManager.h"
#include "Magnum/SceneGraph/AbstractCamera.h"
#include "Magnum/SceneGraph/Camera.h"
#include "Magnum/Shaders/Flat.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 */
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()}))
.setColor(options->color());
mesh->draw(*shader);

2
src/Magnum/DebugTools/ForceRenderer.h

@ -129,7 +129,7 @@ template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ForceRenderer: p
~ForceRenderer();
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>& force;

4
src/Magnum/DebugTools/ObjectRenderer.cpp

@ -29,7 +29,7 @@
#include "Magnum/Mesh.h"
#include "Magnum/DebugTools/ResourceManager.h"
#include "Magnum/MeshTools/Interleave.h"
#include "Magnum/SceneGraph/AbstractCamera.h"
#include "Magnum/SceneGraph/Camera.h"
#include "Magnum/Shaders/VertexColor.h"
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 */
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()}));
mesh->draw(*shader);
}

2
src/Magnum/DebugTools/ObjectRenderer.h

@ -101,7 +101,7 @@ template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ObjectRenderer:
~ObjectRenderer();
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<AbstractShaderProgram, Shaders::VertexColor<dimensions>> shader;

4
src/Magnum/DebugTools/ShapeRenderer.cpp

@ -28,7 +28,7 @@
#include "Magnum/DebugTools/ResourceManager.h"
#include "Magnum/Shapes/Composition.h"
#include "Magnum/Shapes/Shape.h"
#include "Magnum/SceneGraph/AbstractCamera.h"
#include "Magnum/SceneGraph/Camera.h"
#include "Implementation/AxisAlignedBoxRenderer.h"
#include "Implementation/BoxRenderer.h"
@ -122,7 +122,7 @@ template<UnsignedInt dimensions> ShapeRenderer<dimensions>::~ShapeRenderer() {
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();
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();
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;
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
* nothing, if you want to respond to size changes, you should pass the
* new size to @ref DefaultFramebuffer::setViewport() and possibly
* elsewhere (to @ref SceneGraph::AbstractCamera::setViewport() "SceneGraph::Camera*D::setViewport()",
* other framebuffers...).
* elsewhere (to @ref SceneGraph::Camera::setViewport(), other
* framebuffers...).
*
* 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

188
src/Magnum/SceneGraph/AbstractCamera.h

@ -26,180 +26,50 @@
*/
/** @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/Math/Matrix4.h"
#include "Magnum/SceneGraph/AbstractFeature.h"
#include "Magnum/SceneGraph/visibility.h"
#include "Magnum/configure.h"
namespace Magnum { namespace SceneGraph {
/**
@brief Camera aspect ratio policy
#ifdef MAGNUM_BUILD_DEPRECATED
#include "Magnum/SceneGraph/Camera.h"
CORRADE_DEPRECATED_FILE("use Magnum/SceneGraph/Camera.h instead")
@see @ref AbstractCamera::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);
}
namespace Magnum { namespace SceneGraph {
/**
@brief Base for cameras
See Drawable documentation for more information. This class is not directly
instantiatable, use @ref BasicCamera2D or @ref BasicCamera3D subclasses
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;
};
* @copybrief Camera
* @deprecated Use @ref Camera instead.
*/
template<UnsignedInt dimensions, class T> using AbstractCamera CORRADE_DEPRECATED("use Camera instead") = Camera<dimensions, T>;
/**
@brief Base camera for two-dimensional scenes
Convenience alternative to `AbstractCamera<2, T>`. See
@ref AbstractCamera for more information.
@see @ref AbstractCamera2D, @ref AbstractBasicCamera3D
*/
template<class T> using AbstractBasicCamera2D = AbstractCamera<2, T>;
* @copybrief BasicCamera2D
* @deprecated Use @ref BasicCamera2D instead.
*/
template<class T> using AbstractBasicCamera2D CORRADE_DEPRECATED("use BasicCamera2D instead") = BasicCamera2D<T>;
/**
@brief Base camera for two-dimensional float scenes
@see @ref AbstractCamera3D
*/
typedef AbstractBasicCamera2D<Float> AbstractCamera2D;
* @copybrief Camera2D
* @deprecated Use @ref Camera2D instead.
*/
CORRADE_DEPRECATED("use Camera2D instead") typedef Camera2D AbstractCamera2D;
/**
@brief Base camera for three-dimensional scenes
Convenience alternative to `AbstractCamera<3, T>`. See
@ref AbstractCamera for more information.
@see @ref AbstractCamera3D, @ref AbstractBasicCamera2D
*/
template<class T> using AbstractBasicCamera3D = AbstractCamera<3, T>;
* @copybrief BasicCamera3D
* @deprecated Use @ref BasicCamera3D instead.
*/
template<class T> using AbstractBasicCamera3D CORRADE_DEPRECATED("use BasicCamera3D instead") = BasicCamera3D<T>;
/**
@brief Base camera for three-dimensional float scenes
@see @ref AbstractCamera2D
*/
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
* @copybrief Camera3D
* @deprecated Use @ref Camera3D instead.
*/
CORRADE_DEPRECATED("use Camera3D instead") typedef Camera3D AbstractCamera3D;
}}
#else
#error use Magnum/SceneGraph/Camera.h instead
#endif
#endif

76
src/Magnum/SceneGraph/AbstractCamera.hpp

@ -26,76 +26,16 @@
*/
/** @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/SceneGraph/AbstractCamera.h"
#include "Magnum/SceneGraph/Drawable.h"
#include "Magnum/configure.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> 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);
}
}}
#ifdef MAGNUM_BUILD_DEPRECATED
#include "Magnum/SceneGraph/Camera.hpp"
CORRADE_DEPRECATED_FILE("use Magnum/SceneGraph/Camera.hpp instead")
#else
#error use Magnum/SceneGraph/Camera.hpp instead
#endif
#endif

18
src/Magnum/SceneGraph/CMakeLists.txt

@ -32,8 +32,6 @@ set(MagnumSceneGraph_GracefulAssert_SRCS
instantiation.cpp)
set(MagnumSceneGraph_HEADERS
AbstractCamera.h
AbstractCamera.hpp
AbstractFeature.h
AbstractFeature.hpp
AbstractGroupedFeature.h
@ -47,10 +45,8 @@ set(MagnumSceneGraph_HEADERS
Animable.h
Animable.hpp
AnimableGroup.h
Camera2D.h
Camera2D.hpp
Camera3D.h
Camera3D.hpp
Camera.h
Camera.hpp
Drawable.h
Drawable.hpp
DualComplexTransformation.h
@ -69,6 +65,16 @@ set(MagnumSceneGraph_HEADERS
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
add_library(MagnumSceneGraphObjects OBJECT
${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
* @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 {
/**
@brief Camera for two-dimensional scenes
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>;
#ifdef MAGNUM_BUILD_DEPRECATED
#include "Magnum/SceneGraph/Camera.h"
CORRADE_DEPRECATED_FILE("use Magnum/SceneGraph/Camera.h instead")
#else
#error use Magnum/SceneGraph/Camera.h instead
#endif
}}
#endif

23
src/Magnum/SceneGraph/Camera2D.hpp

@ -26,23 +26,16 @@
*/
/** @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/SceneGraph/Camera2D.h"
#include "Magnum/configure.h"
namespace Magnum { namespace SceneGraph {
template<class T> BasicCamera2D<T>::BasicCamera2D(AbstractBasicObject2D<T>& object): AbstractBasicCamera2D<T>(object) {}
template<class T> BasicCamera2D<T>& BasicCamera2D<T>::setProjection(const Math::Vector2<T>& size) {
AbstractBasicCamera2D<T>::rawProjectionMatrix = Math::Matrix3<T>::projection(size);
AbstractBasicCamera2D<T>::fixAspectRatio();
return *this;
}
}}
#ifdef MAGNUM_BUILD_DEPRECATED
#include "Magnum/SceneGraph/Camera.hpp"
CORRADE_DEPRECATED_FILE("use Magnum/SceneGraph/Camera.hpp instead")
#else
#error use Magnum/SceneGraph/Camera.hpp instead
#endif
#endif

120
src/Magnum/SceneGraph/Camera3D.h

@ -26,122 +26,16 @@
*/
/** @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 */
#undef near
#undef far
#ifdef MAGNUM_BUILD_DEPRECATED
#include "Magnum/SceneGraph/Camera.h"
CORRADE_DEPRECATED_FILE("use Magnum/SceneGraph/Camera.h instead")
#else
#error use Magnum/SceneGraph/Camera.h instead
#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

46
src/Magnum/SceneGraph/Camera3D.hpp

@ -26,46 +26,16 @@
*/
/** @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/SceneGraph/Camera3D.h"
#include "Magnum/configure.h"
namespace Magnum { namespace SceneGraph {
template<class T> BasicCamera3D<T>::BasicCamera3D(AbstractBasicObject3D<T>& object): AbstractBasicCamera3D<T>(object), _near(T(0)), _far(T(0)) {}
template<class T> BasicCamera3D<T>& BasicCamera3D<T>::setOrthographic(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>::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;
}
}}
#ifdef MAGNUM_BUILD_DEPRECATED
#include "Magnum/SceneGraph/Camera.hpp"
CORRADE_DEPRECATED_FILE("use Magnum/SceneGraph/Camera.hpp instead")
#else
#error use Magnum/SceneGraph/Camera.hpp instead
#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
@ref DrawableGroup and the whole group can be drawn with particular camera
using @ref AbstractCamera::draw().
using @ref Camera::draw().
## Usage
@ -57,7 +57,7 @@ class RedCube: public Object3D, public SceneGraph::Drawable3D {
}
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))
.setLightPosition(camera.cameraMatrix().transformPoint({5.0f, 5.0f, 7.0f}))
.setTransformationMatrix(transformationMatrix)
@ -110,7 +110,7 @@ information.
auto cameraObject = new Object3D(&scene);
cameraObject->translate(Vector3::zAxis(5.0f));
auto camera = new SceneGraph::Camera3D(&cameraObject);
camera->setPerspective(35.0_degf, 1.0f, 0.001f, 100.0f);
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
*
* 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"
#ifdef MAGNUM_BUILD_DEPRECATED
#include <Corrade/Utility/Macros.h>
#endif
namespace Magnum { namespace SceneGraph {
#ifndef DOXYGEN_GENERATING_OUTPUT
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 */
template<UnsignedInt, class> class AbstractFeature;
@ -100,11 +98,20 @@ template<class T> using BasicAnimableGroup3D = AnimableGroup<3, T>;
typedef BasicAnimableGroup2D<Float> AnimableGroup2D;
typedef BasicAnimableGroup3D<Float> AnimableGroup3D;
template<class> class BasicCamera2D;
template<class> class BasicCamera3D;
template<UnsignedInt, class> class Camera;
template<class T> using BasicCamera2D = Camera<2, T>;
template<class T> using BasicCamera3D = Camera<3, T>;
typedef BasicCamera2D<Float> Camera2D;
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<class T> using BasicDrawable2D = Drawable<2, 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 "Magnum/SceneGraph/AbstractCamera.hpp" /* only for aspectRatioFix(), so it doesn't have to be exported */
#include "Magnum/SceneGraph/Camera2D.h"
#include "Magnum/SceneGraph/Camera3D.h"
#include "Magnum/SceneGraph/Camera.hpp" /* only for aspectRatioFix(), so it doesn't have to be exported */
#include "Magnum/SceneGraph/Camera.h"
#include "Magnum/SceneGraph/Drawable.h"
#include "Magnum/SceneGraph/MatrixTransformation2D.h"
#include "Magnum/SceneGraph/MatrixTransformation3D.h"
@ -124,7 +123,7 @@ void CameraTest::defaultProjection3D() {
void CameraTest::projectionCorrectedInvertedY() {
Object2D o;
Camera2D camera(o);
camera.setProjection({4.0f, -2.0f})
camera.setProjectionMatrix(Matrix3::projection({4.0f, -2.0f}))
.setAspectRatioPolicy(AspectRatioPolicy::Extend)
.setViewport({4, 4});
@ -139,7 +138,7 @@ void CameraTest::projectionSize2D() {
Vector2 projectionSize(4.0f, 3.0f);
Object2D o;
Camera2D camera(o);
camera.setProjection(projectionSize);
camera.setProjectionMatrix(Matrix3::projection(projectionSize));
CORRADE_COMPARE(camera.projectionSize(), projectionSize);
}
@ -147,14 +146,14 @@ void CameraTest::projectionSizeOrthographic() {
Vector2 projectionSizeRectangle(5.0f, 4.0f);
Object3D o;
Camera3D camera(o);
camera.setOrthographic(projectionSizeRectangle, 1, 9);
camera.setProjectionMatrix(Matrix4::orthographicProjection(projectionSizeRectangle, 1, 9));
CORRADE_COMPARE(camera.projectionSize(), projectionSizeRectangle);
}
void CameraTest::projectionSizePerspective() {
Object3D 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));
}
@ -177,7 +176,7 @@ void CameraTest::draw() {
Drawable(AbstractObject3D& object, DrawableGroup3D* group, Matrix4& result): SceneGraph::Drawable3D(object, group), result(result) {}
protected:
void draw(const Matrix4& transformationMatrix, AbstractCamera3D&) override {
void draw(const Matrix4& transformationMatrix, Camera3D&) override {
result = transformationMatrix;
}

9
src/Magnum/SceneGraph/instantiation.cpp

@ -25,8 +25,7 @@
#include "Magnum/SceneGraph/AbstractFeature.hpp"
#include "Magnum/SceneGraph/Animable.hpp"
#include "Magnum/SceneGraph/Camera2D.hpp"
#include "Magnum/SceneGraph/Camera3D.hpp"
#include "Magnum/SceneGraph/Camera.hpp"
#include "Magnum/SceneGraph/Drawable.hpp"
#include "Magnum/SceneGraph/DualComplexTransformation.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<3, Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP AbstractCamera<2, Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP AbstractCamera<3, Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP BasicCamera2D<Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP BasicCamera3D<Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP Camera<2, Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP Camera<3, Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP Drawable<2, Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP Drawable<3, Float>;

Loading…
Cancel
Save