29 #include "trackball.h"
31 #include <GL/freeglut.h>
36 static GLuint tb_lasttime;
37 static GLfloat tb_lastposition[3];
39 static GLfloat tb_angle = 0.0;
40 static GLfloat tb_axis[3];
41 static GLfloat tb_transform[4][4];
43 static GLuint tb_width;
44 static GLuint tb_height;
46 static GLint tb_button = -1;
47 static GLboolean tb_tracking = GL_FALSE;
48 static GLboolean tb_animate = GL_TRUE;
50 static void (*tb_original_idle_func)();
54 _tbPointToVector(
int x,
int y,
int width,
int height,
float v[3])
59 v[0] = (2.0 * x - width) / width;
60 v[1] = (height - 2.0 * y) / height;
61 d = sqrt(v[0] * v[0] + v[1] * v[1]);
62 v[2] = cos((3.14159265 / 2.0) * ((d < 1.0) ? d : 1.0));
63 a = 1.0 / sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
72 tb_original_idle_func();
77 _tbStartMotion(
int x,
int y,
int button,
int time)
82 tb_tracking = GL_TRUE;
84 _tbPointToVector(x, y, tb_width, tb_height, tb_lastposition);
88 _tbStopMotion(
int button,
unsigned time)
93 tb_tracking = GL_FALSE;
95 if (time == tb_lasttime && tb_animate) {
96 glutIdleFunc(_tbAnimate);
100 glutIdleFunc(tb_original_idle_func);
105 tbAnimate(GLboolean animate,
void (*idle_func)())
107 tb_animate = animate;
108 tb_original_idle_func = idle_func;
112 tbInit(GLuint button)
120 glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)tb_transform);
132 glRotatef(tb_angle, tb_axis[0], tb_axis[1], tb_axis[2]);
133 glMultMatrixf((GLfloat *)tb_transform);
134 glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)tb_transform);
137 glMultMatrixf((GLfloat *)tb_transform);
141 tbReshape(
int width,
int height)
151 tbMouse(
int button,
int state,
int x,
int y)
156 if (state == GLUT_DOWN && button == tb_button)
157 _tbStartMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME));
158 else if (state == GLUT_UP && button == tb_button)
159 _tbStopMotion(button, glutGet(GLUT_ELAPSED_TIME));
163 tbMotion(
int x,
int y)
165 GLfloat current_position[3], dx, dy, dz;
170 if (tb_tracking == GL_FALSE)
173 _tbPointToVector(x, y, tb_width, tb_height, current_position);
177 dx = current_position[0] - tb_lastposition[0];
178 dy = current_position[1] - tb_lastposition[1];
179 dz = current_position[2] - tb_lastposition[2];
180 tb_angle = 90.0 * sqrt(dx * dx + dy * dy + dz * dz);
183 tb_axis[0] = tb_lastposition[1] * current_position[2] - tb_lastposition[2] * current_position[1];
184 tb_axis[1] = tb_lastposition[2] * current_position[0] - tb_lastposition[0] * current_position[2];
185 tb_axis[2] = tb_lastposition[0] * current_position[1] - tb_lastposition[1] * current_position[0];
188 tb_lasttime = glutGet(GLUT_ELAPSED_TIME);
189 tb_lastposition[0] = current_position[0];
190 tb_lastposition[1] = current_position[1];
191 tb_lastposition[2] = current_position[2];