/* * Simple trackball-like motion adapted (ripped off) from projtex.c * (written by David Yu and David Blythe). See the SIGGRAPH '96 * Advanced OpenGL course notes. */ #include #include #include #include "tb.h" #include "trackball.h" /* globals */ static GLuint tb_lasttime; float curquat[4]; float lastquat[4]; int beginx, beginy; static GLuint tb_width; static GLuint tb_height; static GLint tb_button = -1; static GLboolean tb_tracking = GL_FALSE; static GLboolean tb_animate = GL_TRUE; static void _tbAnimate(void) { add_quats(lastquat, curquat, curquat); glutPostRedisplay(); } static void _tbStartMotion(int x, int y, int time) { assert(tb_button != -1); glutIdleFunc(0); tb_tracking = GL_TRUE; tb_lasttime = time; beginx = x; beginy = y; } static void _tbStopMotion(unsigned time) { assert(tb_button != -1); tb_tracking = GL_FALSE; if (time == tb_lasttime && tb_animate) { glutIdleFunc(_tbAnimate); } else { if (tb_animate) { glutIdleFunc(0); } } } void tbAnimate(GLboolean animate) { tb_animate = animate; } void tbInit(GLuint button) { tb_button = button; trackball(curquat, 0.0, 0.0, 0.0, 0.0); } void tbMatrix(void) { GLfloat m[4][4]; assert(tb_button != -1); build_rotmatrix(m, curquat); glMultMatrixf(&m[0][0]); } void tbReshape(int width, int height) { assert(tb_button != -1); tb_width = width; tb_height = height; } void tbMouse(int button, int state, int x, int y) { assert(tb_button != -1); if (state == GLUT_DOWN && button == tb_button) _tbStartMotion(x, y, glutGet(GLUT_ELAPSED_TIME)); else if (state == GLUT_UP && button == tb_button) _tbStopMotion(glutGet(GLUT_ELAPSED_TIME)); } void tbMotion(int x, int y) { if (tb_tracking) { trackball(lastquat, (2.0 * beginx - tb_width) / tb_width, (tb_height - 2.0 * beginy) / tb_height, (2.0 * x - tb_width) / tb_width, (tb_height - 2.0 * y) / tb_height ); beginx = x; beginy = y; tb_animate = 1; tb_lasttime = glutGet(GLUT_ELAPSED_TIME); _tbAnimate(); } }