[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: playground/libs/kgllib/extras/kgllib
From: Rivo Laks <rivolaks () hot ! ee>
Date: 2008-03-04 17:58:25
Message-ID: 1204653505.447433.26387.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 782264 by rivol:
Camera now calculates and stores modelview and projection matrices
instead of using utility functions like gluLookAt().
The advantage is that you can now get/set those matrices directly
if necessary (instead of using e.g. setPosition()).
M +97 -4 camera.cpp
M +16 -0 camera.h
--- trunk/playground/libs/kgllib/extras/kgllib/camera.cpp #782263:782264
@@ -19,6 +19,9 @@
#include <kgllib.h>
+#include <math.h>
+
+
using namespace Eigen;
namespace KGLLib
@@ -33,6 +36,8 @@
mPosition = Vector3f(-10, 0, 10);
mLookAt = Vector3f(0, 0, 0);
mUp = Vector3f(0, 1, 0);
+ mModelviewMatrixDirty = true;
+ mProjectionMatrixDirty = true;
}
Camera::~Camera()
@@ -42,32 +47,38 @@
void Camera::setFoV(float fov)
{
mFoV = fov;
+ mProjectionMatrixDirty = true;
}
void Camera::setAspect(float aspect)
{
mAspect = aspect;
+ mProjectionMatrixDirty = true;
}
void Camera::setDepthRange(float near, float far)
{
mDepthNear = near;
mDepthFar = far;
+ mProjectionMatrixDirty = true;
}
void Camera::setPosition(const Eigen::Vector3f& pos)
{
mPosition = pos;
+ mModelviewMatrixDirty = true;
}
void Camera::setLookAt(const Eigen::Vector3f& lookat)
{
mLookAt = lookat;
+ mModelviewMatrixDirty = true;
}
void Camera::setUp(const Eigen::Vector3f& up)
{
mUp = up;
+ mModelviewMatrixDirty = true;
}
void Camera::setDirection(const Eigen::Vector3f& dir)
@@ -77,20 +88,102 @@
void Camera::applyPerspective()
{
+ if (mProjectionMatrixDirty) {
+ recalculateProjectionMatrix();
+ }
+
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- gluPerspective(mFoV, mAspect, mDepthNear, mDepthFar);
+ glMultMatrixf(mProjectionMatrix.array());
glMatrixMode(GL_MODELVIEW);
}
void Camera::applyView(bool reset)
{
+ if (mModelviewMatrixDirty) {
+ recalculateModelviewMatrix();
+ }
+
if (reset) {
glLoadIdentity();
}
- gluLookAt(mPosition.x(), mPosition.y(), mPosition.z(),
- mLookAt.x(), mLookAt.y(), mLookAt.z(),
- mUp.x(), mUp.y(), mUp.z());
+ glMultMatrixf(mModelviewMatrix.array());
}
+void Camera::recalculateModelviewMatrix()
+{
+ // Code from Mesa project, src/glu/sgi/libutil/project.c
+ mModelviewMatrixDirty = false;
+ // Our looking direction
+ Vector3f forward = mLookAt - mPosition;
+ forward.normalize();
+
+ Vector3f side = forward.cross(mUp);
+ side.normalize();
+
+ // Recompute up vector, using cross product
+ Vector3f up = side.cross(forward);
+
+ // Linear component of the modelview matrix
+ Matrix3f linear;
+ linear.setRow(0, side);
+ linear.setRow(1, up);
+ linear.setRow(2, -forward);
+
+ mModelviewMatrix.loadIdentity();
+ mModelviewMatrix.setLinearComponent(linear);
+ mModelviewMatrix.translate(-mPosition);
}
+
+void Camera::recalculateProjectionMatrix()
+{
+ // Code from Mesa project, src/glu/sgi/libutil/project.c
+ mProjectionMatrixDirty = false;
+ mProjectionMatrix.loadIdentity();
+ float radians = mFoV / 2 * M_PI / 180;
+
+ float deltaZ = mDepthFar - mDepthNear;
+ float sine = sin(radians);
+ if ((deltaZ == 0) || (sine == 0) || (mAspect == 0)) {
+ return;
+ }
+ float cotangent = cos(radians) / sine;
+
+ mProjectionMatrix(0, 0) = cotangent / mAspect;
+ mProjectionMatrix(1, 1) = cotangent;
+ mProjectionMatrix(2, 2) = -(mDepthFar + mDepthNear) / deltaZ;
+ mProjectionMatrix(3, 2) = -1;
+ mProjectionMatrix(2, 3) = -2 * mDepthNear * mDepthFar / deltaZ;
+ mProjectionMatrix(3, 3) = 0;
+}
+
+void Camera::setModelviewMatrix(const Eigen::MatrixP3f& modelview)
+{
+ mModelviewMatrix = modelview;
+ mModelviewMatrixDirty = false;
+}
+
+void Camera::setProjectionMatrix(const Eigen::MatrixP3f& projection)
+{
+ mProjectionMatrix = projection;
+ mProjectionMatrixDirty = false;
+}
+
+Eigen::MatrixP3f Camera::modelviewMatrix() const
+{
+ if (mModelviewMatrixDirty) {
+ const_cast<Camera*>(this)->recalculateModelviewMatrix();
+ }
+ return mModelviewMatrix;
+}
+
+Eigen::MatrixP3f Camera::projectionMatrix() const
+{
+ if (mProjectionMatrixDirty) {
+ const_cast<Camera*>(this)->recalculateProjectionMatrix();
+ }
+ return mProjectionMatrix;
+}
+
+
+}
--- trunk/playground/libs/kgllib/extras/kgllib/camera.h #782263:782264
@@ -22,6 +22,7 @@
#include "kgllib.h"
#include <eigen/vector.h>
+#include <eigen/projective.h>
namespace KGLLib
{
@@ -57,11 +58,26 @@
Eigen::Vector3f lookAt() const { return mLookAt; }
Eigen::Vector3f up() const { return mUp; }
+ void setModelviewMatrix(const Eigen::MatrixP3f& modelview);
+ void setProjectionMatrix(const Eigen::MatrixP3f& projection);
+
+ Eigen::MatrixP3f modelviewMatrix() const;
+ Eigen::MatrixP3f projectionMatrix() const;
+
protected:
+ void recalculateModelviewMatrix();
+ void recalculateProjectionMatrix();
+
+protected:
Eigen::Vector3f mPosition;
Eigen::Vector3f mLookAt;
Eigen::Vector3f mUp;
float mFoV, mAspect, mDepthNear, mDepthFar;
+
+ Eigen::MatrixP3f mModelviewMatrix;
+ bool mModelviewMatrixDirty;
+ Eigen::MatrixP3f mProjectionMatrix;
+ bool mProjectionMatrixDirty;
};
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic