blob: c612ad74bf0ffa54d0324462aae489eb9523635f [file] [log] [blame]
Gareth Hughes28861b12000-11-30 01:44:24 +00001/* $Id: geartrain.c,v 1.7 2000/11/30 01:44:24 gareth Exp $ */
Brian Paul392a7002000-03-06 23:34:42 +00002
3/*
Brian Paula74394c2000-04-04 15:20:17 +00004 * GearTrain Simulator * Version: 1.00
Brian Paul392a7002000-03-06 23:34:42 +00005 *
Brian Paula74394c2000-04-04 15:20:17 +00006 * Copyright (C) 1999 Shobhan Kumar Dutta All Rights Reserved.
7 * <skdutta@del3.vsnl.net.in>
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * SHOBHAN KUMAR DUTTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
24 * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
Brian Paul392a7002000-03-06 23:34:42 +000026 */
27
28
29#include <math.h>
30#include <stdlib.h>
31#include <GL/glut.h>
32#include <string.h>
33#include <stdio.h>
34
35#define min(x, y) ( x < y ? x : y )
36
37#ifndef M_PI
38#define M_PI 3.14159265
39#endif /* */
Brian Paul3769b3f2000-03-22 23:14:54 +000040typedef GLfloat TDA[4];
Brian Paul392a7002000-03-06 23:34:42 +000041
42TDA background;
43
44
Gareth Hughes28861b12000-11-30 01:44:24 +000045struct AXLE
Brian Paul392a7002000-03-06 23:34:42 +000046 {
47 char name[20];
48 GLint id;
49 GLfloat radius;
50 GLint axis;
51 TDA color;
52 TDA position;
53 GLfloat length;
54 GLint motored;
55 GLfloat angular_velocity;
56 GLint direction;
57 };
58
59
Gareth Hughes28861b12000-11-30 01:44:24 +000060struct GEAR
Brian Paul392a7002000-03-06 23:34:42 +000061 {
62 char name[20];
63 char type[7];
64 GLint face;
65 GLint id;
66 GLfloat radius;
67 GLfloat width;
68 GLint teeth;
69 GLfloat tooth_depth;
70 GLfloat angle;
71 GLfloat angular_velocity;
72 TDA color;
73 GLint relative_position;
74 TDA position;
75 char axle_name[20];
76 GLint axis;
77 GLint direction;
78 GLint motored;
79 };
80
81
Gareth Hughes28861b12000-11-30 01:44:24 +000082struct BELT
Brian Paul392a7002000-03-06 23:34:42 +000083 {
84 char name[20];
85 GLint id;
86 char gear1_name[20];
87 char gear2_name[20];
88 };
89
90
91FILE * mainfile;
92struct GEAR g[10];
93struct AXLE a[10];
94struct BELT b[10];
95int number_of_gears;
96int number_of_axles;
97int number_of_belts;
98
99
100char Buf1[256], Buf2[256], Buf3[256], Buf4[256], Buf5[256];
101
Gareth Hughes28861b12000-11-30 01:44:24 +0000102static GLint T0 = 0;
103static GLint Frames = 0;
Brian Paul392a7002000-03-06 23:34:42 +0000104
Gareth Hughes28861b12000-11-30 01:44:24 +0000105
106static void
107strset (char buf[], char ch)
Brian Paul392a7002000-03-06 23:34:42 +0000108{
109 int i;
110 for (i = 0; i < strlen (buf); i++)
111 buf[i] = ch;
112}
113
114
Gareth Hughes28861b12000-11-30 01:44:24 +0000115static void
116Clear_Buffers ()
Brian Paul392a7002000-03-06 23:34:42 +0000117{
118 strset (Buf1, 0);
119 strset (Buf2, 0);
120 strset (Buf3, 0);
121 strset (Buf4, 0);
122 strset (Buf5, 0);
123}
124
125
Gareth Hughes28861b12000-11-30 01:44:24 +0000126static void
127LoadTriplet (TDA A)
Brian Paul392a7002000-03-06 23:34:42 +0000128{
129 Clear_Buffers ();
130 fscanf (mainfile, "%s %s %s %s", Buf1, Buf2, Buf3, Buf4);
131 A[0] = atof (Buf2);
132 A[1] = atof (Buf3);
133 A[2] = atof (Buf4);
134}
135
136
Gareth Hughes28861b12000-11-30 01:44:24 +0000137static void
138LoadReal (float *a)
Brian Paul392a7002000-03-06 23:34:42 +0000139{
140 Clear_Buffers ();
141 fscanf (mainfile, "%s %s", Buf1, Buf2);
142 *a = atof (Buf2);
143}
144
145
Gareth Hughes28861b12000-11-30 01:44:24 +0000146static void
147LoadInteger (int *a)
Brian Paul392a7002000-03-06 23:34:42 +0000148{
149 Clear_Buffers ();
150 fscanf (mainfile, "%s %s", Buf1, Buf2);
151 *a = atoi (Buf2);
152}
153
154
Gareth Hughes28861b12000-11-30 01:44:24 +0000155static void
156LoadText (char *a)
Brian Paul392a7002000-03-06 23:34:42 +0000157{
158 Clear_Buffers ();
159 fscanf (mainfile, "%s %s", Buf1, Buf2);
160 strcpy (a, Buf2);
161}
162
163
Gareth Hughes28861b12000-11-30 01:44:24 +0000164static void
165getdata (char filename[])
Brian Paul392a7002000-03-06 23:34:42 +0000166{
167 int gear_count = 0, axle_count = 0, belt_count = 0, i;
Gareth Hughes28861b12000-11-30 01:44:24 +0000168
Brian Paul392a7002000-03-06 23:34:42 +0000169 mainfile = fopen (filename, "r");
Brian Paul5a564052000-03-29 17:56:02 +0000170 if (!mainfile) {
171 printf("Error: couldn't open %s\n", filename);
172 exit(-1);
173 }
174
Brian Paul392a7002000-03-06 23:34:42 +0000175 do
176 {
177 Clear_Buffers ();
178 fscanf (mainfile, "%s", Buf1);
179 if (ferror (mainfile))
180 {
181 printf ("\nError opening file !\n");
182 exit (1);
183 }
184
185 if (!(strcmp (Buf1, "BACKGROUND")))
186 LoadTriplet (background);
Gareth Hughes28861b12000-11-30 01:44:24 +0000187
Brian Paul392a7002000-03-06 23:34:42 +0000188 if (!(strcmp (Buf1, "ANAME")))
189 {
190 LoadText (a[axle_count].name);
191 axle_count++;
192 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000193
Brian Paul392a7002000-03-06 23:34:42 +0000194 if (!(strcmp (Buf1, "ARADIUS")))
195 LoadReal (&a[axle_count - 1].radius);
Gareth Hughes28861b12000-11-30 01:44:24 +0000196
Brian Paul392a7002000-03-06 23:34:42 +0000197 if (!(strcmp (Buf1, "AAXIS")))
198 LoadInteger (&a[axle_count - 1].axis);
Gareth Hughes28861b12000-11-30 01:44:24 +0000199
Brian Paul392a7002000-03-06 23:34:42 +0000200 if (!(strcmp (Buf1, "ACOLOR")))
201 LoadTriplet (a[axle_count - 1].color);
Gareth Hughes28861b12000-11-30 01:44:24 +0000202
Brian Paul392a7002000-03-06 23:34:42 +0000203 if (!(strcmp (Buf1, "APOSITION")))
204 LoadTriplet (a[axle_count - 1].position);
Gareth Hughes28861b12000-11-30 01:44:24 +0000205
Brian Paul392a7002000-03-06 23:34:42 +0000206 if (!(strcmp (Buf1, "ALENGTH")))
207 LoadReal (&a[axle_count - 1].length);
Gareth Hughes28861b12000-11-30 01:44:24 +0000208
Brian Paul392a7002000-03-06 23:34:42 +0000209 if (!(strcmp (Buf1, "AMOTORED")))
210 LoadInteger (&a[axle_count - 1].motored);
Gareth Hughes28861b12000-11-30 01:44:24 +0000211
Brian Paul392a7002000-03-06 23:34:42 +0000212 if (!(strcmp (Buf1, "AANGULARVELOCITY")))
213 LoadReal (&a[axle_count - 1].angular_velocity);
Gareth Hughes28861b12000-11-30 01:44:24 +0000214
Brian Paul392a7002000-03-06 23:34:42 +0000215 if (!(strcmp (Buf1, "ADIRECTION")))
216 LoadInteger (&a[axle_count - 1].direction);
Gareth Hughes28861b12000-11-30 01:44:24 +0000217
Brian Paul392a7002000-03-06 23:34:42 +0000218 if (!(strcmp (Buf1, "GNAME")))
219 {
220 LoadText (g[gear_count].name);
221 gear_count++;
222 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000223
Brian Paul392a7002000-03-06 23:34:42 +0000224 if (!(strcmp (Buf1, "GTYPE")))
225 LoadText (g[gear_count - 1].type);
Gareth Hughes28861b12000-11-30 01:44:24 +0000226
Brian Paul392a7002000-03-06 23:34:42 +0000227 if (!(strcmp (Buf1, "GFACE")))
228 LoadInteger (&g[gear_count - 1].face);
Gareth Hughes28861b12000-11-30 01:44:24 +0000229
Brian Paul392a7002000-03-06 23:34:42 +0000230 if (!(strcmp (Buf1, "GRADIUS")))
231 LoadReal (&g[gear_count - 1].radius);
Gareth Hughes28861b12000-11-30 01:44:24 +0000232
Brian Paul392a7002000-03-06 23:34:42 +0000233 if (!(strcmp (Buf1, "GWIDTH")))
234 LoadReal (&g[gear_count - 1].width);
Gareth Hughes28861b12000-11-30 01:44:24 +0000235
Brian Paul392a7002000-03-06 23:34:42 +0000236 if (!(strcmp (Buf1, "GTEETH")))
237 LoadInteger (&g[gear_count - 1].teeth);
Gareth Hughes28861b12000-11-30 01:44:24 +0000238
Brian Paul392a7002000-03-06 23:34:42 +0000239 if (!(strcmp (Buf1, "GTOOTHDEPTH")))
240 LoadReal (&g[gear_count - 1].tooth_depth);
Gareth Hughes28861b12000-11-30 01:44:24 +0000241
Brian Paul392a7002000-03-06 23:34:42 +0000242 if (!(strcmp (Buf1, "GCOLOR")))
243 LoadTriplet (g[gear_count - 1].color);
Gareth Hughes28861b12000-11-30 01:44:24 +0000244
Brian Paul392a7002000-03-06 23:34:42 +0000245 if (!(strcmp (Buf1, "GAXLE")))
246 LoadText (g[gear_count - 1].axle_name);
Gareth Hughes28861b12000-11-30 01:44:24 +0000247
Brian Paul392a7002000-03-06 23:34:42 +0000248 if (!(strcmp (Buf1, "GPOSITION")))
249 LoadInteger (&g[gear_count - 1].relative_position);
Gareth Hughes28861b12000-11-30 01:44:24 +0000250
Brian Paul392a7002000-03-06 23:34:42 +0000251 if (!(strcmp (Buf1, "BELTNAME")))
252 {
253 LoadText (b[belt_count].name);
254 belt_count++;
255 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000256
Brian Paul392a7002000-03-06 23:34:42 +0000257 if (!(strcmp (Buf1, "GEAR1NAME")))
258 LoadText (b[belt_count - 1].gear1_name);
Gareth Hughes28861b12000-11-30 01:44:24 +0000259
Brian Paul392a7002000-03-06 23:34:42 +0000260 if (!(strcmp (Buf1, "GEAR2NAME")))
261 LoadText (b[belt_count - 1].gear2_name);
262 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000263
Brian Paul392a7002000-03-06 23:34:42 +0000264 while (Buf1[0] != 0);
Gareth Hughes28861b12000-11-30 01:44:24 +0000265
Brian Paul392a7002000-03-06 23:34:42 +0000266 for (i = 0; i < number_of_gears; i++)
267 {
268 g[i].axis = -1;
269 g[i].direction = 0;
270 g[i].angular_velocity = 0.0;
271 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000272
Brian Paul392a7002000-03-06 23:34:42 +0000273 number_of_gears = gear_count;
274 number_of_axles = axle_count;
275 number_of_belts = belt_count;
276 fclose (mainfile);
277}
278
279
Gareth Hughes28861b12000-11-30 01:44:24 +0000280static void
281axle (GLint j, GLfloat radius, GLfloat length)
Brian Paul392a7002000-03-06 23:34:42 +0000282{
283 GLfloat angle, rad, incr = 10.0 * M_PI / 180.0;
Gareth Hughes28861b12000-11-30 01:44:24 +0000284
285 /* draw main cylinder */
Brian Paul392a7002000-03-06 23:34:42 +0000286 glBegin (GL_QUADS);
287 for (angle = 0.0; angle < 360.0; angle += 5.0)
288 {
289 rad = angle * M_PI / 180.0;
290 glNormal3f (cos (rad), sin (rad), 0.0);
291 glVertex3f (radius * cos (rad), radius * sin (rad), length / 2);
292 glVertex3f (radius * cos (rad), radius * sin (rad), -length / 2);
293 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), -length / 2);
294 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), length / 2);
295 }
296 glEnd ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000297
298 /* draw front face */
Brian Paul392a7002000-03-06 23:34:42 +0000299 glNormal3f (0.0, 0.0, 1.0);
300 glBegin (GL_TRIANGLES);
301 for (angle = 0.0; angle < 360.0; angle += 5.0)
302 {
303 rad = angle * M_PI / 180.0;
304 glVertex3f (0.0, 0.0, length / 2);
305 glVertex3f (radius * cos (rad), radius * sin (rad), length / 2);
306 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), length / 2);
307 glVertex3f (0.0, 0.0, length / 2);
308 }
309 glEnd ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000310
311 /* draw back face */
Brian Paul392a7002000-03-06 23:34:42 +0000312 glNormal3f (0.0, 0.0, -1.0);
313 glBegin (GL_TRIANGLES);
314 for (angle = 0.0; angle <= 360.0; angle += 5.0)
315 {
316 rad = angle * M_PI / 180.0;
317 glVertex3f (0.0, 0.0, -length / 2);
318 glVertex3f (radius * cos (rad), radius * sin (rad), -length / 2);
319 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), -length / 2);
320 glVertex3f (0.0, 0.0, -length / 2);
321 }
322 glEnd ();
323}
324
325
326
Gareth Hughes28861b12000-11-30 01:44:24 +0000327static void
328gear (GLint j, char type[], GLfloat radius, GLfloat width,
329 GLint teeth, GLfloat tooth_depth)
Brian Paul392a7002000-03-06 23:34:42 +0000330{
331 GLint i;
332 GLfloat r1, r2;
333 GLfloat angle, da;
334 GLfloat u, v, len, fraction = 0.5;
335 GLfloat n = 1.0;
Brian Paul9d0bc1d2000-04-05 21:36:03 +0000336
Brian Paul392a7002000-03-06 23:34:42 +0000337 r1 = radius - tooth_depth;
338 r2 = radius;
Gareth Hughes28861b12000-11-30 01:44:24 +0000339
Brian Paul392a7002000-03-06 23:34:42 +0000340 da = 2.0 * M_PI / teeth / 4.0;
341 if (!g[j].face)
342 {
343 fraction = -0.5;
344 n = -1.0;
345 }
346 if (!(strcmp (type, "NORMAL")))
347 {
348 fraction = 0.5;
349 n = 1.0;
350 }
351
Gareth Hughes28861b12000-11-30 01:44:24 +0000352 /* draw front face */
Brian Paul392a7002000-03-06 23:34:42 +0000353 if (!(strcmp (type, "NORMAL")))
354 {
355 glNormal3f (0.0, 0.0, 1.0 * n);
356 glBegin (GL_QUAD_STRIP);
357 for (i = 0; i <= teeth; i++)
358 {
359 angle = i * 2.0 * M_PI / teeth;
360 glVertex3f (0.0, 0.0, width * fraction);
361 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
362 glVertex3f (0.0, 0.0, width * fraction);
363 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
364 }
365 glEnd ();
366 }
367 else
368 {
369 glNormal3f (0.0, 0.0, 1.0 * n);
370 glBegin (GL_QUAD_STRIP);
371 for (i = 0; i <= teeth; i++)
372 {
373 angle = i * 2.0 * M_PI / teeth;
374 glVertex3f (0.0, 0.0, width * fraction);
375 glVertex3f ((r2 - width) * cos (angle), (r2 - width) * sin (angle), width * fraction);
376 glVertex3f (0.0, 0.0, width * fraction);
377 glVertex3f ((r2 - width) * cos (angle + 3 * da), (r2 - width) * sin (angle + 3 * da), width * fraction);
378 }
379 glEnd ();
380 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000381
382 /* draw front sides of teeth */
Brian Paul392a7002000-03-06 23:34:42 +0000383 if (!(strcmp (type, "NORMAL")))
384 {
385 glNormal3f (0.0, 0.0, 1.0 * n);
386 glBegin (GL_QUADS);
387 da = 2.0 * M_PI / teeth / 4.0;
388 for (i = 0; i < teeth; i++)
389 {
390 angle = i * 2.0 * M_PI / teeth;
391 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
392 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), width * fraction);
393 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), width * fraction);
394 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
395 }
396 glEnd ();
397 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000398
Brian Paul392a7002000-03-06 23:34:42 +0000399 glNormal3f (0.0, 0.0, -1.0 * n);
Gareth Hughes28861b12000-11-30 01:44:24 +0000400
401 /* draw back face */
Brian Paul392a7002000-03-06 23:34:42 +0000402 glBegin (GL_QUAD_STRIP);
403 for (i = 0; i <= teeth; i++)
404 {
405 angle = i * 2.0 * M_PI / teeth;
406 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
407 glVertex3f (0.0, 0.0, -width * fraction);
408 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
409 glVertex3f (0.0, 0.0, -width * fraction);
410 }
411 glEnd ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000412
413 /* draw back sides of teeth */
Brian Paul392a7002000-03-06 23:34:42 +0000414 glNormal3f (0.0, 0.0, -1.0 * n);
415 glBegin (GL_QUADS);
416 da = 2.0 * M_PI / teeth / 4.0;
417 for (i = 0; i < teeth; i++)
418 {
419 angle = i * 2.0 * M_PI / teeth;
420 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
421 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
422 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
423 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
424 }
425 glEnd ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000426
427
428 /* draw outward faces of teeth */
Brian Paul392a7002000-03-06 23:34:42 +0000429 if (!(strcmp (type, "NORMAL")))
430 {
431 glBegin (GL_QUAD_STRIP);
432 for (i = 0; i < teeth; i++)
433 {
434 angle = i * 2.0 * M_PI / teeth;
Gareth Hughes28861b12000-11-30 01:44:24 +0000435
Brian Paul392a7002000-03-06 23:34:42 +0000436 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
437 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
438 u = r2 * cos (angle + da) - r1 * cos (angle);
439 v = r2 * sin (angle + da) - r1 * sin (angle);
440 len = sqrt (u * u + v * v);
441 u /= len;
442 v /= len;
443 glNormal3f (v, -u, 0.0);
444 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), width * fraction);
445 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
446 glNormal3f (cos (angle), sin (angle), 0.0);
447 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), width * fraction);
448 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
449 u = r1 * cos (angle + 3 * da) - r2 * cos (angle + 2 * da);
450 v = r1 * sin (angle + 3 * da) - r2 * sin (angle + 2 * da);
451 glNormal3f (v, -u, 0.0);
452 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
453 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
454 glNormal3f (cos (angle), sin (angle), 0.0);
455 }
456 }
457 else
458 {
459 glBegin (GL_QUAD_STRIP);
460 for (i = 0; i < teeth; i++)
461 {
462 angle = i * 2.0 * M_PI / teeth;
463 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
464 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
465 u = r2 * cos (angle + da) - r1 * cos (angle);
466 v = r2 * sin (angle + da) - r1 * sin (angle);
467 len = sqrt (u * u + v * v);
468 u /= len;
469 v /= len;
470 glNormal3f (v, -u, 0.0);
471 glVertex3f ((r2 - width) * cos (angle + da), (r2 - width) * sin (angle + da), width * fraction);
472 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
473 glNormal3f (cos (angle), sin (angle), n);
474 glVertex3f ((r2 - width) * cos (angle + 2 * da), (r2 - width) * sin (angle + 2 * da), width * fraction);
475 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
476 u = r1 * cos (angle + 3 * da) - r2 * cos (angle + 2 * da);
477 v = r1 * sin (angle + 3 * da) - r2 * sin (angle + 2 * da);
478 glNormal3f (v, -u, 0.0);
479 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
480 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
481 glNormal3f (cos (angle), sin (angle), n);
482 }
483 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000484
Brian Paul392a7002000-03-06 23:34:42 +0000485 glVertex3f (r1 * cos (0), r1 * sin (0), width * fraction);
486 glVertex3f (r1 * cos (0), r1 * sin (0), -width * fraction);
487 glEnd ();
488}
489
490
Gareth Hughes28861b12000-11-30 01:44:24 +0000491static void
492belt (struct GEAR g1, struct GEAR g2)
Brian Paul392a7002000-03-06 23:34:42 +0000493{
494 GLfloat D, alpha, phi, angle, incr, width;
495 GLint indexes[3] =
496 {
497 0, 0, 0
498 };
Gareth Hughes28861b12000-11-30 01:44:24 +0000499
Brian Paul392a7002000-03-06 23:34:42 +0000500 GLfloat col[3] =
501 {
502 0.0, 0.0, 0.0
503 };
Gareth Hughes28861b12000-11-30 01:44:24 +0000504
Brian Paul392a7002000-03-06 23:34:42 +0000505 width = min (g1.width, g2.width);
506 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));
507 alpha = acos ((g2.position[0] - g1.position[0]) / D);
508 phi = acos ((g1.radius - g2.radius) / D);
509 glBegin (GL_QUADS);
510 glColor3fv (col);
511 glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
512 incr = 1.2 * 360.0 / g1.teeth * M_PI / 180.00;
513 for (angle = alpha + phi; angle <= 2 * M_PI - phi + alpha; angle += 360.0 / g1.teeth * M_PI / 180.00)
514 {
515 glNormal3f (cos (angle), sin (angle), 0.0);
516 glVertex3f (g1.radius * cos (angle), g1.radius * sin (angle), width * 0.5);
517 glVertex3f (g1.radius * cos (angle), g1.radius * sin (angle), -width * 0.5);
518 glVertex3f (g1.radius * cos (angle + incr), g1.radius * sin (angle + incr), -width * 0.5);
519 glVertex3f (g1.radius * cos (angle + incr), g1.radius * sin (angle + incr), width * 0.5);
520 }
521 glEnd ();
522 glBegin (GL_QUADS);
523 glColor3fv (col);
524 glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
525 incr = 1.2 * 360.0 / g2.teeth * M_PI / 180.00;
526 for (angle = -phi + alpha; angle <= phi + alpha; angle += 360.0 / g1.teeth * M_PI / 180.0)
527 {
528 glNormal3f (cos (angle), sin (angle), 0.0);
529 glVertex3f (g2.radius * cos (angle) + g2.position[0] - g1.position[0], g2.radius * sin (angle) + g2.position[1] - g1.position[1], width * 0.5);
530 glVertex3f (g2.radius * cos (angle) + g2.position[0] - g1.position[0], g2.radius * sin (angle) + g2.position[1] - g1.position[1], width * -0.5);
531 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);
532 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);
533 }
534 glEnd ();
535
536 glBegin (GL_QUADS);
537 glColor3fv (col);
538 glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
539 glVertex3f (g1.radius * cos (alpha + phi), g1.radius * sin (alpha + phi), width * 0.5);
540 glVertex3f (g1.radius * cos (alpha + phi), g1.radius * sin (alpha + phi), width * -0.5);
541 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);
542 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);
543 glVertex3f (g1.radius * cos (alpha - phi), g1.radius * sin (alpha - phi), width * 0.5);
544 glVertex3f (g1.radius * cos (alpha - phi), g1.radius * sin (alpha - phi), 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 (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);
547 glEnd ();
548}
549
550
Gareth Hughes28861b12000-11-30 01:44:24 +0000551static int
552axle_find (char axle_name[])
Brian Paul392a7002000-03-06 23:34:42 +0000553{
554 int i;
Gareth Hughes28861b12000-11-30 01:44:24 +0000555
Brian Paul392a7002000-03-06 23:34:42 +0000556 for (i = 0; i < number_of_axles; i++)
557 {
558 if (!(strcmp (axle_name, a[i].name)))
559 break;
560 }
561 return i;
562}
563
564
Gareth Hughes28861b12000-11-30 01:44:24 +0000565static int
566gear_find (char gear_name[])
Brian Paul392a7002000-03-06 23:34:42 +0000567{
568 int i;
Gareth Hughes28861b12000-11-30 01:44:24 +0000569
Brian Paul392a7002000-03-06 23:34:42 +0000570 for (i = 0; i < number_of_gears; i++)
571 {
572 if (!(strcmp (gear_name, g[i].name)))
573 break;
574 }
575 return i;
576}
577
578
Gareth Hughes28861b12000-11-30 01:44:24 +0000579static void
580process ()
Brian Paul392a7002000-03-06 23:34:42 +0000581{
582 GLfloat x, y, z, D, dist;
583 GLint axle_index, i, j, g1, g2, k;
584 char error[80];
Gareth Hughes28861b12000-11-30 01:44:24 +0000585
Brian Paul392a7002000-03-06 23:34:42 +0000586 for (i = 0; i < number_of_gears; i++)
587 {
588 x = 0.0;
589 y = 0.0;
590 z = 0.0;
591 axle_index = axle_find (g[i].axle_name);
592 g[i].axis = a[axle_index].axis;
593 g[i].motored = a[axle_index].motored;
594 if (a[axle_index].motored)
595 {
596 g[i].direction = a[axle_index].direction;
597 g[i].angular_velocity = a[axle_index].angular_velocity;
598 }
599 if (g[i].axis == 0)
600 x = 1.0;
601 else if (g[i].axis == 1)
602 y = 1.0;
603 else
604 z = 1.0;
Gareth Hughes28861b12000-11-30 01:44:24 +0000605
Brian Paul392a7002000-03-06 23:34:42 +0000606 g[i].position[0] = a[axle_index].position[0] + x * g[i].relative_position;
607 g[i].position[1] = a[axle_index].position[1] + y * g[i].relative_position;
608 g[i].position[2] = a[axle_index].position[2] + z * g[i].relative_position;
609 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000610
Brian Paul392a7002000-03-06 23:34:42 +0000611 for (k = 0; k < number_of_axles; k++)
612 {
613 for (i = 0; i < number_of_gears - 1; i++)
614 {
615 for (j = 0; j < number_of_gears; j++)
616 {
617 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))
618 {
619 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));
620 if (D < 1.1 * (g[i].radius - g[i].tooth_depth + g[j].radius - g[j].tooth_depth))
621 {
622 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 +0000623
Brian Paul392a7002000-03-06 23:34:42 +0000624 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
625 exit (1);
626 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000627
Brian Paul392a7002000-03-06 23:34:42 +0000628 if (g[i].axis == 0)
629 {
630 dist = g[i].position[0] - g[j].position[0];
631 }
632 else if (g[i].axis == 1)
633 {
634 dist = g[i].position[1] - g[j].position[1];
635 }
636 else
637 dist = g[i].position[2] - g[j].position[2];
Gareth Hughes28861b12000-11-30 01:44:24 +0000638
Brian Paul392a7002000-03-06 23:34:42 +0000639 dist = fabs (dist);
Gareth Hughes28861b12000-11-30 01:44:24 +0000640
Brian Paul392a7002000-03-06 23:34:42 +0000641 if (dist < (g[i].width / 2 + g[j].width / 2))
642 {
643 if ((g[i].motored) && (!(g[j].motored)) && (D < 0.95 * (g[i].radius + g[j].radius)))
644 {
645 axle_index = axle_find (g[j].axle_name);
646 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))
647 {
648 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
649 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
650 exit (1);
651 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000652
Brian Paul392a7002000-03-06 23:34:42 +0000653 g[j].motored = (a[axle_index].motored = 1);
654 g[j].direction = (a[axle_index].direction = -g[i].direction);
655 a[axle_index].angular_velocity = g[i].angular_velocity * g[i].teeth / g[j].teeth;
656 g[j].angular_velocity = (a[axle_index].angular_velocity *= g[i].radius / g[j].radius);
657 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000658
Brian Paul392a7002000-03-06 23:34:42 +0000659 if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * (g[i].radius + g[j].radius)))
660 {
661 axle_index = axle_find (g[i].axle_name);
662 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))
663 {
664 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
665 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
666 exit (1);
667 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000668
Brian Paul392a7002000-03-06 23:34:42 +0000669 g[i].motored = (a[axle_index].motored = 1);
670 g[i].direction = (a[axle_index].direction = -g[j].direction);
671 a[axle_index].angular_velocity = g[j].angular_velocity * g[j].teeth / g[i].teeth;
672 g[i].angular_velocity = (a[axle_index].angular_velocity *= g[j].radius / g[i].radius);
Gareth Hughes28861b12000-11-30 01:44:24 +0000673
Brian Paul392a7002000-03-06 23:34:42 +0000674 }
675 }
676 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000677
Brian Paul392a7002000-03-06 23:34:42 +0000678 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))
679 {
680 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));
681 if ((g[i].motored) && (!(g[j].motored)) && (D < 0.95 * sqrt (g[i].radius * g[i].radius + g[j].radius * g[j].radius)))
682 {
683 axle_index = axle_find (g[j].axle_name);
684 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))
685 {
686 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
687 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
688 exit (1);
689 }
690 g[j].motored = (a[axle_index].motored = 1);
691 g[j].direction = (a[axle_index].direction = -g[i].direction);
692 a[axle_index].angular_velocity = g[i].angular_velocity * g[i].teeth / g[j].teeth;
693 g[j].angular_velocity = (a[axle_index].angular_velocity *= g[i].radius / g[j].radius);
694 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000695
696
Brian Paul392a7002000-03-06 23:34:42 +0000697 if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * sqrt (g[i].radius * g[i].radius + g[j].radius * g[j].radius)))
698 {
699 axle_index = axle_find (g[i].axle_name);
700 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))
701 {
702 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
703 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
704 exit (1);
705 }
706 g[i].motored = (a[axle_index].motored = 1);
707 g[i].direction = (a[axle_index].direction = -g[j].direction);
708 a[axle_index].angular_velocity = g[j].angular_velocity * g[j].teeth / g[i].teeth;
709 g[i].angular_velocity = (a[axle_index].angular_velocity *= g[j].radius / g[i].radius);
710 }
711 }
712 }
713 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000714
Brian Paul392a7002000-03-06 23:34:42 +0000715 for (i = 0; i < number_of_gears; i++)
716 {
717 axle_index = axle_find (g[i].axle_name);
718 g[i].motored = a[axle_index].motored;
719 if (a[axle_index].motored)
720 {
721 g[i].direction = a[axle_index].direction;
722 g[i].angular_velocity = a[axle_index].angular_velocity;
723 }
724 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000725
Brian Paul392a7002000-03-06 23:34:42 +0000726 for (i = 0; i < number_of_belts; i++)
727 {
728 g1 = gear_find (b[i].gear1_name);
729 g2 = gear_find (b[i].gear2_name);
730 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));
731 if (!((g[g1].axis == g[g2].axis) && (!strcmp (g[g1].type, g[g2].type)) && (!strcmp (g[g1].type, "NORMAL"))))
732 {
733 printf (error, "Belt %s invalid.", b[i].name);
734 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
735 exit (1);
736 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000737
Brian Paul392a7002000-03-06 23:34:42 +0000738 if ((g[g1].axis == g[g2].axis) && (!strcmp (g[g1].type, g[g2].type)) && (!strcmp (g[g1].type, "NORMAL")))
739 {
740 /*
741 if((g[g1].motored)&&(g[g2].motored))
742 if(g[g2].angular_velocity!=(g[g1].angular_velocity*g[g1].radius/g[g2].radius))
743 {
744 printf(error,"Error in belt linkage of gears %s and %s".,g[g1].name,g[g2].name);
745 MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);
746 exit(1);
747 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000748 */
Brian Paul392a7002000-03-06 23:34:42 +0000749 if (g[g1].axis == 0)
750 {
751 dist = g[g1].position[0] - g[g2].position[0];
752 }
753 else if (g[i].axis == 1)
754 {
755 dist = g[g1].position[1] - g[g2].position[1];
756 }
757 else
758 dist = g[g1].position[2] - g[g2].position[2];
Gareth Hughes28861b12000-11-30 01:44:24 +0000759
Brian Paul392a7002000-03-06 23:34:42 +0000760 dist = fabs (dist);
Gareth Hughes28861b12000-11-30 01:44:24 +0000761
Brian Paul392a7002000-03-06 23:34:42 +0000762 if (dist > (g[g1].width / 2 + g[g2].width / 2))
763 {
764 printf (error, "Belt %s invalid.", b[i].name);
765 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
766 exit (1);
767 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000768
Brian Paul392a7002000-03-06 23:34:42 +0000769 if (dist < (g[g1].width / 2 + g[g2].width / 2))
770 {
771 if (D < g[g1].radius + g[g2].radius)
772 {
773 printf (error, "Gears %s and %s too close to be linked with belts", g[g1].name, g[g2].name);
774 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
775 exit (1);
776 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000777
Brian Paul392a7002000-03-06 23:34:42 +0000778 if ((g[g1].motored) && (!(g[g2].motored)))
779 {
780 axle_index = axle_find (g[g2].axle_name);
781 g[g2].motored = (a[axle_index].motored = 1);
782 g[g2].direction = (a[axle_index].direction = g[g1].direction);
783 g[g2].angular_velocity = (a[axle_index].angular_velocity = g[g1].angular_velocity * g[g1].radius / g[g2].radius);
784 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000785
Brian Paul392a7002000-03-06 23:34:42 +0000786 if ((!(g[g1].motored)) && (g[g2].motored))
787 {
788 axle_index = axle_find (g[g1].axle_name);
789 g[g1].motored = (a[axle_index].motored = 1);
790 g[g1].direction = (a[axle_index].direction = g[g2].direction);
791 g[g1].angular_velocity = (a[axle_index].angular_velocity = g[g2].angular_velocity * g[g2].radius / g[g1].radius);
792 }
793 }
794 }
795 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000796
Brian Paul392a7002000-03-06 23:34:42 +0000797 for (i = 0; i < number_of_gears; i++)
798 {
799 axle_index = axle_find (g[i].axle_name);
800 g[i].motored = a[axle_index].motored;
801 if (a[axle_index].motored)
802 {
803 g[i].direction = a[axle_index].direction;
804 g[i].angular_velocity = a[axle_index].angular_velocity;
805 }
806 }
807 }
808}
809
810
811
812GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 10.0;
813
814
Gareth Hughes28861b12000-11-30 01:44:24 +0000815static void
816draw (void)
Brian Paul392a7002000-03-06 23:34:42 +0000817{
818 int i;
819 GLfloat x, y, z;
820 int index;
821
822 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Gareth Hughes28861b12000-11-30 01:44:24 +0000823
Brian Paul392a7002000-03-06 23:34:42 +0000824 glPushMatrix ();
825 glRotatef (view_rotx, 1.0, 0.0, 0.0);
826 glRotatef (view_roty, 0.0, 1.0, 0.0);
827 glRotatef (view_rotz, 0.0, 0.0, 1.0);
Gareth Hughes28861b12000-11-30 01:44:24 +0000828
Brian Paul392a7002000-03-06 23:34:42 +0000829 for (i = 0; i < number_of_gears; i++)
830 {
831 x = 0.0;
832 y = 0.0;
833 z = 0.0;
834 glPushMatrix ();
835/*glTranslatef( -3.0, -2.0, 0.0 );*/
836 glTranslatef (g[i].position[0], g[i].position[1], g[i].position[2]);
837 if (g[i].axis == 0)
838 y = 1.0;
839 else if (g[i].axis == 1)
840 x = 1.0;
841 else
842 z = 1.0;
Gareth Hughes28861b12000-11-30 01:44:24 +0000843
Brian Paul392a7002000-03-06 23:34:42 +0000844 if (z != 1.0)
845 glRotatef (90.0, x, y, z);
Gareth Hughes28861b12000-11-30 01:44:24 +0000846
Brian Paul392a7002000-03-06 23:34:42 +0000847 glRotatef (g[i].direction * g[i].angle, 0.0, 0.0, 1.0);
848 glCallList (g[i].id);
849 glPopMatrix ();
850 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000851
Brian Paul392a7002000-03-06 23:34:42 +0000852 for (i = 0; i < number_of_axles; i++)
853 {
854 x = 0.0;
855 y = 0.0;
856 z = 0.0;
857 glPushMatrix ();
858 glTranslatef (a[i].position[0], a[i].position[1], a[i].position[2]);
859 if (a[i].axis == 0)
860 y = 1.0;
861 else if (a[i].axis == 1)
862 x = 1.0;
863 else
864 z = 1.0;
865
866 if (z != 1.0)
867 glRotatef (90.0, x, y, z);
Gareth Hughes28861b12000-11-30 01:44:24 +0000868
Brian Paul392a7002000-03-06 23:34:42 +0000869 glCallList (a[i].id);
870 glPopMatrix ();
871 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000872
Brian Paul392a7002000-03-06 23:34:42 +0000873 for (i = 0; i < number_of_belts; i++)
874 {
875 x = 0.0;
876 y = 0.0;
877 z = 0.0;
878 glPushMatrix ();
879 index = gear_find (b[i].gear1_name);
880 glTranslatef (g[index].position[0], g[index].position[1], g[index].position[2]);
881 if (g[index].axis == 0)
882 y = 1.0;
883 else if (g[index].axis == 1)
884 x = 1.0;
885 else
886 z = 1.0;
Gareth Hughes28861b12000-11-30 01:44:24 +0000887
Brian Paul392a7002000-03-06 23:34:42 +0000888 if (z != 1.0)
889 glRotatef (90.0, x, y, z);
Gareth Hughes28861b12000-11-30 01:44:24 +0000890
Brian Paul392a7002000-03-06 23:34:42 +0000891 glCallList (b[i].id);
892 glPopMatrix ();
893 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000894
Brian Paul392a7002000-03-06 23:34:42 +0000895 glPopMatrix ();
896 glutSwapBuffers ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000897
898 {
899 GLint t = glutGet(GLUT_ELAPSED_TIME);
900 Frames++;
901 if (t - T0 >= 5000) {
902 GLfloat seconds = (t - T0) / 1000.0;
903 GLfloat fps = Frames / seconds;
904 printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps);
905 T0 = t;
906 Frames = 0;
907 }
908 }
Brian Paul392a7002000-03-06 23:34:42 +0000909}
910
911
912
913
Gareth Hughes28861b12000-11-30 01:44:24 +0000914static void
915idle (void)
Brian Paul392a7002000-03-06 23:34:42 +0000916{
917 int i;
918 for (i = 0; i < number_of_gears; i++)
919 g[i].angle += g[i].angular_velocity;
920 glutPostRedisplay();
921}
922
923
924
925
Gareth Hughes28861b12000-11-30 01:44:24 +0000926/* change view angle, exit upon ESC */
927static void
928key (unsigned char k, int x, int y)
Brian Paul392a7002000-03-06 23:34:42 +0000929{
930 switch (k)
931 {
932 case 'x':
933 view_rotx += 5.0;
934 break;
935 case 'X':
936 view_rotx -= 5.0;
937 break;
938 case 'y':
939 view_roty += 5.0;
940 break;
941 case 'Y':
942 view_roty -= 5.0;
943 break;
944 case 'z':
945 view_rotz += 5.0;
946 break;
947 case 'Z':
948 view_rotz -= 5.0;
949 break;
950 case 0x1B:
951 exit(0);
952 }
953}
954
955
956
957
Gareth Hughes28861b12000-11-30 01:44:24 +0000958/* new window size or exposure */
959static void
960reshape (int width, int height)
Brian Paul392a7002000-03-06 23:34:42 +0000961{
962 glViewport (0, 0, (GLint) width, (GLint) height);
963 glMatrixMode (GL_PROJECTION);
964 glLoadIdentity ();
965 if (width > height)
966 {
967 GLfloat w = (GLfloat) width / (GLfloat) height;
968 glFrustum (-w, w, -1.0, 1.0, 5.0, 60.0);
969 }
970 else
971 {
972 GLfloat h = (GLfloat) height / (GLfloat) width;
973 glFrustum (-1.0, 1.0, -h, h, 5.0, 60.0);
974 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000975
Brian Paul392a7002000-03-06 23:34:42 +0000976 glMatrixMode (GL_MODELVIEW);
977 glLoadIdentity ();
978 glTranslatef (0.0, 0.0, -40.0);
979 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
980}
981
982
983
Gareth Hughes28861b12000-11-30 01:44:24 +0000984static void
985init (void)
Brian Paul392a7002000-03-06 23:34:42 +0000986{
987 GLfloat matShine = 20.00F;
988 GLfloat light0Pos[4] =
989 {
990 0.70F, 0.70F, 1.25F, 0.50F
991 };
992 int i;
Gareth Hughes28861b12000-11-30 01:44:24 +0000993
Brian Paul392a7002000-03-06 23:34:42 +0000994 glClearColor (background[0], background[1], background[2], 1.0F);
995 glClearIndex ((GLfloat) 0.0);
Gareth Hughes28861b12000-11-30 01:44:24 +0000996
Brian Paul392a7002000-03-06 23:34:42 +0000997 glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, matShine);
998 glLightfv (GL_LIGHT0, GL_POSITION, light0Pos);
999 glEnable (GL_LIGHT0);
Gareth Hughes28861b12000-11-30 01:44:24 +00001000
Brian Paul392a7002000-03-06 23:34:42 +00001001 glEnable (GL_LIGHTING);
1002 glEnable (GL_DEPTH_TEST);
1003 for (i = 0; i < number_of_gears; i++)
1004 g[i].angle = 0.0;
Gareth Hughes28861b12000-11-30 01:44:24 +00001005
Brian Paul392a7002000-03-06 23:34:42 +00001006 for (i = 0; i < number_of_gears; i++)
1007 {
1008 g[i].id = glGenLists (1);
1009 glNewList (g[i].id, GL_COMPILE);
1010 glColor3fv (g[i].color);
1011 glMaterialfv (GL_FRONT, GL_SPECULAR, g[i].color);
1012 gear (i, g[i].type, g[i].radius, g[i].width, g[i].teeth, g[i].tooth_depth);
1013 glEndList ();
1014 }
Gareth Hughes28861b12000-11-30 01:44:24 +00001015
Brian Paul392a7002000-03-06 23:34:42 +00001016 for (i = 0; i < number_of_axles; i++)
1017 {
1018 a[i].id = glGenLists (1);
1019 glNewList (a[i].id, GL_COMPILE);
1020 glColor3fv (a[i].color);
1021 glMaterialfv (GL_FRONT, GL_SPECULAR, a[i].color);
1022 axle (i, a[i].radius, a[i].length);
1023 glEndList ();
1024 }
Gareth Hughes28861b12000-11-30 01:44:24 +00001025
Brian Paul392a7002000-03-06 23:34:42 +00001026 for (i = 0; i < number_of_belts; i++)
1027 {
1028 b[i].id = glGenLists (1);
1029 glNewList (b[i].id, GL_COMPILE);
1030 belt (g[gear_find (b[i].gear1_name)], g[gear_find (b[i].gear2_name)]);
1031 glEndList ();
1032 }
Gareth Hughes28861b12000-11-30 01:44:24 +00001033
Brian Paul392a7002000-03-06 23:34:42 +00001034 glEnable (GL_COLOR_MATERIAL);
1035}
1036
1037
1038
Gareth Hughes28861b12000-11-30 01:44:24 +00001039int
1040main (int argc, char *argv[])
Brian Paul392a7002000-03-06 23:34:42 +00001041{
1042 char *file;
1043
1044 if (argc < 2)
1045 file = "geartrain.dat";
1046 else
1047 file = argv[1];
1048
1049 glutInitWindowPosition (0, 0);
1050 glutInitWindowSize(640,480);
1051 glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
Gareth Hughes28861b12000-11-30 01:44:24 +00001052
Brian Paul392a7002000-03-06 23:34:42 +00001053 if (glutCreateWindow ("Gear Train Simulation") == GL_FALSE)
1054 exit (1);
1055
1056 getdata (file);
1057 process ();
1058 init ();
Gareth Hughes28861b12000-11-30 01:44:24 +00001059
Brian Paul392a7002000-03-06 23:34:42 +00001060 glutDisplayFunc (draw);
1061 glutReshapeFunc (reshape);
1062 glutKeyboardFunc (key);
1063 glutIdleFunc (idle);
1064 glutMainLoop ();
1065 return 0;
1066}