blob: 00b6e78b724000f098b84b8e2041b18ac2037f30 [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
Vinson Leee81fe082009-12-26 01:08:26 -080028#include <assert.h>
Brian Paul392a7002000-03-06 23:34:42 +000029#include <math.h>
30#include <stdlib.h>
31#include <GL/glut.h>
32#include <string.h>
33#include <stdio.h>
34
Karl Schultzbffae582001-10-04 19:14:26 +000035#ifndef min
Brian Paul392a7002000-03-06 23:34:42 +000036#define min(x, y) ( x < y ? x : y )
Karl Schultzbffae582001-10-04 19:14:26 +000037#endif
Brian Paul392a7002000-03-06 23:34:42 +000038
39#ifndef M_PI
40#define M_PI 3.14159265
41#endif /* */
Brian Paul3769b3f2000-03-22 23:14:54 +000042typedef GLfloat TDA[4];
Brian Paul392a7002000-03-06 23:34:42 +000043
44TDA background;
45
46
Gareth Hughes28861b12000-11-30 01:44:24 +000047struct AXLE
Brian Paul392a7002000-03-06 23:34:42 +000048 {
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;
59 };
60
61
Gareth Hughes28861b12000-11-30 01:44:24 +000062struct GEAR
Brian Paul392a7002000-03-06 23:34:42 +000063 {
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;
81 };
82
83
Gareth Hughes28861b12000-11-30 01:44:24 +000084struct BELT
Brian Paul392a7002000-03-06 23:34:42 +000085 {
86 char name[20];
87 GLint id;
88 char gear1_name[20];
89 char gear2_name[20];
90 };
91
92
93FILE * mainfile;
94struct GEAR g[10];
95struct AXLE a[10];
96struct BELT b[10];
97int number_of_gears;
98int number_of_axles;
99int number_of_belts;
100
101
102char Buf1[256], Buf2[256], Buf3[256], Buf4[256], Buf5[256];
103
Gareth Hughes28861b12000-11-30 01:44:24 +0000104static GLint T0 = 0;
105static GLint Frames = 0;
Brian Paul392a7002000-03-06 23:34:42 +0000106
Gareth Hughes28861b12000-11-30 01:44:24 +0000107
Karl Schultzbffae582001-10-04 19:14:26 +0000108#ifndef _WIN32
Gareth Hughes28861b12000-11-30 01:44:24 +0000109static void
110strset (char buf[], char ch)
Brian Paul392a7002000-03-06 23:34:42 +0000111{
112 int i;
113 for (i = 0; i < strlen (buf); i++)
114 buf[i] = ch;
115}
Karl Schultzbffae582001-10-04 19:14:26 +0000116#endif
Brian Paul392a7002000-03-06 23:34:42 +0000117
118
Gareth Hughes28861b12000-11-30 01:44:24 +0000119static void
120Clear_Buffers ()
Brian Paul392a7002000-03-06 23:34:42 +0000121{
122 strset (Buf1, 0);
123 strset (Buf2, 0);
124 strset (Buf3, 0);
125 strset (Buf4, 0);
126 strset (Buf5, 0);
127}
128
129
Gareth Hughes28861b12000-11-30 01:44:24 +0000130static void
131LoadTriplet (TDA A)
Brian Paul392a7002000-03-06 23:34:42 +0000132{
Vinson Leee81fe082009-12-26 01:08:26 -0800133 int result;
Brian Paul392a7002000-03-06 23:34:42 +0000134 Clear_Buffers ();
Vinson Leee81fe082009-12-26 01:08:26 -0800135 result = fscanf (mainfile, "%s %s %s %s", Buf1, Buf2, Buf3, Buf4);
136 assert(result != EOF);
Brian Paul392a7002000-03-06 23:34:42 +0000137 A[0] = atof (Buf2);
138 A[1] = atof (Buf3);
139 A[2] = atof (Buf4);
140}
141
142
Gareth Hughes28861b12000-11-30 01:44:24 +0000143static void
144LoadReal (float *a)
Brian Paul392a7002000-03-06 23:34:42 +0000145{
Vinson Leee81fe082009-12-26 01:08:26 -0800146 int result;
Brian Paul392a7002000-03-06 23:34:42 +0000147 Clear_Buffers ();
Vinson Leee81fe082009-12-26 01:08:26 -0800148 result = fscanf (mainfile, "%s %s", Buf1, Buf2);
149 assert(result != EOF);
Brian Paul392a7002000-03-06 23:34:42 +0000150 *a = atof (Buf2);
151}
152
153
Gareth Hughes28861b12000-11-30 01:44:24 +0000154static void
155LoadInteger (int *a)
Brian Paul392a7002000-03-06 23:34:42 +0000156{
Vinson Leee81fe082009-12-26 01:08:26 -0800157 int result;
Brian Paul392a7002000-03-06 23:34:42 +0000158 Clear_Buffers ();
Vinson Leee81fe082009-12-26 01:08:26 -0800159 result = fscanf (mainfile, "%s %s", Buf1, Buf2);
160 assert(result != EOF);
Brian Paul392a7002000-03-06 23:34:42 +0000161 *a = atoi (Buf2);
162}
163
164
Gareth Hughes28861b12000-11-30 01:44:24 +0000165static void
166LoadText (char *a)
Brian Paul392a7002000-03-06 23:34:42 +0000167{
Vinson Leee81fe082009-12-26 01:08:26 -0800168 int result;
Brian Paul392a7002000-03-06 23:34:42 +0000169 Clear_Buffers ();
Vinson Leee81fe082009-12-26 01:08:26 -0800170 result = fscanf (mainfile, "%s %s", Buf1, Buf2);
171 assert(result != EOF);
Brian Paul392a7002000-03-06 23:34:42 +0000172 strcpy (a, Buf2);
173}
174
175
Gareth Hughes28861b12000-11-30 01:44:24 +0000176static void
177getdata (char filename[])
Brian Paul392a7002000-03-06 23:34:42 +0000178{
179 int gear_count = 0, axle_count = 0, belt_count = 0, i;
Gareth Hughes28861b12000-11-30 01:44:24 +0000180
Brian Paul392a7002000-03-06 23:34:42 +0000181 mainfile = fopen (filename, "r");
Brian Paul5a564052000-03-29 17:56:02 +0000182 if (!mainfile) {
183 printf("Error: couldn't open %s\n", filename);
184 exit(-1);
185 }
186
Brian Paul392a7002000-03-06 23:34:42 +0000187 do
188 {
Vinson Leee81fe082009-12-26 01:08:26 -0800189 int result;
Brian Paul392a7002000-03-06 23:34:42 +0000190 Clear_Buffers ();
Vinson Leee81fe082009-12-26 01:08:26 -0800191 result = fscanf (mainfile, "%s", Buf1);
192 (void) result;
Brian Paul392a7002000-03-06 23:34:42 +0000193 if (ferror (mainfile))
194 {
195 printf ("\nError opening file !\n");
196 exit (1);
197 }
198
199 if (!(strcmp (Buf1, "BACKGROUND")))
200 LoadTriplet (background);
Gareth Hughes28861b12000-11-30 01:44:24 +0000201
Brian Paul392a7002000-03-06 23:34:42 +0000202 if (!(strcmp (Buf1, "ANAME")))
203 {
204 LoadText (a[axle_count].name);
205 axle_count++;
206 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000207
Brian Paul392a7002000-03-06 23:34:42 +0000208 if (!(strcmp (Buf1, "ARADIUS")))
209 LoadReal (&a[axle_count - 1].radius);
Gareth Hughes28861b12000-11-30 01:44:24 +0000210
Brian Paul392a7002000-03-06 23:34:42 +0000211 if (!(strcmp (Buf1, "AAXIS")))
212 LoadInteger (&a[axle_count - 1].axis);
Gareth Hughes28861b12000-11-30 01:44:24 +0000213
Brian Paul392a7002000-03-06 23:34:42 +0000214 if (!(strcmp (Buf1, "ACOLOR")))
215 LoadTriplet (a[axle_count - 1].color);
Gareth Hughes28861b12000-11-30 01:44:24 +0000216
Brian Paul392a7002000-03-06 23:34:42 +0000217 if (!(strcmp (Buf1, "APOSITION")))
218 LoadTriplet (a[axle_count - 1].position);
Gareth Hughes28861b12000-11-30 01:44:24 +0000219
Brian Paul392a7002000-03-06 23:34:42 +0000220 if (!(strcmp (Buf1, "ALENGTH")))
221 LoadReal (&a[axle_count - 1].length);
Gareth Hughes28861b12000-11-30 01:44:24 +0000222
Brian Paul392a7002000-03-06 23:34:42 +0000223 if (!(strcmp (Buf1, "AMOTORED")))
224 LoadInteger (&a[axle_count - 1].motored);
Gareth Hughes28861b12000-11-30 01:44:24 +0000225
Brian Paul392a7002000-03-06 23:34:42 +0000226 if (!(strcmp (Buf1, "AANGULARVELOCITY")))
227 LoadReal (&a[axle_count - 1].angular_velocity);
Gareth Hughes28861b12000-11-30 01:44:24 +0000228
Brian Paul392a7002000-03-06 23:34:42 +0000229 if (!(strcmp (Buf1, "ADIRECTION")))
230 LoadInteger (&a[axle_count - 1].direction);
Gareth Hughes28861b12000-11-30 01:44:24 +0000231
Brian Paul392a7002000-03-06 23:34:42 +0000232 if (!(strcmp (Buf1, "GNAME")))
233 {
234 LoadText (g[gear_count].name);
235 gear_count++;
236 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000237
Brian Paul392a7002000-03-06 23:34:42 +0000238 if (!(strcmp (Buf1, "GTYPE")))
239 LoadText (g[gear_count - 1].type);
Gareth Hughes28861b12000-11-30 01:44:24 +0000240
Brian Paul392a7002000-03-06 23:34:42 +0000241 if (!(strcmp (Buf1, "GFACE")))
242 LoadInteger (&g[gear_count - 1].face);
Gareth Hughes28861b12000-11-30 01:44:24 +0000243
Brian Paul392a7002000-03-06 23:34:42 +0000244 if (!(strcmp (Buf1, "GRADIUS")))
245 LoadReal (&g[gear_count - 1].radius);
Gareth Hughes28861b12000-11-30 01:44:24 +0000246
Brian Paul392a7002000-03-06 23:34:42 +0000247 if (!(strcmp (Buf1, "GWIDTH")))
248 LoadReal (&g[gear_count - 1].width);
Gareth Hughes28861b12000-11-30 01:44:24 +0000249
Brian Paul392a7002000-03-06 23:34:42 +0000250 if (!(strcmp (Buf1, "GTEETH")))
251 LoadInteger (&g[gear_count - 1].teeth);
Gareth Hughes28861b12000-11-30 01:44:24 +0000252
Brian Paul392a7002000-03-06 23:34:42 +0000253 if (!(strcmp (Buf1, "GTOOTHDEPTH")))
254 LoadReal (&g[gear_count - 1].tooth_depth);
Gareth Hughes28861b12000-11-30 01:44:24 +0000255
Brian Paul392a7002000-03-06 23:34:42 +0000256 if (!(strcmp (Buf1, "GCOLOR")))
257 LoadTriplet (g[gear_count - 1].color);
Gareth Hughes28861b12000-11-30 01:44:24 +0000258
Brian Paul392a7002000-03-06 23:34:42 +0000259 if (!(strcmp (Buf1, "GAXLE")))
260 LoadText (g[gear_count - 1].axle_name);
Gareth Hughes28861b12000-11-30 01:44:24 +0000261
Brian Paul392a7002000-03-06 23:34:42 +0000262 if (!(strcmp (Buf1, "GPOSITION")))
263 LoadInteger (&g[gear_count - 1].relative_position);
Gareth Hughes28861b12000-11-30 01:44:24 +0000264
Brian Paul392a7002000-03-06 23:34:42 +0000265 if (!(strcmp (Buf1, "BELTNAME")))
266 {
267 LoadText (b[belt_count].name);
268 belt_count++;
269 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000270
Brian Paul392a7002000-03-06 23:34:42 +0000271 if (!(strcmp (Buf1, "GEAR1NAME")))
272 LoadText (b[belt_count - 1].gear1_name);
Gareth Hughes28861b12000-11-30 01:44:24 +0000273
Brian Paul392a7002000-03-06 23:34:42 +0000274 if (!(strcmp (Buf1, "GEAR2NAME")))
275 LoadText (b[belt_count - 1].gear2_name);
276 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000277
Brian Paul392a7002000-03-06 23:34:42 +0000278 while (Buf1[0] != 0);
Gareth Hughes28861b12000-11-30 01:44:24 +0000279
Brian Paul392a7002000-03-06 23:34:42 +0000280 for (i = 0; i < number_of_gears; i++)
281 {
282 g[i].axis = -1;
283 g[i].direction = 0;
284 g[i].angular_velocity = 0.0;
285 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000286
Brian Paul392a7002000-03-06 23:34:42 +0000287 number_of_gears = gear_count;
288 number_of_axles = axle_count;
289 number_of_belts = belt_count;
290 fclose (mainfile);
291}
292
293
Gareth Hughes28861b12000-11-30 01:44:24 +0000294static void
295axle (GLint j, GLfloat radius, GLfloat length)
Brian Paul392a7002000-03-06 23:34:42 +0000296{
297 GLfloat angle, rad, incr = 10.0 * M_PI / 180.0;
Gareth Hughes28861b12000-11-30 01:44:24 +0000298
299 /* draw main cylinder */
Brian Paul392a7002000-03-06 23:34:42 +0000300 glBegin (GL_QUADS);
301 for (angle = 0.0; angle < 360.0; angle += 5.0)
302 {
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);
309 }
310 glEnd ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000311
312 /* draw front face */
Brian Paul392a7002000-03-06 23:34:42 +0000313 glNormal3f (0.0, 0.0, 1.0);
314 glBegin (GL_TRIANGLES);
315 for (angle = 0.0; angle < 360.0; angle += 5.0)
316 {
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);
322 }
323 glEnd ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000324
325 /* draw back face */
Brian Paul392a7002000-03-06 23:34:42 +0000326 glNormal3f (0.0, 0.0, -1.0);
327 glBegin (GL_TRIANGLES);
328 for (angle = 0.0; angle <= 360.0; angle += 5.0)
329 {
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);
335 }
336 glEnd ();
337}
338
339
340
Gareth Hughes28861b12000-11-30 01:44:24 +0000341static void
342gear (GLint j, char type[], GLfloat radius, GLfloat width,
343 GLint teeth, GLfloat tooth_depth)
Brian Paul392a7002000-03-06 23:34:42 +0000344{
345 GLint i;
346 GLfloat r1, r2;
347 GLfloat angle, da;
348 GLfloat u, v, len, fraction = 0.5;
349 GLfloat n = 1.0;
Brian Paul9d0bc1d2000-04-05 21:36:03 +0000350
Brian Paul392a7002000-03-06 23:34:42 +0000351 r1 = radius - tooth_depth;
352 r2 = radius;
Gareth Hughes28861b12000-11-30 01:44:24 +0000353
Brian Paul392a7002000-03-06 23:34:42 +0000354 da = 2.0 * M_PI / teeth / 4.0;
355 if (!g[j].face)
356 {
357 fraction = -0.5;
358 n = -1.0;
359 }
360 if (!(strcmp (type, "NORMAL")))
361 {
362 fraction = 0.5;
363 n = 1.0;
364 }
365
Gareth Hughes28861b12000-11-30 01:44:24 +0000366 /* draw front face */
Brian Paul392a7002000-03-06 23:34:42 +0000367 if (!(strcmp (type, "NORMAL")))
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 (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);
378 }
379 glEnd ();
380 }
381 else
382 {
383 glNormal3f (0.0, 0.0, 1.0 * n);
384 glBegin (GL_QUAD_STRIP);
385 for (i = 0; i <= teeth; i++)
386 {
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);
392 }
393 glEnd ();
394 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000395
396 /* draw front sides of teeth */
Brian Paul392a7002000-03-06 23:34:42 +0000397 if (!(strcmp (type, "NORMAL")))
398 {
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++)
403 {
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);
409 }
410 glEnd ();
411 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000412
Brian Paul392a7002000-03-06 23:34:42 +0000413 glNormal3f (0.0, 0.0, -1.0 * n);
Gareth Hughes28861b12000-11-30 01:44:24 +0000414
415 /* draw back face */
Brian Paul392a7002000-03-06 23:34:42 +0000416 glBegin (GL_QUAD_STRIP);
417 for (i = 0; i <= teeth; i++)
418 {
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);
424 }
425 glEnd ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000426
427 /* draw back sides of teeth */
Brian Paul392a7002000-03-06 23:34:42 +0000428 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++)
432 {
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);
438 }
439 glEnd ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000440
441
442 /* draw outward faces of teeth */
Brian Paul392a7002000-03-06 23:34:42 +0000443 if (!(strcmp (type, "NORMAL")))
444 {
445 glBegin (GL_QUAD_STRIP);
446 for (i = 0; i < teeth; i++)
447 {
448 angle = i * 2.0 * M_PI / teeth;
Gareth Hughes28861b12000-11-30 01:44:24 +0000449
Brian Paul392a7002000-03-06 23:34:42 +0000450 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);
469 }
470 }
471 else
472 {
473 glBegin (GL_QUAD_STRIP);
474 for (i = 0; i < teeth; i++)
475 {
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);
496 }
497 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000498
Brian Paul392a7002000-03-06 23:34:42 +0000499 glVertex3f (r1 * cos (0), r1 * sin (0), width * fraction);
500 glVertex3f (r1 * cos (0), r1 * sin (0), -width * fraction);
501 glEnd ();
502}
503
504
Gareth Hughes28861b12000-11-30 01:44:24 +0000505static void
506belt (struct GEAR g1, struct GEAR g2)
Brian Paul392a7002000-03-06 23:34:42 +0000507{
508 GLfloat D, alpha, phi, angle, incr, width;
509 GLint indexes[3] =
510 {
511 0, 0, 0
512 };
Gareth Hughes28861b12000-11-30 01:44:24 +0000513
Brian Paul392a7002000-03-06 23:34:42 +0000514 GLfloat col[3] =
515 {
516 0.0, 0.0, 0.0
517 };
Gareth Hughes28861b12000-11-30 01:44:24 +0000518
Brian Paul392a7002000-03-06 23:34:42 +0000519 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)
528 {
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);
534 }
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)
541 {
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);
547 }
548 glEnd ();
549
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 ();
562}
563
564
Gareth Hughes28861b12000-11-30 01:44:24 +0000565static int
566axle_find (char axle_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_axles; i++)
571 {
572 if (!(strcmp (axle_name, a[i].name)))
573 break;
574 }
575 return i;
576}
577
578
Gareth Hughes28861b12000-11-30 01:44:24 +0000579static int
580gear_find (char gear_name[])
Brian Paul392a7002000-03-06 23:34:42 +0000581{
582 int i;
Gareth Hughes28861b12000-11-30 01:44:24 +0000583
Brian Paul392a7002000-03-06 23:34:42 +0000584 for (i = 0; i < number_of_gears; i++)
585 {
586 if (!(strcmp (gear_name, g[i].name)))
587 break;
588 }
589 return i;
590}
591
592
Gareth Hughes28861b12000-11-30 01:44:24 +0000593static void
594process ()
Brian Paul392a7002000-03-06 23:34:42 +0000595{
596 GLfloat x, y, z, D, dist;
597 GLint axle_index, i, j, g1, g2, k;
598 char error[80];
Gareth Hughes28861b12000-11-30 01:44:24 +0000599
Brian Paul392a7002000-03-06 23:34:42 +0000600 for (i = 0; i < number_of_gears; i++)
601 {
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)
609 {
610 g[i].direction = a[axle_index].direction;
611 g[i].angular_velocity = a[axle_index].angular_velocity;
612 }
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;
Gareth Hughes28861b12000-11-30 01:44:24 +0000619
Brian Paul392a7002000-03-06 23:34:42 +0000620 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;
623 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000624
Brian Paul392a7002000-03-06 23:34:42 +0000625 for (k = 0; k < number_of_axles; k++)
626 {
627 for (i = 0; i < number_of_gears - 1; i++)
628 {
629 for (j = 0; j < number_of_gears; j++)
630 {
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))
632 {
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))
635 {
636 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 +0000637
Brian Paul392a7002000-03-06 23:34:42 +0000638 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
639 exit (1);
640 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000641
Brian Paul392a7002000-03-06 23:34:42 +0000642 if (g[i].axis == 0)
643 {
644 dist = g[i].position[0] - g[j].position[0];
645 }
646 else if (g[i].axis == 1)
647 {
648 dist = g[i].position[1] - g[j].position[1];
649 }
650 else
651 dist = g[i].position[2] - g[j].position[2];
Gareth Hughes28861b12000-11-30 01:44:24 +0000652
Brian Paul392a7002000-03-06 23:34:42 +0000653 dist = fabs (dist);
Gareth Hughes28861b12000-11-30 01:44:24 +0000654
Brian Paul392a7002000-03-06 23:34:42 +0000655 if (dist < (g[i].width / 2 + g[j].width / 2))
656 {
657 if ((g[i].motored) && (!(g[j].motored)) && (D < 0.95 * (g[i].radius + g[j].radius)))
658 {
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))
661 {
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);
665 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000666
Brian Paul392a7002000-03-06 23:34:42 +0000667 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);
671 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000672
Brian Paul392a7002000-03-06 23:34:42 +0000673 if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * (g[i].radius + g[j].radius)))
674 {
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))
677 {
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);
681 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000682
Brian Paul392a7002000-03-06 23:34:42 +0000683 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);
Gareth Hughes28861b12000-11-30 01:44:24 +0000687
Brian Paul392a7002000-03-06 23:34:42 +0000688 }
689 }
690 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000691
Brian Paul392a7002000-03-06 23:34:42 +0000692 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))
693 {
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)))
696 {
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))
699 {
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);
703 }
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);
708 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000709
710
Brian Paul392a7002000-03-06 23:34:42 +0000711 if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * sqrt (g[i].radius * g[i].radius + g[j].radius * g[j].radius)))
712 {
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))
715 {
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);
719 }
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);
724 }
725 }
726 }
727 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000728
Brian Paul392a7002000-03-06 23:34:42 +0000729 for (i = 0; i < number_of_gears; i++)
730 {
731 axle_index = axle_find (g[i].axle_name);
732 g[i].motored = a[axle_index].motored;
733 if (a[axle_index].motored)
734 {
735 g[i].direction = a[axle_index].direction;
736 g[i].angular_velocity = a[axle_index].angular_velocity;
737 }
738 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000739
Brian Paul392a7002000-03-06 23:34:42 +0000740 for (i = 0; i < number_of_belts; i++)
741 {
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"))))
746 {
747 printf (error, "Belt %s invalid.", b[i].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 == g[g2].axis) && (!strcmp (g[g1].type, g[g2].type)) && (!strcmp (g[g1].type, "NORMAL")))
753 {
754 /*
755 if((g[g1].motored)&&(g[g2].motored))
756 if(g[g2].angular_velocity!=(g[g1].angular_velocity*g[g1].radius/g[g2].radius))
757 {
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);
761 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000762 */
Brian Paul392a7002000-03-06 23:34:42 +0000763 if (g[g1].axis == 0)
764 {
765 dist = g[g1].position[0] - g[g2].position[0];
766 }
767 else if (g[i].axis == 1)
768 {
769 dist = g[g1].position[1] - g[g2].position[1];
770 }
771 else
772 dist = g[g1].position[2] - g[g2].position[2];
Gareth Hughes28861b12000-11-30 01:44:24 +0000773
Brian Paul392a7002000-03-06 23:34:42 +0000774 dist = fabs (dist);
Gareth Hughes28861b12000-11-30 01:44:24 +0000775
Brian Paul392a7002000-03-06 23:34:42 +0000776 if (dist > (g[g1].width / 2 + g[g2].width / 2))
777 {
778 printf (error, "Belt %s invalid.", b[i].name);
779 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
780 exit (1);
781 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000782
Brian Paul392a7002000-03-06 23:34:42 +0000783 if (dist < (g[g1].width / 2 + g[g2].width / 2))
784 {
785 if (D < g[g1].radius + g[g2].radius)
786 {
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);
790 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000791
Brian Paul392a7002000-03-06 23:34:42 +0000792 if ((g[g1].motored) && (!(g[g2].motored)))
793 {
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);
798 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000799
Brian Paul392a7002000-03-06 23:34:42 +0000800 if ((!(g[g1].motored)) && (g[g2].motored))
801 {
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);
806 }
807 }
808 }
809 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000810
Brian Paul392a7002000-03-06 23:34:42 +0000811 for (i = 0; i < number_of_gears; i++)
812 {
813 axle_index = axle_find (g[i].axle_name);
814 g[i].motored = a[axle_index].motored;
815 if (a[axle_index].motored)
816 {
817 g[i].direction = a[axle_index].direction;
818 g[i].angular_velocity = a[axle_index].angular_velocity;
819 }
820 }
821 }
822}
823
824
825
826GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 10.0;
827
828
Gareth Hughes28861b12000-11-30 01:44:24 +0000829static void
830draw (void)
Brian Paul392a7002000-03-06 23:34:42 +0000831{
832 int i;
833 GLfloat x, y, z;
834 int index;
835
836 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Gareth Hughes28861b12000-11-30 01:44:24 +0000837
Brian Paul392a7002000-03-06 23:34:42 +0000838 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);
Gareth Hughes28861b12000-11-30 01:44:24 +0000842
Brian Paul392a7002000-03-06 23:34:42 +0000843 for (i = 0; i < number_of_gears; i++)
844 {
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;
Gareth Hughes28861b12000-11-30 01:44:24 +0000857
Brian Paul392a7002000-03-06 23:34:42 +0000858 if (z != 1.0)
859 glRotatef (90.0, x, y, z);
Gareth Hughes28861b12000-11-30 01:44:24 +0000860
Brian Paul392a7002000-03-06 23:34:42 +0000861 glRotatef (g[i].direction * g[i].angle, 0.0, 0.0, 1.0);
862 glCallList (g[i].id);
863 glPopMatrix ();
864 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000865
Brian Paul392a7002000-03-06 23:34:42 +0000866 for (i = 0; i < number_of_axles; i++)
867 {
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;
879
880 if (z != 1.0)
881 glRotatef (90.0, x, y, z);
Gareth Hughes28861b12000-11-30 01:44:24 +0000882
Brian Paul392a7002000-03-06 23:34:42 +0000883 glCallList (a[i].id);
884 glPopMatrix ();
885 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000886
Brian Paul392a7002000-03-06 23:34:42 +0000887 for (i = 0; i < number_of_belts; i++)
888 {
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;
Gareth Hughes28861b12000-11-30 01:44:24 +0000901
Brian Paul392a7002000-03-06 23:34:42 +0000902 if (z != 1.0)
903 glRotatef (90.0, x, y, z);
Gareth Hughes28861b12000-11-30 01:44:24 +0000904
Brian Paul392a7002000-03-06 23:34:42 +0000905 glCallList (b[i].id);
906 glPopMatrix ();
907 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000908
Brian Paul392a7002000-03-06 23:34:42 +0000909 glPopMatrix ();
910 glutSwapBuffers ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000911
912 {
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);
Keith Whitwelle6479c62009-02-24 12:02:24 +0000919 fflush(stdout);
Gareth Hughes28861b12000-11-30 01:44:24 +0000920 T0 = t;
921 Frames = 0;
922 }
923 }
Brian Paul392a7002000-03-06 23:34:42 +0000924}
925
926
Gareth Hughes28861b12000-11-30 01:44:24 +0000927static void
928idle (void)
Brian Paul392a7002000-03-06 23:34:42 +0000929{
930 int i;
Brian Paul92eddb02005-01-09 17:37:50 +0000931 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;
Brian Paul392a7002000-03-06 23:34:42 +0000937 for (i = 0; i < number_of_gears; i++)
Brian Paul92eddb02005-01-09 17:37:50 +0000938 g[i].angle += g[i].angular_velocity * dt;
Brian Paul392a7002000-03-06 23:34:42 +0000939 glutPostRedisplay();
940}
941
942
943
944
Gareth Hughes28861b12000-11-30 01:44:24 +0000945/* change view angle, exit upon ESC */
946static void
947key (unsigned char k, int x, int y)
Brian Paul392a7002000-03-06 23:34:42 +0000948{
949 switch (k)
950 {
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);
971 }
972}
973
974
975
976
Gareth Hughes28861b12000-11-30 01:44:24 +0000977/* new window size or exposure */
978static void
979reshape (int width, int height)
Brian Paul392a7002000-03-06 23:34:42 +0000980{
981 glViewport (0, 0, (GLint) width, (GLint) height);
982 glMatrixMode (GL_PROJECTION);
983 glLoadIdentity ();
984 if (width > height)
985 {
986 GLfloat w = (GLfloat) width / (GLfloat) height;
987 glFrustum (-w, w, -1.0, 1.0, 5.0, 60.0);
988 }
989 else
990 {
991 GLfloat h = (GLfloat) height / (GLfloat) width;
992 glFrustum (-1.0, 1.0, -h, h, 5.0, 60.0);
993 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000994
Brian Paul392a7002000-03-06 23:34:42 +0000995 glMatrixMode (GL_MODELVIEW);
996 glLoadIdentity ();
997 glTranslatef (0.0, 0.0, -40.0);
998 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
999}
1000
1001
1002
Gareth Hughes28861b12000-11-30 01:44:24 +00001003static void
1004init (void)
Brian Paul392a7002000-03-06 23:34:42 +00001005{
1006 GLfloat matShine = 20.00F;
1007 GLfloat light0Pos[4] =
1008 {
1009 0.70F, 0.70F, 1.25F, 0.50F
1010 };
1011 int i;
Gareth Hughes28861b12000-11-30 01:44:24 +00001012
Brian Paul392a7002000-03-06 23:34:42 +00001013 glClearColor (background[0], background[1], background[2], 1.0F);
1014 glClearIndex ((GLfloat) 0.0);
Gareth Hughes28861b12000-11-30 01:44:24 +00001015
Brian Paul392a7002000-03-06 23:34:42 +00001016 glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, matShine);
1017 glLightfv (GL_LIGHT0, GL_POSITION, light0Pos);
1018 glEnable (GL_LIGHT0);
Gareth Hughes28861b12000-11-30 01:44:24 +00001019
Brian Paul392a7002000-03-06 23:34:42 +00001020 glEnable (GL_LIGHTING);
1021 glEnable (GL_DEPTH_TEST);
1022 for (i = 0; i < number_of_gears; i++)
1023 g[i].angle = 0.0;
Gareth Hughes28861b12000-11-30 01:44:24 +00001024
Brian Paul392a7002000-03-06 23:34:42 +00001025 for (i = 0; i < number_of_gears; i++)
1026 {
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 ();
1033 }
Gareth Hughes28861b12000-11-30 01:44:24 +00001034
Brian Paul392a7002000-03-06 23:34:42 +00001035 for (i = 0; i < number_of_axles; i++)
1036 {
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 ();
1043 }
Gareth Hughes28861b12000-11-30 01:44:24 +00001044
Brian Paul392a7002000-03-06 23:34:42 +00001045 for (i = 0; i < number_of_belts; i++)
1046 {
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 ();
1051 }
Gareth Hughes28861b12000-11-30 01:44:24 +00001052
Brian Paul392a7002000-03-06 23:34:42 +00001053 glEnable (GL_COLOR_MATERIAL);
1054}
1055
1056
1057
Gareth Hughes28861b12000-11-30 01:44:24 +00001058int
1059main (int argc, char *argv[])
Brian Paul392a7002000-03-06 23:34:42 +00001060{
1061 char *file;
1062
Brian Paul392a7002000-03-06 23:34:42 +00001063 glutInitWindowSize(640,480);
Brian Paul263f4322009-12-18 08:12:55 -07001064 glutInit(&argc, argv);
Brian Paul392a7002000-03-06 23:34:42 +00001065 glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
Gareth Hughes28861b12000-11-30 01:44:24 +00001066
Brian Paul392a7002000-03-06 23:34:42 +00001067 if (glutCreateWindow ("Gear Train Simulation") == GL_FALSE)
1068 exit (1);
1069
Brian Paul263f4322009-12-18 08:12:55 -07001070 if (argc < 2)
1071 file = "geartrain.dat";
1072 else
1073 file = argv[1];
1074
Brian Paul392a7002000-03-06 23:34:42 +00001075 getdata (file);
1076 process ();
1077 init ();
Gareth Hughes28861b12000-11-30 01:44:24 +00001078
Brian Paul392a7002000-03-06 23:34:42 +00001079 glutDisplayFunc (draw);
1080 glutReshapeFunc (reshape);
1081 glutKeyboardFunc (key);
1082 glutIdleFunc (idle);
1083 glutMainLoop ();
1084 return 0;
1085}