-void glsnake_idol(glsnake_configuration * bp) {
- /* time since last iteration */
- long iter_msec;
- /* time since the beginning of last morph */
- long morf_msec;
- float iter_angle_max;
- int i;
- struct timeb current_time;
- int still_morphing;
-
- /* Do nothing to the model if we are paused */
- if (bp->paused) {
- /* Avoid busy waiting when nothing is changing */
- usleep(1);
- return;
- }
- /* ftime is winDOS compatible */
- ftime(¤t_time);
-
- /* <spiv> Well, ftime gives time with millisecond resolution.
- * <Jaq> if current time is exactly equal to last iteration,
- * then don't do this block
- * <spiv> (or worse, perhaps... who knows what the OS will do)
- * <spiv> So if no discernable amount of time has passed:
- * <spiv> a) There's no point updating the screen, because
- * it would be the same
- * <spiv> b) The code will divide by zero
- */
- iter_msec = (long) current_time.millitm - bp->last_iteration.millitm +
- ((long) current_time.time - bp->last_iteration.time) * 1000L;
- if (iter_msec) {
- /* save the current time */
- memcpy(&(bp->last_iteration), ¤t_time, sizeof(struct timeb));
-
- /* work out if we have to switch models */
- morf_msec = bp->last_iteration.millitm - bp->last_morph.millitm +
- ((long) (bp->last_iteration.time - bp->last_morph.time) * 1000L);
-
- if ((morf_msec > statictime) && !bp->interactive) {
- memcpy(&(bp->last_morph), &(bp->last_iteration), sizeof(struct timeb));
- start_morph(RAND(bp->m_count), 0, bp);
- }
-
- if (bp->interactive && !bp->morphing) {
- usleep(1);
- return;
- }
-
- if (!bp->dragging && !bp->interactive) {
- bp->roty += 360/((1000/yspin)/iter_msec);
- bp->rotz += 360/((1000/zspin)/iter_msec);
- }
-
- /* work out the maximum angle for this iteration */
- iter_angle_max = 90.0 * (velocity/1000.0) * iter_msec;
-
- still_morphing = 0;
- for (i = 0; i < 24; i++) {
- float cur_angle = bp->node[i].cur_angle;
- float dest_angle = bp->node[i].dest_angle;
- if (cur_angle != dest_angle) {
- still_morphing = 1;
- if (fabs(cur_angle - dest_angle) <= iter_angle_max)
- bp->node[i].cur_angle = dest_angle;
- else if (fmod(cur_angle - dest_angle + 360, 360) > 180)
- bp->node[i].cur_angle = fmod(cur_angle + iter_angle_max, 360);
- else
- bp->node[i].cur_angle = fmod(cur_angle + 360 - iter_angle_max, 360);
- }
- }
-
- if (!still_morphing)
- bp->morphing = 0;
-
- /* colour cycling */
- if (fabs(bp->colour[0] - bp->colour_t[0]) <= fabs(bp->colour_i[0]))
- bp->colour[0] = bp->colour_t[0];
- else
- bp->colour[0] += bp->colour_i[0];
- if (fabs(bp->colour[1] - bp->colour_t[1]) <= fabs(bp->colour_i[1]))
- bp->colour[1] = bp->colour_t[1];
- else
- bp->colour[1] += bp->colour_i[1];
- if (fabs(bp->colour[2] - bp->colour_t[2]) <= fabs(bp->colour_i[2]))
- bp->colour[2] = bp->colour_t[2];
- else
- bp->colour[2] += bp->colour_i[2];
- } else {
- /* We are going too fast, so we may as well let the
- * cpu relax a little by sleeping for a millisecond. */
- usleep(1);
- }
+void glsnake_idol(glsnake_configuration * bp)
+{
+ /* time since last iteration */
+ long iter_msec;
+ /* time since the beginning of last morph */
+ long morf_msec;
+ float iter_angle_max;
+ int i;
+ struct timeval current_time;
+ int still_morphing;
+
+ /* Do nothing to the model if we are paused */
+ if (bp->paused) {
+ /* Avoid busy waiting when nothing is changing */
+ usleep(1);
+ return;
+ }
+
+ {
+# ifdef GETTIMEOFDAY_TWO_ARGS
+ struct timezone tzp;
+ gettimeofday(¤t_time, &tzp);
+# else
+ gettimeofday(¤t_time);
+# endif
+ }
+
+ /* <spiv> Well, ftime gives time with millisecond resolution.
+ * <Jaq> if current time is exactly equal to last iteration,
+ * then don't do this block
+ * <spiv> (or worse, perhaps... who knows what the OS will do)
+ * <spiv> So if no discernable amount of time has passed:
+ * <spiv> a) There's no point updating the screen, because
+ * it would be the same
+ * <spiv> b) The code will divide by zero
+ */
+ iter_msec = ((long) current_time.tv_usec - bp->last_iteration.tv_usec)/1000L +
+ ((long) current_time.tv_sec - bp->last_iteration.tv_sec) * 1000L;
+ if (iter_msec) {
+ /* save the current time */
+ memcpy(&bp->last_iteration, ¤t_time,
+ sizeof(bp->last_iteration));
+
+ /* work out if we have to switch models */
+ morf_msec = (bp->last_iteration.tv_usec - bp->last_morph.tv_usec)/1000L +
+ ((long) (bp->last_iteration.tv_sec - bp->last_morph.tv_sec) * 1000L);
+
+ if ((morf_msec > statictime) && !bp->interactive) {
+ memcpy(&bp->last_morph, &(bp->last_iteration),
+ sizeof(bp->last_morph));
+ start_morph(RAND(bp->m_count), 0, bp);
+ }
+
+ if (bp->interactive && !bp->morphing) {
+ usleep(1);
+ return;
+ }
+
+ if (!bp->dragging && !bp->interactive) {
+ bp->roty += 360/((1000/yspin)/iter_msec);
+ bp->rotz += 360/((1000/zspin)/iter_msec);
+ }
+
+ /* work out the maximum angle for this iteration */
+ iter_angle_max = 90.0 * (velocity/1000.0) * iter_msec;
+
+ still_morphing = 0;
+ for (i = 0; i < 24; i++) {
+ float cur_angle = bp->node[i].cur_angle;
+ float dest_angle = bp->node[i].dest_angle;
+ if (cur_angle != dest_angle) {
+ still_morphing = 1;
+ if (fabs(cur_angle - dest_angle) <= iter_angle_max)
+ bp->node[i].cur_angle = dest_angle;
+ else if (fmod(cur_angle - dest_angle + 360, 360) > 180)
+ bp->node[i].cur_angle = fmod(cur_angle + iter_angle_max, 360);
+ else
+ bp->node[i].cur_angle = fmod(cur_angle + 360 - iter_angle_max, 360);
+ }
+ }
+
+ if (!still_morphing)
+ bp->morphing = 0;
+
+ /* colour cycling */
+ if (fabs(bp->colour[0] - bp->colour_t[0]) <= fabs(bp->colour_i[0]))
+ bp->colour[0] = bp->colour_t[0];
+ else
+ bp->colour[0] += bp->colour_i[0];
+ if (fabs(bp->colour[1] - bp->colour_t[1]) <= fabs(bp->colour_i[1]))
+ bp->colour[1] = bp->colour_t[1];
+ else
+ bp->colour[1] += bp->colour_i[1];
+ if (fabs(bp->colour[2] - bp->colour_t[2]) <= fabs(bp->colour_i[2]))
+ bp->colour[2] = bp->colour_t[2];
+ else
+ bp->colour[2] += bp->colour_i[2];
+ } else {
+ /* We are going too fast, so we may as well let the
+ * cpu relax a little by sleeping for a millisecond. */
+ usleep(1);
+ }
+}
+
+static void
+snake_bounding_box (ModeInfo *mi,
+ GLfloat *x1, GLfloat *y1, GLfloat *z1,
+ GLfloat *x2, GLfloat *y2, GLfloat *z2)
+{
+ glsnake_configuration *bp = &glc[MI_SCREEN(mi)];
+ int i;
+ GLdouble identity[16] = { 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1 };
+ GLint vp[4] = { 0, 0, 1, 1 };
+ *x1 = *x2 = 0;
+ *y1 = *y2 = 0;
+ *z1 = *z2 = 0;
+
+ glPushMatrix();
+ glLoadIdentity();
+ for (i = 0; i < 24; i++)
+ {
+ GLdouble model[16];
+ GLdouble x, y, z;
+ GLfloat ang = bp->node[i].cur_angle;
+
+ glGetDoublev (GL_MODELVIEW_MATRIX, model);
+ gluProject (0, 0, 0, model, identity, vp, &x, &y, &z);
+fprintf (stderr, "%2d: %5.2f %5.2f %5.2f\n", i, (float)x, (float)y, (float)z);
+
+ if (x < *x1) *x1 = x;
+ else if (x > *x2) *x2 = x;
+ if (y < *y1) *y1 = y;
+ else if (y > *y2) *y2 = y;
+ if (z < *z1) *z1 = z;
+ else if (z > *z2) *z2 = z;
+
+ glTranslatef(0.5, 0.5, 0.5);
+ glRotatef(90, 0.0, 0.0, -1.0);
+ glTranslatef(1.0 + explode, 0.0, 0.0);
+ glRotatef(180 + ang, 1.0, 0.0, 0.0);
+ glTranslatef(-0.5, -0.5, -0.5);
+ }
+fprintf(stderr, "\n");
+ glPopMatrix();
+
+#if 0
+ *x1 -= 1;
+ *y1 -= 1;
+ *z1 -= 1;
+ *x2 += 1;
+ *y2 += 1;
+ *z2 += 1;
+#endif
+}
+
+
+static void
+draw_bounding_box (ModeInfo *mi)
+{
+ static GLfloat c1[4] = { 0.4, 0.4, 0.4, 1.0 };
+ static GLfloat c2[4] = { 1.0, 0.0, 0.0, 1.0 };
+ int wire = MI_IS_WIREFRAME(mi);
+ GLfloat x1, y1, z1, x2, y2, z2;
+ snake_bounding_box (mi, &x1, &y1, &z1, &x2, &y2, &z2);
+
+ glColor3f (c1[0], c1[1], c1[2]);
+/* glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, c1);*/
+ glFrontFace(GL_CCW);
+
+ glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
+ glNormal3f(0, 1, 0);
+ glVertex3f(x1, y1, z1); glVertex3f(x1, y1, z2);
+ glVertex3f(x2, y1, z2); glVertex3f(x2, y1, z1);
+ glEnd();
+ glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
+ glNormal3f(0, -1, 0);
+ glVertex3f(x2, y2, z1); glVertex3f(x2, y2, z2);
+ glVertex3f(x1, y2, z2); glVertex3f(x1, y2, z1);
+ glEnd();
+ glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
+ glNormal3f(0, 0, 1);
+ glVertex3f(x1, y1, z1); glVertex3f(x2, y1, z1);
+ glVertex3f(x2, y2, z1); glVertex3f(x1, y2, z1);
+ glEnd();
+ glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
+ glNormal3f(0, 0, -1);
+ glVertex3f(x1, y2, z2); glVertex3f(x2, y2, z2);
+ glVertex3f(x2, y1, z2); glVertex3f(x1, y1, z2);
+ glEnd();
+ glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
+ glNormal3f(1, 0, 0);
+ glVertex3f(x1, y2, z1); glVertex3f(x1, y2, z2);
+ glVertex3f(x1, y1, z2); glVertex3f(x1, y1, z1);
+ glEnd();
+ glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
+ glNormal3f(-1, 0, 0);
+ glVertex3f(x2, y1, z1); glVertex3f(x2, y1, z2);
+ glVertex3f(x2, y2, z2); glVertex3f(x2, y2, z1);
+ glEnd();
+
+ glPushAttrib (GL_LIGHTING);
+ glDisable (GL_LIGHTING);
+
+ glColor3f (c2[0], c2[1], c2[2]);
+ glBegin(GL_LINES);
+ if (x1 > 0) x1 = 0; if (x2 < 0) x2 = 0;
+ if (y1 > 0) y1 = 0; if (y2 < 0) y2 = 0;
+ if (z1 > 0) z1 = 0; if (z2 < 0) z2 = 0;
+ glVertex3f(x1, 0, 0); glVertex3f(x2, 0, 0);
+ glVertex3f(0 , y1, 0); glVertex3f(0, y2, 0);
+ glVertex3f(0, 0, z1); glVertex3f(0, 0, z2);
+ glEnd();
+
+ glPopAttrib();