Subversion Repositories gelsvn

Rev

Rev 90 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#ifndef __SIMPLETRACKBALL_H__
#define __SIMPLETRACKBALL_H__

#include "CGLA/CGLA.h"
#include "CGLA/Vec3f.h"


namespace Graphics
{

/** \brief Simple trackball class. 

    Use it to let the mouse movement control the viewing transformation. 

                Typical usage:
                Construct the trackball as a global variable. Call the roll function
                from the GLUT mouse motion callback. Setup an idle callback which only
                calls glutPostRedisplay and call gl_view from the display function to
                set up the view transform.

                Deficiencies: This trackball has many shortcomings. For instance
                you cannot pan but only zoom and rotate. Go fix those problems!
*/
                class SimpleTrackBall
                {
                                CGLA::Vec3f center;
        
                                float r;     // Distance to center (origin)
                                float theta; // Horizontal angle (azimuth)
                                float phi;   // vertical angle (zenith)
        
                                float da;    // angle increment
                                float dr;    // zoom increment

                                bool firsttime;   // used by the roll function
                                float oldx, oldy;

                                int X,Y,Z;

                                void roll_x(float dx);
                                void roll_y(float dy);

                public:

                                /** Constructor. Call with the distance to the center. */
                                SimpleTrackBall(const CGLA::Vec3f& _center, float _r): 
                                                center(_center),
                                                r(_r), theta(M_PI/2.0f), phi(0.0f), 
                                                da(M_PI/100.0f), dr(r/100.0f), firsttime(true),
                                                X(0), Y(1), Z(2)
                                                {} 

                                /** Call this to set up OpenGL viewing matrix. It will also 
                                                clear the view matrix. */
                                void gl_view() const;

                                void get_view(CGLA::Vec3f& c, CGLA::Vec3f& e, CGLA::Vec3f& u)
                                                {
                                                                const CGLA::Vec3f up(0,1,0);
                                                                float x = r * sin(theta) * cos(phi);
                                                                float y = r * cos(theta);
                                                                float z = r * sin(theta) * sin(phi);
                                                                CGLA::Vec3f dir(x,y,z);
                                                                CGLA::Vec3f eye = center + CGLA::Vec3f(dir[X], dir[Y], dir[Z]);
                                                                c = center;
                                                                e = eye;
                                                                u = CGLA::Vec3f(up[X], up[Y], up[Z]);
                                                }

                                void up_axis(char up);

                                /** Move away. Typically called from the keyboard callback */
                                void farther()
                                                {
                                                                r += dr;
                                                }
                
                                /** Move closer. Typically called from the keyboard callback */
                                void closer()
                                                {
                                                                r = CGLA::s_max(0.0f, r - dr);
                                                }

                                /** Roll ball. Call with the x,y coordinates. This function is typically
                                                called from GLUT's mouse motion callback. */
                                void roll(int x, int y);

                                void set_center(const CGLA::Vec3f& _center)
                                                {
                                                                center = _center;
                                                }
                };

}
#endif