source: GTP/branches/IllumWPdeliver2008dec/IlluminationWP/demos/Standalone/Hierarchical Systems Demo [OpenGL]/RESOURCES/include/glh/glh_glut.h @ 3255

Revision 3255, 19.9 KB checked in by szirmay, 15 years ago (diff)
Line 
1/*
2    glh - is a platform-indepenedent C++ OpenGL helper library
3
4
5    Copyright (c) 2000 Cass Everitt
6        Copyright (c) 2000 NVIDIA Corporation
7    All rights reserved.
8
9    Redistribution and use in source and binary forms, with or
10        without modification, are permitted provided that the following
11        conditions are met:
12
13     * Redistributions of source code must retain the above
14           copyright notice, this list of conditions and the following
15           disclaimer.
16
17     * Redistributions in binary form must reproduce the above
18           copyright notice, this list of conditions and the following
19           disclaimer in the documentation and/or other materials
20           provided with the distribution.
21
22     * The names of contributors to this software may not be used
23           to endorse or promote products derived from this software
24           without specific prior written permission.
25
26       THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27           ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28           LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
29           FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
30           REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31           INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
32           BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33           LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
34           CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35           LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
36           ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37           POSSIBILITY OF SUCH DAMAGE.
38
39
40    Cass Everitt - cass@r3.nu
41*/
42
43#ifndef GLH_GLUT_H
44#define GLH_GLUT_H
45
46// some helper functions and object to
47// make writing simple glut programs even easier! :-)
48
49#ifdef MACOS
50#include <GLUT/glut.h>
51#else
52#include <GL/glut.h>
53#endif
54
55#include <glh/glh_convenience.h>
56#include <algorithm>
57#include <list>
58
59namespace glh
60{
61
62  class glut_interactor
63  {
64  public:
65        glut_interactor() { enabled = true; }
66
67        virtual void display() {}
68        virtual void idle() {}
69        virtual void keyboard(unsigned char key, int x, int y) {}
70        virtual void menu_status(int status, int x, int y) {}
71        virtual void motion(int x, int y) {}
72        virtual void mouse(int button, int state, int x, int y) {}
73        virtual void passive_motion(int x, int y) {}
74        virtual void reshape(int w, int h) {}
75        virtual void special(int  key, int x, int y) {}
76        virtual void timer(int value) {}
77        virtual void visibility(int v) {}
78
79        virtual void enable()  { enabled = true; }
80        virtual void disable() { enabled = false; }
81
82        bool enabled;
83  };
84
85  std::list<glut_interactor *> interactors;
86  bool propagate;
87
88  void glut_display_function()
89  {
90        propagate = true;
91        for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
92                (*it)->display();
93  }
94
95  void glut_idle_function()
96  {
97        propagate = true;
98        for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
99                (*it)->idle();
100  }
101
102  void glut_keyboard_function(unsigned char k, int x, int y)
103  {
104        propagate = true;
105        for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
106          (*it)->keyboard(k, x, y);
107  }
108
109  void glut_menu_status_function(int status, int x, int y)
110  {
111        propagate = true;
112        for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
113                (*it)->menu_status(status, x, y);
114  }
115
116  void glut_motion_function(int x, int y)
117  {
118        propagate = true;
119        for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
120                (*it)->motion(x, y);
121  }
122
123  void glut_mouse_function(int button, int state, int x, int y)
124  {
125        propagate = true;
126        for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
127          (*it)->mouse(button, state, x, y);
128  }
129 
130  void glut_passive_motion_function(int x, int y)
131  {
132        propagate = true;
133        for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
134                (*it)->passive_motion(x, y);
135  }
136
137  void glut_reshape_function(int w, int h)
138  {
139        propagate = true;
140        for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
141          (*it)->reshape(w,h);
142  }
143
144  void glut_special_function(int k, int x, int y)
145  {
146        propagate = true;
147        for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
148          (*it)->special(k, x, y);
149  }
150
151  void glut_timer_function(int v)
152  {
153        propagate = true;
154        for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
155          (*it)->timer(v);
156  }
157
158  void glut_visibility_function(int v)
159  {
160        propagate = true;
161        for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
162          (*it)->visibility(v);
163  }
164
165  // stop processing the current event
166  inline void glut_event_processed()
167  {
168          propagate = false;
169  }
170
171  inline void glut_helpers_initialize()
172  {
173        glutDisplayFunc(glut_display_function);
174        glutIdleFunc(0);
175        glutKeyboardFunc(glut_keyboard_function);
176        glutMenuStatusFunc(glut_menu_status_function);
177        glutMotionFunc(glut_motion_function);
178        glutMouseFunc(glut_mouse_function);
179        glutPassiveMotionFunc(glut_passive_motion_function);
180        glutReshapeFunc(glut_reshape_function);
181        glutSpecialFunc(glut_special_function);
182        glutVisibilityFunc(glut_visibility_function);
183  }
184
185  inline void glut_remove_interactor(glut_interactor *gi)
186  {
187          std::list<glut_interactor *>::iterator it =
188                  std::find(interactors.begin(), interactors.end(), gi);
189        if(it != interactors.end())
190          interactors.erase(it);
191  }
192
193  inline void glut_add_interactor(glut_interactor *gi, bool append=true)
194  {
195        glut_remove_interactor(gi);
196        if(append)
197                interactors.push_back(gi);
198        else
199                interactors.push_front(gi);
200  }
201
202  inline void glut_timer(int msec, int value)
203  {
204        glutTimerFunc(msec, glut_timer_function, value);
205  }
206
207  inline void glut_idle(bool do_idle)
208  {
209        glutIdleFunc(do_idle ? glut_idle_function : 0);
210  }
211
212  class glut_callbacks : public glut_interactor
213  {
214  public:
215        glut_callbacks() :
216                display_function(0),
217                idle_function(0),
218                keyboard_function(0),
219                menu_status_function(0),
220                motion_function(0),
221                mouse_function(0),
222                passive_motion_function(0),
223                reshape_function(0),
224                special_function(0),
225                timer_function(0),
226                visibility_function()
227        {}
228
229        virtual void display()
230        { if(display_function) display_function(); }
231
232        virtual void idle()
233        { if(idle_function) idle_function(); }
234
235        virtual void keyboard(unsigned char k, int x, int y)
236        { if(keyboard_function) keyboard_function(k, x, y); }
237
238        virtual void menu_status(int status, int x, int y)
239        { if(menu_status_function) menu_status_function(status, x, y); }
240
241        virtual void motion(int x, int y)
242        { if(motion_function) motion_function(x,y); }
243
244        virtual void mouse(int button, int state, int x, int y)
245        { if(mouse_function) mouse_function(button, state, x, y); }
246
247        virtual void passive_motion(int x, int y)
248        { if(passive_motion_function) passive_motion_function(x, y); }
249
250        virtual void reshape(int w, int h)
251        { if(reshape_function) reshape_function(w, h); }
252
253        virtual void special(int key, int x, int y)
254        { if(special_function) special_function(key, x, y); }
255
256        virtual void timer(int value)
257        { if(timer_function) timer_function(value); }
258
259        virtual void visibility(int v)
260        { if(visibility_function) visibility_function(v); }
261
262        void (* display_function) ();
263        void (* idle_function) ();
264        void (* keyboard_function) (unsigned char, int, int);
265        void (* menu_status_function) (int, int, int);
266        void (* motion_function) (int, int);
267        void (* mouse_function) (int, int, int, int);
268        void (* passive_motion_function) (int, int);
269        void (* reshape_function) (int, int);
270        void (* special_function) (int, int, int);
271        void (* timer_function) (int);
272        void (* visibility_function) (int);
273
274  };
275
276
277
278  class glut_perspective_reshaper : public glut_interactor
279  {
280  public:
281          glut_perspective_reshaper(float infovy = 60.f, float inzNear = .1f, float inzFar = 10.f)
282                  : fovy(infovy), zNear(inzNear), zFar(inzFar), aspect_factor(1) {}
283         
284          void reshape(int w, int h)
285          {
286                  width = w; height = h;
287
288                  if(enabled) apply();
289          }
290
291          void apply()
292          {
293                  glViewport(0,0,width,height);
294                  glMatrixMode(GL_PROJECTION);
295                  glLoadIdentity();
296                  apply_perspective();
297                  glMatrixMode(GL_MODELVIEW);
298          }
299          void apply_perspective()
300          {
301                  aspect = aspect_factor * float(width)/float(height);
302          if ( aspect < 1 )
303                  {
304                          // fovy is a misnomer.. we really mean the fov applies to the
305                          // smaller dimension
306                          float fovx = fovy;
307                          float real_fov = to_degrees(2 * atan(tan(to_radians(fovx/2))/aspect));
308              gluPerspective(real_fov, aspect, zNear, zFar);
309                  }
310          else
311                    gluPerspective(fovy, aspect, zNear, zFar);
312          }
313          int width, height;
314          float fovy, aspect, zNear, zFar;
315          float aspect_factor;
316  };
317
318  // activates/deactivates on a particular mouse button
319  // and calculates deltas while active
320  class glut_simple_interactor : public glut_interactor
321  {
322  public:
323        glut_simple_interactor()
324        {
325          activate_on = GLUT_LEFT_BUTTON;
326          active = false;
327          use_modifiers = true;
328          modifiers = 0;
329          width = height = 0;
330          x0 = y0 = x = y = dx = dy = 0;
331        }
332
333        virtual void mouse(int button, int state, int X, int Y)
334        {
335          if(enabled && button == activate_on && state == GLUT_DOWN &&
336                 (! use_modifiers || (modifiers == glutGetModifiers())) )
337          {
338                  active = true;
339                  x = x0 = X;
340                  y = y0 = Y;
341                  dx = dy = 0;
342          }
343          else if (enabled && button == activate_on && state == GLUT_UP)
344          {
345                if(dx == 0 && dy == 0)
346                        update();
347                active = false;
348                dx = dy = 0;
349          }
350        }
351
352        virtual void motion(int X, int Y)
353        {
354          if(enabled && active)
355          {
356                dx = X - x;   dy = y - Y;
357                x = X;   y = Y;
358                update();
359          }
360        }
361
362        void reshape(int w, int h)
363        {
364                  width = w; height = h;
365        }
366
367        virtual void apply_transform() = 0;
368        virtual void apply_inverse_transform() = 0;
369        virtual matrix4f get_transform() = 0;
370        virtual matrix4f get_inverse_transform() = 0;
371
372        virtual void update() {}
373
374        int activate_on;
375        bool use_modifiers;
376        int modifiers;
377        bool active;
378        int x0, y0;
379        int x, y;
380        int dx, dy;
381        int width, height;
382  };
383
384
385  class glut_pan : public glut_simple_interactor
386  {
387  public:
388        glut_pan()
389        {
390          scale = .01f;
391          invert_increment = false;
392          parent_rotation = 0;
393        }
394        void update()
395        {
396          vec3f v(dx, dy, 0);
397          if(parent_rotation != 0) parent_rotation->mult_vec(v);
398
399          if(invert_increment)
400                  pan -= v * scale;
401          else
402                  pan += v * scale;
403          glutPostRedisplay();
404        }
405
406        void apply_transform()
407        {
408          //cerr << "Applying transform: " << (x - x0) << ", " << (y - y0) << endl;
409          glTranslatef(pan[0], pan[1], pan[2]);
410        }
411       
412        void apply_inverse_transform()
413        {
414          //cerr << "Applying transform: " << (x - x0) << ", " << (y - y0) << endl;
415          glTranslatef(-pan[0], -pan[1], -pan[2]);
416        }
417
418        matrix4f get_transform()
419        {
420                matrix4f m;
421                m.make_identity();
422                m.set_translate(pan);
423                return m;
424        }       
425
426        matrix4f get_inverse_transform()
427        {
428                matrix4f m;
429                m.make_identity();
430                m.set_translate(-pan);
431                return m;
432        }       
433
434
435        bool invert_increment;
436        const rotationf * parent_rotation;
437        vec3f pan;
438        float scale;
439  };
440
441 
442  class glut_dolly : public glut_simple_interactor
443  {
444  public:
445        glut_dolly()
446        {
447          scale = .01f;
448          invert_increment = false;
449          parent_rotation = 0;
450        }
451        void update()
452        {
453          vec3f v(0,0,dy);
454          if(parent_rotation != 0) parent_rotation->mult_vec(v);
455
456          if(invert_increment)
457                  dolly += v * scale;
458          else
459                  dolly -= v * scale;
460          glutPostRedisplay();
461        }
462
463        void apply_transform()
464        {
465          //cerr << "Applying transform: " << (x - x0) << ", " << (y - y0) << endl;
466          glTranslatef(dolly[0], dolly[1], dolly[2]);
467        }
468
469        void apply_inverse_transform()
470        {
471          //cerr << "Applying transform: " << (x - x0) << ", " << (y - y0) << endl;
472          glTranslatef(-dolly[0], -dolly[1], -dolly[2]);
473        }
474       
475        matrix4f get_transform()
476        {
477                matrix4f m;
478                m.make_identity();
479                m.set_translate(dolly);
480                return m;
481        }       
482
483        matrix4f get_inverse_transform()
484        {
485                matrix4f m;
486                m.make_identity();
487                m.set_translate(-dolly);
488                return m;
489        }       
490
491
492        bool invert_increment;
493        const rotationf * parent_rotation;
494        vec3f dolly;
495        float scale;
496  };
497
498
499  class glut_trackball : public glut_simple_interactor
500  {
501  public:
502        glut_trackball()
503        {
504                r = rotationf(vec3f(0, 1, 0), 0);
505                centroid = vec3f(0,0,0);
506                scale = 1;
507                invert_increment = false;
508                parent_rotation = 0;
509                legacy_mode = false;
510        }
511
512        void update()
513        {
514        if(dx == 0 && dy == 0)
515                {
516                        incr = rotationf();
517                        return;
518                }
519               
520                if(legacy_mode)
521                {
522                        vec3f v(dy, -dx, 0);
523                        float len = v.normalize();
524                        if(parent_rotation != 0) parent_rotation->mult_vec(v);
525                        //r.mult_dir(vec3f(v), v);
526                        if(invert_increment)
527                                incr.set_value(v, -len * scale * -.01);
528                        else
529                                incr.set_value(v, len * scale * -.01);
530                }
531                else
532                {
533                        float min = width < height ? width : height;
534                        min /= 2.f;
535                        vec3f offset(width/2.f, height/2.f, 0);
536                        vec3f a(x-dx, height - (y+dy), 0);
537                        vec3f b(   x, height -     y , 0);
538                        a -= offset;
539                        b -= offset;
540                        a /= min;
541                        b /= min;
542
543                        a[2] = pow(2.0f, -0.5f * a.length());
544                        a.normalize();
545                        b[2] = pow(2.0f, -0.5f * b.length());
546                        b.normalize();
547
548
549                        vec3f axis = a.cross(b);
550                        axis.normalize();
551
552                        float angle = acos(a.dot(b));
553
554                        if(parent_rotation != 0) parent_rotation->mult_vec(axis);
555
556                        if(invert_increment)
557                                incr.set_value(axis, -angle * scale);
558                        else
559                                incr.set_value(axis, angle * scale);
560                               
561                }
562
563                // fixme: shouldn't operator*() preserve 'r' in this case?
564                if(incr[3] != 0)
565                        r = incr * r;
566                glutPostRedisplay();
567        }
568
569        void increment_rotation()
570        {
571                if(active) return;
572                // fixme: shouldn't operator*() preserve 'r' in this case?
573                if(incr[3] != 0)
574                        r = incr * r;
575                glutPostRedisplay();
576        }
577
578        void apply_transform()
579        {
580                glTranslatef(centroid[0], centroid[1], centroid[2]);
581                glh_rotate(r);
582                glTranslatef(-centroid[0], -centroid[1], -centroid[2]);
583        }
584
585        void apply_inverse_transform()
586        {
587                glTranslatef(centroid[0], centroid[1], centroid[2]);
588                glh_rotate(r.inverse());
589                glTranslatef(-centroid[0], -centroid[1], -centroid[2]);
590        }
591
592
593        matrix4f get_transform()
594        {
595                matrix4f mt, mr, minvt;
596                mt.set_translate(centroid);
597                r.get_value(mr);
598                minvt.set_translate(-centroid);
599                return mt * mr * minvt;
600        }
601
602        matrix4f get_inverse_transform()
603        {
604                matrix4f mt, mr, minvt;
605                mt.set_translate(centroid);
606                r.inverse().get_value(mr);
607                minvt.set_translate(-centroid);
608                return mt * mr * minvt;
609        }
610
611        bool invert_increment;
612        const rotationf * parent_rotation;
613        rotationf r;
614        vec3f centroid;
615        float scale;
616        bool legacy_mode;
617        rotationf incr;
618  };
619
620 
621  class glut_rotate : public glut_simple_interactor
622  {
623  public:
624        glut_rotate()
625        {
626          rotate_x = rotate_y = 0;
627          scale = 1;
628        }
629        void update()
630        {
631          rotate_x += dx * scale;
632          rotate_y += dy * scale;
633          glutPostRedisplay();
634        }
635
636        void apply_transform()
637        {
638          glRotatef(rotate_x, 0, 1, 0);
639          glRotatef(rotate_y, -1, 0, 0);
640        }
641
642        void apply_inverse_transform()
643        {
644          glRotatef(-rotate_y, -1, 0, 0);
645          glRotatef(-rotate_x, 0, 1, 0);
646        }
647
648        matrix4f get_transform()
649        {
650                rotationf rx(to_radians(rotate_x), 0, 1, 0);
651                rotationf ry(to_radians(rotate_y), -1, 0, 0);
652                matrix4f mx, my;
653                rx.get_value(mx);
654                ry.get_value(my);
655                return mx * my;
656        }       
657
658        matrix4f get_inverse_transform()
659        {
660                rotationf rx(to_radians(-rotate_x), 0, 1, 0);
661                rotationf ry(to_radians(-rotate_y), -1, 0, 0);
662                matrix4f mx, my;
663                rx.get_value(mx);
664                ry.get_value(my);
665                return my * mx;
666        }       
667
668        float rotate_x, rotate_y, scale;
669  };
670
671  class glut_mouse_to_keyboard : public glut_simple_interactor
672  {
673  public:
674          glut_mouse_to_keyboard()
675          {
676                  keyboard_function = 0;
677                  pos_dx_key = neg_dx_key = pos_dy_key = neg_dy_key = 0;
678          }
679          void apply_transform() {}
680
681          void apply_inverse_transform() {}
682
683          matrix4f get_transform() {return matrix4f();}
684
685          matrix4f get_inverse_transform() {return matrix4f();}
686
687          void update()
688          {
689                  if(!keyboard_function) return;
690                  if(dx > 0)
691                        keyboard_function(pos_dx_key, x, y);
692                  else if(dx < 0)
693                        keyboard_function(neg_dx_key, x, y);
694                  if(dy > 0)
695                        keyboard_function(pos_dy_key, x, y);
696                  else if(dy < 0)
697                        keyboard_function(neg_dy_key, x, y);           
698          }
699          unsigned char pos_dx_key, neg_dx_key, pos_dy_key, neg_dy_key;
700          void (*keyboard_function)(unsigned char, int, int);
701  };
702
703  inline void glut_exit_on_escape(unsigned char k, int x = 0, int y = 0)
704  { if(k==27) exit(0); }
705
706  struct glut_simple_mouse_interactor : public glut_interactor
707  {
708
709  public:
710        glut_simple_mouse_interactor(int num_buttons_to_use=3)
711        {
712          configure_buttons(num_buttons_to_use);
713          camera_mode = false;
714        }
715
716        void enable()
717        {
718                trackball.enable();
719                pan.enable();
720                dolly.enable();
721        }
722
723        void disable()
724        {
725                trackball.disable();
726                pan.disable();
727                dolly.disable();
728        }
729
730        void set_camera_mode(bool cam)
731        {
732                camera_mode = cam;
733                if(camera_mode)
734                {
735                        trackball.invert_increment = true;
736                        pan.invert_increment = true;
737                        dolly.invert_increment = true;
738                        pan.parent_rotation = & trackball.r;
739                        dolly.parent_rotation = & trackball.r;
740                }
741                else
742                {
743                        trackball.invert_increment = false;
744                        pan.invert_increment = false;
745                        dolly.invert_increment = false;
746                        if(pan.parent_rotation == &trackball.r) pan.parent_rotation = 0;
747                        if(dolly.parent_rotation == &trackball.r) dolly.parent_rotation = 0;
748                }
749        }
750        void configure_buttons(int num_buttons_to_use = 3)
751        {
752          switch(num_buttons_to_use)
753          {
754          case 1:
755                trackball.activate_on = GLUT_LEFT_BUTTON;
756                trackball.modifiers = 0;
757
758                pan.activate_on = GLUT_LEFT_BUTTON;
759                pan.modifiers = GLUT_ACTIVE_SHIFT;
760
761
762                dolly.activate_on = GLUT_LEFT_BUTTON;
763                dolly.modifiers = GLUT_ACTIVE_CTRL;
764
765                break;
766
767          case 2:
768                trackball.activate_on = GLUT_LEFT_BUTTON;
769                trackball.modifiers = 0;
770
771                pan.activate_on = GLUT_MIDDLE_BUTTON;
772                pan.modifiers = 0;
773
774
775                dolly.activate_on = GLUT_LEFT_BUTTON;
776                dolly.modifiers = GLUT_ACTIVE_CTRL;
777
778                break;
779
780          case 3:
781          default:
782                trackball.activate_on = GLUT_LEFT_BUTTON;
783                trackball.modifiers = 0;
784
785                pan.activate_on = GLUT_MIDDLE_BUTTON;
786                pan.modifiers = 0;
787
788                dolly.activate_on = GLUT_RIGHT_BUTTON;
789                dolly.modifiers = 0;
790
791                break;
792          }
793        }
794
795        virtual void motion(int x, int y)
796        {
797
798                trackball.motion(x,y);
799
800                pan.motion(x,y);
801
802                dolly.motion(x,y);
803        }
804        virtual void mouse(int button, int state, int x, int y)
805        {
806          trackball.mouse(button, state, x, y);
807          pan.mouse(button, state, x, y);
808          dolly.mouse(button, state, x, y);
809        }
810
811        virtual void reshape(int x, int y)
812        {
813                trackball.reshape(x,y);
814                pan.reshape(x,y);
815                dolly.reshape(x,y);
816        }
817
818        void apply_transform()
819        {
820          pan.apply_transform();
821          dolly.apply_transform();
822          trackball.apply_transform();
823        }
824
825        void apply_inverse_transform()
826        {
827          trackball.apply_inverse_transform();
828          dolly.apply_inverse_transform();
829          pan.apply_inverse_transform();
830        }
831
832        matrix4f get_transform()
833        {
834          return ( pan.get_transform()       *
835                           dolly.get_transform()     *
836                           trackball.get_transform() );
837        }
838
839        matrix4f get_inverse_transform()
840        {
841          return ( trackball.get_inverse_transform() *
842                           dolly.get_inverse_transform()     *
843                           pan.get_inverse_transform()       );
844        }
845
846        void set_parent_rotation(rotationf *rp)
847        {
848                trackball.parent_rotation = rp;
849                dolly.parent_rotation = rp;
850                pan.parent_rotation = rp;
851        }
852
853        bool camera_mode;
854        glut_trackball trackball;
855        glut_pan  pan;
856        glut_dolly dolly;
857  };
858
859}
860
861#endif
Note: See TracBrowser for help on using the repository browser.