KJB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gui_trackball.h
Go to the documentation of this file.
1 /* $Id: gui_trackball.h 18278 2014-11-25 01:42:10Z ksimek $ */
2 /* {{{=========================================================================== *
3  |
4  | Copyright (c) 1994-2011 by Kobus Barnard (author)
5  |
6  | Personal and educational use of this code is granted, provided that this
7  | header is kept intact, and that the authorship is not misrepresented, that
8  | its use is acknowledged in publications, and relevant papers are cited.
9  |
10  | For other use contact the author (kobus AT cs DOT arizona DOT edu).
11  |
12  | Please note that the code in this file has not necessarily been adequately
13  | tested. Naturally, there is no guarantee of performance, support, or fitness
14  | for any particular task. Nonetheless, I am interested in hearing about
15  | problems that you encounter.
16  |
17  | Author: Kyle Simek
18  * =========================================================================== }}}*/
19 
20 // vim: tabstop=4 shiftwidth=4 foldmethod=marker
21 
22 #ifndef KJB_CPP_GUI_TRACKBALL_H
23 #define KJB_CPP_GUI_TRACKBALL_H
24 
25 #ifdef KJB_HAVE_OPENGL
26 #include <m_cpp/m_vector.h>
27 #include <m_cpp/m_vector_d.h>
28 #include <g_cpp/g_quaternion.h>
29 #include <gr_cpp/gr_primitive.h>
30 #include <gr_cpp/gr_opengl.h>
32 
33 #ifdef KJB_HAVE_GLUT
34 #include <gr_cpp/gr_glut.h>
35 #endif
36 
37 #include <boost/bind.hpp>
38 
39 namespace kjb
40 {
41 namespace gui
42 {
43 
44 // forward declaration
45 class Viewer;
46 
63 class Trackball
64 {
65  enum Mouse_mode {no_mode, rotate_mode, zoom_mode, slide_mode} ;
66 public:
72  Trackball(double diameter = 0.7, double x = 0.5, double y = 0.5) :
73  sphere_center_(x,y),
74  sphere_radius_(diameter / 2.0),
75  click_pt_(), // size = 0 is intentional
76  drag_pt_(3),
77  cur_q_(),
78  delta_q_(),
79  cur_mouse_x_(),
80  cur_mouse_y_(),
81  cur_t_(kjb::Vector(0, 0, -10)),
82  xy_scale_(1.0),
83  mode_(no_mode),
84  offset_x_(0),
85  offset_y_(0),
86  width_(1),
87  height_(1),
88  base_cam_(1.0, 1000.0),
89  cam_(base_cam_),
90  cam_dirty_(false),
91  fixed_fovy_(DEFAULT_FOVY * M_PI/180),
92  object_origin_(0.0, 0.0, 0.0),
93  ACCELERATION_FACTOR(1.0/200.0)
94  {
95 
96  base_cam_.set_world_origin(kjb::Vector(cur_t_.begin(), cur_t_.end()));
97  cam_ = base_cam_;
98 
99  set_focal_from_fovy_();
100  }
101 
102 #ifdef KJB_HAVE_GLUT
103  void bind(kjb::opengl::Glut_window& wnd)
105  {
106  using namespace boost;
107 
108  wnd.set_mouse_callback(boost::bind(&Trackball::glut_mouse_down, this, _1, _2, _3, _4));
109  wnd.set_motion_callback(boost::bind(&Trackball::glut_mouse_move, this, _1, _2));
110 
111  update_viewport();
112  }
113 #endif
114 
116  void attach(Viewer& wnd);
117 
118  void update_viewport();
119 
120  void update_viewport(int x, int y, int width, int height);
121 
125  bool glut_mouse_down(int button, int state, int x, int y)
126  {
127  return opengl_mouse_down(button, state, x, height_ - y - 1);
128  }
129 
133  bool opengl_mouse_down(int button, int state, int x, int y);
134 
143  void rotate_mouse_down(double x, double y);
144 
146  bool glut_mouse_move(int x, int y)
147  {
148  return opengl_mouse_move(x, height_ - y - 1);
149  }
150 
152  bool opengl_mouse_move(int x, int y);
153 
157  void zoom_mouse_move(int x, int y);
158 
162  void slide_mouse_move(int x, int y);
163 
167  void translate_mouse_down(int x, int y);
168 
176  void rotate_mouse_move(double x, double y);
177 
178  // Call when dragging is done
179  void rotate_mouse_up();
180 
182  const Quaternion get_orientation()
183  {
184  update_camera_();
185  return cam_.get_orientation();
186  }
187 
188  void set_extrinsic(const kjb::Matrix& extrinsic)
189  {
190  set_extrinsic_dispatch_(extrinsic);
191  }
192 
193  void set_extrinsic(const kjb::Matrix4& extrinsic)
194  {
195  set_extrinsic_dispatch_(extrinsic);
196  }
197 
201  template <class Matrix_type>
202  void set_extrinsic_dispatch_(const Matrix_type& extrinsic);
203 
204  void set_clipping_planes(double near, double far);
205 
209  void set_camera(const Perspective_camera& cam);
210 
213  void set_camera(const Perspective_camera& cam, double height);
214 
215  void set_camera_same_fovy(const Perspective_camera& cam);
216 
217  const kjb::Perspective_camera& get_camera() const;
218 
223  void set_object_origin(const Vector3& o);
224 
225  const Vector3& get_object_origin() const;
226 
229  void reset();
230 
232  inline void prepare_for_rendering()
233  {
234  return prepare_for_rendering_dispatch_(false, 0, 0, 0, 0);
235  }
236 
243  inline void prepare_for_picking(double x, double y, double width, double height)
244  {
245  return prepare_for_rendering_dispatch_(
246  true, x, y, width, height);
247  }
248 
249  void prepare_for_rendering_dispatch_(bool selecting, double select_x, double select_y, double select_dx, double select_dy );
250 
251  void render_object_origin();
252 
253 // /// manually set the trackball orientation
254 // // unclear how to handle non-zero object origin; disabling for now
255 // void set_orientation(const Quaternion& q)
256 // {
257 // // make sure mouse isn't down
258 // assert(click_pt_.size() == 0);
259 //
260 // delta_q_.reset_identity();
261 // cur_q_.reset_identity();
262 //
264 // base_cam_.set_orientation(q);
265 // cam_.set_orientation(q);
266 // }
267 
269  void render();
270 
271  // returns what the trackball thinks the viewport height is
272  int viewport_width()
273  {
274  return width_;
275  }
276 
277  // returns what the trackball thinks the viewport height is
278  int viewport_height()
279  {
280  return height_;
281  }
282 
283  // returns what the trackball thinks the viewport x_offset is
284  int viewport_x_offset()
285  {
286  return offset_x_;
287  }
288 
289  // returns what the trackball thinks the viewport y_offset is
290  int viewport_y_offset()
291  {
292  return offset_x_;
293  }
294 private:
295  // returns the focal length in pixels
296  double get_focal_length_() const
297  {
298  return cam_.get_focal_length();
299  }
300 
302  double get_xy_scale_() const
303  {
304  // z is always negative (origin is always in front of us)
305  // so we negate it here.
306  return -(cur_t_[2]) / get_focal_length_();
307  }
308 
309 
310  double get_z(double x, double y);
311 
312 private:
313  void update_camera_() const;
314 
315 
316  double get_fovy_from_focal_(double focal_length, double image_height);
317 
318  void set_focal_from_fovy_();
319 private:
320 // double near_;
321 // double far_;
322 
323  Vector sphere_center_;
324  double sphere_radius_;
325 
326  Vector click_pt_;
327  Vector drag_pt_;
328 
329  Quaternion cur_q_;
330  Quaternion delta_q_;
331 
332  int cur_mouse_x_;
333  int cur_mouse_y_;
334 
335  kjb::Vector3 cur_t_;
336  double xy_scale_;
337 
338  Mouse_mode mode_;
339 
340  int offset_x_;
341  int offset_y_;
342  int width_;
343  int height_;
344 
345  kjb::Perspective_camera base_cam_;
346  mutable kjb::Perspective_camera cam_;
347  mutable bool cam_dirty_;
348 
349  double fixed_fovy_;
350  Vector3 object_origin_;
351 
352  const double ACCELERATION_FACTOR;
353  static const float DEFAULT_FOVY;
354 };
355 } // namespace gui
356 } // namespace kjb
357 
358 #endif /* HAVE_OPENGL */
359 #endif
Definition: gr_opengl.h:41
Vector_d< 3 > Vector3
Definition: g_quaternion.h:37
height
Definition: APPgetLargeConnectedEdges.m:33
This class implements vectors, in the linear-algebra sense, with real-valued elements.
Definition: m_vector.h:87
St_perspective_camera for modeling a perspective camera using the classic Forsyth and Ponce parametri...
Definition: perspective_camera.h:93
x
Definition: APPgetLargeConnectedEdges.m:100
void render(const Cuboid &c)
Definition: psi_weighted_box.cpp:56
#define M_PI
Definition: fft.cpp:206
This class implements matrices, in the linear-algebra sense, with real-valued elements.
Definition: m_matrix.h:94
Definition for the Vector class, a thin wrapper on the KJB Vector struct and its related functionalit...