From 73419be9e6506ce84e69ad8f6baafedeada7ddb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 20 Jun 2015 16:28:43 +0200 Subject: [PATCH] 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. --- src/Magnum/DebugTools/ForceRenderer.cpp | 4 +- src/Magnum/DebugTools/ForceRenderer.h | 2 +- src/Magnum/DebugTools/ObjectRenderer.cpp | 4 +- src/Magnum/DebugTools/ObjectRenderer.h | 2 +- src/Magnum/DebugTools/ShapeRenderer.cpp | 4 +- src/Magnum/DebugTools/ShapeRenderer.h | 2 +- src/Magnum/Platform/Sdl2Application.h | 4 +- src/Magnum/SceneGraph/AbstractCamera.h | 188 +++----------- src/Magnum/SceneGraph/AbstractCamera.hpp | 76 +----- src/Magnum/SceneGraph/CMakeLists.txt | 18 +- src/Magnum/SceneGraph/Camera.h | 284 ++++++++++++++++++++++ src/Magnum/SceneGraph/Camera.hpp | 107 ++++++++ src/Magnum/SceneGraph/Camera2D.h | 84 +------ src/Magnum/SceneGraph/Camera2D.hpp | 23 +- src/Magnum/SceneGraph/Camera3D.h | 120 +-------- src/Magnum/SceneGraph/Camera3D.hpp | 46 +--- src/Magnum/SceneGraph/Drawable.h | 10 +- src/Magnum/SceneGraph/SceneGraph.h | 23 +- src/Magnum/SceneGraph/Test/CameraTest.cpp | 15 +- src/Magnum/SceneGraph/instantiation.cpp | 9 +- 20 files changed, 511 insertions(+), 514 deletions(-) create mode 100644 src/Magnum/SceneGraph/Camera.h create mode 100644 src/Magnum/SceneGraph/Camera.hpp diff --git a/src/Magnum/DebugTools/ForceRenderer.cpp b/src/Magnum/DebugTools/ForceRenderer.cpp index 27471c379..f537e6276 100644 --- a/src/Magnum/DebugTools/ForceRenderer.cpp +++ b/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 ForceRenderer::ForceRenderer(SceneG /* To avoid deleting pointers to incomplete type on destruction of Resource members */ template ForceRenderer::~ForceRenderer() = default; -template void ForceRenderer::draw(const MatrixTypeFor& transformationMatrix, SceneGraph::AbstractCamera& camera) { +template void ForceRenderer::draw(const MatrixTypeFor& transformationMatrix, SceneGraph::Camera& camera) { shader->setTransformationProjectionMatrix(camera.projectionMatrix()*Implementation::forceRendererTransformation(transformationMatrix.transformPoint(forcePosition), force)*MatrixTypeFor::scaling(VectorTypeFor{options->scale()})) .setColor(options->color()); mesh->draw(*shader); diff --git a/src/Magnum/DebugTools/ForceRenderer.h b/src/Magnum/DebugTools/ForceRenderer.h index a10b4b422..99814a42d 100644 --- a/src/Magnum/DebugTools/ForceRenderer.h +++ b/src/Magnum/DebugTools/ForceRenderer.h @@ -129,7 +129,7 @@ template class MAGNUM_DEBUGTOOLS_EXPORT ForceRenderer: p ~ForceRenderer(); private: - void draw(const MatrixTypeFor& transformationMatrix, SceneGraph::AbstractCamera& camera) override; + void draw(const MatrixTypeFor& transformationMatrix, SceneGraph::Camera& camera) override; const VectorTypeFor forcePosition; const VectorTypeFor& force; diff --git a/src/Magnum/DebugTools/ObjectRenderer.cpp b/src/Magnum/DebugTools/ObjectRenderer.cpp index e2185c867..deca905c3 100644 --- a/src/Magnum/DebugTools/ObjectRenderer.cpp +++ b/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 ObjectRenderer::ObjectRenderer(Scen /* To avoid deleting pointers to incomplete type on destruction of Resource members */ template ObjectRenderer::~ObjectRenderer() = default; -template void ObjectRenderer::draw(const MatrixTypeFor& transformationMatrix, SceneGraph::AbstractCamera& camera) { +template void ObjectRenderer::draw(const MatrixTypeFor& transformationMatrix, SceneGraph::Camera& camera) { shader->setTransformationProjectionMatrix(camera.projectionMatrix()*transformationMatrix*MatrixTypeFor::scaling(VectorTypeFor{options->size()})); mesh->draw(*shader); } diff --git a/src/Magnum/DebugTools/ObjectRenderer.h b/src/Magnum/DebugTools/ObjectRenderer.h index 4eec65806..99d98a801 100644 --- a/src/Magnum/DebugTools/ObjectRenderer.h +++ b/src/Magnum/DebugTools/ObjectRenderer.h @@ -101,7 +101,7 @@ template class MAGNUM_DEBUGTOOLS_EXPORT ObjectRenderer: ~ObjectRenderer(); private: - void draw(const MatrixTypeFor& transformationMatrix, SceneGraph::AbstractCamera& camera) override; + void draw(const MatrixTypeFor& transformationMatrix, SceneGraph::Camera& camera) override; Resource options; Resource> shader; diff --git a/src/Magnum/DebugTools/ShapeRenderer.cpp b/src/Magnum/DebugTools/ShapeRenderer.cpp index ffd0cd3fe..6e1d28b73 100644 --- a/src/Magnum/DebugTools/ShapeRenderer.cpp +++ b/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 ShapeRenderer::~ShapeRenderer() { for(auto i: renderers) delete i; } -template void ShapeRenderer::draw(const MatrixTypeFor&, SceneGraph::AbstractCamera& camera) { +template void ShapeRenderer::draw(const MatrixTypeFor&, SceneGraph::Camera& camera) { const MatrixTypeFor projectionMatrix = camera.projectionMatrix()*camera.cameraMatrix(); for(auto i: renderers) i->draw(options, projectionMatrix); } diff --git a/src/Magnum/DebugTools/ShapeRenderer.h b/src/Magnum/DebugTools/ShapeRenderer.h index 57c1129ab..c67dc10f2 100644 --- a/src/Magnum/DebugTools/ShapeRenderer.h +++ b/src/Magnum/DebugTools/ShapeRenderer.h @@ -161,7 +161,7 @@ template class MAGNUM_DEBUGTOOLS_EXPORT ShapeRenderer: p ~ShapeRenderer(); private: - void draw(const MatrixTypeFor& transformationMatrix, SceneGraph::AbstractCamera& camera) override; + void draw(const MatrixTypeFor& transformationMatrix, SceneGraph::Camera& camera) override; Resource options; std::vector*> renderers; diff --git a/src/Magnum/Platform/Sdl2Application.h b/src/Magnum/Platform/Sdl2Application.h index b2118135c..4b83d6ef7 100644 --- a/src/Magnum/Platform/Sdl2Application.h +++ b/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 diff --git a/src/Magnum/SceneGraph/AbstractCamera.h b/src/Magnum/SceneGraph/AbstractCamera.h index e0dea603f..38e0188db 100644 --- a/src/Magnum/SceneGraph/AbstractCamera.h +++ b/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 MatrixTypeFor aspectRatioFix(AspectRatioPolicy aspectRatioPolicy, const Math::Vector2& 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 class AbstractCamera: public AbstractFeature { - public: - /** @brief Aspect ratio policy */ - AspectRatioPolicy aspectRatioPolicy() const { return _aspectRatioPolicy; } - - /** - * @brief Set aspect ratio policy - * @return Reference to self (for method chaining) - */ - AbstractCamera& 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 cameraMatrix() { - AbstractFeature::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 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 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& group); - - protected: - /** - * @brief Constructor - * @param object Object holding the camera - */ - explicit AbstractCamera(AbstractObject& object); - - ~AbstractCamera(); - - /** Recalculates camera matrix */ - void cleanInverted(const MatrixTypeFor& invertedAbsoluteTransformationMatrix) override { - _cameraMatrix = invertedAbsoluteTransformationMatrix; - } - - #ifndef DOXYGEN_GENERATING_OUTPUT - void fixAspectRatio(); - - MatrixTypeFor rawProjectionMatrix; - AspectRatioPolicy _aspectRatioPolicy; - #endif - - private: - MatrixTypeFor _projectionMatrix; - MatrixTypeFor _cameraMatrix; - - Vector2i _viewport; -}; + * @copybrief Camera + * @deprecated Use @ref Camera instead. + */ +template using AbstractCamera CORRADE_DEPRECATED("use Camera instead") = Camera; /** -@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 using AbstractBasicCamera2D = AbstractCamera<2, T>; + * @copybrief BasicCamera2D + * @deprecated Use @ref BasicCamera2D instead. + */ +template using AbstractBasicCamera2D CORRADE_DEPRECATED("use BasicCamera2D instead") = BasicCamera2D; /** -@brief Base camera for two-dimensional float scenes - -@see @ref AbstractCamera3D -*/ -typedef AbstractBasicCamera2D 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 using AbstractBasicCamera3D = AbstractCamera<3, T>; + * @copybrief BasicCamera3D + * @deprecated Use @ref BasicCamera3D instead. + */ +template using AbstractBasicCamera3D CORRADE_DEPRECATED("use BasicCamera3D instead") = BasicCamera3D; /** -@brief Base camera for three-dimensional float scenes - -@see @ref AbstractCamera2D -*/ -typedef AbstractBasicCamera3D 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 diff --git a/src/Magnum/SceneGraph/AbstractCamera.hpp b/src/Magnum/SceneGraph/AbstractCamera.hpp index 7ec09b488..4a22b3028 100644 --- a/src/Magnum/SceneGraph/AbstractCamera.hpp +++ b/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 MatrixTypeFor aspectRatioFix(AspectRatioPolicy aspectRatioPolicy, const Math::Vector2& 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(0)).all() && (viewport > Vector2i(0)).all()); - Math::Vector2 relativeAspectRatio = Math::Vector2(viewport)*projectionScale; - - /* Extend on larger side = scale larger side down - Clip on smaller side = scale smaller side up */ - return MatrixTypeFor::scaling(Math::Vector::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 AbstractCamera::AbstractCamera(AbstractObject& object): AbstractFeature(object), _aspectRatioPolicy(AspectRatioPolicy::NotPreserved) { - AbstractFeature::setCachedTransformations(CachedTransformation::InvertedAbsolute); -} - -template AbstractCamera::~AbstractCamera() = default; - -template void AbstractCamera::fixAspectRatio() { - _projectionMatrix = Implementation::aspectRatioFix(_aspectRatioPolicy, {Math::abs(rawProjectionMatrix[0].x()), Math::abs(rawProjectionMatrix[1].y())}, _viewport)*rawProjectionMatrix; -} - -template AbstractCamera& AbstractCamera::setAspectRatioPolicy(AspectRatioPolicy policy) { - _aspectRatioPolicy = policy; - fixAspectRatio(); - return *this; -} - -template void AbstractCamera::setViewport(const Vector2i& size) { - _viewport = size; - fixAspectRatio(); -} - -template void AbstractCamera::draw(DrawableGroup& group) { - AbstractObject* scene = AbstractFeature::object().scene(); - CORRADE_ASSERT(scene, "Camera::draw(): cannot draw when camera is not part of any scene", ); - - /* Compute camera matrix */ - AbstractFeature::object().setClean(); - - /* Compute transformations of all objects in the group relative to the camera */ - std::vector>> objects; - objects.reserve(group.size()); - for(std::size_t i = 0; i != group.size(); ++i) - objects.push_back(group[i].object()); - std::vector> 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 diff --git a/src/Magnum/SceneGraph/CMakeLists.txt b/src/Magnum/SceneGraph/CMakeLists.txt index db9ec6027..bfb465e62 100644 --- a/src/Magnum/SceneGraph/CMakeLists.txt +++ b/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} diff --git a/src/Magnum/SceneGraph/Camera.h b/src/Magnum/SceneGraph/Camera.h new file mode 100644 index 000000000..4e0999e01 --- /dev/null +++ b/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š + + 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 MatrixTypeFor aspectRatioFix(AspectRatioPolicy aspectRatioPolicy, const Math::Vector2& 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 class Camera: public AbstractFeature { + 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& 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, U>::value>::type> Camera(U& object): Camera{static_cast&>(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& 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 cameraMatrix() { + AbstractFeature::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 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& setProjectionMatrix(const MatrixTypeFor& matrix); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief Set projection + * @deprecated Use @ref setProjectionMatrix() with @ref Matrix3::projection() instead. + */ + template::type> CORRADE_DEPRECATED("use setProjectionMatrix() with Matrix3::projection() instead") BasicCamera2D& setProjection(const Math::Vector2& size) { + return setProjectionMatrix(Math::Matrix3::projection(size)); + } + + /** + * @brief Set orthographic projection + * @deprecated Use @ref setProjectionMatrix() with + * @ref Matrix4::orthographicProjection() instead. + */ + template::type> CORRADE_DEPRECATED("use setProjectionMatrix() with Matrix4::orthographicProjection() instead") BasicCamera3D& setOrthographic(const Math::Vector2& size, T near, T far) { + return setProjectionMatrix(Math::Matrix4::orthographicProjection(size, near, far)); + } + + /** + * @brief Set perspective projection + * @deprecated Use @ref setProjectionMatrix() with + * @ref Matrix4::perspectiveProjection() instead. + */ + template::type> CORRADE_DEPRECATED("use setProjectionMatrix() with Matrix4::orthographicProjection() instead") BasicCamera3D& setPerspective(const Math::Vector2& size, T near, T far) { + return setProjectionMatrix(Math::Matrix4::perspectiveProjection(size, near, far)); + } + + /** + * @brief Set perspective projection + * @deprecated Use @ref setProjectionMatrix() with + * @ref Matrix4::perspectiveProjection() instead. + */ + template::type> CORRADE_DEPRECATED("use setProjectionMatrix() with Matrix4::orthographicProjection() instead") BasicCamera3D& setPerspective(Math::Rad fov, T aspectRatio, T near, T far) { + return setProjectionMatrix(Math::Matrix4::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 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& group); + + private: + /** Recalculates camera matrix */ + void cleanInverted(const MatrixTypeFor& invertedAbsoluteTransformationMatrix) override { + _cameraMatrix = invertedAbsoluteTransformationMatrix; + } + + #ifndef DOXYGEN_GENERATING_OUTPUT + void fixAspectRatio(); + + MatrixTypeFor _rawProjectionMatrix; + AspectRatioPolicy _aspectRatioPolicy; + #endif + + MatrixTypeFor _projectionMatrix; + MatrixTypeFor _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 using BasicCamera2D = Camera<2, T>; + +/** +@brief Camera for two-dimensional float scenes + +@see @ref Camera3D +*/ +typedef BasicCamera2D 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 using BasicCamera3D = Camera<3, T>; + +/** +@brief Camera for three-dimensional float scenes + +@see @ref Camera2D +*/ +typedef BasicCamera3D 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 diff --git a/src/Magnum/SceneGraph/Camera.hpp b/src/Magnum/SceneGraph/Camera.hpp new file mode 100644 index 000000000..1a7e64acc --- /dev/null +++ b/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š + + 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 MatrixTypeFor aspectRatioFix(AspectRatioPolicy aspectRatioPolicy, const Math::Vector2& 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(0)).all() && (viewport > Vector2i(0)).all()); + Math::Vector2 relativeAspectRatio = Math::Vector2(viewport)*projectionScale; + + /* Extend on larger side = scale larger side down + Clip on smaller side = scale smaller side up */ + return MatrixTypeFor::scaling(Math::Vector::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 Camera::Camera(AbstractObject& object): AbstractFeature(object), _aspectRatioPolicy(AspectRatioPolicy::NotPreserved) { + AbstractFeature::setCachedTransformations(CachedTransformation::InvertedAbsolute); +} + +template Camera::~Camera() = default; + +template void Camera::fixAspectRatio() { + _projectionMatrix = Implementation::aspectRatioFix(_aspectRatioPolicy, {Math::abs(_rawProjectionMatrix[0].x()), Math::abs(_rawProjectionMatrix[1].y())}, _viewport)*_rawProjectionMatrix; +} + +template Camera& Camera::setAspectRatioPolicy(AspectRatioPolicy policy) { + _aspectRatioPolicy = policy; + fixAspectRatio(); + return *this; +} + +template Camera& Camera::setProjectionMatrix(const MatrixTypeFor& matrix) { + _rawProjectionMatrix = matrix; + fixAspectRatio(); + return *this; +} + +template void Camera::setViewport(const Vector2i& size) { + _viewport = size; + fixAspectRatio(); +} + +template void Camera::draw(DrawableGroup& group) { + AbstractObject* scene = AbstractFeature::object().scene(); + CORRADE_ASSERT(scene, "Camera::draw(): cannot draw when camera is not part of any scene", ); + + /* Compute camera matrix */ + AbstractFeature::object().setClean(); + + /* Compute transformations of all objects in the group relative to the camera */ + std::vector>> objects; + objects.reserve(group.size()); + for(std::size_t i = 0; i != group.size(); ++i) + objects.push_back(group[i].object()); + std::vector> 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 diff --git a/src/Magnum/SceneGraph/Camera2D.h b/src/Magnum/SceneGraph/Camera2D.h index ceb1ed056..d4cb8f191 100644 --- a/src/Magnum/SceneGraph/Camera2D.h +++ b/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 BasicCamera2D: public AbstractBasicCamera2D { - 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& 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, U>::value>::type> BasicCamera2D(U& object): BasicCamera2D(static_cast&>(object)) {} - #endif - - /** - * @brief Set projection - * @param size Size of the view - * @return Reference to self (for method chaining) - * - * @see @ref Matrix3::projection() - */ - BasicCamera2D& setProjection(const Math::Vector2& size); - - /* Overloads to remove WTF-factor from method chaining order */ - #ifndef DOXYGEN_GENERATING_OUTPUT - BasicCamera2D& setAspectRatioPolicy(AspectRatioPolicy policy) { - AbstractBasicCamera2D::setAspectRatioPolicy(policy); - return *this; - } - #endif -}; - -/** -@brief Camera for two-dimensional float scenes - -@see @ref Camera3D -*/ -typedef BasicCamera2D Camera2D; - -#if defined(CORRADE_TARGET_WINDOWS) && !defined(__MINGW32__) -extern template class MAGNUM_SCENEGRAPH_EXPORT BasicCamera2D; +#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 diff --git a/src/Magnum/SceneGraph/Camera2D.hpp b/src/Magnum/SceneGraph/Camera2D.hpp index 252219b1b..aaf908964 100644 --- a/src/Magnum/SceneGraph/Camera2D.hpp +++ b/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 BasicCamera2D::BasicCamera2D(AbstractBasicObject2D& object): AbstractBasicCamera2D(object) {} - -template BasicCamera2D& BasicCamera2D::setProjection(const Math::Vector2& size) { - AbstractBasicCamera2D::rawProjectionMatrix = Math::Matrix3::projection(size); - - AbstractBasicCamera2D::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 diff --git a/src/Magnum/SceneGraph/Camera3D.h b/src/Magnum/SceneGraph/Camera3D.h index d659bd29b..11703ff70 100644 --- a/src/Magnum/SceneGraph/Camera3D.h +++ b/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 BasicCamera3D: public AbstractBasicCamera3D { - public: - /** - * @brief Constructor - * @param object Object holding this feature - */ - explicit BasicCamera3D(AbstractBasicObject3D& 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, U>::value>::type> BasicCamera3D(U& object): BasicCamera3D(static_cast&>(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& setOrthographic(const Math::Vector2& 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& setPerspective(const Math::Vector2& 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& setPerspective(Math::Rad 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& setAspectRatioPolicy(AspectRatioPolicy policy) { - AbstractBasicCamera3D::setAspectRatioPolicy(policy); - return *this; - } - #endif - - private: - T _near, _far; -}; - -/** -@brief Camera for three-dimensional float scenes - -@see @ref Camera2D -*/ -typedef BasicCamera3D Camera3D; - -#if defined(CORRADE_TARGET_WINDOWS) && !defined(__MINGW32__) -extern template class MAGNUM_SCENEGRAPH_EXPORT BasicCamera3D; -#endif - -}} - #endif diff --git a/src/Magnum/SceneGraph/Camera3D.hpp b/src/Magnum/SceneGraph/Camera3D.hpp index 4355192e9..4449e49c6 100644 --- a/src/Magnum/SceneGraph/Camera3D.hpp +++ b/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 BasicCamera3D::BasicCamera3D(AbstractBasicObject3D& object): AbstractBasicCamera3D(object), _near(T(0)), _far(T(0)) {} - -template BasicCamera3D& BasicCamera3D::setOrthographic(const Math::Vector2& size, T near, T far) { - /** @todo Get near/far from the matrix */ - _near = near; - _far = far; - - AbstractBasicCamera3D::rawProjectionMatrix = Math::Matrix4::orthographicProjection(size, near, far); - AbstractBasicCamera3D::fixAspectRatio(); - return *this; -} - -template BasicCamera3D& BasicCamera3D::setPerspective(const Math::Vector2& size, T near, T far) { - /** @todo Get near/far from the matrix */ - _near = near; - _far = far; - - AbstractBasicCamera3D::rawProjectionMatrix = Math::Matrix4::perspectiveProjection(size, near, far); - AbstractBasicCamera3D::fixAspectRatio(); - return *this; -} - -template BasicCamera3D& BasicCamera3D::setPerspective(Math::Rad fov, T aspectRatio, T near, T far) { - /** @todo Get near/far from the matrix */ - _near = near; - _far = far; - - AbstractBasicCamera3D::rawProjectionMatrix = Math::Matrix4::perspectiveProjection(fov, aspectRatio, near, far); - AbstractBasicCamera3D::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 diff --git a/src/Magnum/SceneGraph/Drawable.h b/src/Magnum/SceneGraph/Drawable.h index 89cc49d52..1b0777f13 100644 --- a/src/Magnum/SceneGraph/Drawable.h +++ b/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 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& transformationMatrix, AbstractCamera& camera) = 0; + virtual void draw(const MatrixTypeFor& transformationMatrix, Camera& camera) = 0; }; /** diff --git a/src/Magnum/SceneGraph/SceneGraph.h b/src/Magnum/SceneGraph/SceneGraph.h index 2f7f59b80..cfddcaa29 100644 --- a/src/Magnum/SceneGraph/SceneGraph.h +++ b/src/Magnum/SceneGraph/SceneGraph.h @@ -31,17 +31,15 @@ #include "Magnum/Types.h" +#ifdef MAGNUM_BUILD_DEPRECATED +#include +#endif + namespace Magnum { namespace SceneGraph { #ifndef DOXYGEN_GENERATING_OUTPUT enum class AspectRatioPolicy: UnsignedByte; -template class AbstractCamera; -template using AbstractBasicCamera2D = AbstractCamera<2, T>; -template using AbstractBasicCamera3D = AbstractCamera<3, T>; -typedef AbstractBasicCamera2D AbstractCamera2D; -typedef AbstractBasicCamera3D AbstractCamera3D; - /* Enum CachedTransformation and CachedTransformations used only directly */ template class AbstractFeature; @@ -100,11 +98,20 @@ template using BasicAnimableGroup3D = AnimableGroup<3, T>; typedef BasicAnimableGroup2D AnimableGroup2D; typedef BasicAnimableGroup3D AnimableGroup3D; -template class BasicCamera2D; -template class BasicCamera3D; +template class Camera; +template using BasicCamera2D = Camera<2, T>; +template using BasicCamera3D = Camera<3, T>; typedef BasicCamera2D Camera2D; typedef BasicCamera3D Camera3D; +#ifdef MAGNUM_BUILD_DEPRECATED +template using AbstractCamera CORRADE_DEPRECATED("use BasicCamera2D instead") = Camera; +template using AbstractBasicCamera2D CORRADE_DEPRECATED("use BasicCamera2D instead") = BasicCamera2D; +CORRADE_DEPRECATED("use Camera2D instead") typedef Camera2D AbstractCamera2D; +template using AbstractBasicCamera3D CORRADE_DEPRECATED("use BasicCamera3D instead") = BasicCamera3D; +CORRADE_DEPRECATED("use Camera3D instead") typedef Camera3D AbstractCamera3D; +#endif + template class Drawable; template using BasicDrawable2D = Drawable<2, T>; template using BasicDrawable3D = Drawable<3, T>; diff --git a/src/Magnum/SceneGraph/Test/CameraTest.cpp b/src/Magnum/SceneGraph/Test/CameraTest.cpp index 03165e8da..7d0ea7ea4 100644 --- a/src/Magnum/SceneGraph/Test/CameraTest.cpp +++ b/src/Magnum/SceneGraph/Test/CameraTest.cpp @@ -25,9 +25,8 @@ #include -#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; } diff --git a/src/Magnum/SceneGraph/instantiation.cpp b/src/Magnum/SceneGraph/instantiation.cpp index 08ba7aab7..44afe9799 100644 --- a/src/Magnum/SceneGraph/instantiation.cpp +++ b/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; -template class MAGNUM_SCENEGRAPH_EXPORT_HPP BasicCamera3D; +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>;