source: pacpussensors/trunk/Vislab/lib3dv/eigen/demos/opengl/camera.cpp@ 140

Last change on this file since 140 was 136, checked in by ldecherf, 8 years ago

Doc

File size: 5.8 KB
Line 
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
10#include "camera.h"
11
12#include "gpuhelper.h"
13#include <GL/glu.h>
14
15#include "Eigen/LU"
16using namespace Eigen;
17
18Camera::Camera()
19 : mViewIsUptodate(false), mProjIsUptodate(false)
20{
21 mViewMatrix.setIdentity();
22
23 mFovY = M_PI/3.;
24 mNearDist = 1.;
25 mFarDist = 50000.;
26
27 mVpX = 0;
28 mVpY = 0;
29
30 setPosition(Vector3f::Constant(100.));
31 setTarget(Vector3f::Zero());
32}
33
34Camera& Camera::operator=(const Camera& other)
35{
36 mViewIsUptodate = false;
37 mProjIsUptodate = false;
38
39 mVpX = other.mVpX;
40 mVpY = other.mVpY;
41 mVpWidth = other.mVpWidth;
42 mVpHeight = other.mVpHeight;
43
44 mTarget = other.mTarget;
45 mFovY = other.mFovY;
46 mNearDist = other.mNearDist;
47 mFarDist = other.mFarDist;
48
49 mViewMatrix = other.mViewMatrix;
50 mProjectionMatrix = other.mProjectionMatrix;
51
52 return *this;
53}
54
55Camera::Camera(const Camera& other)
56{
57 *this = other;
58}
59
60Camera::~Camera()
61{
62}
63
64
65void Camera::setViewport(uint offsetx, uint offsety, uint width, uint height)
66{
67 mVpX = offsetx;
68 mVpY = offsety;
69 mVpWidth = width;
70 mVpHeight = height;
71
72 mProjIsUptodate = false;
73}
74
75void Camera::setViewport(uint width, uint height)
76{
77 mVpWidth = width;
78 mVpHeight = height;
79
80 mProjIsUptodate = false;
81}
82
83void Camera::setFovY(float value)
84{
85 mFovY = value;
86 mProjIsUptodate = false;
87}
88
89Vector3f Camera::direction(void) const
90{
91 return - (orientation() * Vector3f::UnitZ());
92}
93Vector3f Camera::up(void) const
94{
95 return orientation() * Vector3f::UnitY();
96}
97Vector3f Camera::right(void) const
98{
99 return orientation() * Vector3f::UnitX();
100}
101
102void Camera::setDirection(const Vector3f& newDirection)
103{
104 // TODO implement it computing the rotation between newDirection and current dir ?
105 Vector3f up = this->up();
106
107 Matrix3f camAxes;
108
109 camAxes.col(2) = (-newDirection).normalized();
110 camAxes.col(0) = up.cross( camAxes.col(2) ).normalized();
111 camAxes.col(1) = camAxes.col(2).cross( camAxes.col(0) ).normalized();
112 setOrientation(Quaternionf(camAxes));
113
114 mViewIsUptodate = false;
115}
116
117void Camera::setTarget(const Vector3f& target)
118{
119 mTarget = target;
120 if (!mTarget.isApprox(position()))
121 {
122 Vector3f newDirection = mTarget - position();
123 setDirection(newDirection.normalized());
124 }
125}
126
127void Camera::setPosition(const Vector3f& p)
128{
129 mFrame.position = p;
130 mViewIsUptodate = false;
131}
132
133void Camera::setOrientation(const Quaternionf& q)
134{
135 mFrame.orientation = q;
136 mViewIsUptodate = false;
137}
138
139void Camera::setFrame(const Frame& f)
140{
141 mFrame = f;
142 mViewIsUptodate = false;
143}
144
145void Camera::rotateAroundTarget(const Quaternionf& q)
146{
147 Matrix4f mrot, mt, mtm;
148
149 // update the transform matrix
150 updateViewMatrix();
151 Vector3f t = mViewMatrix * mTarget;
152
153 mViewMatrix = Translation3f(t)
154 * q
155 * Translation3f(-t)
156 * mViewMatrix;
157
158 Quaternionf qa(mViewMatrix.linear());
159 qa = qa.conjugate();
160 setOrientation(qa);
161 setPosition(- (qa * mViewMatrix.translation()) );
162
163 mViewIsUptodate = true;
164}
165
166void Camera::localRotate(const Quaternionf& q)
167{
168 float dist = (position() - mTarget).norm();
169 setOrientation(orientation() * q);
170 mTarget = position() + dist * direction();
171 mViewIsUptodate = false;
172}
173
174void Camera::zoom(float d)
175{
176 float dist = (position() - mTarget).norm();
177 if(dist > d)
178 {
179 setPosition(position() + direction() * d);
180 mViewIsUptodate = false;
181 }
182}
183
184void Camera::localTranslate(const Vector3f& t)
185{
186 Vector3f trans = orientation() * t;
187 setPosition( position() + trans );
188 setTarget( mTarget + trans );
189
190 mViewIsUptodate = false;
191}
192
193void Camera::updateViewMatrix(void) const
194{
195 if(!mViewIsUptodate)
196 {
197 Quaternionf q = orientation().conjugate();
198 mViewMatrix.linear() = q.toRotationMatrix();
199 mViewMatrix.translation() = - (mViewMatrix.linear() * position());
200
201 mViewIsUptodate = true;
202 }
203}
204
205const Affine3f& Camera::viewMatrix(void) const
206{
207 updateViewMatrix();
208 return mViewMatrix;
209}
210
211void Camera::updateProjectionMatrix(void) const
212{
213 if(!mProjIsUptodate)
214 {
215 mProjectionMatrix.setIdentity();
216 float aspect = float(mVpWidth)/float(mVpHeight);
217 float theta = mFovY*0.5;
218 float range = mFarDist - mNearDist;
219 float invtan = 1./tan(theta);
220
221 mProjectionMatrix(0,0) = invtan / aspect;
222 mProjectionMatrix(1,1) = invtan;
223 mProjectionMatrix(2,2) = -(mNearDist + mFarDist) / range;
224 mProjectionMatrix(3,2) = -1;
225 mProjectionMatrix(2,3) = -2 * mNearDist * mFarDist / range;
226 mProjectionMatrix(3,3) = 0;
227
228 mProjIsUptodate = true;
229 }
230}
231
232const Matrix4f& Camera::projectionMatrix(void) const
233{
234 updateProjectionMatrix();
235 return mProjectionMatrix;
236}
237
238void Camera::activateGL(void)
239{
240 glViewport(vpX(), vpY(), vpWidth(), vpHeight());
241 gpu.loadMatrix(projectionMatrix(),GL_PROJECTION);
242 gpu.loadMatrix(viewMatrix().matrix(),GL_MODELVIEW);
243}
244
245
246Vector3f Camera::unProject(const Vector2f& uv, float depth) const
247{
248 Matrix4f inv = mViewMatrix.inverse().matrix();
249 return unProject(uv, depth, inv);
250}
251
252Vector3f Camera::unProject(const Vector2f& uv, float depth, const Matrix4f& invModelview) const
253{
254 updateViewMatrix();
255 updateProjectionMatrix();
256
257 Vector3f a(2.*uv.x()/float(mVpWidth)-1., 2.*uv.y()/float(mVpHeight)-1., 1.);
258 a.x() *= depth/mProjectionMatrix(0,0);
259 a.y() *= depth/mProjectionMatrix(1,1);
260 a.z() = -depth;
261 // FIXME /\/|
262 Vector4f b = invModelview * Vector4f(a.x(), a.y(), a.z(), 1.);
263 return Vector3f(b.x(), b.y(), b.z());
264}
Note: See TracBrowser for help on using the repository browser.