Voxel
 All Classes Namespaces Files Functions Typedefs Enumerations Enumerator Macros Pages
renderer_camera.h
Go to the documentation of this file.
1 #pragma once
2 
3 #ifndef RENDERER_CAMERA_H
4 #define RENDERER_CAMERA_H
5 
6 
7 /**
8  \file
9  \brief Contains Renderer::Camera class.
10 */
11 
12 
13 
14 
15 #include "vector.h"
16 
17 #include <cmath>
18 
19 
20 
21 
22 namespace Renderer {
23 
24 
25 
26 
27 /*==============================================================================
28  Camera class
29 ==============================================================================*/
30 
31 
32 /**
33  \brief Camera class.
34 
35  Represents a [camera matrix](http://en.wikipedia.org/wiki/Camera_matrix),
36  consisting of a position, three vectors, and a zoom level. Following
37  convention, the \c Z vector points backwards (i.e. towards the observer,
38  from the scene), the \c Y vector points up (i.e. towards the top of the
39  screen), and the \c X vector points right (i.e. the right side of the
40  screen). Pictorially:
41 
42  |Y
43  |
44  P----X
45  /
46  /Z
47 
48  Where the observer (at position \c P) is looking along the direction
49  opposite \c Z, with \c Y and \c X defining the orientation of the viewing
50  frustum. The 3x4 camera matrix is simply <tt>[X,Y,Z,P]</tt>.
51 */
52 struct Camera {
53 
54  /// \brief Initializes a Camera matrix, and orthonormalizes the vectors.
55  inline Camera(
56  Vector< double, 3 > const& xx,
57  Vector< double, 3 > const& yy,
58  Vector< double, 3 > const& zz,
59  Vector< double, 3 > const& position,
60  double const zoom = 1
61  );
62 
63 
64  inline Vector< double, 3 > const& VectorX() const; ///< Returns the X vector.
65  inline Vector< double, 3 > const& VectorY() const; ///< Returns the Y vector.
66  inline Vector< double, 3 > const& VectorZ() const; ///< Returns the Z vector.
67  inline Vector< double, 3 > const& Position() const; ///< Returns the position.
68  inline double const& Zoom() const; ///< Returns the zoom level.
69 
70 
71  inline void MoveRight( double const distance ); ///< Move the camera right (in camera coordinates) by the specified \p distance.
72  inline void MoveUp( double const distance ); ///< Move the camera up (in camera coordinates) by the specified \p distance.
73  inline void MoveBackward( double const distance ); ///< Move the camera backwards (in camera coordinates) by the specified \p distance.
74 
75  inline void MoveLeft( double const distance ); ///< Move the camera left (in camera coordinates) by the specified \p distance.
76  inline void MoveDown( double const distance ); ///< Move the camera down (in camera coordinates) by the specified \p distance.
77  inline void MoveForward( double const distance ); ///< Move the camera forwards (in camera coordinates) by the specified \p distance.
78 
79  inline void TurnCounterclockwise( double const angle ); ///< Roll the camera counterclockwise (in camera coordinates) by the specified \p angle (measured in radians).
80  inline void TurnDown( double const angle ); ///< Yaw the camera down (in camera coordinates) by the specified \p angle (measured in radians).
81  inline void TurnLeft( double const angle ); ///< Pitch the camera left (in camera coordinates) by the specified \p angle (measured in radians).
82 
83  inline void TurnClockwise( double const angle ); ///< Roll the camera clockwise (in camera coordinates) by the specified \p angle (measured in radians).
84  inline void TurnUp( double const angle ); ///< Yaw the camera up (in camera coordinates) by the specified \p angle (measured in radians).
85  inline void TurnRight( double const angle ); ///< Pitch the camera right (in camera coordinates) by the specified \p angle (measured in radians).
86 
87  inline void ZoomOut( double const amount ); ///< Zooms in by the specified \p amount.
88  inline void ZoomIn( double const amount ); ///< Zooms in by the specified \p amount.
89  inline void ZoomTo( double const zoom = 1 ); ///< Sets the zoom level.
90 
91 
92  inline void Normalize(); ///< Orthonormalize the X, Y and Z vectors.
93 
94 
95 private:
96 
100  Vector< double, 3 > m_position;
101  double m_zoom;
102 };
103 
104 
105 
106 
107 /*==============================================================================
108  Camera methods
109 ==============================================================================*/
110 
111 
113  Vector< double, 3 > const& xx,
114  Vector< double, 3 > const& yy,
115  Vector< double, 3 > const& zz,
116  Vector< double, 3 > const& position,
117  double const zoom
118 ) :
119  m_xx( xx ),
120  m_yy( yy ),
121  m_zz( zz ),
122  m_position( position ),
123  m_zoom( zoom )
124 {
125  assert( m_zoom > 0 );
126  Normalize();
127 }
128 
129 
131 
132  return m_xx;
133 }
134 
135 
137 
138  return m_yy;
139 }
140 
141 
143 
144  return m_zz;
145 }
146 
147 
149 
150  return m_position;
151 }
152 
153 
154 double const& Camera::Zoom() const {
155 
156  return m_zoom;
157 }
158 
159 
160 void Camera::MoveRight( double const distance ) {
161 
162  m_position += m_xx * distance;
163 }
164 
165 
166 void Camera::MoveUp( double const distance ) {
167 
168  m_position += m_yy * distance;
169 }
170 
171 
172 void Camera::MoveBackward( double const distance ) {
173 
174  m_position += m_zz * distance;
175 }
176 
177 
178 void Camera::MoveLeft( double const distance ) {
179 
180  MoveRight( -distance );
181 }
182 
183 
184 void Camera::MoveDown( double const distance ) {
185 
186  MoveUp( -distance );
187 }
188 
189 
190 void Camera::MoveForward( double const distance ) {
191 
192  MoveBackward( -distance );
193 }
194 
195 
196 void Camera::TurnCounterclockwise( double const angle ) {
197 
198  Vector< double, 3 > const xx = m_xx;
199  Vector< double, 3 > const yy = m_yy;
200  double const cosine = std::cos( angle );
201  double const sine = std::sin( angle );
202 
203  m_xx = xx * cosine + yy * sine;
204  m_yy = yy * cosine - xx * sine;
205 }
206 
207 
208 void Camera::TurnDown( double const angle ) {
209 
210  Vector< double, 3 > const yy = m_yy;
211  Vector< double, 3 > const zz = m_zz;
212  double const cosine = std::cos( angle );
213  double const sine = std::sin( angle );
214 
215  m_yy = yy * cosine + zz * sine;
216  m_zz = zz * cosine - yy * sine;
217 }
218 
219 
220 void Camera::TurnLeft( double const angle ) {
221 
222  Vector< double, 3 > const zz = m_zz;
223  Vector< double, 3 > const xx = m_xx;
224  double const cosine = std::cos( angle );
225  double const sine = std::sin( angle );
226 
227  m_zz = zz * cosine + xx * sine;
228  m_xx = xx * cosine - zz * sine;
229 }
230 
231 
232 void Camera::TurnClockwise( double const angle ) {
233 
234  TurnCounterclockwise( -angle );
235 }
236 
237 
238 void Camera::TurnUp( double const angle ) {
239 
240  TurnDown( -angle );
241 }
242 
243 
244 void Camera::TurnRight( double const angle ) {
245 
246  TurnLeft( -angle );
247 }
248 
249 
250 void Camera::ZoomOut( double const amount ) {
251 
252  m_zoom = std::exp( std::log( m_zoom ) + amount );
253 }
254 
255 
256 void Camera::ZoomIn( double const amount ) {
257 
258  ZoomIn( -amount );
259 }
260 
261 
262 void Camera::ZoomTo( double const zoom ) {
263 
264  assert( zoom > 0 );
265  m_zoom = zoom;
266 }
267 
268 
270 
271  /*
272  Orthonormalize using Gram-Schmidt, progressing from the "most
273  important" to "least important" directions. The left/right vector will
274  change most, forward/backward least, and up/down in-between.
275  */
276 
277  m_zz /= m_zz.Norm();
278 
279  m_yy -= Dot( m_yy, m_zz ) * m_zz;
280  m_yy /= m_yy.Norm();
281 
282  m_xx -= Dot( m_xx, m_zz ) * m_zz;
283  m_xx -= Dot( m_xx, m_yy ) * m_yy;
284  m_xx /= m_xx.Norm();
285 }
286 
287 
288 
289 
290 } // namespace Renderer
291 
292 
293 
294 
295 #endif // RENDERER_CAMERA_H