29 #include "trackball.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)
79 if (tb_button == -1)
return;
81 tb_tracking = GL_TRUE;
83 _tbPointToVector(x, y, tb_width, tb_height, tb_lastposition);
87 _tbStopMotion(
int button,
unsigned time)
89 if (tb_button == -1)
return;
91 tb_tracking = GL_FALSE;
93 if (time == tb_lasttime && tb_animate) {
94 glutIdleFunc(_tbAnimate);
98 glutIdleFunc(tb_original_idle_func);
103 tbAnimate(GLboolean animate,
void (* idle_func)())
105 tb_animate = animate;
106 tb_original_idle_func = idle_func;
110 tbInit(GLuint button)
118 glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)tb_transform);
125 if (tb_button == -1)
return;
129 glRotatef(tb_angle, tb_axis[0], tb_axis[1], tb_axis[2]);
130 glMultMatrixf((GLfloat *)tb_transform);
131 glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)tb_transform);
134 glMultMatrixf((GLfloat *)tb_transform);
138 tbReshape(
int width,
int height)
140 if (tb_button == -1)
return;
147 tbMouse(
int button,
int state,
int x,
int y)
149 if (tb_button == -1)
return;
151 if (state == GLUT_DOWN && button == tb_button)
152 _tbStartMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME));
153 else if (state == GLUT_UP && button == tb_button)
154 _tbStopMotion(button, glutGet(GLUT_ELAPSED_TIME));
158 tbMotion(
int x,
int y)
160 GLfloat current_position[3], dx, dy, dz;
162 if (tb_button == -1)
return;
164 if (tb_tracking == GL_FALSE)
167 _tbPointToVector(x, y, tb_width, tb_height, current_position);
171 dx = current_position[0] - tb_lastposition[0];
172 dy = current_position[1] - tb_lastposition[1];
173 dz = current_position[2] - tb_lastposition[2];
174 tb_angle = 90.0 * sqrt(dx * dx + dy * dy + dz * dz);
177 tb_axis[0] = tb_lastposition[1] * current_position[2] -
178 tb_lastposition[2] * current_position[1];
179 tb_axis[1] = tb_lastposition[2] * current_position[0] -
180 tb_lastposition[0] * current_position[2];
181 tb_axis[2] = tb_lastposition[0] * current_position[1] -
182 tb_lastposition[1] * current_position[0];
185 tb_lasttime = glutGet(GLUT_ELAPSED_TIME);
186 tb_lastposition[0] = current_position[0];
187 tb_lastposition[1] = current_position[1];
188 tb_lastposition[2] = current_position[2];