blob: 98addb8eb4bf61a74c6d46d2e22ee2effb8ef627 [file] [log] [blame]
Karl Schultzbffae582001-10-04 19:14:26 +00001/* $Id: geartrain.c,v 1.8 2001/10/04 19:14:26 kschultz 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
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{
133 Clear_Buffers ();
134 fscanf (mainfile, "%s %s %s %s", Buf1, Buf2, Buf3, Buf4);
135 A[0] = atof (Buf2);
136 A[1] = atof (Buf3);
137 A[2] = atof (Buf4);
138}
139
140
Gareth Hughes28861b12000-11-30 01:44:24 +0000141static void
142LoadReal (float *a)
Brian Paul392a7002000-03-06 23:34:42 +0000143{
144 Clear_Buffers ();
145 fscanf (mainfile, "%s %s", Buf1, Buf2);
146 *a = atof (Buf2);
147}
148
149
Gareth Hughes28861b12000-11-30 01:44:24 +0000150static void
151LoadInteger (int *a)
Brian Paul392a7002000-03-06 23:34:42 +0000152{
153 Clear_Buffers ();
154 fscanf (mainfile, "%s %s", Buf1, Buf2);
155 *a = atoi (Buf2);
156}
157
158
Gareth Hughes28861b12000-11-30 01:44:24 +0000159static void
160LoadText (char *a)
Brian Paul392a7002000-03-06 23:34:42 +0000161{
162 Clear_Buffers ();
163 fscanf (mainfile, "%s %s", Buf1, Buf2);
164 strcpy (a, Buf2);
165}
166
167
Gareth Hughes28861b12000-11-30 01:44:24 +0000168static void
169getdata (char filename[])
Brian Paul392a7002000-03-06 23:34:42 +0000170{
171 int gear_count = 0, axle_count = 0, belt_count = 0, i;
Gareth Hughes28861b12000-11-30 01:44:24 +0000172
Brian Paul392a7002000-03-06 23:34:42 +0000173 mainfile = fopen (filename, "r");
Brian Paul5a564052000-03-29 17:56:02 +0000174 if (!mainfile) {
175 printf("Error: couldn't open %s\n", filename);
176 exit(-1);
177 }
178
Brian Paul392a7002000-03-06 23:34:42 +0000179 do
180 {
181 Clear_Buffers ();
182 fscanf (mainfile, "%s", Buf1);
183 if (ferror (mainfile))
184 {
185 printf ("\nError opening file !\n");
186 exit (1);
187 }
188
189 if (!(strcmp (Buf1, "BACKGROUND")))
190 LoadTriplet (background);
Gareth Hughes28861b12000-11-30 01:44:24 +0000191
Brian Paul392a7002000-03-06 23:34:42 +0000192 if (!(strcmp (Buf1, "ANAME")))
193 {
194 LoadText (a[axle_count].name);
195 axle_count++;
196 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000197
Brian Paul392a7002000-03-06 23:34:42 +0000198 if (!(strcmp (Buf1, "ARADIUS")))
199 LoadReal (&a[axle_count - 1].radius);
Gareth Hughes28861b12000-11-30 01:44:24 +0000200
Brian Paul392a7002000-03-06 23:34:42 +0000201 if (!(strcmp (Buf1, "AAXIS")))
202 LoadInteger (&a[axle_count - 1].axis);
Gareth Hughes28861b12000-11-30 01:44:24 +0000203
Brian Paul392a7002000-03-06 23:34:42 +0000204 if (!(strcmp (Buf1, "ACOLOR")))
205 LoadTriplet (a[axle_count - 1].color);
Gareth Hughes28861b12000-11-30 01:44:24 +0000206
Brian Paul392a7002000-03-06 23:34:42 +0000207 if (!(strcmp (Buf1, "APOSITION")))
208 LoadTriplet (a[axle_count - 1].position);
Gareth Hughes28861b12000-11-30 01:44:24 +0000209
Brian Paul392a7002000-03-06 23:34:42 +0000210 if (!(strcmp (Buf1, "ALENGTH")))
211 LoadReal (&a[axle_count - 1].length);
Gareth Hughes28861b12000-11-30 01:44:24 +0000212
Brian Paul392a7002000-03-06 23:34:42 +0000213 if (!(strcmp (Buf1, "AMOTORED")))
214 LoadInteger (&a[axle_count - 1].motored);
Gareth Hughes28861b12000-11-30 01:44:24 +0000215
Brian Paul392a7002000-03-06 23:34:42 +0000216 if (!(strcmp (Buf1, "AANGULARVELOCITY")))
217 LoadReal (&a[axle_count - 1].angular_velocity);
Gareth Hughes28861b12000-11-30 01:44:24 +0000218
Brian Paul392a7002000-03-06 23:34:42 +0000219 if (!(strcmp (Buf1, "ADIRECTION")))
220 LoadInteger (&a[axle_count - 1].direction);
Gareth Hughes28861b12000-11-30 01:44:24 +0000221
Brian Paul392a7002000-03-06 23:34:42 +0000222 if (!(strcmp (Buf1, "GNAME")))
223 {
224 LoadText (g[gear_count].name);
225 gear_count++;
226 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000227
Brian Paul392a7002000-03-06 23:34:42 +0000228 if (!(strcmp (Buf1, "GTYPE")))
229 LoadText (g[gear_count - 1].type);
Gareth Hughes28861b12000-11-30 01:44:24 +0000230
Brian Paul392a7002000-03-06 23:34:42 +0000231 if (!(strcmp (Buf1, "GFACE")))
232 LoadInteger (&g[gear_count - 1].face);
Gareth Hughes28861b12000-11-30 01:44:24 +0000233
Brian Paul392a7002000-03-06 23:34:42 +0000234 if (!(strcmp (Buf1, "GRADIUS")))
235 LoadReal (&g[gear_count - 1].radius);
Gareth Hughes28861b12000-11-30 01:44:24 +0000236
Brian Paul392a7002000-03-06 23:34:42 +0000237 if (!(strcmp (Buf1, "GWIDTH")))
238 LoadReal (&g[gear_count - 1].width);
Gareth Hughes28861b12000-11-30 01:44:24 +0000239
Brian Paul392a7002000-03-06 23:34:42 +0000240 if (!(strcmp (Buf1, "GTEETH")))
241 LoadInteger (&g[gear_count - 1].teeth);
Gareth Hughes28861b12000-11-30 01:44:24 +0000242
Brian Paul392a7002000-03-06 23:34:42 +0000243 if (!(strcmp (Buf1, "GTOOTHDEPTH")))
244 LoadReal (&g[gear_count - 1].tooth_depth);
Gareth Hughes28861b12000-11-30 01:44:24 +0000245
Brian Paul392a7002000-03-06 23:34:42 +0000246 if (!(strcmp (Buf1, "GCOLOR")))
247 LoadTriplet (g[gear_count - 1].color);
Gareth Hughes28861b12000-11-30 01:44:24 +0000248
Brian Paul392a7002000-03-06 23:34:42 +0000249 if (!(strcmp (Buf1, "GAXLE")))
250 LoadText (g[gear_count - 1].axle_name);
Gareth Hughes28861b12000-11-30 01:44:24 +0000251
Brian Paul392a7002000-03-06 23:34:42 +0000252 if (!(strcmp (Buf1, "GPOSITION")))
253 LoadInteger (&g[gear_count - 1].relative_position);
Gareth Hughes28861b12000-11-30 01:44:24 +0000254
Brian Paul392a7002000-03-06 23:34:42 +0000255 if (!(strcmp (Buf1, "BELTNAME")))
256 {
257 LoadText (b[belt_count].name);
258 belt_count++;
259 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000260
Brian Paul392a7002000-03-06 23:34:42 +0000261 if (!(strcmp (Buf1, "GEAR1NAME")))
262 LoadText (b[belt_count - 1].gear1_name);
Gareth Hughes28861b12000-11-30 01:44:24 +0000263
Brian Paul392a7002000-03-06 23:34:42 +0000264 if (!(strcmp (Buf1, "GEAR2NAME")))
265 LoadText (b[belt_count - 1].gear2_name);
266 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000267
Brian Paul392a7002000-03-06 23:34:42 +0000268 while (Buf1[0] != 0);
Gareth Hughes28861b12000-11-30 01:44:24 +0000269
Brian Paul392a7002000-03-06 23:34:42 +0000270 for (i = 0; i < number_of_gears; i++)
271 {
272 g[i].axis = -1;
273 g[i].direction = 0;
274 g[i].angular_velocity = 0.0;
275 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000276
Brian Paul392a7002000-03-06 23:34:42 +0000277 number_of_gears = gear_count;
278 number_of_axles = axle_count;
279 number_of_belts = belt_count;
280 fclose (mainfile);
281}
282
283
Gareth Hughes28861b12000-11-30 01:44:24 +0000284static void
285axle (GLint j, GLfloat radius, GLfloat length)
Brian Paul392a7002000-03-06 23:34:42 +0000286{
287 GLfloat angle, rad, incr = 10.0 * M_PI / 180.0;
Gareth Hughes28861b12000-11-30 01:44:24 +0000288
289 /* draw main cylinder */
Brian Paul392a7002000-03-06 23:34:42 +0000290 glBegin (GL_QUADS);
291 for (angle = 0.0; angle < 360.0; angle += 5.0)
292 {
293 rad = angle * M_PI / 180.0;
294 glNormal3f (cos (rad), sin (rad), 0.0);
295 glVertex3f (radius * cos (rad), radius * sin (rad), length / 2);
296 glVertex3f (radius * cos (rad), radius * sin (rad), -length / 2);
297 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), -length / 2);
298 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), length / 2);
299 }
300 glEnd ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000301
302 /* draw front face */
Brian Paul392a7002000-03-06 23:34:42 +0000303 glNormal3f (0.0, 0.0, 1.0);
304 glBegin (GL_TRIANGLES);
305 for (angle = 0.0; angle < 360.0; angle += 5.0)
306 {
307 rad = angle * M_PI / 180.0;
308 glVertex3f (0.0, 0.0, length / 2);
309 glVertex3f (radius * cos (rad), radius * sin (rad), length / 2);
310 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), length / 2);
311 glVertex3f (0.0, 0.0, length / 2);
312 }
313 glEnd ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000314
315 /* draw back face */
Brian Paul392a7002000-03-06 23:34:42 +0000316 glNormal3f (0.0, 0.0, -1.0);
317 glBegin (GL_TRIANGLES);
318 for (angle = 0.0; angle <= 360.0; angle += 5.0)
319 {
320 rad = angle * M_PI / 180.0;
321 glVertex3f (0.0, 0.0, -length / 2);
322 glVertex3f (radius * cos (rad), radius * sin (rad), -length / 2);
323 glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), -length / 2);
324 glVertex3f (0.0, 0.0, -length / 2);
325 }
326 glEnd ();
327}
328
329
330
Gareth Hughes28861b12000-11-30 01:44:24 +0000331static void
332gear (GLint j, char type[], GLfloat radius, GLfloat width,
333 GLint teeth, GLfloat tooth_depth)
Brian Paul392a7002000-03-06 23:34:42 +0000334{
335 GLint i;
336 GLfloat r1, r2;
337 GLfloat angle, da;
338 GLfloat u, v, len, fraction = 0.5;
339 GLfloat n = 1.0;
Brian Paul9d0bc1d2000-04-05 21:36:03 +0000340
Brian Paul392a7002000-03-06 23:34:42 +0000341 r1 = radius - tooth_depth;
342 r2 = radius;
Gareth Hughes28861b12000-11-30 01:44:24 +0000343
Brian Paul392a7002000-03-06 23:34:42 +0000344 da = 2.0 * M_PI / teeth / 4.0;
345 if (!g[j].face)
346 {
347 fraction = -0.5;
348 n = -1.0;
349 }
350 if (!(strcmp (type, "NORMAL")))
351 {
352 fraction = 0.5;
353 n = 1.0;
354 }
355
Gareth Hughes28861b12000-11-30 01:44:24 +0000356 /* draw front face */
Brian Paul392a7002000-03-06 23:34:42 +0000357 if (!(strcmp (type, "NORMAL")))
358 {
359 glNormal3f (0.0, 0.0, 1.0 * n);
360 glBegin (GL_QUAD_STRIP);
361 for (i = 0; i <= teeth; i++)
362 {
363 angle = i * 2.0 * M_PI / teeth;
364 glVertex3f (0.0, 0.0, width * fraction);
365 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
366 glVertex3f (0.0, 0.0, width * fraction);
367 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
368 }
369 glEnd ();
370 }
371 else
372 {
373 glNormal3f (0.0, 0.0, 1.0 * n);
374 glBegin (GL_QUAD_STRIP);
375 for (i = 0; i <= teeth; i++)
376 {
377 angle = i * 2.0 * M_PI / teeth;
378 glVertex3f (0.0, 0.0, width * fraction);
379 glVertex3f ((r2 - width) * cos (angle), (r2 - width) * sin (angle), width * fraction);
380 glVertex3f (0.0, 0.0, width * fraction);
381 glVertex3f ((r2 - width) * cos (angle + 3 * da), (r2 - width) * sin (angle + 3 * da), width * fraction);
382 }
383 glEnd ();
384 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000385
386 /* draw front sides of teeth */
Brian Paul392a7002000-03-06 23:34:42 +0000387 if (!(strcmp (type, "NORMAL")))
388 {
389 glNormal3f (0.0, 0.0, 1.0 * n);
390 glBegin (GL_QUADS);
391 da = 2.0 * M_PI / teeth / 4.0;
392 for (i = 0; i < teeth; i++)
393 {
394 angle = i * 2.0 * M_PI / teeth;
395 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
396 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), width * fraction);
397 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), width * fraction);
398 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
399 }
400 glEnd ();
401 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000402
Brian Paul392a7002000-03-06 23:34:42 +0000403 glNormal3f (0.0, 0.0, -1.0 * n);
Gareth Hughes28861b12000-11-30 01:44:24 +0000404
405 /* draw back face */
Brian Paul392a7002000-03-06 23:34:42 +0000406 glBegin (GL_QUAD_STRIP);
407 for (i = 0; i <= teeth; i++)
408 {
409 angle = i * 2.0 * M_PI / teeth;
410 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
411 glVertex3f (0.0, 0.0, -width * fraction);
412 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
413 glVertex3f (0.0, 0.0, -width * fraction);
414 }
415 glEnd ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000416
417 /* draw back sides of teeth */
Brian Paul392a7002000-03-06 23:34:42 +0000418 glNormal3f (0.0, 0.0, -1.0 * n);
419 glBegin (GL_QUADS);
420 da = 2.0 * M_PI / teeth / 4.0;
421 for (i = 0; i < teeth; i++)
422 {
423 angle = i * 2.0 * M_PI / teeth;
424 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
425 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
426 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
427 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
428 }
429 glEnd ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000430
431
432 /* draw outward faces of teeth */
Brian Paul392a7002000-03-06 23:34:42 +0000433 if (!(strcmp (type, "NORMAL")))
434 {
435 glBegin (GL_QUAD_STRIP);
436 for (i = 0; i < teeth; i++)
437 {
438 angle = i * 2.0 * M_PI / teeth;
Gareth Hughes28861b12000-11-30 01:44:24 +0000439
Brian Paul392a7002000-03-06 23:34:42 +0000440 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
441 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
442 u = r2 * cos (angle + da) - r1 * cos (angle);
443 v = r2 * sin (angle + da) - r1 * sin (angle);
444 len = sqrt (u * u + v * v);
445 u /= len;
446 v /= len;
447 glNormal3f (v, -u, 0.0);
448 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), width * fraction);
449 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
450 glNormal3f (cos (angle), sin (angle), 0.0);
451 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), width * fraction);
452 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
453 u = r1 * cos (angle + 3 * da) - r2 * cos (angle + 2 * da);
454 v = r1 * sin (angle + 3 * da) - r2 * sin (angle + 2 * da);
455 glNormal3f (v, -u, 0.0);
456 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
457 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
458 glNormal3f (cos (angle), sin (angle), 0.0);
459 }
460 }
461 else
462 {
463 glBegin (GL_QUAD_STRIP);
464 for (i = 0; i < teeth; i++)
465 {
466 angle = i * 2.0 * M_PI / teeth;
467 glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
468 glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
469 u = r2 * cos (angle + da) - r1 * cos (angle);
470 v = r2 * sin (angle + da) - r1 * sin (angle);
471 len = sqrt (u * u + v * v);
472 u /= len;
473 v /= len;
474 glNormal3f (v, -u, 0.0);
475 glVertex3f ((r2 - width) * cos (angle + da), (r2 - width) * sin (angle + da), width * fraction);
476 glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
477 glNormal3f (cos (angle), sin (angle), n);
478 glVertex3f ((r2 - width) * cos (angle + 2 * da), (r2 - width) * sin (angle + 2 * da), width * fraction);
479 glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
480 u = r1 * cos (angle + 3 * da) - r2 * cos (angle + 2 * da);
481 v = r1 * sin (angle + 3 * da) - r2 * sin (angle + 2 * da);
482 glNormal3f (v, -u, 0.0);
483 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
484 glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
485 glNormal3f (cos (angle), sin (angle), n);
486 }
487 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000488
Brian Paul392a7002000-03-06 23:34:42 +0000489 glVertex3f (r1 * cos (0), r1 * sin (0), width * fraction);
490 glVertex3f (r1 * cos (0), r1 * sin (0), -width * fraction);
491 glEnd ();
492}
493
494
Gareth Hughes28861b12000-11-30 01:44:24 +0000495static void
496belt (struct GEAR g1, struct GEAR g2)
Brian Paul392a7002000-03-06 23:34:42 +0000497{
498 GLfloat D, alpha, phi, angle, incr, width;
499 GLint indexes[3] =
500 {
501 0, 0, 0
502 };
Gareth Hughes28861b12000-11-30 01:44:24 +0000503
Brian Paul392a7002000-03-06 23:34:42 +0000504 GLfloat col[3] =
505 {
506 0.0, 0.0, 0.0
507 };
Gareth Hughes28861b12000-11-30 01:44:24 +0000508
Brian Paul392a7002000-03-06 23:34:42 +0000509 width = min (g1.width, g2.width);
510 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));
511 alpha = acos ((g2.position[0] - g1.position[0]) / D);
512 phi = acos ((g1.radius - g2.radius) / D);
513 glBegin (GL_QUADS);
514 glColor3fv (col);
515 glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
516 incr = 1.2 * 360.0 / g1.teeth * M_PI / 180.00;
517 for (angle = alpha + phi; angle <= 2 * M_PI - phi + alpha; angle += 360.0 / g1.teeth * M_PI / 180.00)
518 {
519 glNormal3f (cos (angle), sin (angle), 0.0);
520 glVertex3f (g1.radius * cos (angle), g1.radius * sin (angle), width * 0.5);
521 glVertex3f (g1.radius * cos (angle), g1.radius * sin (angle), -width * 0.5);
522 glVertex3f (g1.radius * cos (angle + incr), g1.radius * sin (angle + incr), -width * 0.5);
523 glVertex3f (g1.radius * cos (angle + incr), g1.radius * sin (angle + incr), width * 0.5);
524 }
525 glEnd ();
526 glBegin (GL_QUADS);
527 glColor3fv (col);
528 glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
529 incr = 1.2 * 360.0 / g2.teeth * M_PI / 180.00;
530 for (angle = -phi + alpha; angle <= phi + alpha; angle += 360.0 / g1.teeth * M_PI / 180.0)
531 {
532 glNormal3f (cos (angle), sin (angle), 0.0);
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) + g2.position[0] - g1.position[0], g2.radius * sin (angle) + 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 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);
537 }
538 glEnd ();
539
540 glBegin (GL_QUADS);
541 glColor3fv (col);
542 glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
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 glVertex3f (g1.radius * cos (alpha - phi), g1.radius * sin (alpha - phi), width * 0.5);
548 glVertex3f (g1.radius * cos (alpha - phi), g1.radius * sin (alpha - phi), 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 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);
551 glEnd ();
552}
553
554
Gareth Hughes28861b12000-11-30 01:44:24 +0000555static int
556axle_find (char axle_name[])
Brian Paul392a7002000-03-06 23:34:42 +0000557{
558 int i;
Gareth Hughes28861b12000-11-30 01:44:24 +0000559
Brian Paul392a7002000-03-06 23:34:42 +0000560 for (i = 0; i < number_of_axles; i++)
561 {
562 if (!(strcmp (axle_name, a[i].name)))
563 break;
564 }
565 return i;
566}
567
568
Gareth Hughes28861b12000-11-30 01:44:24 +0000569static int
570gear_find (char gear_name[])
Brian Paul392a7002000-03-06 23:34:42 +0000571{
572 int i;
Gareth Hughes28861b12000-11-30 01:44:24 +0000573
Brian Paul392a7002000-03-06 23:34:42 +0000574 for (i = 0; i < number_of_gears; i++)
575 {
576 if (!(strcmp (gear_name, g[i].name)))
577 break;
578 }
579 return i;
580}
581
582
Gareth Hughes28861b12000-11-30 01:44:24 +0000583static void
584process ()
Brian Paul392a7002000-03-06 23:34:42 +0000585{
586 GLfloat x, y, z, D, dist;
587 GLint axle_index, i, j, g1, g2, k;
588 char error[80];
Gareth Hughes28861b12000-11-30 01:44:24 +0000589
Brian Paul392a7002000-03-06 23:34:42 +0000590 for (i = 0; i < number_of_gears; i++)
591 {
592 x = 0.0;
593 y = 0.0;
594 z = 0.0;
595 axle_index = axle_find (g[i].axle_name);
596 g[i].axis = a[axle_index].axis;
597 g[i].motored = a[axle_index].motored;
598 if (a[axle_index].motored)
599 {
600 g[i].direction = a[axle_index].direction;
601 g[i].angular_velocity = a[axle_index].angular_velocity;
602 }
603 if (g[i].axis == 0)
604 x = 1.0;
605 else if (g[i].axis == 1)
606 y = 1.0;
607 else
608 z = 1.0;
Gareth Hughes28861b12000-11-30 01:44:24 +0000609
Brian Paul392a7002000-03-06 23:34:42 +0000610 g[i].position[0] = a[axle_index].position[0] + x * g[i].relative_position;
611 g[i].position[1] = a[axle_index].position[1] + y * g[i].relative_position;
612 g[i].position[2] = a[axle_index].position[2] + z * g[i].relative_position;
613 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000614
Brian Paul392a7002000-03-06 23:34:42 +0000615 for (k = 0; k < number_of_axles; k++)
616 {
617 for (i = 0; i < number_of_gears - 1; i++)
618 {
619 for (j = 0; j < number_of_gears; j++)
620 {
621 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))
622 {
623 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));
624 if (D < 1.1 * (g[i].radius - g[i].tooth_depth + g[j].radius - g[j].tooth_depth))
625 {
626 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 +0000627
Brian Paul392a7002000-03-06 23:34:42 +0000628 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
629 exit (1);
630 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000631
Brian Paul392a7002000-03-06 23:34:42 +0000632 if (g[i].axis == 0)
633 {
634 dist = g[i].position[0] - g[j].position[0];
635 }
636 else if (g[i].axis == 1)
637 {
638 dist = g[i].position[1] - g[j].position[1];
639 }
640 else
641 dist = g[i].position[2] - g[j].position[2];
Gareth Hughes28861b12000-11-30 01:44:24 +0000642
Brian Paul392a7002000-03-06 23:34:42 +0000643 dist = fabs (dist);
Gareth Hughes28861b12000-11-30 01:44:24 +0000644
Brian Paul392a7002000-03-06 23:34:42 +0000645 if (dist < (g[i].width / 2 + g[j].width / 2))
646 {
647 if ((g[i].motored) && (!(g[j].motored)) && (D < 0.95 * (g[i].radius + g[j].radius)))
648 {
649 axle_index = axle_find (g[j].axle_name);
650 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))
651 {
652 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
653 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
654 exit (1);
655 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000656
Brian Paul392a7002000-03-06 23:34:42 +0000657 g[j].motored = (a[axle_index].motored = 1);
658 g[j].direction = (a[axle_index].direction = -g[i].direction);
659 a[axle_index].angular_velocity = g[i].angular_velocity * g[i].teeth / g[j].teeth;
660 g[j].angular_velocity = (a[axle_index].angular_velocity *= g[i].radius / g[j].radius);
661 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000662
Brian Paul392a7002000-03-06 23:34:42 +0000663 if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * (g[i].radius + g[j].radius)))
664 {
665 axle_index = axle_find (g[i].axle_name);
666 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))
667 {
668 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
669 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
670 exit (1);
671 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000672
Brian Paul392a7002000-03-06 23:34:42 +0000673 g[i].motored = (a[axle_index].motored = 1);
674 g[i].direction = (a[axle_index].direction = -g[j].direction);
675 a[axle_index].angular_velocity = g[j].angular_velocity * g[j].teeth / g[i].teeth;
676 g[i].angular_velocity = (a[axle_index].angular_velocity *= g[j].radius / g[i].radius);
Gareth Hughes28861b12000-11-30 01:44:24 +0000677
Brian Paul392a7002000-03-06 23:34:42 +0000678 }
679 }
680 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000681
Brian Paul392a7002000-03-06 23:34:42 +0000682 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))
683 {
684 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));
685 if ((g[i].motored) && (!(g[j].motored)) && (D < 0.95 * sqrt (g[i].radius * g[i].radius + g[j].radius * g[j].radius)))
686 {
687 axle_index = axle_find (g[j].axle_name);
688 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))
689 {
690 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
691 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
692 exit (1);
693 }
694 g[j].motored = (a[axle_index].motored = 1);
695 g[j].direction = (a[axle_index].direction = -g[i].direction);
696 a[axle_index].angular_velocity = g[i].angular_velocity * g[i].teeth / g[j].teeth;
697 g[j].angular_velocity = (a[axle_index].angular_velocity *= g[i].radius / g[j].radius);
698 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000699
700
Brian Paul392a7002000-03-06 23:34:42 +0000701 if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * sqrt (g[i].radius * g[i].radius + g[j].radius * g[j].radius)))
702 {
703 axle_index = axle_find (g[i].axle_name);
704 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))
705 {
706 printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
707 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
708 exit (1);
709 }
710 g[i].motored = (a[axle_index].motored = 1);
711 g[i].direction = (a[axle_index].direction = -g[j].direction);
712 a[axle_index].angular_velocity = g[j].angular_velocity * g[j].teeth / g[i].teeth;
713 g[i].angular_velocity = (a[axle_index].angular_velocity *= g[j].radius / g[i].radius);
714 }
715 }
716 }
717 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000718
Brian Paul392a7002000-03-06 23:34:42 +0000719 for (i = 0; i < number_of_gears; i++)
720 {
721 axle_index = axle_find (g[i].axle_name);
722 g[i].motored = a[axle_index].motored;
723 if (a[axle_index].motored)
724 {
725 g[i].direction = a[axle_index].direction;
726 g[i].angular_velocity = a[axle_index].angular_velocity;
727 }
728 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000729
Brian Paul392a7002000-03-06 23:34:42 +0000730 for (i = 0; i < number_of_belts; i++)
731 {
732 g1 = gear_find (b[i].gear1_name);
733 g2 = gear_find (b[i].gear2_name);
734 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));
735 if (!((g[g1].axis == g[g2].axis) && (!strcmp (g[g1].type, g[g2].type)) && (!strcmp (g[g1].type, "NORMAL"))))
736 {
737 printf (error, "Belt %s invalid.", b[i].name);
738 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
739 exit (1);
740 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000741
Brian Paul392a7002000-03-06 23:34:42 +0000742 if ((g[g1].axis == g[g2].axis) && (!strcmp (g[g1].type, g[g2].type)) && (!strcmp (g[g1].type, "NORMAL")))
743 {
744 /*
745 if((g[g1].motored)&&(g[g2].motored))
746 if(g[g2].angular_velocity!=(g[g1].angular_velocity*g[g1].radius/g[g2].radius))
747 {
748 printf(error,"Error in belt linkage of gears %s and %s".,g[g1].name,g[g2].name);
749 MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);
750 exit(1);
751 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000752 */
Brian Paul392a7002000-03-06 23:34:42 +0000753 if (g[g1].axis == 0)
754 {
755 dist = g[g1].position[0] - g[g2].position[0];
756 }
757 else if (g[i].axis == 1)
758 {
759 dist = g[g1].position[1] - g[g2].position[1];
760 }
761 else
762 dist = g[g1].position[2] - g[g2].position[2];
Gareth Hughes28861b12000-11-30 01:44:24 +0000763
Brian Paul392a7002000-03-06 23:34:42 +0000764 dist = fabs (dist);
Gareth Hughes28861b12000-11-30 01:44:24 +0000765
Brian Paul392a7002000-03-06 23:34:42 +0000766 if (dist > (g[g1].width / 2 + g[g2].width / 2))
767 {
768 printf (error, "Belt %s invalid.", b[i].name);
769 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
770 exit (1);
771 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000772
Brian Paul392a7002000-03-06 23:34:42 +0000773 if (dist < (g[g1].width / 2 + g[g2].width / 2))
774 {
775 if (D < g[g1].radius + g[g2].radius)
776 {
777 printf (error, "Gears %s and %s too close to be linked with belts", g[g1].name, g[g2].name);
778 /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
779 exit (1);
780 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000781
Brian Paul392a7002000-03-06 23:34:42 +0000782 if ((g[g1].motored) && (!(g[g2].motored)))
783 {
784 axle_index = axle_find (g[g2].axle_name);
785 g[g2].motored = (a[axle_index].motored = 1);
786 g[g2].direction = (a[axle_index].direction = g[g1].direction);
787 g[g2].angular_velocity = (a[axle_index].angular_velocity = g[g1].angular_velocity * g[g1].radius / g[g2].radius);
788 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000789
Brian Paul392a7002000-03-06 23:34:42 +0000790 if ((!(g[g1].motored)) && (g[g2].motored))
791 {
792 axle_index = axle_find (g[g1].axle_name);
793 g[g1].motored = (a[axle_index].motored = 1);
794 g[g1].direction = (a[axle_index].direction = g[g2].direction);
795 g[g1].angular_velocity = (a[axle_index].angular_velocity = g[g2].angular_velocity * g[g2].radius / g[g1].radius);
796 }
797 }
798 }
799 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000800
Brian Paul392a7002000-03-06 23:34:42 +0000801 for (i = 0; i < number_of_gears; i++)
802 {
803 axle_index = axle_find (g[i].axle_name);
804 g[i].motored = a[axle_index].motored;
805 if (a[axle_index].motored)
806 {
807 g[i].direction = a[axle_index].direction;
808 g[i].angular_velocity = a[axle_index].angular_velocity;
809 }
810 }
811 }
812}
813
814
815
816GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 10.0;
817
818
Gareth Hughes28861b12000-11-30 01:44:24 +0000819static void
820draw (void)
Brian Paul392a7002000-03-06 23:34:42 +0000821{
822 int i;
823 GLfloat x, y, z;
824 int index;
825
826 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Gareth Hughes28861b12000-11-30 01:44:24 +0000827
Brian Paul392a7002000-03-06 23:34:42 +0000828 glPushMatrix ();
829 glRotatef (view_rotx, 1.0, 0.0, 0.0);
830 glRotatef (view_roty, 0.0, 1.0, 0.0);
831 glRotatef (view_rotz, 0.0, 0.0, 1.0);
Gareth Hughes28861b12000-11-30 01:44:24 +0000832
Brian Paul392a7002000-03-06 23:34:42 +0000833 for (i = 0; i < number_of_gears; i++)
834 {
835 x = 0.0;
836 y = 0.0;
837 z = 0.0;
838 glPushMatrix ();
839/*glTranslatef( -3.0, -2.0, 0.0 );*/
840 glTranslatef (g[i].position[0], g[i].position[1], g[i].position[2]);
841 if (g[i].axis == 0)
842 y = 1.0;
843 else if (g[i].axis == 1)
844 x = 1.0;
845 else
846 z = 1.0;
Gareth Hughes28861b12000-11-30 01:44:24 +0000847
Brian Paul392a7002000-03-06 23:34:42 +0000848 if (z != 1.0)
849 glRotatef (90.0, x, y, z);
Gareth Hughes28861b12000-11-30 01:44:24 +0000850
Brian Paul392a7002000-03-06 23:34:42 +0000851 glRotatef (g[i].direction * g[i].angle, 0.0, 0.0, 1.0);
852 glCallList (g[i].id);
853 glPopMatrix ();
854 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000855
Brian Paul392a7002000-03-06 23:34:42 +0000856 for (i = 0; i < number_of_axles; i++)
857 {
858 x = 0.0;
859 y = 0.0;
860 z = 0.0;
861 glPushMatrix ();
862 glTranslatef (a[i].position[0], a[i].position[1], a[i].position[2]);
863 if (a[i].axis == 0)
864 y = 1.0;
865 else if (a[i].axis == 1)
866 x = 1.0;
867 else
868 z = 1.0;
869
870 if (z != 1.0)
871 glRotatef (90.0, x, y, z);
Gareth Hughes28861b12000-11-30 01:44:24 +0000872
Brian Paul392a7002000-03-06 23:34:42 +0000873 glCallList (a[i].id);
874 glPopMatrix ();
875 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000876
Brian Paul392a7002000-03-06 23:34:42 +0000877 for (i = 0; i < number_of_belts; i++)
878 {
879 x = 0.0;
880 y = 0.0;
881 z = 0.0;
882 glPushMatrix ();
883 index = gear_find (b[i].gear1_name);
884 glTranslatef (g[index].position[0], g[index].position[1], g[index].position[2]);
885 if (g[index].axis == 0)
886 y = 1.0;
887 else if (g[index].axis == 1)
888 x = 1.0;
889 else
890 z = 1.0;
Gareth Hughes28861b12000-11-30 01:44:24 +0000891
Brian Paul392a7002000-03-06 23:34:42 +0000892 if (z != 1.0)
893 glRotatef (90.0, x, y, z);
Gareth Hughes28861b12000-11-30 01:44:24 +0000894
Brian Paul392a7002000-03-06 23:34:42 +0000895 glCallList (b[i].id);
896 glPopMatrix ();
897 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000898
Brian Paul392a7002000-03-06 23:34:42 +0000899 glPopMatrix ();
900 glutSwapBuffers ();
Gareth Hughes28861b12000-11-30 01:44:24 +0000901
902 {
903 GLint t = glutGet(GLUT_ELAPSED_TIME);
904 Frames++;
905 if (t - T0 >= 5000) {
906 GLfloat seconds = (t - T0) / 1000.0;
907 GLfloat fps = Frames / seconds;
908 printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps);
909 T0 = t;
910 Frames = 0;
911 }
912 }
Brian Paul392a7002000-03-06 23:34:42 +0000913}
914
915
916
917
Gareth Hughes28861b12000-11-30 01:44:24 +0000918static void
919idle (void)
Brian Paul392a7002000-03-06 23:34:42 +0000920{
921 int i;
922 for (i = 0; i < number_of_gears; i++)
923 g[i].angle += g[i].angular_velocity;
924 glutPostRedisplay();
925}
926
927
928
929
Gareth Hughes28861b12000-11-30 01:44:24 +0000930/* change view angle, exit upon ESC */
931static void
932key (unsigned char k, int x, int y)
Brian Paul392a7002000-03-06 23:34:42 +0000933{
934 switch (k)
935 {
936 case 'x':
937 view_rotx += 5.0;
938 break;
939 case 'X':
940 view_rotx -= 5.0;
941 break;
942 case 'y':
943 view_roty += 5.0;
944 break;
945 case 'Y':
946 view_roty -= 5.0;
947 break;
948 case 'z':
949 view_rotz += 5.0;
950 break;
951 case 'Z':
952 view_rotz -= 5.0;
953 break;
954 case 0x1B:
955 exit(0);
956 }
957}
958
959
960
961
Gareth Hughes28861b12000-11-30 01:44:24 +0000962/* new window size or exposure */
963static void
964reshape (int width, int height)
Brian Paul392a7002000-03-06 23:34:42 +0000965{
966 glViewport (0, 0, (GLint) width, (GLint) height);
967 glMatrixMode (GL_PROJECTION);
968 glLoadIdentity ();
969 if (width > height)
970 {
971 GLfloat w = (GLfloat) width / (GLfloat) height;
972 glFrustum (-w, w, -1.0, 1.0, 5.0, 60.0);
973 }
974 else
975 {
976 GLfloat h = (GLfloat) height / (GLfloat) width;
977 glFrustum (-1.0, 1.0, -h, h, 5.0, 60.0);
978 }
Gareth Hughes28861b12000-11-30 01:44:24 +0000979
Brian Paul392a7002000-03-06 23:34:42 +0000980 glMatrixMode (GL_MODELVIEW);
981 glLoadIdentity ();
982 glTranslatef (0.0, 0.0, -40.0);
983 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
984}
985
986
987
Gareth Hughes28861b12000-11-30 01:44:24 +0000988static void
989init (void)
Brian Paul392a7002000-03-06 23:34:42 +0000990{
991 GLfloat matShine = 20.00F;
992 GLfloat light0Pos[4] =
993 {
994 0.70F, 0.70F, 1.25F, 0.50F
995 };
996 int i;
Gareth Hughes28861b12000-11-30 01:44:24 +0000997
Brian Paul392a7002000-03-06 23:34:42 +0000998 glClearColor (background[0], background[1], background[2], 1.0F);
999 glClearIndex ((GLfloat) 0.0);
Gareth Hughes28861b12000-11-30 01:44:24 +00001000
Brian Paul392a7002000-03-06 23:34:42 +00001001 glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, matShine);
1002 glLightfv (GL_LIGHT0, GL_POSITION, light0Pos);
1003 glEnable (GL_LIGHT0);
Gareth Hughes28861b12000-11-30 01:44:24 +00001004
Brian Paul392a7002000-03-06 23:34:42 +00001005 glEnable (GL_LIGHTING);
1006 glEnable (GL_DEPTH_TEST);
1007 for (i = 0; i < number_of_gears; i++)
1008 g[i].angle = 0.0;
Gareth Hughes28861b12000-11-30 01:44:24 +00001009
Brian Paul392a7002000-03-06 23:34:42 +00001010 for (i = 0; i < number_of_gears; i++)
1011 {
1012 g[i].id = glGenLists (1);
1013 glNewList (g[i].id, GL_COMPILE);
1014 glColor3fv (g[i].color);
1015 glMaterialfv (GL_FRONT, GL_SPECULAR, g[i].color);
1016 gear (i, g[i].type, g[i].radius, g[i].width, g[i].teeth, g[i].tooth_depth);
1017 glEndList ();
1018 }
Gareth Hughes28861b12000-11-30 01:44:24 +00001019
Brian Paul392a7002000-03-06 23:34:42 +00001020 for (i = 0; i < number_of_axles; i++)
1021 {
1022 a[i].id = glGenLists (1);
1023 glNewList (a[i].id, GL_COMPILE);
1024 glColor3fv (a[i].color);
1025 glMaterialfv (GL_FRONT, GL_SPECULAR, a[i].color);
1026 axle (i, a[i].radius, a[i].length);
1027 glEndList ();
1028 }
Gareth Hughes28861b12000-11-30 01:44:24 +00001029
Brian Paul392a7002000-03-06 23:34:42 +00001030 for (i = 0; i < number_of_belts; i++)
1031 {
1032 b[i].id = glGenLists (1);
1033 glNewList (b[i].id, GL_COMPILE);
1034 belt (g[gear_find (b[i].gear1_name)], g[gear_find (b[i].gear2_name)]);
1035 glEndList ();
1036 }
Gareth Hughes28861b12000-11-30 01:44:24 +00001037
Brian Paul392a7002000-03-06 23:34:42 +00001038 glEnable (GL_COLOR_MATERIAL);
1039}
1040
1041
1042
Gareth Hughes28861b12000-11-30 01:44:24 +00001043int
1044main (int argc, char *argv[])
Brian Paul392a7002000-03-06 23:34:42 +00001045{
1046 char *file;
1047
1048 if (argc < 2)
1049 file = "geartrain.dat";
1050 else
1051 file = argv[1];
1052
1053 glutInitWindowPosition (0, 0);
1054 glutInitWindowSize(640,480);
1055 glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
Gareth Hughes28861b12000-11-30 01:44:24 +00001056
Brian Paul392a7002000-03-06 23:34:42 +00001057 if (glutCreateWindow ("Gear Train Simulation") == GL_FALSE)
1058 exit (1);
1059
1060 getdata (file);
1061 process ();
1062 init ();
Gareth Hughes28861b12000-11-30 01:44:24 +00001063
Brian Paul392a7002000-03-06 23:34:42 +00001064 glutDisplayFunc (draw);
1065 glutReshapeFunc (reshape);
1066 glutKeyboardFunc (key);
1067 glutIdleFunc (idle);
1068 glutMainLoop ();
1069 return 0;
1070}