00001 #ifndef OPENTISSUE_UTILITY_GL_GL_CAMERA_H
00002 #define OPENTISSUE_UTILITY_GL_GL_CAMERA_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/utility/gl/gl_trackball.h>
00013 #include <vector>
00014 #include <cassert>
00015
00016 namespace OpenTissue
00017 {
00018 namespace gl
00019 {
00020
00037 template<typename math_types>
00038 class Camera : public TrackBall<math_types>
00039 {
00040 public:
00041
00042 typedef TrackBall<math_types> base_class;
00043 typedef typename math_types::real_type real_type;
00044 typedef typename math_types::vector3_type vector3_type;
00045 typedef typename math_types::matrix3x3_type matrix3x3_type;
00046
00047 protected:
00048
00049 vector3_type m_position;
00050 vector3_type m_target;
00051 vector3_type m_up;
00052 vector3_type m_dof;
00053 vector3_type m_right;
00054 GLfloat m_modelview[ 16 ];
00055
00056 protected:
00057
00058 bool m_orbit_mode;
00059 bool m_target_locked;
00060 vector3_type m_tmp_position;
00061 vector3_type m_tmp_target;
00062 vector3_type m_tmp_up;
00063
00064 public:
00065
00066 vector3_type const & up() const { return m_up; }
00067 vector3_type const & target() const { return m_target; }
00068 vector3_type const & position() const { return m_position; }
00069 vector3_type const & right() const { return m_right; }
00070 vector3_type const & dof() const { return m_dof; }
00071 GLfloat const * get_modelview_matrix()const {return m_modelview; };
00072 bool & orbit_mode(){return m_orbit_mode;};
00073 bool const & orbit_mode()const {return m_orbit_mode;};
00074 bool & target_locked(){return m_target_locked;};
00075 bool const & target_locked()const {return m_target_locked;};
00076
00077 public:
00078
00079 Camera()
00080 : m_orbit_mode(true)
00081 , m_target_locked(false)
00082 {
00083 init(vector3_type(0,0,40),vector3_type(0,0,0),vector3_type(0,1,0));
00084 };
00085
00095 void init(vector3_type const & position_, vector3_type const & target_, vector3_type const & up_)
00096 {
00097 m_position = position_;
00098 m_target = target_;
00099 m_up = up_;
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 m_dof = unit(m_target - m_position);
00112 m_right = unit(m_dof % m_up);
00113 m_up = m_right % m_dof;
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 m_modelview[ 0 ] = m_right(0); m_modelview[ 4 ] = m_right(1); m_modelview[ 8 ] = m_right(2); m_modelview[ 12 ] = -m_right*m_position;
00131 m_modelview[ 1 ] = m_up(0); m_modelview[ 5 ] = m_up(1); m_modelview[ 9 ] = m_up(2); m_modelview[ 13 ] = -m_up*m_position;
00132 m_modelview[ 2 ] = -m_dof(0); m_modelview[ 6 ] = -m_dof(1); m_modelview[ 10 ] = -m_dof(2); m_modelview[ 14 ] = m_dof*m_position;
00133 m_modelview[ 3 ] = 0.0f; m_modelview[ 7 ] = 0.0f; m_modelview[ 11 ] = 0.0f; m_modelview[ 15 ] = 1.0f;
00134 };
00135
00143 real_type depth(vector3_type const & r)const { return m_dof*(r-m_position); }
00144
00145 public:
00146
00152 void rotate(matrix3x3_type const & R)
00153 {
00154 matrix3x3_type Rc;
00155 Rc(0,0) = m_right(0); Rc(0,1) = m_right(1); Rc(0,2) = m_right(2);
00156 Rc(1,0) = m_up(0); Rc(1,1) = m_up(1); Rc(1,2) = m_up(2);
00157 Rc(2,0) = -m_dof(0); Rc(2,1) = -m_dof(1); Rc(2,2) = -m_dof(2);
00158 matrix3x3_type H = trans(Rc)*R*Rc;
00159 if(!m_target_locked)
00160 {
00161 m_target = H*(m_target - m_position) + m_position;
00162 }
00163 m_up = H*m_up;
00164 init(m_position,m_target,m_up);
00165 };
00166
00172 void orbit(matrix3x3_type const & R)
00173 {
00174 matrix3x3_type Rc;
00175 Rc(0,0) = m_right(0); Rc(0,1) = m_right(1); Rc(0,2) = m_right(2);
00176 Rc(1,0) = m_up(0); Rc(1,1) = m_up(1); Rc(1,2) = m_up(2);
00177 Rc(2,0) = -m_dof(0); Rc(2,1) = -m_dof(1); Rc(2,2) = -m_dof(2);
00178 matrix3x3_type H = trans(Rc)*R*Rc;
00179
00180 m_position = H*(m_position-m_target) + m_target;
00181 m_up = H*m_up;
00182 init(m_position,m_target,m_up);
00183 };
00184
00191 void pan(real_type const & x, real_type const & y)
00192 {
00193 vector3_type panx = x * m_right;
00194 vector3_type pany = y * unit(m_right % m_dof);
00195 m_position += panx;
00196 m_position += pany;
00197 if(!m_target_locked)
00198 {
00199 m_target += panx;
00200 m_target += pany;
00201 }
00202 init(m_position,m_target,m_up);
00203 };
00204
00209 void move(real_type const & distance)
00210 {
00211 m_position += m_dof*distance;
00212 if(!m_target_locked)
00213 m_target += m_dof*distance;
00214 init(m_position,m_target,m_up);
00215 };
00216
00217 public:
00218
00224 void mouse_down(real_type const & sx,real_type const & sy)
00225 {
00226 m_tmp_position = m_position;
00227 m_tmp_target = m_target;
00228 m_tmp_up = m_up;
00229 base_class::mouse_down(sx,sy);
00230 };
00231
00237 void mouse_up(real_type const & sx,real_type const & sy)
00238 {
00239 base_class::mouse_up(sx,sy);
00240 init(m_tmp_position, m_tmp_target, m_tmp_up);
00241 if(m_orbit_mode)
00242 orbit( trans( this->get_incremental_rotation() ));
00243 else
00244 rotate( this->get_incremental_rotation() );
00245 };
00246
00252 void mouse_move(real_type const & sx,real_type const & sy)
00253 {
00254 base_class::mouse_move(sx,sy);
00255 init(m_tmp_position, m_tmp_target, m_tmp_up);
00256 if(m_orbit_mode)
00257 orbit( trans( this->get_incremental_rotation() ));
00258 else
00259 rotate( this->get_incremental_rotation() );
00260 }
00261
00262 };
00263
00268 template<typename types>
00269 inline void MultCameraMatrix(Camera<types> const & camera)
00270 {
00271 glMultMatrixf( camera.get_modelview_matrix() );
00272 }
00273
00278 template<typename types>
00279 inline void LoadCameraMatrix(Camera<types> const & camera)
00280 {
00281 glLoadMatrixf( camera.get_modelview_matrix() );
00282 }
00283
00284 }
00285
00286 }
00287
00288
00289 #endif