blob: d2a195f39a214ea212d68b559205214847ec6477 [file] [log] [blame]
Brian Paul392a7002000-03-06 23:34:42 +00001
2/*
Brian Paula74394c2000-04-04 15:20:17 +00003 * GearTrain Simulator * Version: 1.00
Brian Paul392a7002000-03-06 23:34:42 +00004 *
Brian Paula74394c2000-04-04 15:20:17 +00005 * Copyright (C) 1999 Shobhan Kumar Dutta All Rights Reserved.
6 * <skdutta@del3.vsnl.net.in>
7 *
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:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
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.
Brian Paul392a7002000-03-06 23:34:42 +000025 */
26
27
28#include <math.h>
29#include <stdlib.h>
30#include <GL/glut.h>
31#include <string.h>
32#include <stdio.h>
33
Karl Schultzbffae582001-10-04 19:14:26 +000034#ifndef min
Brian Paul392a7002000-03-06 23:34:42 +000035#define min(x, y) ( x < y ? x : y )
Karl Schultzbffae582001-10-04 19:14:26 +000036#endif
Brian Paul392a7002000-03-06 23:34:42 +000037
38#ifndef M_PI
39#define M_PI 3.14159265
40#endif /* */
Brian Paul3769b3f2000-03-22 23:14:54 +000041typedef GLfloat TDA[4];
Brian Paul392a7002000-03-06 23:34:42 +000042
43TDA background;
44
45
Gareth Hughes28861b12000-11-30 01:44:24 +000046struct AXLE
Brian Paul392a7002000-03-06 23:34:42 +000047 {
48 char name[20];
49 GLint id;
50 GLfloat radius;
51 GLint axis;
52 TDA color;
53 TDA position;
54 GLfloat length;
55 GLint motored;
56 GLfloat angular_velocity;
57 GLint direction;
58 };
59
60
Gareth Hughes28861b12000-11-30 01:44:24 +000061struct GEAR
Brian Paul392a7002000-03-06 23:34:42 +000062 {
63 char name[20];
64 char type[7];
65 GLint face;
66 GLint id;
67 GLfloat radius;
68 GLfloat width;
69 GLint teeth;
70 GLfloat tooth_depth;
71 GLfloat angle;
72 GLfloat angular_velocity;
73 TDA color;
74 GLint relative_position;
75 TDA position;
76 char axle_name[20];
77 GLint axis;
78 GLint direction;
79 GLint motored;
80 };
81
82
Gareth Hughes28861b12000-11-30 01:44:24 +000083struct BELT
Brian Paul392a7002000-03-06 23:34:42 +000084 {
85 char name[20];
86 GLint id;
87 char gear1_name[20];
88 char gear2_name[20];
89 };
90
91
92FILE * mainfile;
93struct GEAR g[10];
94struct AXLE a[10];
95struct BELT b[10];
96int number_of_gears;
97int number_of_axles;
98int number_of_belts;
99
100
101char Buf1[256], Buf2[256], Buf3[256], Buf4[256], Buf5[256];
102
Gareth Hughes28861b12000-11-30 01:44:24 +0000103static GLint T0 = 0;
104static GLint Frames = 0;
Brian Paul392a7002000-03-06 23:34:42 +0000105
Gareth Hughes28861b12000-11-30 01:44:24 +0000106
Karl Schultzbffae582001-10-04 19:14:26 +0000107#ifndef _WIN32
Gareth Hughes28861b12000-11-30 01:44:24 +0000108static void
109strset (char buf[], char ch)
Brian Paul392a7002000-03-06 23:34:42 +0000110{
111 int i;
112 for (i = 0; i < strlen (buf); i++)
113 buf[i] = ch;
114}
Karl Schultzbffae582001-10-04 19:14:26 +0000115#endif
Brian Paul392a7002000-03-06 23:34:42 +0000116
117
Gareth Hughes28861b12000-11-30 01:44:24 +0000118static void
119Clear_Buffers ()
Brian Paul392a7002000-03-06 23:34:42 +0000120{
121 strset (Buf1, 0);
122 strset (Buf2, 0);
123 strset (Buf3, 0);
124 strset (Buf4, 0);
125 strset (Buf5, 0);
126}
127
128
Gareth Hughes28861b12000-11-30 01:44:24 +0000129static void
130LoadTriplet (TDA A)
Brian Paul392a7002000-03-06 23:34:42 +0000131{
132 Clear_Buffers ();
133 fscanf (mainfile, "%s %s %s %s", Buf1, Buf2, Buf3, Buf4);
134 A[0] = atof (Buf2);
135 A[1] = atof (Buf3);
136 A[2] = atof (Buf4);
137}
138
139
Gareth Hughes28861b12000-11-30 01:44:24 +0000140static void
141LoadReal (float *a)
Brian Paul392a7002000-03-06 23:34:42 +0000142{
143 Clear_Buffers ();
144 fscanf (mainfile, "%s %s", Buf1, Buf2);
145 *a = atof (Buf2);
146}
147
148
Gareth Hughes28861b12000-11-30 01:44:24 +0000149static void
150LoadInteger (int *a)
Brian Paul392a7002000-03-06 23:34:42 +0000151{
152 Clear_Buffers ();
153 fscanf (mainfile, "%s %s", Buf1, Buf2);
154 *a = atoi (Buf2);
155}
156
157
Gareth Hughes28861b12000-11-30 01:44:24 +0000158static void
159LoadText (char *a)
Brian Paul392a7002000-03-06 23:34:42 +0000160{
161 Clear_Buffers ();
162 fscanf (mainfile, "%s %s", Buf1, Buf2);
163 strcpy (a, Buf2);
164}
165
166
Gareth Hughes28861b12000-11-30 01:44:24 +0000167static void
168getdata (char filename[])
Brian Paul392a7002000-03-06 23:34:42 +0000169{
170 int gear_count = 0, axle_count = 0, belt_count = 0, i;
Gareth Hughes28861b12000-11-30 01:44:24 +0000171
Brian Paul392a7002000-03-06 23:34:42 +0000172 mainfile = fopen (filename, "r");
Brian Paul5a564052000-03-29 17:56:02 +0000173 if (!mainfile) {
174 printf("Error: couldn't open %s\n", filename);
175 exit(-1);
176 }
177
Brian Paul392a7002000-03-06 23:34:42 +0000178 do
179 {
180 Clear_Buffers ();
181 fscanf (mainfile, "%s", Buf1);
182 if (ferror (mainfile))
183 {
184 printf ("\nError opening file !\n");
185 exit (1);
186 }
187
188 if (!(strcmp (Buf1, "BACKGROUND")))
189 LoadTriplet (background);
Gareth Hughes28861b12000-11-30 01:44:24 +0000190
Brian Paul392a7002000-03-06 23:34:42 +0000191 if (!(strcmp (Buf1, "ANAME")))
192 {
193 LoadText (a[axle_count].name);
194 axle_count++;
195 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000196
Brian Paul392a7002000-03-06 23:34:42 +0000197 if (!(strcmp (Buf1, "ARADIUS")))
198 LoadReal (&a[axle_count - 1].radius);
Gareth Hughes28861b12000-11-30 01:44:24 +0000199
Brian Paul392a7002000-03-06 23:34:42 +0000200 if (!(strcmp (Buf1, "AAXIS")))
201 LoadInteger (&a[axle_count - 1].axis);
Gareth Hughes28861b12000-11-30 01:44:24 +0000202
Brian Paul392a7002000-03-06 23:34:42 +0000203 if (!(strcmp (Buf1, "ACOLOR")))
204 LoadTriplet (a[axle_count - 1].color);
Gareth Hughes28861b12000-11-30 01:44:24 +0000205
Brian Paul392a7002000-03-06 23:34:42 +0000206 if (!(strcmp (Buf1, "APOSITION")))
207 LoadTriplet (a[axle_count - 1].position);
Gareth Hughes28861b12000-11-30 01:44:24 +0000208
Brian Paul392a7002000-03-06 23:34:42 +0000209 if (!(strcmp (Buf1, "ALENGTH")))
210 LoadReal (&a[axle_count - 1].length);
Gareth Hughes28861b12000-11-30 01:44:24 +0000211
Brian Paul392a7002000-03-06 23:34:42 +0000212 if (!(strcmp (Buf1, "AMOTORED")))
213 LoadInteger (&a[axle_count - 1].motored);
Gareth Hughes28861b12000-11-30 01:44:24 +0000214
Brian Paul392a7002000-03-06 23:34:42 +0000215 if (!(strcmp (Buf1, "AANGULARVELOCITY")))
216 LoadReal (&a[axle_count - 1].angular_velocity);
Gareth Hughes28861b12000-11-30 01:44:24 +0000217
Brian Paul392a7002000-03-06 23:34:42 +0000218 if (!(strcmp (Buf1, "ADIRECTION")))
219 LoadInteger (&a[axle_count - 1].direction);
Gareth Hughes28861b12000-11-30 01:44:24 +0000220
Brian Paul392a7002000-03-06 23:34:42 +0000221 if (!(strcmp (Buf1, "GNAME")))
222 {
223 LoadText (g[gear_count].name);
224 gear_count++;
225 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000226
Brian Paul392a7002000-03-06 23:34:42 +0000227 if (!(strcmp (Buf1, "GTYPE")))
228 LoadText (g[gear_count - 1].type);
Gareth Hughes28861b12000-11-30 01:44:24 +0000229
Brian Paul392a7002000-03-06 23:34:42 +0000230 if (!(strcmp (Buf1, "GFACE")))
231 LoadInteger (&g[gear_count - 1].face);
Gareth Hughes28861b12000-11-30 01:44:24 +0000232
Brian Paul392a7002000-03-06 23:34:42 +0000233 if (!(strcmp (Buf1, "GRADIUS")))
234 LoadReal (&g[gear_count - 1].radius);
Gareth Hughes28861b12000-11-30 01:44:24 +0000235
Brian Paul392a7002000-03-06 23:34:42 +0000236 if (!(strcmp (Buf1, "GWIDTH")))
237 LoadReal (&g[gear_count - 1].width);
Gareth Hughes28861b12000-11-30 01:44:24 +0000238
Brian Paul392a7002000-03-06 23:34:42 +0000239 if (!(strcmp (Buf1, "GTEETH")))
240 LoadInteger (&g[gear_count - 1].teeth);
Gareth Hughes28861b12000-11-30 01:44:24 +0000241
Brian Paul392a7002000-03-06 23:34:42 +0000242 if (!(strcmp (Buf1, "GTOOTHDEPTH")))
243 LoadReal (&g[gear_count - 1].tooth_depth);
Gareth Hughes28861b12000-11-30 01:44:24 +0000244
Brian Paul392a7002000-03-06 23:34:42 +0000245 if (!(strcmp (Buf1, "GCOLOR")))
246 LoadTriplet (g[gear_count - 1].color);
Gareth Hughes28861b12000-11-30 01:44:24 +0000247
Brian Paul392a7002000-03-06 23:34:42 +0000248 if (!(strcmp (Buf1, "GAXLE")))
249 LoadText (g[gear_count - 1].axle_name);
Gareth Hughes28861b12000-11-30 01:44:24 +0000250
Brian Paul392a7002000-03-06 23:34:42 +0000251 if (!(strcmp (Buf1, "GPOSITION")))
252 LoadInteger (&g[gear_count - 1].relative_position);
Gareth Hughes28861b12000-11-30 01:44:24 +0000253
Brian Paul392a7002000-03-06 23:34:42 +0000254 if (!(strcmp (Buf1, "BELTNAME")))
255 {
256 LoadText (b[belt_count].name);
257 belt_count++;
258 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000259
Brian Paul392a7002000-03-06 23:34:42 +0000260 if (!(strcmp (Buf1, "GEAR1NAME")))
261 LoadText (b[belt_count - 1].gear1_name);
Gareth Hughes28861b12000-11-30 01:44:24 +0000262
Brian Paul392a7002000-03-06 23:34:42 +0000263 if (!(strcmp (Buf1, "GEAR2NAME")))
264 LoadText (b[belt_count - 1].gear2_name);
265 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000266
Brian Paul392a7002000-03-06 23:34:42 +0000267 while (Buf1[0] != 0);
Gareth Hughes28861b12000-11-30 01:44:24 +0000268
Brian Paul392a7002000-03-06 23:34:42 +0000269 for (i = 0; i < number_of_gears; i++)
270 {
271 g[i].axis = -1;
272 g[i].direction = 0;
273 g[i].angular_velocity = 0.0;
274 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000275
Brian Paul392a7002000-03-06 23:34:42 +0000276 number_of_gears = gear_count;
277 number_of_axles = axle_count;
278 number_of_belts = belt_count;
279 fclose (mainfile);
280}
281
282
Gareth Hughes28861b12000-11-30 01:44:24 +0000283static void
284axle (GLint j, GLfloat radius, GLfloat length)
Brian Paul392a7002000-03-06 23:34:42 +0000285{
286 GLfloat angle, rad, incr = 10.0 * M_PI / 180.0;
Gareth Hughes28861b12000-11-30 01:44:24 +0000287
288 /* draw main cylinder */
Brian Paul392a7002000-03-06 23:34:42 +0000289 glBegin (GL_QUADS);
290 for (angle = 0.0; angle < 360.0; angle += 5.0)
291 {
292 rad = angle * M_PI / 180.0;
293 glNormal3f (cos (rad), sin (rad), 0.0);
294 glVertex3f (radius * cos (rad), radius * sin (rad), length / 2);
295 glVertex3f (radius * cos (rad), radius * sin (rad), -length / 2);
296 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), -length / 2);
297 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), length / 2);
298 }
299 glEnd ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000300
301 /* draw front face */
Brian Paul392a7002000-03-06 23:34:42 +0000302 glNormal3f (0.0, 0.0, 1.0);
303 glBegin (GL_TRIANGLES);
304 for (angle = 0.0; angle < 360.0; angle += 5.0)
305 {
306 rad = angle * M_PI / 180.0;
307 glVertex3f (0.0, 0.0, length / 2);
308 glVertex3f (radius * cos (rad), radius * sin (rad), length / 2);
309 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), length / 2);
310 glVertex3f (0.0, 0.0, length / 2);
311 }
312 glEnd ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000313
314 /* draw back face */
Brian Paul392a7002000-03-06 23:34:42 +0000315 glNormal3f (0.0, 0.0, -1.0);
316 glBegin (GL_TRIANGLES);
317 for (angle = 0.0; angle <= 360.0; angle += 5.0)
318 {
319 rad = angle * M_PI / 180.0;
320 glVertex3f (0.0, 0.0, -length / 2);
321 glVertex3f (radius * cos (rad), radius * sin (rad), -length / 2);
322 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), -length / 2);
323 glVertex3f (0.0, 0.0, -length / 2);
324 }
325 glEnd ();
326}
327
328
329
Gareth Hughes28861b12000-11-30 01:44:24 +0000330static void
331gear (GLint j, char type[], GLfloat radius, GLfloat width,
332 GLint teeth, GLfloat tooth_depth)
Brian Paul392a7002000-03-06 23:34:42 +0000333{
334 GLint i;
335 GLfloat r1, r2;
336 GLfloat angle, da;
337 GLfloat u, v, len, fraction = 0.5;
338 GLfloat n = 1.0;
Brian Paul9d0bc1d2000-04-05 21:36:03 +0000339
Brian Paul392a7002000-03-06 23:34:42 +0000340 r1 = radius - tooth_depth;
341 r2 = radius;
Gareth Hughes28861b12000-11-30 01:44:24 +0000342
Brian Paul392a7002000-03-06 23:34:42 +0000343 da = 2.0 * M_PI / teeth / 4.0;
344 if (!g[j].face)
345 {
346 fraction = -0.5;
347 n = -1.0;
348 }
349 if (!(strcmp (type, "NORMAL")))
350 {
351 fraction = 0.5;
352 n = 1.0;
353 }
354
Gareth Hughes28861b12000-11-30 01:44:24 +0000355 /* draw front face */
Brian Paul392a7002000-03-06 23:34:42 +0000356 if (!(strcmp (type, "NORMAL")))
357 {
358 glNormal3f (0.0, 0.0, 1.0 * n);
359 glBegin (GL_QUAD_STRIP);
360 for (i = 0; i <= teeth; i++)
361 {
362 angle = i * 2.0 * M_PI / teeth;
363 glVertex3f (0.0, 0.0, width * fraction);
364 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
365 glVertex3f (0.0, 0.0, width * fraction);
366 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
367 }
368 glEnd ();
369 }
370 else
371 {
372 glNormal3f (0.0, 0.0, 1.0 * n);
373 glBegin (GL_QUAD_STRIP);
374 for (i = 0; i <= teeth; i++)
375 {
376 angle = i * 2.0 * M_PI / teeth;
377 glVertex3f (0.0, 0.0, width * fraction);
378 glVertex3f ((r2 - width) * cos (angle), (r2 - width) * sin (angle), width * fraction);
379 glVertex3f (0.0, 0.0, width * fraction);
380 glVertex3f ((r2 - width) * cos (angle + 3 * da), (r2 - width) * sin (angle + 3 * da), width * fraction);
381 }
382 glEnd ();
383 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000384
385 /* draw front sides of teeth */
Brian Paul392a7002000-03-06 23:34:42 +0000386 if (!(strcmp (type, "NORMAL")))
387 {
388 glNormal3f (0.0, 0.0, 1.0 * n);
389 glBegin (GL_QUADS);
390 da = 2.0 * M_PI / teeth / 4.0;
391 for (i = 0; i < teeth; i++)
392 {
393 angle = i * 2.0 * M_PI / teeth;
394 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
395 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), width * fraction);
396 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), width * fraction);
397 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
398 }
399 glEnd ();
400 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000401
Brian Paul392a7002000-03-06 23:34:42 +0000402 glNormal3f (0.0, 0.0, -1.0 * n);
Gareth Hughes28861b12000-11-30 01:44:24 +0000403
404 /* draw back face */
Brian Paul392a7002000-03-06 23:34:42 +0000405 glBegin (GL_QUAD_STRIP);
406 for (i = 0; i <= teeth; i++)
407 {
408 angle = i * 2.0 * M_PI / teeth;
409 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
410 glVertex3f (0.0, 0.0, -width * fraction);
411 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
412 glVertex3f (0.0, 0.0, -width * fraction);
413 }
414 glEnd ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000415
416 /* draw back sides of teeth */
Brian Paul392a7002000-03-06 23:34:42 +0000417 glNormal3f (0.0, 0.0, -1.0 * n);
418 glBegin (GL_QUADS);
419 da = 2.0 * M_PI / teeth / 4.0;
420 for (i = 0; i < teeth; i++)
421 {
422 angle = i * 2.0 * M_PI / teeth;
423 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
424 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
425 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
426 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
427 }
428 glEnd ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000429
430
431 /* draw outward faces of teeth */
Brian Paul392a7002000-03-06 23:34:42 +0000432 if (!(strcmp (type, "NORMAL")))
433 {
434 glBegin (GL_QUAD_STRIP);
435 for (i = 0; i < teeth; i++)
436 {
437 angle = i * 2.0 * M_PI / teeth;
Gareth Hughes28861b12000-11-30 01:44:24 +0000438
Brian Paul392a7002000-03-06 23:34:42 +0000439 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
440 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
441 u = r2 * cos (angle + da) - r1 * cos (angle);
442 v = r2 * sin (angle + da) - r1 * sin (angle);
443 len = sqrt (u * u + v * v);
444 u /= len;
445 v /= len;
446 glNormal3f (v, -u, 0.0);
447 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), width * fraction);
448 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
449 glNormal3f (cos (angle), sin (angle), 0.0);
450 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), width * fraction);
451 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
452 u = r1 * cos (angle + 3 * da) - r2 * cos (angle + 2 * da);
453 v = r1 * sin (angle + 3 * da) - r2 * sin (angle + 2 * da);
454 glNormal3f (v, -u, 0.0);
455 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
456 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
457 glNormal3f (cos (angle), sin (angle), 0.0);
458 }
459 }
460 else
461 {
462 glBegin (GL_QUAD_STRIP);
463 for (i = 0; i < teeth; i++)
464 {
465 angle = i * 2.0 * M_PI / teeth;
466 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
467 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
468 u = r2 * cos (angle + da) - r1 * cos (angle);
469 v = r2 * sin (angle + da) - r1 * sin (angle);
470 len = sqrt (u * u + v * v);
471 u /= len;
472 v /= len;
473 glNormal3f (v, -u, 0.0);
474 glVertex3f ((r2 - width) * cos (angle + da), (r2 - width) * sin (angle + da), width * fraction);
475 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
476 glNormal3f (cos (angle), sin (angle), n);
477 glVertex3f ((r2 - width) * cos (angle + 2 * da), (r2 - width) * sin (angle + 2 * da), width * fraction);
478 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
479 u = r1 * cos (angle + 3 * da) - r2 * cos (angle + 2 * da);
480 v = r1 * sin (angle + 3 * da) - r2 * sin (angle + 2 * da);
481 glNormal3f (v, -u, 0.0);
482 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
483 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
484 glNormal3f (cos (angle), sin (angle), n);
485 }
486 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000487
Brian Paul392a7002000-03-06 23:34:42 +0000488 glVertex3f (r1 * cos (0), r1 * sin (0), width * fraction);
489 glVertex3f (r1 * cos (0), r1 * sin (0), -width * fraction);
490 glEnd ();
491}
492
493
Gareth Hughes28861b12000-11-30 01:44:24 +0000494static void
495belt (struct GEAR g1, struct GEAR g2)
Brian Paul392a7002000-03-06 23:34:42 +0000496{
497 GLfloat D, alpha, phi, angle, incr, width;
498 GLint indexes[3] =
499 {
500 0, 0, 0
501 };
Gareth Hughes28861b12000-11-30 01:44:24 +0000502
Brian Paul392a7002000-03-06 23:34:42 +0000503 GLfloat col[3] =
504 {
505 0.0, 0.0, 0.0
506 };
Gareth Hughes28861b12000-11-30 01:44:24 +0000507
Brian Paul392a7002000-03-06 23:34:42 +0000508 width = min (g1.width, g2.width);
509 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));
510 alpha = acos ((g2.position[0] - g1.position[0]) / D);
511 phi = acos ((g1.radius - g2.radius) / D);
512 glBegin (GL_QUADS);
513 glColor3fv (col);
514 glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
515 incr = 1.2 * 360.0 / g1.teeth * M_PI / 180.00;
516 for (angle = alpha + phi; angle <= 2 * M_PI - phi + alpha; angle += 360.0 / g1.teeth * M_PI / 180.00)
517 {
518 glNormal3f (cos (angle), sin (angle), 0.0);
519 glVertex3f (g1.radius * cos (angle), g1.radius * sin (angle), width * 0.5);
520 glVertex3f (g1.radius * cos (angle), g1.radius * sin (angle), -width * 0.5);
521 glVertex3f (g1.radius * cos (angle + incr), g1.radius * sin (angle + incr), -width * 0.5);
522 glVertex3f (g1.radius * cos (angle + incr), g1.radius * sin (angle + incr), width * 0.5);
523 }
524 glEnd ();
525 glBegin (GL_QUADS);
526 glColor3fv (col);
527 glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
528 incr = 1.2 * 360.0 / g2.teeth * M_PI / 180.00;
529 for (angle = -phi + alpha; angle <= phi + alpha; angle += 360.0 / g1.teeth * M_PI / 180.0)
530 {
531 glNormal3f (cos (angle), sin (angle), 0.0);
532 glVertex3f (g2.radius * cos (angle) + g2.position[0] - g1.position[0], g2.radius * sin (angle) + g2.position[1] - g1.position[1], width * 0.5);
533 glVertex3f (g2.radius * cos (angle) + g2.position[0] - g1.position[0], g2.radius * sin (angle) + g2.position[1] - g1.position[1], width * -0.5);
534 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);
535 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);
536 }
537 glEnd ();
538
539 glBegin (GL_QUADS);
540 glColor3fv (col);
541 glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
542 glVertex3f (g1.radius * cos (alpha + phi), g1.radius * sin (alpha + phi), width * 0.5);
543 glVertex3f (g1.radius * cos (alpha + phi), g1.radius * sin (alpha + phi), width * -0.5);
544 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);
545 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);
546 glVertex3f (g1.radius * cos (alpha - phi), g1.radius * sin (alpha - phi), width * 0.5);
547 glVertex3f (g1.radius * cos (alpha - phi), g1.radius * sin (alpha - phi), width * -0.5);
548 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);
549 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);
550 glEnd ();
551}
552
553
Gareth Hughes28861b12000-11-30 01:44:24 +0000554static int
555axle_find (char axle_name[])
Brian Paul392a7002000-03-06 23:34:42 +0000556{
557 int i;
Gareth Hughes28861b12000-11-30 01:44:24 +0000558
Brian Paul392a7002000-03-06 23:34:42 +0000559 for (i = 0; i < number_of_axles; i++)
560 {
561 if (!(strcmp (axle_name, a[i].name)))
562 break;
563 }
564 return i;
565}
566
567
Gareth Hughes28861b12000-11-30 01:44:24 +0000568static int
569gear_find (char gear_name[])
Brian Paul392a7002000-03-06 23:34:42 +0000570{
571 int i;
Gareth Hughes28861b12000-11-30 01:44:24 +0000572
Brian Paul392a7002000-03-06 23:34:42 +0000573 for (i = 0; i < number_of_gears; i++)
574 {
575 if (!(strcmp (gear_name, g[i].name)))
576 break;
577 }
578 return i;
579}
580
581
Gareth Hughes28861b12000-11-30 01:44:24 +0000582static void
583process ()
Brian Paul392a7002000-03-06 23:34:42 +0000584{
585 GLfloat x, y, z, D, dist;
586 GLint axle_index, i, j, g1, g2, k;
587 char error[80];
Gareth Hughes28861b12000-11-30 01:44:24 +0000588
Brian Paul392a7002000-03-06 23:34:42 +0000589 for (i = 0; i < number_of_gears; i++)
590 {
591 x = 0.0;
592 y = 0.0;
593 z = 0.0;
594 axle_index = axle_find (g[i].axle_name);
595 g[i].axis = a[axle_index].axis;
596 g[i].motored = a[axle_index].motored;
597 if (a[axle_index].motored)
598 {
599 g[i].direction = a[axle_index].direction;
600 g[i].angular_velocity = a[axle_index].angular_velocity;
601 }
602 if (g[i].axis == 0)
603 x = 1.0;
604 else if (g[i].axis == 1)
605 y = 1.0;
606 else
607 z = 1.0;
Gareth Hughes28861b12000-11-30 01:44:24 +0000608
Brian Paul392a7002000-03-06 23:34:42 +0000609 g[i].position[0] = a[axle_index].position[0] + x * g[i].relative_position;
610 g[i].position[1] = a[axle_index].position[1] + y * g[i].relative_position;
611 g[i].position[2] = a[axle_index].position[2] + z * g[i].relative_position;
612 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000613
Brian Paul392a7002000-03-06 23:34:42 +0000614 for (k = 0; k < number_of_axles; k++)
615 {
616 for (i = 0; i < number_of_gears - 1; i++)
617 {
618 for (j = 0; j < number_of_gears; j++)
619 {
620 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))
621 {
622 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));
623 if (D < 1.1 * (g[i].radius - g[i].tooth_depth + g[j].radius - g[j].tooth_depth))
624 {
625 printf (error, "Gear %s and %s are too close to each other.", g[i].name, g[j].name);
Gareth Hughes28861b12000-11-30 01:44:24 +0000626
Brian Paul392a7002000-03-06 23:34:42 +0000627 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
628 exit (1);
629 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000630
Brian Paul392a7002000-03-06 23:34:42 +0000631 if (g[i].axis == 0)
632 {
633 dist = g[i].position[0] - g[j].position[0];
634 }
635 else if (g[i].axis == 1)
636 {
637 dist = g[i].position[1] - g[j].position[1];
638 }
639 else
640 dist = g[i].position[2] - g[j].position[2];
Gareth Hughes28861b12000-11-30 01:44:24 +0000641
Brian Paul392a7002000-03-06 23:34:42 +0000642 dist = fabs (dist);
Gareth Hughes28861b12000-11-30 01:44:24 +0000643
Brian Paul392a7002000-03-06 23:34:42 +0000644 if (dist < (g[i].width / 2 + g[j].width / 2))
645 {
646 if ((g[i].motored) && (!(g[j].motored)) && (D < 0.95 * (g[i].radius + g[j].radius)))
647 {
648 axle_index = axle_find (g[j].axle_name);
649 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))
650 {
651 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
652 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
653 exit (1);
654 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000655
Brian Paul392a7002000-03-06 23:34:42 +0000656 g[j].motored = (a[axle_index].motored = 1);
657 g[j].direction = (a[axle_index].direction = -g[i].direction);
658 a[axle_index].angular_velocity = g[i].angular_velocity * g[i].teeth / g[j].teeth;
659 g[j].angular_velocity = (a[axle_index].angular_velocity *= g[i].radius / g[j].radius);
660 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000661
Brian Paul392a7002000-03-06 23:34:42 +0000662 if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * (g[i].radius + g[j].radius)))
663 {
664 axle_index = axle_find (g[i].axle_name);
665 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))
666 {
667 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
668 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
669 exit (1);
670 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000671
Brian Paul392a7002000-03-06 23:34:42 +0000672 g[i].motored = (a[axle_index].motored = 1);
673 g[i].direction = (a[axle_index].direction = -g[j].direction);
674 a[axle_index].angular_velocity = g[j].angular_velocity * g[j].teeth / g[i].teeth;
675 g[i].angular_velocity = (a[axle_index].angular_velocity *= g[j].radius / g[i].radius);
Gareth Hughes28861b12000-11-30 01:44:24 +0000676
Brian Paul392a7002000-03-06 23:34:42 +0000677 }
678 }
679 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000680
Brian Paul392a7002000-03-06 23:34:42 +0000681 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))
682 {
683 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));
684 if ((g[i].motored) && (!(g[j].motored)) && (D < 0.95 * sqrt (g[i].radius * g[i].radius + g[j].radius * g[j].radius)))
685 {
686 axle_index = axle_find (g[j].axle_name);
687 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))
688 {
689 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
690 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
691 exit (1);
692 }
693 g[j].motored = (a[axle_index].motored = 1);
694 g[j].direction = (a[axle_index].direction = -g[i].direction);
695 a[axle_index].angular_velocity = g[i].angular_velocity * g[i].teeth / g[j].teeth;
696 g[j].angular_velocity = (a[axle_index].angular_velocity *= g[i].radius / g[j].radius);
697 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000698
699
Brian Paul392a7002000-03-06 23:34:42 +0000700 if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * sqrt (g[i].radius * g[i].radius + g[j].radius * g[j].radius)))
701 {
702 axle_index = axle_find (g[i].axle_name);
703 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))
704 {
705 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
706 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
707 exit (1);
708 }
709 g[i].motored = (a[axle_index].motored = 1);
710 g[i].direction = (a[axle_index].direction = -g[j].direction);
711 a[axle_index].angular_velocity = g[j].angular_velocity * g[j].teeth / g[i].teeth;
712 g[i].angular_velocity = (a[axle_index].angular_velocity *= g[j].radius / g[i].radius);
713 }
714 }
715 }
716 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000717
Brian Paul392a7002000-03-06 23:34:42 +0000718 for (i = 0; i < number_of_gears; i++)
719 {
720 axle_index = axle_find (g[i].axle_name);
721 g[i].motored = a[axle_index].motored;
722 if (a[axle_index].motored)
723 {
724 g[i].direction = a[axle_index].direction;
725 g[i].angular_velocity = a[axle_index].angular_velocity;
726 }
727 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000728
Brian Paul392a7002000-03-06 23:34:42 +0000729 for (i = 0; i < number_of_belts; i++)
730 {
731 g1 = gear_find (b[i].gear1_name);
732 g2 = gear_find (b[i].gear2_name);
733 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));
734 if (!((g[g1].axis == g[g2].axis) && (!strcmp (g[g1].type, g[g2].type)) && (!strcmp (g[g1].type, "NORMAL"))))
735 {
736 printf (error, "Belt %s invalid.", b[i].name);
737 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
738 exit (1);
739 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000740
Brian Paul392a7002000-03-06 23:34:42 +0000741 if ((g[g1].axis == g[g2].axis) && (!strcmp (g[g1].type, g[g2].type)) && (!strcmp (g[g1].type, "NORMAL")))
742 {
743 /*
744 if((g[g1].motored)&&(g[g2].motored))
745 if(g[g2].angular_velocity!=(g[g1].angular_velocity*g[g1].radius/g[g2].radius))
746 {
747 printf(error,"Error in belt linkage of gears %s and %s".,g[g1].name,g[g2].name);
748 MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);
749 exit(1);
750 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000751 */
Brian Paul392a7002000-03-06 23:34:42 +0000752 if (g[g1].axis == 0)
753 {
754 dist = g[g1].position[0] - g[g2].position[0];
755 }
756 else if (g[i].axis == 1)
757 {
758 dist = g[g1].position[1] - g[g2].position[1];
759 }
760 else
761 dist = g[g1].position[2] - g[g2].position[2];
Gareth Hughes28861b12000-11-30 01:44:24 +0000762
Brian Paul392a7002000-03-06 23:34:42 +0000763 dist = fabs (dist);
Gareth Hughes28861b12000-11-30 01:44:24 +0000764
Brian Paul392a7002000-03-06 23:34:42 +0000765 if (dist > (g[g1].width / 2 + g[g2].width / 2))
766 {
767 printf (error, "Belt %s invalid.", b[i].name);
768 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
769 exit (1);
770 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000771
Brian Paul392a7002000-03-06 23:34:42 +0000772 if (dist < (g[g1].width / 2 + g[g2].width / 2))
773 {
774 if (D < g[g1].radius + g[g2].radius)
775 {
776 printf (error, "Gears %s and %s too close to be linked with belts", g[g1].name, g[g2].name);
777 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
778 exit (1);
779 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000780
Brian Paul392a7002000-03-06 23:34:42 +0000781 if ((g[g1].motored) && (!(g[g2].motored)))
782 {
783 axle_index = axle_find (g[g2].axle_name);
784 g[g2].motored = (a[axle_index].motored = 1);
785 g[g2].direction = (a[axle_index].direction = g[g1].direction);
786 g[g2].angular_velocity = (a[axle_index].angular_velocity = g[g1].angular_velocity * g[g1].radius / g[g2].radius);
787 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000788
Brian Paul392a7002000-03-06 23:34:42 +0000789 if ((!(g[g1].motored)) && (g[g2].motored))
790 {
791 axle_index = axle_find (g[g1].axle_name);
792 g[g1].motored = (a[axle_index].motored = 1);
793 g[g1].direction = (a[axle_index].direction = g[g2].direction);
794 g[g1].angular_velocity = (a[axle_index].angular_velocity = g[g2].angular_velocity * g[g2].radius / g[g1].radius);
795 }
796 }
797 }
798 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000799
Brian Paul392a7002000-03-06 23:34:42 +0000800 for (i = 0; i < number_of_gears; i++)
801 {
802 axle_index = axle_find (g[i].axle_name);
803 g[i].motored = a[axle_index].motored;
804 if (a[axle_index].motored)
805 {
806 g[i].direction = a[axle_index].direction;
807 g[i].angular_velocity = a[axle_index].angular_velocity;
808 }
809 }
810 }
811}
812
813
814
815GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 10.0;
816
817
Gareth Hughes28861b12000-11-30 01:44:24 +0000818static void
819draw (void)
Brian Paul392a7002000-03-06 23:34:42 +0000820{
821 int i;
822 GLfloat x, y, z;
823 int index;
824
825 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Gareth Hughes28861b12000-11-30 01:44:24 +0000826
Brian Paul392a7002000-03-06 23:34:42 +0000827 glPushMatrix ();
828 glRotatef (view_rotx, 1.0, 0.0, 0.0);
829 glRotatef (view_roty, 0.0, 1.0, 0.0);
830 glRotatef (view_rotz, 0.0, 0.0, 1.0);
Gareth Hughes28861b12000-11-30 01:44:24 +0000831
Brian Paul392a7002000-03-06 23:34:42 +0000832 for (i = 0; i < number_of_gears; i++)
833 {
834 x = 0.0;
835 y = 0.0;
836 z = 0.0;
837 glPushMatrix ();
838/*glTranslatef( -3.0, -2.0, 0.0 );*/
839 glTranslatef (g[i].position[0], g[i].position[1], g[i].position[2]);
840 if (g[i].axis == 0)
841 y = 1.0;
842 else if (g[i].axis == 1)
843 x = 1.0;
844 else
845 z = 1.0;
Gareth Hughes28861b12000-11-30 01:44:24 +0000846
Brian Paul392a7002000-03-06 23:34:42 +0000847 if (z != 1.0)
848 glRotatef (90.0, x, y, z);
Gareth Hughes28861b12000-11-30 01:44:24 +0000849
Brian Paul392a7002000-03-06 23:34:42 +0000850 glRotatef (g[i].direction * g[i].angle, 0.0, 0.0, 1.0);
851 glCallList (g[i].id);
852 glPopMatrix ();
853 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000854
Brian Paul392a7002000-03-06 23:34:42 +0000855 for (i = 0; i < number_of_axles; i++)
856 {
857 x = 0.0;
858 y = 0.0;
859 z = 0.0;
860 glPushMatrix ();
861 glTranslatef (a[i].position[0], a[i].position[1], a[i].position[2]);
862 if (a[i].axis == 0)
863 y = 1.0;
864 else if (a[i].axis == 1)
865 x = 1.0;
866 else
867 z = 1.0;
868
869 if (z != 1.0)
870 glRotatef (90.0, x, y, z);
Gareth Hughes28861b12000-11-30 01:44:24 +0000871
Brian Paul392a7002000-03-06 23:34:42 +0000872 glCallList (a[i].id);
873 glPopMatrix ();
874 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000875
Brian Paul392a7002000-03-06 23:34:42 +0000876 for (i = 0; i < number_of_belts; i++)
877 {
878 x = 0.0;
879 y = 0.0;
880 z = 0.0;
881 glPushMatrix ();
882 index = gear_find (b[i].gear1_name);
883 glTranslatef (g[index].position[0], g[index].position[1], g[index].position[2]);
884 if (g[index].axis == 0)
885 y = 1.0;
886 else if (g[index].axis == 1)
887 x = 1.0;
888 else
889 z = 1.0;
Gareth Hughes28861b12000-11-30 01:44:24 +0000890
Brian Paul392a7002000-03-06 23:34:42 +0000891 if (z != 1.0)
892 glRotatef (90.0, x, y, z);
Gareth Hughes28861b12000-11-30 01:44:24 +0000893
Brian Paul392a7002000-03-06 23:34:42 +0000894 glCallList (b[i].id);
895 glPopMatrix ();
896 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000897
Brian Paul392a7002000-03-06 23:34:42 +0000898 glPopMatrix ();
899 glutSwapBuffers ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000900
901 {
902 GLint t = glutGet(GLUT_ELAPSED_TIME);
903 Frames++;
904 if (t - T0 >= 5000) {
905 GLfloat seconds = (t - T0) / 1000.0;
906 GLfloat fps = Frames / seconds;
907 printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps);
Keith Whitwelle6479c62009-02-24 12:02:24 +0000908 fflush(stdout);
Gareth Hughes28861b12000-11-30 01:44:24 +0000909 T0 = t;
910 Frames = 0;
911 }
912 }
Brian Paul392a7002000-03-06 23:34:42 +0000913}
914
915
Gareth Hughes28861b12000-11-30 01:44:24 +0000916static void
917idle (void)
Brian Paul392a7002000-03-06 23:34:42 +0000918{
919 int i;
Brian Paul92eddb02005-01-09 17:37:50 +0000920 static double t0 = -1.;
921 double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
922 if (t0 < 0.0)
923 t0 = t;
924 dt = t - t0;
925 t0 = t;
Brian Paul392a7002000-03-06 23:34:42 +0000926 for (i = 0; i < number_of_gears; i++)
Brian Paul92eddb02005-01-09 17:37:50 +0000927 g[i].angle += g[i].angular_velocity * dt;
Brian Paul392a7002000-03-06 23:34:42 +0000928 glutPostRedisplay();
929}
930
931
932
933
Gareth Hughes28861b12000-11-30 01:44:24 +0000934/* change view angle, exit upon ESC */
935static void
936key (unsigned char k, int x, int y)
Brian Paul392a7002000-03-06 23:34:42 +0000937{
938 switch (k)
939 {
940 case 'x':
941 view_rotx += 5.0;
942 break;
943 case 'X':
944 view_rotx -= 5.0;
945 break;
946 case 'y':
947 view_roty += 5.0;
948 break;
949 case 'Y':
950 view_roty -= 5.0;
951 break;
952 case 'z':
953 view_rotz += 5.0;
954 break;
955 case 'Z':
956 view_rotz -= 5.0;
957 break;
958 case 0x1B:
959 exit(0);
960 }
961}
962
963
964
965
Gareth Hughes28861b12000-11-30 01:44:24 +0000966/* new window size or exposure */
967static void
968reshape (int width, int height)
Brian Paul392a7002000-03-06 23:34:42 +0000969{
970 glViewport (0, 0, (GLint) width, (GLint) height);
971 glMatrixMode (GL_PROJECTION);
972 glLoadIdentity ();
973 if (width > height)
974 {
975 GLfloat w = (GLfloat) width / (GLfloat) height;
976 glFrustum (-w, w, -1.0, 1.0, 5.0, 60.0);
977 }
978 else
979 {
980 GLfloat h = (GLfloat) height / (GLfloat) width;
981 glFrustum (-1.0, 1.0, -h, h, 5.0, 60.0);
982 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000983
Brian Paul392a7002000-03-06 23:34:42 +0000984 glMatrixMode (GL_MODELVIEW);
985 glLoadIdentity ();
986 glTranslatef (0.0, 0.0, -40.0);
987 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
988}
989
990
991
Gareth Hughes28861b12000-11-30 01:44:24 +0000992static void
993init (void)
Brian Paul392a7002000-03-06 23:34:42 +0000994{
995 GLfloat matShine = 20.00F;
996 GLfloat light0Pos[4] =
997 {
998 0.70F, 0.70F, 1.25F, 0.50F
999 };
1000 int i;
Gareth Hughes28861b12000-11-30 01:44:24 +00001001
Brian Paul392a7002000-03-06 23:34:42 +00001002 glClearColor (background[0], background[1], background[2], 1.0F);
1003 glClearIndex ((GLfloat) 0.0);
Gareth Hughes28861b12000-11-30 01:44:24 +00001004
Brian Paul392a7002000-03-06 23:34:42 +00001005 glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, matShine);
1006 glLightfv (GL_LIGHT0, GL_POSITION, light0Pos);
1007 glEnable (GL_LIGHT0);
Gareth Hughes28861b12000-11-30 01:44:24 +00001008
Brian Paul392a7002000-03-06 23:34:42 +00001009 glEnable (GL_LIGHTING);
1010 glEnable (GL_DEPTH_TEST);
1011 for (i = 0; i < number_of_gears; i++)
1012 g[i].angle = 0.0;
Gareth Hughes28861b12000-11-30 01:44:24 +00001013
Brian Paul392a7002000-03-06 23:34:42 +00001014 for (i = 0; i < number_of_gears; i++)
1015 {
1016 g[i].id = glGenLists (1);
1017 glNewList (g[i].id, GL_COMPILE);
1018 glColor3fv (g[i].color);
1019 glMaterialfv (GL_FRONT, GL_SPECULAR, g[i].color);
1020 gear (i, g[i].type, g[i].radius, g[i].width, g[i].teeth, g[i].tooth_depth);
1021 glEndList ();
1022 }
Gareth Hughes28861b12000-11-30 01:44:24 +00001023
Brian Paul392a7002000-03-06 23:34:42 +00001024 for (i = 0; i < number_of_axles; i++)
1025 {
1026 a[i].id = glGenLists (1);
1027 glNewList (a[i].id, GL_COMPILE);
1028 glColor3fv (a[i].color);
1029 glMaterialfv (GL_FRONT, GL_SPECULAR, a[i].color);
1030 axle (i, a[i].radius, a[i].length);
1031 glEndList ();
1032 }
Gareth Hughes28861b12000-11-30 01:44:24 +00001033
Brian Paul392a7002000-03-06 23:34:42 +00001034 for (i = 0; i < number_of_belts; i++)
1035 {
1036 b[i].id = glGenLists (1);
1037 glNewList (b[i].id, GL_COMPILE);
1038 belt (g[gear_find (b[i].gear1_name)], g[gear_find (b[i].gear2_name)]);
1039 glEndList ();
1040 }
Gareth Hughes28861b12000-11-30 01:44:24 +00001041
Brian Paul392a7002000-03-06 23:34:42 +00001042 glEnable (GL_COLOR_MATERIAL);
1043}
1044
1045
1046
Gareth Hughes28861b12000-11-30 01:44:24 +00001047int
1048main (int argc, char *argv[])
Brian Paul392a7002000-03-06 23:34:42 +00001049{
1050 char *file;
1051
Brian Paul392a7002000-03-06 23:34:42 +00001052 glutInitWindowSize(640,480);
Brian Paul263f4322009-12-18 08:12:55 -07001053 glutInit(&argc, argv);
Brian Paul392a7002000-03-06 23:34:42 +00001054 glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
Gareth Hughes28861b12000-11-30 01:44:24 +00001055
Brian Paul392a7002000-03-06 23:34:42 +00001056 if (glutCreateWindow ("Gear Train Simulation") == GL_FALSE)
1057 exit (1);
1058
Brian Paul263f4322009-12-18 08:12:55 -07001059 if (argc < 2)
1060 file = "geartrain.dat";
1061 else
1062 file = argv[1];
1063
Brian Paul392a7002000-03-06 23:34:42 +00001064 getdata (file);
1065 process ();
1066 init ();
Gareth Hughes28861b12000-11-30 01:44:24 +00001067
Brian Paul392a7002000-03-06 23:34:42 +00001068 glutDisplayFunc (draw);
1069 glutReshapeFunc (reshape);
1070 glutKeyboardFunc (key);
1071 glutIdleFunc (idle);
1072 glutMainLoop ();
1073 return 0;
1074}