Browse Source

Simplified camera projection matrix creation.

It doesn't need to be decomposed in many matrix multiplications which
still fail to go properly together.
vectorfields
Vladimír Vondruš 14 years ago
parent
commit
4a207c6556
  1. 37
      src/SceneGraph/Camera.cpp
  2. 2
      src/SceneGraph/Camera.h

37
src/SceneGraph/Camera.cpp

@ -94,12 +94,15 @@ void Camera3D::setOrthographic(const Vector2& size, GLfloat near, GLfloat far) {
_near = near; _near = near;
_far = far; _far = far;
/* Scale the volume down so it fits in (-1, 1) in all directions */ Vector2 xyScale = 2.0f/size;
GLfloat zScale = 2/(far-near); GLfloat zScale = 2.0f/(near-far);
rawProjectionMatrix = Matrix4::scaling({2.0f/size, -zScale});
/* Move the volume on z into (-1, 1) range */ rawProjectionMatrix = Matrix4(
rawProjectionMatrix = Matrix4::translation(Vector3::zAxis(-1-near*zScale))*rawProjectionMatrix; xyScale.x(), 0.0f, 0.0f, 0.0f,
0.0f, xyScale.y(), 0.0f, 0.0f,
0.0f, 0.0f, zScale, 0.0f,
0.0f, 0.0f, near*zScale-1, 1.0f
);
projectionAspectRatio = size; projectionAspectRatio = size;
fixAspectRatio(); fixAspectRatio();
@ -109,23 +112,15 @@ void Camera3D::setPerspective(GLfloat fov, GLfloat near, GLfloat far) {
_near = near; _near = near;
_far = far; _far = far;
/* First move the volume on z in (-1, 1) range */ GLfloat xyScale = 1.0f/tan(fov/2);
rawProjectionMatrix = Matrix4::translation(Vector3::zAxis(2*far*near/(far+near))); GLfloat zScale = 1.0f/(near-far);
/* Then apply magic perspective matrix (with reversed Z) */
static const Matrix4 a(1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, -1.0f, -1.0f,
0.0f, 0.0f, 0.0f, 0.0f);
rawProjectionMatrix = a*rawProjectionMatrix;
/* Then scale the volume down so it fits in (-1, 1) in all directions */
GLfloat xyScale = 1/tan(fov/2);
GLfloat zScale = 1+2*near/(far-near);
rawProjectionMatrix = Matrix4::scaling({xyScale, xyScale, zScale})*rawProjectionMatrix;
/* And... another magic */ rawProjectionMatrix = Matrix4(
rawProjectionMatrix[3][3] = 0; xyScale, 0.0f, 0.0f, 0.0f,
0.0f, xyScale, 0.0f, 0.0f,
0.0f, 0.0f, (far+near)*zScale, -1.0f,
0.0f, 0.0f, (2*far*near)*zScale, 0.0f
);
projectionAspectRatio = Vector2(xyScale); projectionAspectRatio = Vector2(xyScale);
fixAspectRatio(); fixAspectRatio();

2
src/SceneGraph/Camera.h

@ -198,7 +198,7 @@ class SCENEGRAPH_EXPORT Camera3D: public Camera<Matrix4, Vector3, Object3D, Scen
* Sets orthographic projection to the default OpenGL cube (range @f$ [-1; 1] @f$ in all directions). * Sets orthographic projection to the default OpenGL cube (range @f$ [-1; 1] @f$ in all directions).
* @see setOrthographic(), setPerspective() * @see setOrthographic(), setPerspective()
*/ */
inline Camera3D(Object3D* parent = nullptr): Camera(parent), _near(0.0), _far(0.0) {} inline Camera3D(Object3D* parent = nullptr): Camera(parent), _near(0.0f), _far(0.0f) {}
/** /**
* @brief Set orthographic projection * @brief Set orthographic projection

Loading…
Cancel
Save