gltb.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:4k
源码类别:

GIS编程

开发平台:

Visual C++

  1. /*
  2.  *  Simple trackball-like motion adapted (ripped off) from projtex.c
  3.  *  (written by David Yu and David Blythe).  See the SIGGRAPH '96
  4.  *  Advanced OpenGL course notes.
  5.  */
  6. #include <math.h>
  7. #include <stdio.h>
  8. #include <assert.h>
  9. #include <GL/glut.h>
  10. #include "gltb.h"
  11. #define GLTB_TIME_EPSILON  10
  12. static GLuint    gltb_lasttime;
  13. static GLfloat   gltb_lastposition[3];
  14. static GLfloat   gltb_angle = 0.0;
  15. static GLfloat   gltb_axis[3];
  16. static GLfloat   gltb_transform[4][4];
  17. static GLuint    gltb_width;
  18. static GLuint    gltb_height;
  19. static GLint     gltb_button = -1;
  20. static GLboolean gltb_tracking = GL_FALSE;
  21. static GLboolean gltb_animate = GL_TRUE;
  22. static void
  23. _gltbPointToVector(int x, int y, int width, int height, float v[3])
  24. {
  25.   float d, a;
  26.   /* project x, y onto a hemi-sphere centered within width, height. */
  27.   v[0] = (2.0 * x - width) / width;
  28.   v[1] = (height - 2.0 * y) / height;
  29.   d = sqrt(v[0] * v[0] + v[1] * v[1]);
  30.   v[2] = cos((3.14159265 / 2.0) * ((d < 1.0) ? d : 1.0));
  31.   a = 1.0 / sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
  32.   v[0] *= a;
  33.   v[1] *= a;
  34.   v[2] *= a;
  35. }
  36. static void
  37. _gltbAnimate(void)
  38. {
  39.   glutPostRedisplay();
  40. }
  41. void
  42. _gltbStartMotion(int x, int y, int button, int time)
  43. {
  44.   assert(gltb_button != -1);
  45.   gltb_tracking = GL_TRUE;
  46.   gltb_lasttime = time;
  47.   _gltbPointToVector(x, y, gltb_width, gltb_height, gltb_lastposition);
  48. }
  49. void
  50. _gltbStopMotion(int button, unsigned time)
  51. {
  52.   assert(gltb_button != -1);
  53.   gltb_tracking = GL_FALSE;
  54.   if (time - gltb_lasttime < GLTB_TIME_EPSILON && gltb_animate) {
  55.       glutIdleFunc(_gltbAnimate);
  56.   } else {
  57.     gltb_angle = 0;
  58.     if (gltb_animate)
  59.       glutIdleFunc(0);
  60.   }
  61. }
  62. void
  63. gltbAnimate(GLboolean animate)
  64. {
  65.   gltb_animate = animate;
  66. }
  67. void
  68. gltbInit(GLuint button)
  69. {
  70.   gltb_button = button;
  71.   gltb_angle = 0.0;
  72.   /* put the identity in the trackball transform */
  73.   glPushMatrix();
  74.   glLoadIdentity();
  75.   glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)gltb_transform);
  76.   glPopMatrix();
  77. }
  78. void
  79. gltbMatrix(void)
  80. {
  81.   assert(gltb_button != -1);
  82.   glPushMatrix();
  83.   glLoadIdentity();
  84.   glRotatef(gltb_angle, gltb_axis[0], gltb_axis[1], gltb_axis[2]);
  85.   glMultMatrixf((GLfloat*)gltb_transform);
  86.   glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)gltb_transform);
  87.   glPopMatrix();
  88.   glMultMatrixf((GLfloat*)gltb_transform);
  89. }
  90. void
  91. gltbReshape(int width, int height)
  92. {
  93.   assert(gltb_button != -1);
  94.   gltb_width  = width;
  95.   gltb_height = height;
  96. }
  97. void
  98. gltbMouse(int button, int state, int x, int y)
  99. {
  100.   assert(gltb_button != -1);
  101.   if (state == GLUT_DOWN && button == gltb_button)
  102.     _gltbStartMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME));
  103.   else if (state == GLUT_UP && button == gltb_button)
  104.     _gltbStopMotion(button, glutGet(GLUT_ELAPSED_TIME));
  105. }
  106. void
  107. gltbMotion(int x, int y)
  108. {
  109.   GLfloat current_position[3], dx, dy, dz;
  110.   assert(gltb_button != -1);
  111.   if (gltb_tracking == GL_FALSE)
  112.     return;
  113.   _gltbPointToVector(x, y, gltb_width, gltb_height, current_position);
  114.   /* calculate the angle to rotate by (directly proportional to the
  115.      length of the mouse movement) */
  116.   dx = current_position[0] - gltb_lastposition[0];
  117.   dy = current_position[1] - gltb_lastposition[1];
  118.   dz = current_position[2] - gltb_lastposition[2];
  119.   gltb_angle = 90.0 * sqrt(dx * dx + dy * dy + dz * dz);
  120.   /* calculate the axis of rotation (cross product) */
  121.   gltb_axis[0] = gltb_lastposition[1] * current_position[2] - 
  122.                gltb_lastposition[2] * current_position[1];
  123.   gltb_axis[1] = gltb_lastposition[2] * current_position[0] - 
  124.                gltb_lastposition[0] * current_position[2];
  125.   gltb_axis[2] = gltb_lastposition[0] * current_position[1] - 
  126.                gltb_lastposition[1] * current_position[0];
  127.   /* XXX - constrain motion */
  128.   gltb_axis[2] = 0;
  129.   /* reset for next time */
  130.   gltb_lasttime = glutGet(GLUT_ELAPSED_TIME);
  131.   gltb_lastposition[0] = current_position[0];
  132.   gltb_lastposition[1] = current_position[1];
  133.   gltb_lastposition[2] = current_position[2];
  134.   /* remember to draw new position */
  135.   glutPostRedisplay();
  136. }