gallium: change remaining util functions to use cso sampler views
[mesa/mesa-lb.git] / progs / demos / geartrain.c
blob00b6e78b724000f098b84b8e2041b18ac2037f30
2 /*
3 * GearTrain Simulator * Version: 1.00
5 * Copyright (C) 1999 Shobhan Kumar Dutta All Rights Reserved.
6 * <skdutta@del3.vsnl.net.in>
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * SHOBHAN KUMAR DUTTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
23 * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
28 #include <assert.h>
29 #include <math.h>
30 #include <stdlib.h>
31 #include <GL/glut.h>
32 #include <string.h>
33 #include <stdio.h>
35 #ifndef min
36 #define min(x, y) ( x < y ? x : y )
37 #endif
39 #ifndef M_PI
40 #define M_PI 3.14159265
41 #endif /* */
42 typedef GLfloat TDA[4];
44 TDA background;
47 struct AXLE
49 char name[20];
50 GLint id;
51 GLfloat radius;
52 GLint axis;
53 TDA color;
54 TDA position;
55 GLfloat length;
56 GLint motored;
57 GLfloat angular_velocity;
58 GLint direction;
62 struct GEAR
64 char name[20];
65 char type[7];
66 GLint face;
67 GLint id;
68 GLfloat radius;
69 GLfloat width;
70 GLint teeth;
71 GLfloat tooth_depth;
72 GLfloat angle;
73 GLfloat angular_velocity;
74 TDA color;
75 GLint relative_position;
76 TDA position;
77 char axle_name[20];
78 GLint axis;
79 GLint direction;
80 GLint motored;
84 struct BELT
86 char name[20];
87 GLint id;
88 char gear1_name[20];
89 char gear2_name[20];
93 FILE * mainfile;
94 struct GEAR g[10];
95 struct AXLE a[10];
96 struct BELT b[10];
97 int number_of_gears;
98 int number_of_axles;
99 int number_of_belts;
102 char Buf1[256], Buf2[256], Buf3[256], Buf4[256], Buf5[256];
104 static GLint T0 = 0;
105 static GLint Frames = 0;
108 #ifndef _WIN32
109 static void
110 strset (char buf[], char ch)
112 int i;
113 for (i = 0; i < strlen (buf); i++)
114 buf[i] = ch;
116 #endif
119 static void
120 Clear_Buffers ()
122 strset (Buf1, 0);
123 strset (Buf2, 0);
124 strset (Buf3, 0);
125 strset (Buf4, 0);
126 strset (Buf5, 0);
130 static void
131 LoadTriplet (TDA A)
133 int result;
134 Clear_Buffers ();
135 result = fscanf (mainfile, "%s %s %s %s", Buf1, Buf2, Buf3, Buf4);
136 assert(result != EOF);
137 A[0] = atof (Buf2);
138 A[1] = atof (Buf3);
139 A[2] = atof (Buf4);
143 static void
144 LoadReal (float *a)
146 int result;
147 Clear_Buffers ();
148 result = fscanf (mainfile, "%s %s", Buf1, Buf2);
149 assert(result != EOF);
150 *a = atof (Buf2);
154 static void
155 LoadInteger (int *a)
157 int result;
158 Clear_Buffers ();
159 result = fscanf (mainfile, "%s %s", Buf1, Buf2);
160 assert(result != EOF);
161 *a = atoi (Buf2);
165 static void
166 LoadText (char *a)
168 int result;
169 Clear_Buffers ();
170 result = fscanf (mainfile, "%s %s", Buf1, Buf2);
171 assert(result != EOF);
172 strcpy (a, Buf2);
176 static void
177 getdata (char filename[])
179 int gear_count = 0, axle_count = 0, belt_count = 0, i;
181 mainfile = fopen (filename, "r");
182 if (!mainfile) {
183 printf("Error: couldn't open %s\n", filename);
184 exit(-1);
189 int result;
190 Clear_Buffers ();
191 result = fscanf (mainfile, "%s", Buf1);
192 (void) result;
193 if (ferror (mainfile))
195 printf ("\nError opening file !\n");
196 exit (1);
199 if (!(strcmp (Buf1, "BACKGROUND")))
200 LoadTriplet (background);
202 if (!(strcmp (Buf1, "ANAME")))
204 LoadText (a[axle_count].name);
205 axle_count++;
208 if (!(strcmp (Buf1, "ARADIUS")))
209 LoadReal (&a[axle_count - 1].radius);
211 if (!(strcmp (Buf1, "AAXIS")))
212 LoadInteger (&a[axle_count - 1].axis);
214 if (!(strcmp (Buf1, "ACOLOR")))
215 LoadTriplet (a[axle_count - 1].color);
217 if (!(strcmp (Buf1, "APOSITION")))
218 LoadTriplet (a[axle_count - 1].position);
220 if (!(strcmp (Buf1, "ALENGTH")))
221 LoadReal (&a[axle_count - 1].length);
223 if (!(strcmp (Buf1, "AMOTORED")))
224 LoadInteger (&a[axle_count - 1].motored);
226 if (!(strcmp (Buf1, "AANGULARVELOCITY")))
227 LoadReal (&a[axle_count - 1].angular_velocity);
229 if (!(strcmp (Buf1, "ADIRECTION")))
230 LoadInteger (&a[axle_count - 1].direction);
232 if (!(strcmp (Buf1, "GNAME")))
234 LoadText (g[gear_count].name);
235 gear_count++;
238 if (!(strcmp (Buf1, "GTYPE")))
239 LoadText (g[gear_count - 1].type);
241 if (!(strcmp (Buf1, "GFACE")))
242 LoadInteger (&g[gear_count - 1].face);
244 if (!(strcmp (Buf1, "GRADIUS")))
245 LoadReal (&g[gear_count - 1].radius);
247 if (!(strcmp (Buf1, "GWIDTH")))
248 LoadReal (&g[gear_count - 1].width);
250 if (!(strcmp (Buf1, "GTEETH")))
251 LoadInteger (&g[gear_count - 1].teeth);
253 if (!(strcmp (Buf1, "GTOOTHDEPTH")))
254 LoadReal (&g[gear_count - 1].tooth_depth);
256 if (!(strcmp (Buf1, "GCOLOR")))
257 LoadTriplet (g[gear_count - 1].color);
259 if (!(strcmp (Buf1, "GAXLE")))
260 LoadText (g[gear_count - 1].axle_name);
262 if (!(strcmp (Buf1, "GPOSITION")))
263 LoadInteger (&g[gear_count - 1].relative_position);
265 if (!(strcmp (Buf1, "BELTNAME")))
267 LoadText (b[belt_count].name);
268 belt_count++;
271 if (!(strcmp (Buf1, "GEAR1NAME")))
272 LoadText (b[belt_count - 1].gear1_name);
274 if (!(strcmp (Buf1, "GEAR2NAME")))
275 LoadText (b[belt_count - 1].gear2_name);
278 while (Buf1[0] != 0);
280 for (i = 0; i < number_of_gears; i++)
282 g[i].axis = -1;
283 g[i].direction = 0;
284 g[i].angular_velocity = 0.0;
287 number_of_gears = gear_count;
288 number_of_axles = axle_count;
289 number_of_belts = belt_count;
290 fclose (mainfile);
294 static void
295 axle (GLint j, GLfloat radius, GLfloat length)
297 GLfloat angle, rad, incr = 10.0 * M_PI / 180.0;
299 /* draw main cylinder */
300 glBegin (GL_QUADS);
301 for (angle = 0.0; angle < 360.0; angle += 5.0)
303 rad = angle * M_PI / 180.0;
304 glNormal3f (cos (rad), sin (rad), 0.0);
305 glVertex3f (radius * cos (rad), radius * sin (rad), length / 2);
306 glVertex3f (radius * cos (rad), radius * sin (rad), -length / 2);
307 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), -length / 2);
308 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), length / 2);
310 glEnd ();
312 /* draw front face */
313 glNormal3f (0.0, 0.0, 1.0);
314 glBegin (GL_TRIANGLES);
315 for (angle = 0.0; angle < 360.0; angle += 5.0)
317 rad = angle * M_PI / 180.0;
318 glVertex3f (0.0, 0.0, length / 2);
319 glVertex3f (radius * cos (rad), radius * sin (rad), length / 2);
320 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), length / 2);
321 glVertex3f (0.0, 0.0, length / 2);
323 glEnd ();
325 /* draw back face */
326 glNormal3f (0.0, 0.0, -1.0);
327 glBegin (GL_TRIANGLES);
328 for (angle = 0.0; angle <= 360.0; angle += 5.0)
330 rad = angle * M_PI / 180.0;
331 glVertex3f (0.0, 0.0, -length / 2);
332 glVertex3f (radius * cos (rad), radius * sin (rad), -length / 2);
333 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), -length / 2);
334 glVertex3f (0.0, 0.0, -length / 2);
336 glEnd ();
341 static void
342 gear (GLint j, char type[], GLfloat radius, GLfloat width,
343 GLint teeth, GLfloat tooth_depth)
345 GLint i;
346 GLfloat r1, r2;
347 GLfloat angle, da;
348 GLfloat u, v, len, fraction = 0.5;
349 GLfloat n = 1.0;
351 r1 = radius - tooth_depth;
352 r2 = radius;
354 da = 2.0 * M_PI / teeth / 4.0;
355 if (!g[j].face)
357 fraction = -0.5;
358 n = -1.0;
360 if (!(strcmp (type, "NORMAL")))
362 fraction = 0.5;
363 n = 1.0;
366 /* draw front face */
367 if (!(strcmp (type, "NORMAL")))
369 glNormal3f (0.0, 0.0, 1.0 * n);
370 glBegin (GL_QUAD_STRIP);
371 for (i = 0; i <= teeth; i++)
373 angle = i * 2.0 * M_PI / teeth;
374 glVertex3f (0.0, 0.0, width * fraction);
375 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
376 glVertex3f (0.0, 0.0, width * fraction);
377 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
379 glEnd ();
381 else
383 glNormal3f (0.0, 0.0, 1.0 * n);
384 glBegin (GL_QUAD_STRIP);
385 for (i = 0; i <= teeth; i++)
387 angle = i * 2.0 * M_PI / teeth;
388 glVertex3f (0.0, 0.0, width * fraction);
389 glVertex3f ((r2 - width) * cos (angle), (r2 - width) * sin (angle), width * fraction);
390 glVertex3f (0.0, 0.0, width * fraction);
391 glVertex3f ((r2 - width) * cos (angle + 3 * da), (r2 - width) * sin (angle + 3 * da), width * fraction);
393 glEnd ();
396 /* draw front sides of teeth */
397 if (!(strcmp (type, "NORMAL")))
399 glNormal3f (0.0, 0.0, 1.0 * n);
400 glBegin (GL_QUADS);
401 da = 2.0 * M_PI / teeth / 4.0;
402 for (i = 0; i < teeth; i++)
404 angle = i * 2.0 * M_PI / teeth;
405 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
406 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), width * fraction);
407 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), width * fraction);
408 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
410 glEnd ();
413 glNormal3f (0.0, 0.0, -1.0 * n);
415 /* draw back face */
416 glBegin (GL_QUAD_STRIP);
417 for (i = 0; i <= teeth; i++)
419 angle = i * 2.0 * M_PI / teeth;
420 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
421 glVertex3f (0.0, 0.0, -width * fraction);
422 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
423 glVertex3f (0.0, 0.0, -width * fraction);
425 glEnd ();
427 /* draw back sides of teeth */
428 glNormal3f (0.0, 0.0, -1.0 * n);
429 glBegin (GL_QUADS);
430 da = 2.0 * M_PI / teeth / 4.0;
431 for (i = 0; i < teeth; i++)
433 angle = i * 2.0 * M_PI / teeth;
434 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
435 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
436 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
437 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
439 glEnd ();
442 /* draw outward faces of teeth */
443 if (!(strcmp (type, "NORMAL")))
445 glBegin (GL_QUAD_STRIP);
446 for (i = 0; i < teeth; i++)
448 angle = i * 2.0 * M_PI / teeth;
450 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
451 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
452 u = r2 * cos (angle + da) - r1 * cos (angle);
453 v = r2 * sin (angle + da) - r1 * sin (angle);
454 len = sqrt (u * u + v * v);
455 u /= len;
456 v /= len;
457 glNormal3f (v, -u, 0.0);
458 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), width * fraction);
459 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
460 glNormal3f (cos (angle), sin (angle), 0.0);
461 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), width * fraction);
462 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
463 u = r1 * cos (angle + 3 * da) - r2 * cos (angle + 2 * da);
464 v = r1 * sin (angle + 3 * da) - r2 * sin (angle + 2 * da);
465 glNormal3f (v, -u, 0.0);
466 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
467 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
468 glNormal3f (cos (angle), sin (angle), 0.0);
471 else
473 glBegin (GL_QUAD_STRIP);
474 for (i = 0; i < teeth; i++)
476 angle = i * 2.0 * M_PI / teeth;
477 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
478 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
479 u = r2 * cos (angle + da) - r1 * cos (angle);
480 v = r2 * sin (angle + da) - r1 * sin (angle);
481 len = sqrt (u * u + v * v);
482 u /= len;
483 v /= len;
484 glNormal3f (v, -u, 0.0);
485 glVertex3f ((r2 - width) * cos (angle + da), (r2 - width) * sin (angle + da), width * fraction);
486 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
487 glNormal3f (cos (angle), sin (angle), n);
488 glVertex3f ((r2 - width) * cos (angle + 2 * da), (r2 - width) * sin (angle + 2 * da), width * fraction);
489 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
490 u = r1 * cos (angle + 3 * da) - r2 * cos (angle + 2 * da);
491 v = r1 * sin (angle + 3 * da) - r2 * sin (angle + 2 * da);
492 glNormal3f (v, -u, 0.0);
493 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
494 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
495 glNormal3f (cos (angle), sin (angle), n);
499 glVertex3f (r1 * cos (0), r1 * sin (0), width * fraction);
500 glVertex3f (r1 * cos (0), r1 * sin (0), -width * fraction);
501 glEnd ();
505 static void
506 belt (struct GEAR g1, struct GEAR g2)
508 GLfloat D, alpha, phi, angle, incr, width;
509 GLint indexes[3] =
511 0, 0, 0
514 GLfloat col[3] =
516 0.0, 0.0, 0.0
519 width = min (g1.width, g2.width);
520 D = sqrt (pow (g1.position[0] - g2.position[0], 2) + pow (g1.position[1] - g2.position[1], 2) + pow (g1.position[2] - g2.position[2], 2));
521 alpha = acos ((g2.position[0] - g1.position[0]) / D);
522 phi = acos ((g1.radius - g2.radius) / D);
523 glBegin (GL_QUADS);
524 glColor3fv (col);
525 glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
526 incr = 1.2 * 360.0 / g1.teeth * M_PI / 180.00;
527 for (angle = alpha + phi; angle <= 2 * M_PI - phi + alpha; angle += 360.0 / g1.teeth * M_PI / 180.00)
529 glNormal3f (cos (angle), sin (angle), 0.0);
530 glVertex3f (g1.radius * cos (angle), g1.radius * sin (angle), width * 0.5);
531 glVertex3f (g1.radius * cos (angle), g1.radius * sin (angle), -width * 0.5);
532 glVertex3f (g1.radius * cos (angle + incr), g1.radius * sin (angle + incr), -width * 0.5);
533 glVertex3f (g1.radius * cos (angle + incr), g1.radius * sin (angle + incr), width * 0.5);
535 glEnd ();
536 glBegin (GL_QUADS);
537 glColor3fv (col);
538 glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
539 incr = 1.2 * 360.0 / g2.teeth * M_PI / 180.00;
540 for (angle = -phi + alpha; angle <= phi + alpha; angle += 360.0 / g1.teeth * M_PI / 180.0)
542 glNormal3f (cos (angle), sin (angle), 0.0);
543 glVertex3f (g2.radius * cos (angle) + g2.position[0] - g1.position[0], g2.radius * sin (angle) + g2.position[1] - g1.position[1], width * 0.5);
544 glVertex3f (g2.radius * cos (angle) + g2.position[0] - g1.position[0], g2.radius * sin (angle) + g2.position[1] - g1.position[1], width * -0.5);
545 glVertex3f (g2.radius * cos (angle + incr) + g2.position[0] - g1.position[0], g2.radius * sin (angle + incr) + g2.position[1] - g1.position[1], width * -0.5);
546 glVertex3f (g2.radius * cos (angle + incr) + g2.position[0] - g1.position[0], g2.radius * sin (angle + incr) + g2.position[1] - g1.position[1], width * 0.5);
548 glEnd ();
550 glBegin (GL_QUADS);
551 glColor3fv (col);
552 glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
553 glVertex3f (g1.radius * cos (alpha + phi), g1.radius * sin (alpha + phi), width * 0.5);
554 glVertex3f (g1.radius * cos (alpha + phi), g1.radius * sin (alpha + phi), width * -0.5);
555 glVertex3f (g2.radius * cos (alpha + phi) + g2.position[0] - g1.position[0], g2.radius * sin (alpha + phi) + g2.position[1] - g1.position[1], width * -0.5);
556 glVertex3f (g2.radius * cos (alpha + phi) + g2.position[0] - g1.position[0], g2.radius * sin (alpha + phi) + g2.position[1] - g1.position[1], width * 0.5);
557 glVertex3f (g1.radius * cos (alpha - phi), g1.radius * sin (alpha - phi), width * 0.5);
558 glVertex3f (g1.radius * cos (alpha - phi), g1.radius * sin (alpha - phi), width * -0.5);
559 glVertex3f (g2.radius * cos (alpha - phi) + g2.position[0] - g1.position[0], g2.radius * sin (alpha - phi) + g2.position[1] - g1.position[1], width * -0.5);
560 glVertex3f (g2.radius * cos (alpha - phi) + g2.position[0] - g1.position[0], g2.radius * sin (alpha - phi) + g2.position[1] - g1.position[1], width * 0.5);
561 glEnd ();
565 static int
566 axle_find (char axle_name[])
568 int i;
570 for (i = 0; i < number_of_axles; i++)
572 if (!(strcmp (axle_name, a[i].name)))
573 break;
575 return i;
579 static int
580 gear_find (char gear_name[])
582 int i;
584 for (i = 0; i < number_of_gears; i++)
586 if (!(strcmp (gear_name, g[i].name)))
587 break;
589 return i;
593 static void
594 process ()
596 GLfloat x, y, z, D, dist;
597 GLint axle_index, i, j, g1, g2, k;
598 char error[80];
600 for (i = 0; i < number_of_gears; i++)
602 x = 0.0;
603 y = 0.0;
604 z = 0.0;
605 axle_index = axle_find (g[i].axle_name);
606 g[i].axis = a[axle_index].axis;
607 g[i].motored = a[axle_index].motored;
608 if (a[axle_index].motored)
610 g[i].direction = a[axle_index].direction;
611 g[i].angular_velocity = a[axle_index].angular_velocity;
613 if (g[i].axis == 0)
614 x = 1.0;
615 else if (g[i].axis == 1)
616 y = 1.0;
617 else
618 z = 1.0;
620 g[i].position[0] = a[axle_index].position[0] + x * g[i].relative_position;
621 g[i].position[1] = a[axle_index].position[1] + y * g[i].relative_position;
622 g[i].position[2] = a[axle_index].position[2] + z * g[i].relative_position;
625 for (k = 0; k < number_of_axles; k++)
627 for (i = 0; i < number_of_gears - 1; i++)
629 for (j = 0; j < number_of_gears; j++)
631 if (!(strcmp (g[i].type, g[j].type)) && (!(strcmp (g[i].type, "NORMAL"))) && ((strcmp (g[i].axle_name, g[j].axle_name) != 0)) && (g[i].axis == g[j].axis))
633 D = sqrt (pow (g[i].position[0] - g[j].position[0], 2) + pow (g[i].position[1] - g[j].position[1], 2) + pow (g[i].position[2] - g[j].position[2], 2));
634 if (D < 1.1 * (g[i].radius - g[i].tooth_depth + g[j].radius - g[j].tooth_depth))
636 printf (error, "Gear %s and %s are too close to each other.", g[i].name, g[j].name);
638 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
639 exit (1);
642 if (g[i].axis == 0)
644 dist = g[i].position[0] - g[j].position[0];
646 else if (g[i].axis == 1)
648 dist = g[i].position[1] - g[j].position[1];
650 else
651 dist = g[i].position[2] - g[j].position[2];
653 dist = fabs (dist);
655 if (dist < (g[i].width / 2 + g[j].width / 2))
657 if ((g[i].motored) && (!(g[j].motored)) && (D < 0.95 * (g[i].radius + g[j].radius)))
659 axle_index = axle_find (g[j].axle_name);
660 if ((a[axle_index].direction != 0) && (g[j].angular_velocity != g[i].angular_velocity * g[i].teeth / g[j].teeth * g[i].radius / g[j].radius))
662 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
663 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
664 exit (1);
667 g[j].motored = (a[axle_index].motored = 1);
668 g[j].direction = (a[axle_index].direction = -g[i].direction);
669 a[axle_index].angular_velocity = g[i].angular_velocity * g[i].teeth / g[j].teeth;
670 g[j].angular_velocity = (a[axle_index].angular_velocity *= g[i].radius / g[j].radius);
673 if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * (g[i].radius + g[j].radius)))
675 axle_index = axle_find (g[i].axle_name);
676 if ((a[axle_index].direction != 0) && (g[i].angular_velocity != g[j].angular_velocity * g[j].teeth / g[i].teeth * g[j].radius / g[i].radius))
678 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
679 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
680 exit (1);
683 g[i].motored = (a[axle_index].motored = 1);
684 g[i].direction = (a[axle_index].direction = -g[j].direction);
685 a[axle_index].angular_velocity = g[j].angular_velocity * g[j].teeth / g[i].teeth;
686 g[i].angular_velocity = (a[axle_index].angular_velocity *= g[j].radius / g[i].radius);
692 if (!(strcmp (g[i].type, g[j].type)) && (!(strcmp (g[i].type, "BEVEL"))) && ((strcmp (g[i].axle_name, g[j].axle_name) != 0)) && (g[i].axis != g[j].axis))
694 D = sqrt (pow (g[i].position[0] - g[j].position[0], 2) + pow (g[i].position[1] - g[j].position[1], 2) + pow (g[i].position[2] - g[j].position[2], 2));
695 if ((g[i].motored) && (!(g[j].motored)) && (D < 0.95 * sqrt (g[i].radius * g[i].radius + g[j].radius * g[j].radius)))
697 axle_index = axle_find (g[j].axle_name);
698 if ((a[axle_index].direction != 0) && (g[j].angular_velocity != g[i].angular_velocity * g[i].teeth / g[j].teeth * g[i].radius / g[j].radius))
700 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
701 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
702 exit (1);
704 g[j].motored = (a[axle_index].motored = 1);
705 g[j].direction = (a[axle_index].direction = -g[i].direction);
706 a[axle_index].angular_velocity = g[i].angular_velocity * g[i].teeth / g[j].teeth;
707 g[j].angular_velocity = (a[axle_index].angular_velocity *= g[i].radius / g[j].radius);
711 if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * sqrt (g[i].radius * g[i].radius + g[j].radius * g[j].radius)))
713 axle_index = axle_find (g[i].axle_name);
714 if ((a[axle_index].direction != 0) && (g[i].angular_velocity != g[j].angular_velocity * g[j].teeth / g[i].teeth * g[j].radius / g[i].radius))
716 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
717 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
718 exit (1);
720 g[i].motored = (a[axle_index].motored = 1);
721 g[i].direction = (a[axle_index].direction = -g[j].direction);
722 a[axle_index].angular_velocity = g[j].angular_velocity * g[j].teeth / g[i].teeth;
723 g[i].angular_velocity = (a[axle_index].angular_velocity *= g[j].radius / g[i].radius);
729 for (i = 0; i < number_of_gears; i++)
731 axle_index = axle_find (g[i].axle_name);
732 g[i].motored = a[axle_index].motored;
733 if (a[axle_index].motored)
735 g[i].direction = a[axle_index].direction;
736 g[i].angular_velocity = a[axle_index].angular_velocity;
740 for (i = 0; i < number_of_belts; i++)
742 g1 = gear_find (b[i].gear1_name);
743 g2 = gear_find (b[i].gear2_name);
744 D = sqrt (pow (g[g1].position[0] - g[g2].position[0], 2) + pow (g[g1].position[1] - g[g2].position[1], 2) + pow (g[g1].position[2] - g[g2].position[2], 2));
745 if (!((g[g1].axis == g[g2].axis) && (!strcmp (g[g1].type, g[g2].type)) && (!strcmp (g[g1].type, "NORMAL"))))
747 printf (error, "Belt %s invalid.", b[i].name);
748 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
749 exit (1);
752 if ((g[g1].axis == g[g2].axis) && (!strcmp (g[g1].type, g[g2].type)) && (!strcmp (g[g1].type, "NORMAL")))
755 if((g[g1].motored)&&(g[g2].motored))
756 if(g[g2].angular_velocity!=(g[g1].angular_velocity*g[g1].radius/g[g2].radius))
758 printf(error,"Error in belt linkage of gears %s and %s".,g[g1].name,g[g2].name);
759 MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);
760 exit(1);
763 if (g[g1].axis == 0)
765 dist = g[g1].position[0] - g[g2].position[0];
767 else if (g[i].axis == 1)
769 dist = g[g1].position[1] - g[g2].position[1];
771 else
772 dist = g[g1].position[2] - g[g2].position[2];
774 dist = fabs (dist);
776 if (dist > (g[g1].width / 2 + g[g2].width / 2))
778 printf (error, "Belt %s invalid.", b[i].name);
779 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
780 exit (1);
783 if (dist < (g[g1].width / 2 + g[g2].width / 2))
785 if (D < g[g1].radius + g[g2].radius)
787 printf (error, "Gears %s and %s too close to be linked with belts", g[g1].name, g[g2].name);
788 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
789 exit (1);
792 if ((g[g1].motored) && (!(g[g2].motored)))
794 axle_index = axle_find (g[g2].axle_name);
795 g[g2].motored = (a[axle_index].motored = 1);
796 g[g2].direction = (a[axle_index].direction = g[g1].direction);
797 g[g2].angular_velocity = (a[axle_index].angular_velocity = g[g1].angular_velocity * g[g1].radius / g[g2].radius);
800 if ((!(g[g1].motored)) && (g[g2].motored))
802 axle_index = axle_find (g[g1].axle_name);
803 g[g1].motored = (a[axle_index].motored = 1);
804 g[g1].direction = (a[axle_index].direction = g[g2].direction);
805 g[g1].angular_velocity = (a[axle_index].angular_velocity = g[g2].angular_velocity * g[g2].radius / g[g1].radius);
811 for (i = 0; i < number_of_gears; i++)
813 axle_index = axle_find (g[i].axle_name);
814 g[i].motored = a[axle_index].motored;
815 if (a[axle_index].motored)
817 g[i].direction = a[axle_index].direction;
818 g[i].angular_velocity = a[axle_index].angular_velocity;
826 GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 10.0;
829 static void
830 draw (void)
832 int i;
833 GLfloat x, y, z;
834 int index;
836 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
838 glPushMatrix ();
839 glRotatef (view_rotx, 1.0, 0.0, 0.0);
840 glRotatef (view_roty, 0.0, 1.0, 0.0);
841 glRotatef (view_rotz, 0.0, 0.0, 1.0);
843 for (i = 0; i < number_of_gears; i++)
845 x = 0.0;
846 y = 0.0;
847 z = 0.0;
848 glPushMatrix ();
849 /*glTranslatef( -3.0, -2.0, 0.0 );*/
850 glTranslatef (g[i].position[0], g[i].position[1], g[i].position[2]);
851 if (g[i].axis == 0)
852 y = 1.0;
853 else if (g[i].axis == 1)
854 x = 1.0;
855 else
856 z = 1.0;
858 if (z != 1.0)
859 glRotatef (90.0, x, y, z);
861 glRotatef (g[i].direction * g[i].angle, 0.0, 0.0, 1.0);
862 glCallList (g[i].id);
863 glPopMatrix ();
866 for (i = 0; i < number_of_axles; i++)
868 x = 0.0;
869 y = 0.0;
870 z = 0.0;
871 glPushMatrix ();
872 glTranslatef (a[i].position[0], a[i].position[1], a[i].position[2]);
873 if (a[i].axis == 0)
874 y = 1.0;
875 else if (a[i].axis == 1)
876 x = 1.0;
877 else
878 z = 1.0;
880 if (z != 1.0)
881 glRotatef (90.0, x, y, z);
883 glCallList (a[i].id);
884 glPopMatrix ();
887 for (i = 0; i < number_of_belts; i++)
889 x = 0.0;
890 y = 0.0;
891 z = 0.0;
892 glPushMatrix ();
893 index = gear_find (b[i].gear1_name);
894 glTranslatef (g[index].position[0], g[index].position[1], g[index].position[2]);
895 if (g[index].axis == 0)
896 y = 1.0;
897 else if (g[index].axis == 1)
898 x = 1.0;
899 else
900 z = 1.0;
902 if (z != 1.0)
903 glRotatef (90.0, x, y, z);
905 glCallList (b[i].id);
906 glPopMatrix ();
909 glPopMatrix ();
910 glutSwapBuffers ();
913 GLint t = glutGet(GLUT_ELAPSED_TIME);
914 Frames++;
915 if (t - T0 >= 5000) {
916 GLfloat seconds = (t - T0) / 1000.0;
917 GLfloat fps = Frames / seconds;
918 printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps);
919 fflush(stdout);
920 T0 = t;
921 Frames = 0;
927 static void
928 idle (void)
930 int i;
931 static double t0 = -1.;
932 double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
933 if (t0 < 0.0)
934 t0 = t;
935 dt = t - t0;
936 t0 = t;
937 for (i = 0; i < number_of_gears; i++)
938 g[i].angle += g[i].angular_velocity * dt;
939 glutPostRedisplay();
945 /* change view angle, exit upon ESC */
946 static void
947 key (unsigned char k, int x, int y)
949 switch (k)
951 case 'x':
952 view_rotx += 5.0;
953 break;
954 case 'X':
955 view_rotx -= 5.0;
956 break;
957 case 'y':
958 view_roty += 5.0;
959 break;
960 case 'Y':
961 view_roty -= 5.0;
962 break;
963 case 'z':
964 view_rotz += 5.0;
965 break;
966 case 'Z':
967 view_rotz -= 5.0;
968 break;
969 case 0x1B:
970 exit(0);
977 /* new window size or exposure */
978 static void
979 reshape (int width, int height)
981 glViewport (0, 0, (GLint) width, (GLint) height);
982 glMatrixMode (GL_PROJECTION);
983 glLoadIdentity ();
984 if (width > height)
986 GLfloat w = (GLfloat) width / (GLfloat) height;
987 glFrustum (-w, w, -1.0, 1.0, 5.0, 60.0);
989 else
991 GLfloat h = (GLfloat) height / (GLfloat) width;
992 glFrustum (-1.0, 1.0, -h, h, 5.0, 60.0);
995 glMatrixMode (GL_MODELVIEW);
996 glLoadIdentity ();
997 glTranslatef (0.0, 0.0, -40.0);
998 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1003 static void
1004 init (void)
1006 GLfloat matShine = 20.00F;
1007 GLfloat light0Pos[4] =
1009 0.70F, 0.70F, 1.25F, 0.50F
1011 int i;
1013 glClearColor (background[0], background[1], background[2], 1.0F);
1014 glClearIndex ((GLfloat) 0.0);
1016 glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, matShine);
1017 glLightfv (GL_LIGHT0, GL_POSITION, light0Pos);
1018 glEnable (GL_LIGHT0);
1020 glEnable (GL_LIGHTING);
1021 glEnable (GL_DEPTH_TEST);
1022 for (i = 0; i < number_of_gears; i++)
1023 g[i].angle = 0.0;
1025 for (i = 0; i < number_of_gears; i++)
1027 g[i].id = glGenLists (1);
1028 glNewList (g[i].id, GL_COMPILE);
1029 glColor3fv (g[i].color);
1030 glMaterialfv (GL_FRONT, GL_SPECULAR, g[i].color);
1031 gear (i, g[i].type, g[i].radius, g[i].width, g[i].teeth, g[i].tooth_depth);
1032 glEndList ();
1035 for (i = 0; i < number_of_axles; i++)
1037 a[i].id = glGenLists (1);
1038 glNewList (a[i].id, GL_COMPILE);
1039 glColor3fv (a[i].color);
1040 glMaterialfv (GL_FRONT, GL_SPECULAR, a[i].color);
1041 axle (i, a[i].radius, a[i].length);
1042 glEndList ();
1045 for (i = 0; i < number_of_belts; i++)
1047 b[i].id = glGenLists (1);
1048 glNewList (b[i].id, GL_COMPILE);
1049 belt (g[gear_find (b[i].gear1_name)], g[gear_find (b[i].gear2_name)]);
1050 glEndList ();
1053 glEnable (GL_COLOR_MATERIAL);
1059 main (int argc, char *argv[])
1061 char *file;
1063 glutInitWindowSize(640,480);
1064 glutInit(&argc, argv);
1065 glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
1067 if (glutCreateWindow ("Gear Train Simulation") == GL_FALSE)
1068 exit (1);
1070 if (argc < 2)
1071 file = "geartrain.dat";
1072 else
1073 file = argv[1];
1075 getdata (file);
1076 process ();
1077 init ();
1079 glutDisplayFunc (draw);
1080 glutReshapeFunc (reshape);
1081 glutKeyboardFunc (key);
1082 glutIdleFunc (idle);
1083 glutMainLoop ();
1084 return 0;