Browse Source

Camera: computing projection scale directly from projection matrix.

Storing scale as independent (and inverted) value and updating it
separately from projection matrix is just plain wrong.
vectorfields
Vladimír Vondruš 14 years ago
parent
commit
236e0abc58
  1. 11
      src/SceneGraph/Camera.cpp
  2. 5
      src/SceneGraph/Camera.h
  3. 24
      src/SceneGraph/Test/CameraTest.cpp

11
src/SceneGraph/Camera.cpp

@ -24,12 +24,12 @@ namespace Magnum { namespace SceneGraph {
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<class MatrixType> MatrixType aspectRatioFix(AspectRatioPolicy aspectRatioPolicy, const Vector2& projectionAspectRatio, const Math::Vector2<GLsizei>& viewport) {
template<class MatrixType> MatrixType aspectRatioFix(AspectRatioPolicy aspectRatioPolicy, const Vector2& projectionScale, const Math::Vector2<GLsizei>& viewport) {
/* Don't divide by zero / don't preserve anything */
if(projectionAspectRatio.x() == 0 || projectionAspectRatio.y() == 0 || viewport.x() == 0 || viewport.y() == 0 || aspectRatioPolicy == AspectRatioPolicy::NotPreserved)
if(projectionScale.x() == 0 || projectionScale.y() == 0 || viewport.x() == 0 || viewport.y() == 0 || aspectRatioPolicy == AspectRatioPolicy::NotPreserved)
return MatrixType();
Vector2 relativeAspectRatio = Vector2::from(viewport)/projectionAspectRatio;
Vector2 relativeAspectRatio = Vector2::from(viewport)*projectionScale;
/* Extend on larger side = scale larger side down
Clip on smaller side = scale smaller side up */
@ -46,7 +46,7 @@ template Matrix4 aspectRatioFix<Matrix4>(AspectRatioPolicy, const Vector2&, cons
}
#endif
template<class MatrixType, class VectorType, class ObjectType, class SceneType, class CameraType> Camera<MatrixType, VectorType, ObjectType, SceneType, CameraType>::Camera(ObjectType* parent): ObjectType(parent), projectionAspectRatio(1.0f), _aspectRatioPolicy(AspectRatioPolicy::NotPreserved) {}
template<class MatrixType, class VectorType, class ObjectType, class SceneType, class CameraType> Camera<MatrixType, VectorType, ObjectType, SceneType, CameraType>::Camera(ObjectType* parent): ObjectType(parent), _aspectRatioPolicy(AspectRatioPolicy::NotPreserved) {}
template<class MatrixType, class VectorType, class ObjectType, class SceneType, class CameraType> void Camera<MatrixType, VectorType, ObjectType, SceneType, CameraType>::setViewport(const Math::Vector2<GLsizei>& size) {
Framebuffer::setViewport({0, 0}, size);
@ -86,7 +86,6 @@ void Camera2D::setProjection(const Vector2& size) {
/* Scale the volume down so it fits in (-1, 1) in all directions */
rawProjectionMatrix = Matrix3::scaling(2.0f/size);
projectionAspectRatio = size;
fixAspectRatio();
}
@ -104,7 +103,6 @@ void Camera3D::setOrthographic(const Vector2& size, GLfloat near, GLfloat far) {
0.0f, 0.0f, near*zScale-1, 1.0f
);
projectionAspectRatio = size;
fixAspectRatio();
}
@ -122,7 +120,6 @@ void Camera3D::setPerspective(GLfloat fov, GLfloat near, GLfloat far) {
0.0f, 0.0f, (2*far*near)*zScale, 0.0f
);
projectionAspectRatio = Vector2(xyScale);
fixAspectRatio();
}

5
src/SceneGraph/Camera.h

@ -38,7 +38,7 @@ namespace Implementation {
template<size_t dimensions> class Camera {};
template<class MatrixType> MatrixType aspectRatioFix(AspectRatioPolicy aspectRatioPolicy, const Vector2& projectionAspectRatio, const Math::Vector2<GLsizei>& viewport);
template<class MatrixType> MatrixType aspectRatioFix(AspectRatioPolicy aspectRatioPolicy, const Vector2& projectionScale, const Math::Vector2<GLsizei>& viewport);
/* These templates are instantiated in source file */
extern template SCENEGRAPH_EXPORT Matrix3 aspectRatioFix<Matrix3>(AspectRatioPolicy, const Vector2&, const Math::Vector2<GLsizei>&);
@ -131,10 +131,9 @@ template<class MatrixType, class VectorType, class ObjectType, class SceneType,
#ifndef DOXYGEN_GENERATING_OUTPUT
inline void fixAspectRatio() {
_projectionMatrix = Implementation::aspectRatioFix<MatrixType>(_aspectRatioPolicy, projectionAspectRatio, _viewport)*rawProjectionMatrix;
_projectionMatrix = Implementation::aspectRatioFix<MatrixType>(_aspectRatioPolicy, {rawProjectionMatrix[0].x(), rawProjectionMatrix[1].y()}, _viewport)*rawProjectionMatrix;
}
Vector2 projectionAspectRatio;
MatrixType rawProjectionMatrix;
AspectRatioPolicy _aspectRatioPolicy;
#endif

24
src/SceneGraph/Test/CameraTest.cpp

@ -31,45 +31,45 @@ CameraTest::CameraTest() {
}
void CameraTest::fixAspectRatio() {
Vector2 projectionSize(2, 3);
Vector2 projectionScale(0.5f, 1.0f/3.0f);
Math::Vector2<GLsizei> size(400, 300);
/* Division by zero */
Vector2 projectionSizeZeroY(2, 0);
Vector2 projectionSizeZeroX(0, 2);
Vector2 projectionScaleZeroY(0.5f, 0.0f);
Vector2 projectionScaleZeroX(0.0f, 0.5f);
Math::Vector2<GLsizei> sizeZeroY(400, 0);
Math::Vector2<GLsizei> sizeZeroX(0, 300);
CORRADE_COMPARE(Implementation::aspectRatioFix<Matrix4>(Implementation::AspectRatioPolicy::Clip, projectionSizeZeroX, size), Matrix4());
CORRADE_COMPARE(Implementation::aspectRatioFix<Matrix4>(Implementation::AspectRatioPolicy::Clip, projectionSizeZeroY, size), Matrix4());
CORRADE_COMPARE(Implementation::aspectRatioFix<Matrix4>(Implementation::AspectRatioPolicy::Clip, projectionSize, sizeZeroY), Matrix4());
CORRADE_COMPARE(Implementation::aspectRatioFix<Matrix4>(Implementation::AspectRatioPolicy::Extend, projectionSize, sizeZeroX), Matrix4());
CORRADE_COMPARE(Implementation::aspectRatioFix<Matrix4>(Implementation::AspectRatioPolicy::Clip, projectionScaleZeroX, size), Matrix4());
CORRADE_COMPARE(Implementation::aspectRatioFix<Matrix4>(Implementation::AspectRatioPolicy::Clip, projectionScaleZeroY, size), Matrix4());
CORRADE_COMPARE(Implementation::aspectRatioFix<Matrix4>(Implementation::AspectRatioPolicy::Clip, projectionScale, sizeZeroY), Matrix4());
CORRADE_COMPARE(Implementation::aspectRatioFix<Matrix4>(Implementation::AspectRatioPolicy::Extend, projectionScale, sizeZeroX), Matrix4());
/* Not preserved */
CORRADE_COMPARE(Implementation::aspectRatioFix<Matrix4>(Implementation::AspectRatioPolicy::NotPreserved, projectionSize, size), Matrix4());
CORRADE_COMPARE(Implementation::aspectRatioFix<Matrix4>(Implementation::AspectRatioPolicy::NotPreserved, projectionScale, size), Matrix4());
/* Clip */
Matrix4 expectedClip(1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 4.0f/3.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
CORRADE_COMPARE(Implementation::aspectRatioFix<Matrix4>(Implementation::AspectRatioPolicy::Clip, Vector2(2.0f), size), expectedClip);
CORRADE_COMPARE(Implementation::aspectRatioFix<Matrix4>(Implementation::AspectRatioPolicy::Clip, Vector2(0.5f), size), expectedClip);
Matrix4 expectedClipRectangle(1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 2.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
CORRADE_COMPARE(Implementation::aspectRatioFix<Matrix4>(Implementation::AspectRatioPolicy::Clip, projectionSize, size), expectedClipRectangle);
CORRADE_COMPARE(Implementation::aspectRatioFix<Matrix4>(Implementation::AspectRatioPolicy::Clip, projectionScale, size), expectedClipRectangle);
/* Extend */
Matrix4 expectedExtend(3.0f/4.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
CORRADE_COMPARE(Implementation::aspectRatioFix<Matrix4>(Implementation::AspectRatioPolicy::Extend, Vector2(2.0f), size), expectedExtend);
CORRADE_COMPARE(Implementation::aspectRatioFix<Matrix4>(Implementation::AspectRatioPolicy::Extend, Vector2(0.5f), size), expectedExtend);
Matrix4 expectedExtendRectangle(0.5f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
CORRADE_COMPARE(Implementation::aspectRatioFix<Matrix4>(Implementation::AspectRatioPolicy::Extend, projectionSize, size), expectedExtendRectangle);
CORRADE_COMPARE(Implementation::aspectRatioFix<Matrix4>(Implementation::AspectRatioPolicy::Extend, projectionScale, size), expectedExtendRectangle);
}
void CameraTest::defaultProjection2D() {

Loading…
Cancel
Save