132001f49Smrg 232001f49Smrg/* 332001f49Smrg * GearTrain Simulator * Version: 1.00 432001f49Smrg * 532001f49Smrg * Copyright (C) 1999 Shobhan Kumar Dutta All Rights Reserved. 632001f49Smrg * <skdutta@del3.vsnl.net.in> 732001f49Smrg * 832001f49Smrg * Permission is hereby granted, free of charge, to any person obtaining a 932001f49Smrg * copy of this software and associated documentation files (the "Software"), 1032001f49Smrg * to deal in the Software without restriction, including without limitation 1132001f49Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1232001f49Smrg * and/or sell copies of the Software, and to permit persons to whom the 1332001f49Smrg * Software is furnished to do so, subject to the following conditions: 1432001f49Smrg * 1532001f49Smrg * The above copyright notice and this permission notice shall be included 1632001f49Smrg * in all copies or substantial portions of the Software. 1732001f49Smrg * 1832001f49Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1932001f49Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2032001f49Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2132001f49Smrg * SHOBHAN KUMAR DUTTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 2232001f49Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 2332001f49Smrg * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 2432001f49Smrg * SOFTWARE. 2532001f49Smrg */ 2632001f49Smrg 2732001f49Smrg 2832001f49Smrg#include <assert.h> 2932001f49Smrg#include <math.h> 3032001f49Smrg#include <stdlib.h> 3132001f49Smrg#include "glut_wrap.h" 3232001f49Smrg#include <string.h> 3332001f49Smrg#include <stdio.h> 3432001f49Smrg 3532001f49Smrg#ifndef min 3632001f49Smrg#define min(x, y) ( x < y ? x : y ) 3732001f49Smrg#endif 3832001f49Smrg 3932001f49Smrg#ifndef M_PI 4032001f49Smrg#define M_PI 3.14159265 4132001f49Smrg#endif /* */ 4232001f49Smrgtypedef GLfloat TDA[4]; 4332001f49Smrg 4432001f49SmrgTDA background; 4532001f49Smrg 4632001f49Smrg 4732001f49Smrgstruct AXLE 4832001f49Smrg { 4932001f49Smrg char name[20]; 5032001f49Smrg GLint id; 5132001f49Smrg GLfloat radius; 5232001f49Smrg GLint axis; 5332001f49Smrg TDA color; 5432001f49Smrg TDA position; 5532001f49Smrg GLfloat length; 5632001f49Smrg GLint motored; 5732001f49Smrg GLfloat angular_velocity; 5832001f49Smrg GLint direction; 5932001f49Smrg }; 6032001f49Smrg 6132001f49Smrg 6232001f49Smrgstruct GEAR 6332001f49Smrg { 6432001f49Smrg char name[20]; 6532001f49Smrg char type[7]; 6632001f49Smrg GLint face; 6732001f49Smrg GLint id; 6832001f49Smrg GLfloat radius; 6932001f49Smrg GLfloat width; 7032001f49Smrg GLint teeth; 7132001f49Smrg GLfloat tooth_depth; 7232001f49Smrg GLfloat angle; 7332001f49Smrg GLfloat angular_velocity; 7432001f49Smrg TDA color; 7532001f49Smrg GLint relative_position; 7632001f49Smrg TDA position; 7732001f49Smrg char axle_name[20]; 7832001f49Smrg GLint axis; 7932001f49Smrg GLint direction; 8032001f49Smrg GLint motored; 8132001f49Smrg }; 8232001f49Smrg 8332001f49Smrg 8432001f49Smrgstruct BELT 8532001f49Smrg { 8632001f49Smrg char name[20]; 8732001f49Smrg GLint id; 8832001f49Smrg char gear1_name[20]; 8932001f49Smrg char gear2_name[20]; 9032001f49Smrg }; 9132001f49Smrg 9232001f49Smrg 9332001f49SmrgFILE * mainfile; 9432001f49Smrgstruct GEAR g[10]; 9532001f49Smrgstruct AXLE a[10]; 9632001f49Smrgstruct BELT b[10]; 9732001f49Smrgint number_of_gears; 9832001f49Smrgint number_of_axles; 9932001f49Smrgint number_of_belts; 10032001f49Smrg 10132001f49Smrg 10232001f49Smrgchar Buf1[256], Buf2[256], Buf3[256], Buf4[256], Buf5[256]; 10332001f49Smrg 10432001f49Smrgstatic GLint T0 = 0; 10532001f49Smrgstatic GLint Frames = 0; 10632001f49Smrg 10732001f49Smrg 10832001f49Smrgstatic void 10932001f49SmrgClear_Buffers (void) 11032001f49Smrg{ 11132001f49Smrg memset (Buf1, '\0', 256); 11232001f49Smrg memset (Buf2, '\0', 256); 11332001f49Smrg memset (Buf3, '\0', 256); 11432001f49Smrg memset (Buf4, '\0', 256); 11532001f49Smrg memset (Buf5, '\0', 256); 11632001f49Smrg} 11732001f49Smrg 11832001f49Smrg 11932001f49Smrgstatic void 12032001f49SmrgLoadTriplet (TDA A) 12132001f49Smrg{ 12232001f49Smrg int result; 12332001f49Smrg Clear_Buffers (); 12432001f49Smrg result = fscanf (mainfile, "%s %s %s %s", Buf1, Buf2, Buf3, Buf4); 12532001f49Smrg assert(result != EOF); 12632001f49Smrg A[0] = atof (Buf2); 12732001f49Smrg A[1] = atof (Buf3); 12832001f49Smrg A[2] = atof (Buf4); 12932001f49Smrg} 13032001f49Smrg 13132001f49Smrg 13232001f49Smrgstatic void 13332001f49SmrgLoadReal (float *a) 13432001f49Smrg{ 13532001f49Smrg int result; 13632001f49Smrg Clear_Buffers (); 13732001f49Smrg result = fscanf (mainfile, "%s %s", Buf1, Buf2); 13832001f49Smrg assert(result != EOF); 13932001f49Smrg *a = atof (Buf2); 14032001f49Smrg} 14132001f49Smrg 14232001f49Smrg 14332001f49Smrgstatic void 14432001f49SmrgLoadInteger (int *a) 14532001f49Smrg{ 14632001f49Smrg int result; 14732001f49Smrg Clear_Buffers (); 14832001f49Smrg result = fscanf (mainfile, "%s %s", Buf1, Buf2); 14932001f49Smrg assert(result != EOF); 15032001f49Smrg *a = atoi (Buf2); 15132001f49Smrg} 15232001f49Smrg 15332001f49Smrg 15432001f49Smrgstatic void 15532001f49SmrgLoadText (char *a) 15632001f49Smrg{ 15732001f49Smrg int result; 15832001f49Smrg Clear_Buffers (); 15932001f49Smrg result = fscanf (mainfile, "%s %s", Buf1, Buf2); 16032001f49Smrg assert(result != EOF); 16132001f49Smrg strcpy (a, Buf2); 16232001f49Smrg} 16332001f49Smrg 16432001f49Smrg 16532001f49Smrgstatic void 16632001f49Smrggetdata (char filename[]) 16732001f49Smrg{ 16832001f49Smrg int gear_count = 0, axle_count = 0, belt_count = 0, i; 16932001f49Smrg 17032001f49Smrg mainfile = fopen (filename, "r"); 17132001f49Smrg if (!mainfile) { 17232001f49Smrg printf("Error: couldn't open %s\n", filename); 17332001f49Smrg exit(-1); 17432001f49Smrg } 17532001f49Smrg 17632001f49Smrg do 17732001f49Smrg { 17832001f49Smrg int result; 17932001f49Smrg Clear_Buffers (); 18032001f49Smrg result = fscanf (mainfile, "%s", Buf1); 18132001f49Smrg (void) result; 18232001f49Smrg if (ferror (mainfile)) 18332001f49Smrg { 18432001f49Smrg printf ("\nError opening file !\n"); 18532001f49Smrg exit (1); 18632001f49Smrg } 18732001f49Smrg 18832001f49Smrg if (!(strcmp (Buf1, "BACKGROUND"))) 18932001f49Smrg LoadTriplet (background); 19032001f49Smrg 19132001f49Smrg if (!(strcmp (Buf1, "ANAME"))) 19232001f49Smrg { 19332001f49Smrg LoadText (a[axle_count].name); 19432001f49Smrg axle_count++; 19532001f49Smrg } 19632001f49Smrg 19732001f49Smrg if (!(strcmp (Buf1, "ARADIUS"))) 19832001f49Smrg LoadReal (&a[axle_count - 1].radius); 19932001f49Smrg 20032001f49Smrg if (!(strcmp (Buf1, "AAXIS"))) 20132001f49Smrg LoadInteger (&a[axle_count - 1].axis); 20232001f49Smrg 20332001f49Smrg if (!(strcmp (Buf1, "ACOLOR"))) 20432001f49Smrg LoadTriplet (a[axle_count - 1].color); 20532001f49Smrg 20632001f49Smrg if (!(strcmp (Buf1, "APOSITION"))) 20732001f49Smrg LoadTriplet (a[axle_count - 1].position); 20832001f49Smrg 20932001f49Smrg if (!(strcmp (Buf1, "ALENGTH"))) 21032001f49Smrg LoadReal (&a[axle_count - 1].length); 21132001f49Smrg 21232001f49Smrg if (!(strcmp (Buf1, "AMOTORED"))) 21332001f49Smrg LoadInteger (&a[axle_count - 1].motored); 21432001f49Smrg 21532001f49Smrg if (!(strcmp (Buf1, "AANGULARVELOCITY"))) 21632001f49Smrg LoadReal (&a[axle_count - 1].angular_velocity); 21732001f49Smrg 21832001f49Smrg if (!(strcmp (Buf1, "ADIRECTION"))) 21932001f49Smrg LoadInteger (&a[axle_count - 1].direction); 22032001f49Smrg 22132001f49Smrg if (!(strcmp (Buf1, "GNAME"))) 22232001f49Smrg { 22332001f49Smrg LoadText (g[gear_count].name); 22432001f49Smrg gear_count++; 22532001f49Smrg } 22632001f49Smrg 22732001f49Smrg if (!(strcmp (Buf1, "GTYPE"))) 22832001f49Smrg LoadText (g[gear_count - 1].type); 22932001f49Smrg 23032001f49Smrg if (!(strcmp (Buf1, "GFACE"))) 23132001f49Smrg LoadInteger (&g[gear_count - 1].face); 23232001f49Smrg 23332001f49Smrg if (!(strcmp (Buf1, "GRADIUS"))) 23432001f49Smrg LoadReal (&g[gear_count - 1].radius); 23532001f49Smrg 23632001f49Smrg if (!(strcmp (Buf1, "GWIDTH"))) 23732001f49Smrg LoadReal (&g[gear_count - 1].width); 23832001f49Smrg 23932001f49Smrg if (!(strcmp (Buf1, "GTEETH"))) 24032001f49Smrg LoadInteger (&g[gear_count - 1].teeth); 24132001f49Smrg 24232001f49Smrg if (!(strcmp (Buf1, "GTOOTHDEPTH"))) 24332001f49Smrg LoadReal (&g[gear_count - 1].tooth_depth); 24432001f49Smrg 24532001f49Smrg if (!(strcmp (Buf1, "GCOLOR"))) 24632001f49Smrg LoadTriplet (g[gear_count - 1].color); 24732001f49Smrg 24832001f49Smrg if (!(strcmp (Buf1, "GAXLE"))) 24932001f49Smrg LoadText (g[gear_count - 1].axle_name); 25032001f49Smrg 25132001f49Smrg if (!(strcmp (Buf1, "GPOSITION"))) 25232001f49Smrg LoadInteger (&g[gear_count - 1].relative_position); 25332001f49Smrg 25432001f49Smrg if (!(strcmp (Buf1, "BELTNAME"))) 25532001f49Smrg { 25632001f49Smrg LoadText (b[belt_count].name); 25732001f49Smrg belt_count++; 25832001f49Smrg } 25932001f49Smrg 26032001f49Smrg if (!(strcmp (Buf1, "GEAR1NAME"))) 26132001f49Smrg LoadText (b[belt_count - 1].gear1_name); 26232001f49Smrg 26332001f49Smrg if (!(strcmp (Buf1, "GEAR2NAME"))) 26432001f49Smrg LoadText (b[belt_count - 1].gear2_name); 26532001f49Smrg } 26632001f49Smrg while (Buf1[0] != 0); 26732001f49Smrg 26832001f49Smrg number_of_gears = gear_count; 26932001f49Smrg number_of_axles = axle_count; 27032001f49Smrg number_of_belts = belt_count; 27132001f49Smrg 27232001f49Smrg for (i = 0; i < number_of_gears; i++) 27332001f49Smrg { 27432001f49Smrg g[i].axis = -1; 27532001f49Smrg g[i].direction = 0; 27632001f49Smrg g[i].angular_velocity = 0.0; 27732001f49Smrg } 27832001f49Smrg 27932001f49Smrg fclose (mainfile); 28032001f49Smrg} 28132001f49Smrg 28232001f49Smrg 28332001f49Smrgstatic void 28432001f49Smrgaxle (GLint j, GLfloat radius, GLfloat length) 28532001f49Smrg{ 28632001f49Smrg GLfloat angle, rad, incr = 10.0 * M_PI / 180.0; 28732001f49Smrg 28832001f49Smrg /* draw main cylinder */ 28932001f49Smrg glBegin (GL_QUADS); 29032001f49Smrg for (angle = 0.0; angle < 360.0; angle += 5.0) 29132001f49Smrg { 29232001f49Smrg rad = angle * M_PI / 180.0; 29332001f49Smrg glNormal3f (cos (rad), sin (rad), 0.0); 29432001f49Smrg glVertex3f (radius * cos (rad), radius * sin (rad), length / 2); 29532001f49Smrg glVertex3f (radius * cos (rad), radius * sin (rad), -length / 2); 29632001f49Smrg glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), -length / 2); 29732001f49Smrg glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), length / 2); 29832001f49Smrg } 29932001f49Smrg glEnd (); 30032001f49Smrg 30132001f49Smrg /* draw front face */ 30232001f49Smrg glNormal3f (0.0, 0.0, 1.0); 30332001f49Smrg glBegin (GL_TRIANGLES); 30432001f49Smrg for (angle = 0.0; angle < 360.0; angle += 5.0) 30532001f49Smrg { 30632001f49Smrg rad = angle * M_PI / 180.0; 30732001f49Smrg glVertex3f (0.0, 0.0, length / 2); 30832001f49Smrg glVertex3f (radius * cos (rad), radius * sin (rad), length / 2); 30932001f49Smrg glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), length / 2); 31032001f49Smrg glVertex3f (0.0, 0.0, length / 2); 31132001f49Smrg } 31232001f49Smrg glEnd (); 31332001f49Smrg 31432001f49Smrg /* draw back face */ 31532001f49Smrg glNormal3f (0.0, 0.0, -1.0); 31632001f49Smrg glBegin (GL_TRIANGLES); 31732001f49Smrg for (angle = 0.0; angle <= 360.0; angle += 5.0) 31832001f49Smrg { 31932001f49Smrg rad = angle * M_PI / 180.0; 32032001f49Smrg glVertex3f (0.0, 0.0, -length / 2); 32132001f49Smrg glVertex3f (radius * cos (rad), radius * sin (rad), -length / 2); 32232001f49Smrg glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), -length / 2); 32332001f49Smrg glVertex3f (0.0, 0.0, -length / 2); 32432001f49Smrg } 32532001f49Smrg glEnd (); 32632001f49Smrg} 32732001f49Smrg 32832001f49Smrg 32932001f49Smrg 33032001f49Smrgstatic void 33132001f49Smrggear (GLint j, char type[], GLfloat radius, GLfloat width, 33232001f49Smrg GLint teeth, GLfloat tooth_depth) 33332001f49Smrg{ 33432001f49Smrg GLint i; 33532001f49Smrg GLfloat r1, r2_front, r2_back; 33632001f49Smrg GLfloat angle, da; 33732001f49Smrg GLfloat u, v, len, fraction = 0.5; 33832001f49Smrg GLfloat n = 1.0; 33932001f49Smrg 34032001f49Smrg r1 = radius - tooth_depth; 34132001f49Smrg r2_front = r2_back = radius; 34232001f49Smrg 34332001f49Smrg fraction = 0.5; 34432001f49Smrg n = 1.0; 34532001f49Smrg 34632001f49Smrg da = 2.0 * M_PI / teeth / 4.0; 34732001f49Smrg if (!(strcmp (type, "BEVEL"))) 34832001f49Smrg { 34932001f49Smrg if (g[j].face) 35032001f49Smrg r2_front = radius - width; 35132001f49Smrg else 35232001f49Smrg r2_back = radius - width; 35332001f49Smrg } 35432001f49Smrg 35532001f49Smrg /* draw front face */ 35632001f49Smrg glNormal3f (0.0, 0.0, 1.0 * n); 35732001f49Smrg glBegin (GL_QUAD_STRIP); 35832001f49Smrg for (i = 0; i <= teeth; i++) 35932001f49Smrg { 36032001f49Smrg angle = i * 2.0 * M_PI / teeth; 36132001f49Smrg glVertex3f (0.0, 0.0, width * fraction); 36232001f49Smrg glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction); 36332001f49Smrg glVertex3f (0.0, 0.0, width * fraction); 36432001f49Smrg glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction); 36532001f49Smrg } 36632001f49Smrg glEnd (); 36732001f49Smrg 36832001f49Smrg /* draw front sides of teeth */ 36932001f49Smrg glNormal3f (0.0, 0.0, 1.0 * n); 37032001f49Smrg glBegin (GL_QUADS); 37132001f49Smrg da = 2.0 * M_PI / teeth / 4.0; 37232001f49Smrg for (i = 0; i < teeth; i++) 37332001f49Smrg { 37432001f49Smrg angle = i * 2.0 * M_PI / teeth; 37532001f49Smrg glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction); 37632001f49Smrg glVertex3f (r2_front * cos (angle + da), r2_front * sin (angle + da), width * fraction); 37732001f49Smrg glVertex3f (r2_front * cos (angle + 2 * da), r2_front * sin (angle + 2 * da), width * fraction); 37832001f49Smrg glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction); 37932001f49Smrg } 38032001f49Smrg glEnd (); 38132001f49Smrg 38232001f49Smrg /* draw back face */ 38332001f49Smrg glNormal3f (0.0, 0.0, -1.0 * n); 38432001f49Smrg glBegin (GL_QUAD_STRIP); 38532001f49Smrg for (i = 0; i <= teeth; i++) 38632001f49Smrg { 38732001f49Smrg angle = i * 2.0 * M_PI / teeth; 38832001f49Smrg glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction); 38932001f49Smrg glVertex3f (0.0, 0.0, -width * fraction); 39032001f49Smrg glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction); 39132001f49Smrg glVertex3f (0.0, 0.0, -width * fraction); 39232001f49Smrg } 39332001f49Smrg glEnd (); 39432001f49Smrg 39532001f49Smrg /* draw back sides of teeth */ 39632001f49Smrg glNormal3f (0.0, 0.0, -1.0 * n); 39732001f49Smrg glBegin (GL_QUADS); 39832001f49Smrg da = 2.0 * M_PI / teeth / 4.0; 39932001f49Smrg for (i = 0; i < teeth; i++) 40032001f49Smrg { 40132001f49Smrg angle = i * 2.0 * M_PI / teeth; 40232001f49Smrg glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction); 40332001f49Smrg glVertex3f (r2_back * cos (angle + 2 * da), r2_back * sin (angle + 2 * da), -width * fraction); 40432001f49Smrg glVertex3f (r2_back * cos (angle + da), r2_back * sin (angle + da), -width * fraction); 40532001f49Smrg glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction); 40632001f49Smrg } 40732001f49Smrg glEnd (); 40832001f49Smrg 40932001f49Smrg 41032001f49Smrg /* draw outward faces of teeth. The visible faces are the backfaces, for testing purposes */ 41132001f49Smrg glBegin (GL_QUAD_STRIP); 41232001f49Smrg for (i = 0; i < teeth; i++) 41332001f49Smrg { 41432001f49Smrg angle = i * 2.0 * M_PI / teeth; 41532001f49Smrg 41632001f49Smrg glNormal3f (-cos (angle - 0.5*da), -sin (angle - 0.5*da), 0.0); 41732001f49Smrg glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction); 41832001f49Smrg glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction); 41932001f49Smrg u = (r2_front+r2_back)/2.0 * cos (angle + da) - r1 * cos (angle); 42032001f49Smrg v = (r2_front+r2_back)/2.0 * sin (angle + da) - r1 * sin (angle); 42132001f49Smrg len = sqrt (u * u + v * v); 42232001f49Smrg u /= len; 42332001f49Smrg v /= len; 42432001f49Smrg glNormal3f (-v, u, 0.0); 42532001f49Smrg glVertex3f (r2_back * cos (angle + da), r2_back * sin (angle + da), -width * fraction); 42632001f49Smrg glVertex3f (r2_front * cos (angle + da), r2_front * sin (angle + da), width * fraction); 42732001f49Smrg glNormal3f (-cos (angle + 1.5*da), -sin (angle + 1.5*da), 0.0); 42832001f49Smrg glVertex3f (r2_back * cos (angle + 2 * da), r2_back * sin (angle + 2 * da), -width * fraction); 42932001f49Smrg glVertex3f (r2_front * cos (angle + 2 * da), r2_front * sin (angle + 2 * da), width * fraction); 43032001f49Smrg u = r1 * cos (angle + 3 * da) - (r2_front+r2_back)/2.0 * cos (angle + 2 * da); 43132001f49Smrg v = r1 * sin (angle + 3 * da) - (r2_front+r2_back)/2.0 * sin (angle + 2 * da); 43232001f49Smrg len = sqrt (u * u + v * v); 43332001f49Smrg u /= len; 43432001f49Smrg v /= len; 43532001f49Smrg glNormal3f (-v, u, 0.0); 43632001f49Smrg glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction); 43732001f49Smrg glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction); 43832001f49Smrg glNormal3f (-cos (angle + 3.5*da), -sin (angle + 3.5*da), 0.0); 43932001f49Smrg } 44032001f49Smrg 44132001f49Smrg glNormal3f (-cos (-0.5*da), -sin (-0.5*da), 0.0); 44232001f49Smrg glVertex3f (r1 * cos (0), r1 * sin (0), -width * fraction); 44332001f49Smrg glVertex3f (r1 * cos (0), r1 * sin (0), width * fraction); 44432001f49Smrg glEnd (); 44532001f49Smrg} 44632001f49Smrg 44732001f49Smrg 44832001f49Smrgstatic void 44932001f49Smrgbelt (struct GEAR g1, struct GEAR g2) 45032001f49Smrg{ 45132001f49Smrg GLfloat D, alpha, phi, angle, incr, width; 45232001f49Smrg GLint indexes[3] = 45332001f49Smrg { 45432001f49Smrg 0, 0, 0 45532001f49Smrg }; 45632001f49Smrg 45732001f49Smrg GLfloat col[3] = 45832001f49Smrg { 45932001f49Smrg 0.0, 0.0, 0.0 46032001f49Smrg }; 46132001f49Smrg 46232001f49Smrg width = min (g1.width, g2.width); 46332001f49Smrg 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)); 46432001f49Smrg alpha = acos ((g2.position[0] - g1.position[0]) / D); 46532001f49Smrg phi = acos ((g1.radius - g2.radius) / D); 46632001f49Smrg glBegin (GL_QUADS); 46732001f49Smrg glColor3fv (col); 46832001f49Smrg glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes); 46932001f49Smrg incr = 1.2 * 360.0 / g1.teeth * M_PI / 180.00; 47032001f49Smrg for (angle = alpha + phi; angle <= 2 * M_PI - phi + alpha; angle += 360.0 / g1.teeth * M_PI / 180.00) 47132001f49Smrg { 47232001f49Smrg glNormal3f (cos (angle), sin (angle), 0.0); 47332001f49Smrg glVertex3f (g1.radius * cos (angle), g1.radius * sin (angle), width * 0.5); 47432001f49Smrg glVertex3f (g1.radius * cos (angle), g1.radius * sin (angle), -width * 0.5); 47532001f49Smrg glVertex3f (g1.radius * cos (angle + incr), g1.radius * sin (angle + incr), -width * 0.5); 47632001f49Smrg glVertex3f (g1.radius * cos (angle + incr), g1.radius * sin (angle + incr), width * 0.5); 47732001f49Smrg } 47832001f49Smrg glEnd (); 47932001f49Smrg glBegin (GL_QUADS); 48032001f49Smrg glColor3fv (col); 48132001f49Smrg glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes); 48232001f49Smrg incr = 1.2 * 360.0 / g2.teeth * M_PI / 180.00; 48332001f49Smrg for (angle = -phi + alpha; angle <= phi + alpha; angle += 360.0 / g1.teeth * M_PI / 180.0) 48432001f49Smrg { 48532001f49Smrg glNormal3f (cos (angle), sin (angle), 0.0); 48632001f49Smrg glVertex3f (g2.radius * cos (angle) + g2.position[0] - g1.position[0], g2.radius * sin (angle) + g2.position[1] - g1.position[1], width * 0.5); 48732001f49Smrg glVertex3f (g2.radius * cos (angle) + g2.position[0] - g1.position[0], g2.radius * sin (angle) + g2.position[1] - g1.position[1], width * -0.5); 48832001f49Smrg 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); 48932001f49Smrg 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); 49032001f49Smrg } 49132001f49Smrg glEnd (); 49232001f49Smrg 49332001f49Smrg glBegin (GL_QUADS); 49432001f49Smrg glColor3fv (col); 49532001f49Smrg glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes); 49632001f49Smrg glVertex3f (g1.radius * cos (alpha + phi), g1.radius * sin (alpha + phi), width * 0.5); 49732001f49Smrg glVertex3f (g1.radius * cos (alpha + phi), g1.radius * sin (alpha + phi), width * -0.5); 49832001f49Smrg 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); 49932001f49Smrg 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); 50032001f49Smrg glVertex3f (g1.radius * cos (alpha - phi), g1.radius * sin (alpha - phi), width * 0.5); 50132001f49Smrg glVertex3f (g1.radius * cos (alpha - phi), g1.radius * sin (alpha - phi), width * -0.5); 50232001f49Smrg 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); 50332001f49Smrg 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); 50432001f49Smrg glEnd (); 50532001f49Smrg} 50632001f49Smrg 50732001f49Smrg 50832001f49Smrgstatic int 50932001f49Smrgaxle_find (char axle_name[]) 51032001f49Smrg{ 51132001f49Smrg int i; 51232001f49Smrg 51332001f49Smrg for (i = 0; i < number_of_axles; i++) 51432001f49Smrg { 51532001f49Smrg if (!(strcmp (axle_name, a[i].name))) 51632001f49Smrg break; 51732001f49Smrg } 51832001f49Smrg return i; 51932001f49Smrg} 52032001f49Smrg 52132001f49Smrg 52232001f49Smrgstatic int 52332001f49Smrggear_find (char gear_name[]) 52432001f49Smrg{ 52532001f49Smrg int i; 52632001f49Smrg 52732001f49Smrg for (i = 0; i < number_of_gears; i++) 52832001f49Smrg { 52932001f49Smrg if (!(strcmp (gear_name, g[i].name))) 53032001f49Smrg break; 53132001f49Smrg } 53232001f49Smrg return i; 53332001f49Smrg} 53432001f49Smrg 53532001f49Smrg 53632001f49Smrgstatic void 53732001f49Smrgprocess (void) 53832001f49Smrg{ 53932001f49Smrg GLfloat x, y, z, D, dist; 54032001f49Smrg GLint axle_index, i, j, g1, g2, k; 54132001f49Smrg 54232001f49Smrg for (i = 0; i < number_of_gears; i++) 54332001f49Smrg { 54432001f49Smrg x = 0.0; 54532001f49Smrg y = 0.0; 54632001f49Smrg z = 0.0; 54732001f49Smrg axle_index = axle_find (g[i].axle_name); 54832001f49Smrg g[i].axis = a[axle_index].axis; 54932001f49Smrg g[i].motored = a[axle_index].motored; 55032001f49Smrg if (a[axle_index].motored) 55132001f49Smrg { 55232001f49Smrg g[i].direction = a[axle_index].direction; 55332001f49Smrg g[i].angular_velocity = a[axle_index].angular_velocity; 55432001f49Smrg } 55532001f49Smrg if (g[i].axis == 0) 55632001f49Smrg x = 1.0; 55732001f49Smrg else if (g[i].axis == 1) 55832001f49Smrg y = 1.0; 55932001f49Smrg else 56032001f49Smrg z = 1.0; 56132001f49Smrg 56232001f49Smrg g[i].position[0] = a[axle_index].position[0] + x * g[i].relative_position; 56332001f49Smrg g[i].position[1] = a[axle_index].position[1] + y * g[i].relative_position; 56432001f49Smrg g[i].position[2] = a[axle_index].position[2] + z * g[i].relative_position; 56532001f49Smrg } 56632001f49Smrg 56732001f49Smrg for (k = 0; k < number_of_axles; k++) 56832001f49Smrg { 56932001f49Smrg for (i = 0; i < number_of_gears - 1; i++) 57032001f49Smrg { 57132001f49Smrg for (j = 0; j < number_of_gears; j++) 57232001f49Smrg { 57332001f49Smrg 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)) 57432001f49Smrg { 57532001f49Smrg 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)); 57632001f49Smrg if (D < 1.1 * (g[i].radius - g[i].tooth_depth + g[j].radius - g[j].tooth_depth)) 57732001f49Smrg { 57832001f49Smrg printf ("Gear %s and %s are too close to each other.", g[i].name, g[j].name); 57932001f49Smrg exit (1); 58032001f49Smrg } 58132001f49Smrg 58232001f49Smrg if (g[i].axis == 0) 58332001f49Smrg { 58432001f49Smrg dist = g[i].position[0] - g[j].position[0]; 58532001f49Smrg } 58632001f49Smrg else if (g[i].axis == 1) 58732001f49Smrg { 58832001f49Smrg dist = g[i].position[1] - g[j].position[1]; 58932001f49Smrg } 59032001f49Smrg else 59132001f49Smrg dist = g[i].position[2] - g[j].position[2]; 59232001f49Smrg 59332001f49Smrg dist = fabs (dist); 59432001f49Smrg 59532001f49Smrg if (dist < (g[i].width / 2 + g[j].width / 2)) 59632001f49Smrg { 59732001f49Smrg if ((g[i].motored) && (!(g[j].motored)) && (D < 0.95 * (g[i].radius + g[j].radius))) 59832001f49Smrg { 59932001f49Smrg axle_index = axle_find (g[j].axle_name); 60032001f49Smrg 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)) 60132001f49Smrg { 60232001f49Smrg printf ("Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name); 60332001f49Smrg exit (1); 60432001f49Smrg } 60532001f49Smrg 60632001f49Smrg g[j].motored = (a[axle_index].motored = 1); 60732001f49Smrg g[j].direction = (a[axle_index].direction = -g[i].direction); 60832001f49Smrg a[axle_index].angular_velocity = g[i].angular_velocity * g[i].teeth / g[j].teeth; 60932001f49Smrg g[j].angular_velocity = (a[axle_index].angular_velocity *= g[i].radius / g[j].radius); 61032001f49Smrg } 61132001f49Smrg 61232001f49Smrg if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * (g[i].radius + g[j].radius))) 61332001f49Smrg { 61432001f49Smrg axle_index = axle_find (g[i].axle_name); 61532001f49Smrg 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)) 61632001f49Smrg { 61732001f49Smrg printf ("Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name); 61832001f49Smrg exit (1); 61932001f49Smrg } 62032001f49Smrg 62132001f49Smrg g[i].motored = (a[axle_index].motored = 1); 62232001f49Smrg g[i].direction = (a[axle_index].direction = -g[j].direction); 62332001f49Smrg a[axle_index].angular_velocity = g[j].angular_velocity * g[j].teeth / g[i].teeth; 62432001f49Smrg g[i].angular_velocity = (a[axle_index].angular_velocity *= g[j].radius / g[i].radius); 62532001f49Smrg 62632001f49Smrg } 62732001f49Smrg } 62832001f49Smrg } 62932001f49Smrg 63032001f49Smrg 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)) 63132001f49Smrg { 63232001f49Smrg 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)); 63332001f49Smrg if ((g[i].motored) && (!(g[j].motored)) && (D < 0.95 * sqrt (g[i].radius * g[i].radius + g[j].radius * g[j].radius))) 63432001f49Smrg { 63532001f49Smrg axle_index = axle_find (g[j].axle_name); 63632001f49Smrg 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)) 63732001f49Smrg { 63832001f49Smrg printf ("Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name); 63932001f49Smrg exit (1); 64032001f49Smrg } 64132001f49Smrg g[j].motored = (a[axle_index].motored = 1); 64232001f49Smrg g[j].direction = (a[axle_index].direction = -g[i].direction); 64332001f49Smrg a[axle_index].angular_velocity = g[i].angular_velocity * g[i].teeth / g[j].teeth; 64432001f49Smrg g[j].angular_velocity = (a[axle_index].angular_velocity *= g[i].radius / g[j].radius); 64532001f49Smrg } 64632001f49Smrg 64732001f49Smrg 64832001f49Smrg if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * sqrt (g[i].radius * g[i].radius + g[j].radius * g[j].radius))) 64932001f49Smrg { 65032001f49Smrg axle_index = axle_find (g[i].axle_name); 65132001f49Smrg 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)) 65232001f49Smrg { 65332001f49Smrg printf ("Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name); 65432001f49Smrg exit (1); 65532001f49Smrg } 65632001f49Smrg g[i].motored = (a[axle_index].motored = 1); 65732001f49Smrg g[i].direction = (a[axle_index].direction = -g[j].direction); 65832001f49Smrg a[axle_index].angular_velocity = g[j].angular_velocity * g[j].teeth / g[i].teeth; 65932001f49Smrg g[i].angular_velocity = (a[axle_index].angular_velocity *= g[j].radius / g[i].radius); 66032001f49Smrg } 66132001f49Smrg } 66232001f49Smrg } 66332001f49Smrg } 66432001f49Smrg 66532001f49Smrg for (i = 0; i < number_of_gears; i++) 66632001f49Smrg { 66732001f49Smrg axle_index = axle_find (g[i].axle_name); 66832001f49Smrg g[i].motored = a[axle_index].motored; 66932001f49Smrg if (a[axle_index].motored) 67032001f49Smrg { 67132001f49Smrg g[i].direction = a[axle_index].direction; 67232001f49Smrg g[i].angular_velocity = a[axle_index].angular_velocity; 67332001f49Smrg } 67432001f49Smrg } 67532001f49Smrg 67632001f49Smrg for (i = 0; i < number_of_belts; i++) 67732001f49Smrg { 67832001f49Smrg g1 = gear_find (b[i].gear1_name); 67932001f49Smrg g2 = gear_find (b[i].gear2_name); 68032001f49Smrg 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)); 68132001f49Smrg if (!((g[g1].axis == g[g2].axis) && (!strcmp (g[g1].type, g[g2].type)) && (!strcmp (g[g1].type, "NORMAL")))) 68232001f49Smrg { 68332001f49Smrg printf ("Belt %s invalid.", b[i].name); 68432001f49Smrg exit (1); 68532001f49Smrg } 68632001f49Smrg 68732001f49Smrg if ((g[g1].axis == g[g2].axis) && (!strcmp (g[g1].type, g[g2].type)) && (!strcmp (g[g1].type, "NORMAL"))) 68832001f49Smrg { 68932001f49Smrg /* 69032001f49Smrg if((g[g1].motored)&&(g[g2].motored)) 69132001f49Smrg if(g[g2].angular_velocity!=(g[g1].angular_velocity*g[g1].radius/g[g2].radius)) 69232001f49Smrg { 69332001f49Smrg printf("Error in belt linkage of gears %s and %s".,g[g1].name,g[g2].name); 69432001f49Smrg exit(1); 69532001f49Smrg } 69632001f49Smrg */ 69732001f49Smrg if (g[g1].axis == 0) 69832001f49Smrg { 69932001f49Smrg dist = g[g1].position[0] - g[g2].position[0]; 70032001f49Smrg } 70132001f49Smrg else if (g[i].axis == 1) 70232001f49Smrg { 70332001f49Smrg dist = g[g1].position[1] - g[g2].position[1]; 70432001f49Smrg } 70532001f49Smrg else 70632001f49Smrg dist = g[g1].position[2] - g[g2].position[2]; 70732001f49Smrg 70832001f49Smrg dist = fabs (dist); 70932001f49Smrg 71032001f49Smrg if (dist > (g[g1].width / 2 + g[g2].width / 2)) 71132001f49Smrg { 71232001f49Smrg printf ("Belt %s invalid.", b[i].name); 71332001f49Smrg exit (1); 71432001f49Smrg } 71532001f49Smrg 71632001f49Smrg if (dist < (g[g1].width / 2 + g[g2].width / 2)) 71732001f49Smrg { 71832001f49Smrg if (D < g[g1].radius + g[g2].radius) 71932001f49Smrg { 72032001f49Smrg printf ("Gears %s and %s too close to be linked with belts", g[g1].name, g[g2].name); 72132001f49Smrg exit (1); 72232001f49Smrg } 72332001f49Smrg 72432001f49Smrg if ((g[g1].motored) && (!(g[g2].motored))) 72532001f49Smrg { 72632001f49Smrg axle_index = axle_find (g[g2].axle_name); 72732001f49Smrg g[g2].motored = (a[axle_index].motored = 1); 72832001f49Smrg g[g2].direction = (a[axle_index].direction = g[g1].direction); 72932001f49Smrg g[g2].angular_velocity = (a[axle_index].angular_velocity = g[g1].angular_velocity * g[g1].radius / g[g2].radius); 73032001f49Smrg } 73132001f49Smrg 73232001f49Smrg if ((!(g[g1].motored)) && (g[g2].motored)) 73332001f49Smrg { 73432001f49Smrg axle_index = axle_find (g[g1].axle_name); 73532001f49Smrg g[g1].motored = (a[axle_index].motored = 1); 73632001f49Smrg g[g1].direction = (a[axle_index].direction = g[g2].direction); 73732001f49Smrg g[g1].angular_velocity = (a[axle_index].angular_velocity = g[g2].angular_velocity * g[g2].radius / g[g1].radius); 73832001f49Smrg } 73932001f49Smrg } 74032001f49Smrg } 74132001f49Smrg } 74232001f49Smrg 74332001f49Smrg for (i = 0; i < number_of_gears; i++) 74432001f49Smrg { 74532001f49Smrg axle_index = axle_find (g[i].axle_name); 74632001f49Smrg g[i].motored = a[axle_index].motored; 74732001f49Smrg if (a[axle_index].motored) 74832001f49Smrg { 74932001f49Smrg g[i].direction = a[axle_index].direction; 75032001f49Smrg g[i].angular_velocity = a[axle_index].angular_velocity; 75132001f49Smrg } 75232001f49Smrg } 75332001f49Smrg } 75432001f49Smrg} 75532001f49Smrg 75632001f49Smrg 75732001f49Smrg 75832001f49SmrgGLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 10.0; 75932001f49Smrg 76032001f49Smrg 76132001f49Smrgstatic void 76232001f49Smrgdraw (void) 76332001f49Smrg{ 76432001f49Smrg int i; 76532001f49Smrg GLfloat x, y, z; 76632001f49Smrg int index; 76732001f49Smrg 76832001f49Smrg glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 76932001f49Smrg 77032001f49Smrg glPushMatrix (); 77132001f49Smrg glRotatef (view_rotx, 1.0, 0.0, 0.0); 77232001f49Smrg glRotatef (view_roty, 0.0, 1.0, 0.0); 77332001f49Smrg glRotatef (view_rotz, 0.0, 0.0, 1.0); 77432001f49Smrg 77532001f49Smrg for (i = 0; i < number_of_gears; i++) 77632001f49Smrg { 77732001f49Smrg x = 0.0; 77832001f49Smrg y = 0.0; 77932001f49Smrg z = 0.0; 78032001f49Smrg glPushMatrix (); 78132001f49Smrg/*glTranslatef( -3.0, -2.0, 0.0 );*/ 78232001f49Smrg glTranslatef (g[i].position[0], g[i].position[1], g[i].position[2]); 78332001f49Smrg if (g[i].axis == 0) 78432001f49Smrg y = 1.0; 78532001f49Smrg else if (g[i].axis == 1) 78632001f49Smrg x = 1.0; 78732001f49Smrg else 78832001f49Smrg z = 1.0; 78932001f49Smrg 79032001f49Smrg if (z != 1.0) 79132001f49Smrg glRotatef (90.0, x, y, z); 79232001f49Smrg 79332001f49Smrg glRotatef (g[i].direction * g[i].angle, 0.0, 0.0, 1.0); 79432001f49Smrg glCallList (g[i].id); 79532001f49Smrg glPopMatrix (); 79632001f49Smrg } 79732001f49Smrg 79832001f49Smrg for (i = 0; i < number_of_axles; i++) 79932001f49Smrg { 80032001f49Smrg x = 0.0; 80132001f49Smrg y = 0.0; 80232001f49Smrg z = 0.0; 80332001f49Smrg glPushMatrix (); 80432001f49Smrg glTranslatef (a[i].position[0], a[i].position[1], a[i].position[2]); 80532001f49Smrg if (a[i].axis == 0) 80632001f49Smrg y = 1.0; 80732001f49Smrg else if (a[i].axis == 1) 80832001f49Smrg x = 1.0; 80932001f49Smrg else 81032001f49Smrg z = 1.0; 81132001f49Smrg 81232001f49Smrg if (z != 1.0) 81332001f49Smrg glRotatef (90.0, x, y, z); 81432001f49Smrg 81532001f49Smrg glCallList (a[i].id); 81632001f49Smrg glPopMatrix (); 81732001f49Smrg } 81832001f49Smrg 81932001f49Smrg for (i = 0; i < number_of_belts; i++) 82032001f49Smrg { 82132001f49Smrg x = 0.0; 82232001f49Smrg y = 0.0; 82332001f49Smrg z = 0.0; 82432001f49Smrg glPushMatrix (); 82532001f49Smrg index = gear_find (b[i].gear1_name); 82632001f49Smrg glTranslatef (g[index].position[0], g[index].position[1], g[index].position[2]); 82732001f49Smrg if (g[index].axis == 0) 82832001f49Smrg y = 1.0; 82932001f49Smrg else if (g[index].axis == 1) 83032001f49Smrg x = 1.0; 83132001f49Smrg else 83232001f49Smrg z = 1.0; 83332001f49Smrg 83432001f49Smrg if (z != 1.0) 83532001f49Smrg glRotatef (90.0, x, y, z); 83632001f49Smrg 83732001f49Smrg glCallList (b[i].id); 83832001f49Smrg glPopMatrix (); 83932001f49Smrg } 84032001f49Smrg 84132001f49Smrg glPopMatrix (); 84232001f49Smrg glutSwapBuffers (); 84332001f49Smrg 84432001f49Smrg { 84532001f49Smrg GLint t = glutGet(GLUT_ELAPSED_TIME); 84632001f49Smrg Frames++; 84732001f49Smrg if (t - T0 >= 5000) { 84832001f49Smrg GLfloat seconds = (t - T0) / 1000.0; 84932001f49Smrg GLfloat fps = Frames / seconds; 85032001f49Smrg printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps); 85132001f49Smrg fflush(stdout); 85232001f49Smrg T0 = t; 85332001f49Smrg Frames = 0; 85432001f49Smrg } 85532001f49Smrg } 85632001f49Smrg} 85732001f49Smrg 85832001f49Smrg 85932001f49Smrgstatic void 86032001f49Smrgidle (void) 86132001f49Smrg{ 86232001f49Smrg int i; 86332001f49Smrg static double t0 = -1.; 86432001f49Smrg double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0; 86532001f49Smrg if (t0 < 0.0) 86632001f49Smrg t0 = t; 86732001f49Smrg dt = t - t0; 86832001f49Smrg t0 = t; 86932001f49Smrg for (i = 0; i < number_of_gears; i++) 87032001f49Smrg g[i].angle += g[i].angular_velocity * dt; 87132001f49Smrg glutPostRedisplay(); 87232001f49Smrg} 87332001f49Smrg 87432001f49Smrg 87532001f49Smrg 87632001f49Smrg 87732001f49Smrg/* change view angle, exit upon ESC */ 87832001f49Smrgstatic void 87932001f49Smrgkey (unsigned char k, int x, int y) 88032001f49Smrg{ 88132001f49Smrg switch (k) 88232001f49Smrg { 88332001f49Smrg case 'x': 88432001f49Smrg view_rotx += 5.0; 88532001f49Smrg break; 88632001f49Smrg case 'X': 88732001f49Smrg view_rotx -= 5.0; 88832001f49Smrg break; 88932001f49Smrg case 'y': 89032001f49Smrg view_roty += 5.0; 89132001f49Smrg break; 89232001f49Smrg case 'Y': 89332001f49Smrg view_roty -= 5.0; 89432001f49Smrg break; 89532001f49Smrg case 'z': 89632001f49Smrg view_rotz += 5.0; 89732001f49Smrg break; 89832001f49Smrg case 'Z': 89932001f49Smrg view_rotz -= 5.0; 90032001f49Smrg break; 90132001f49Smrg case 0x1B: 90232001f49Smrg exit(0); 90332001f49Smrg } 90432001f49Smrg} 90532001f49Smrg 90632001f49Smrg 90732001f49Smrg 90832001f49Smrg 90932001f49Smrg/* new window size or exposure */ 91032001f49Smrgstatic void 91132001f49Smrgreshape (int width, int height) 91232001f49Smrg{ 91332001f49Smrg glViewport (0, 0, (GLint) width, (GLint) height); 91432001f49Smrg glMatrixMode (GL_PROJECTION); 91532001f49Smrg glLoadIdentity (); 91632001f49Smrg if (width > height) 91732001f49Smrg { 91832001f49Smrg GLfloat w = (GLfloat) width / (GLfloat) height; 91932001f49Smrg glFrustum (-w, w, -1.0, 1.0, 5.0, 60.0); 92032001f49Smrg } 92132001f49Smrg else 92232001f49Smrg { 92332001f49Smrg GLfloat h = (GLfloat) height / (GLfloat) width; 92432001f49Smrg glFrustum (-1.0, 1.0, -h, h, 5.0, 60.0); 92532001f49Smrg } 92632001f49Smrg 92732001f49Smrg glMatrixMode (GL_MODELVIEW); 92832001f49Smrg glLoadIdentity (); 92932001f49Smrg glTranslatef (0.0, 0.0, -40.0); 93032001f49Smrg glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 93132001f49Smrg} 93232001f49Smrg 93332001f49Smrg 93432001f49Smrg 93532001f49Smrgstatic void 93632001f49Smrginit (void) 93732001f49Smrg{ 93832001f49Smrg GLfloat matShine = 20.00F; 93932001f49Smrg const GLfloat light0Pos[4] = 94032001f49Smrg { 94132001f49Smrg 0.70F, 0.70F, 1.25F, 0.50F 94232001f49Smrg }; 94332001f49Smrg int i; 94432001f49Smrg 94532001f49Smrg glShadeModel(GL_FLAT); 94632001f49Smrg glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1); 94732001f49Smrg 94832001f49Smrg glClearColor (background[0], background[1], background[2], 1.0F); 94932001f49Smrg glClearIndex ((GLfloat) 0.0); 95032001f49Smrg 95132001f49Smrg glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, matShine); 95232001f49Smrg glLightfv (GL_LIGHT0, GL_POSITION, light0Pos); 95332001f49Smrg glEnable (GL_LIGHT0); 95432001f49Smrg 95532001f49Smrg glEnable (GL_LIGHTING); 95632001f49Smrg glEnable (GL_DEPTH_TEST); 95732001f49Smrg for (i = 0; i < number_of_gears; i++) 95832001f49Smrg g[i].angle = 0.0; 95932001f49Smrg 96032001f49Smrg for (i = 0; i < number_of_gears; i++) 96132001f49Smrg { 96232001f49Smrg g[i].id = glGenLists (1); 96332001f49Smrg glNewList (g[i].id, GL_COMPILE); 96432001f49Smrg glColor3fv (g[i].color); 96532001f49Smrg glMaterialfv (GL_FRONT, GL_SPECULAR, g[i].color); 96632001f49Smrg gear (i, g[i].type, g[i].radius, g[i].width, g[i].teeth, g[i].tooth_depth); 96732001f49Smrg glEndList (); 96832001f49Smrg } 96932001f49Smrg 97032001f49Smrg for (i = 0; i < number_of_axles; i++) 97132001f49Smrg { 97232001f49Smrg a[i].id = glGenLists (1); 97332001f49Smrg glNewList (a[i].id, GL_COMPILE); 97432001f49Smrg glColor3fv (a[i].color); 97532001f49Smrg glMaterialfv (GL_FRONT, GL_SPECULAR, a[i].color); 97632001f49Smrg axle (i, a[i].radius, a[i].length); 97732001f49Smrg glEndList (); 97832001f49Smrg } 97932001f49Smrg 98032001f49Smrg for (i = 0; i < number_of_belts; i++) 98132001f49Smrg { 98232001f49Smrg b[i].id = glGenLists (1); 98332001f49Smrg glNewList (b[i].id, GL_COMPILE); 98432001f49Smrg belt (g[gear_find (b[i].gear1_name)], g[gear_find (b[i].gear2_name)]); 98532001f49Smrg glEndList (); 98632001f49Smrg } 98732001f49Smrg 98832001f49Smrg glEnable (GL_COLOR_MATERIAL); 98932001f49Smrg} 99032001f49Smrg 99132001f49Smrg 99232001f49Smrg 99332001f49Smrgint 99432001f49Smrgmain (int argc, char *argv[]) 99532001f49Smrg{ 99632001f49Smrg char *file; 99732001f49Smrg 99832001f49Smrg glutInitWindowSize(640,480); 99932001f49Smrg glutInit(&argc, argv); 100032001f49Smrg glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE ); 100132001f49Smrg 100232001f49Smrg if (glutCreateWindow ("Gear Train Simulation") == GL_FALSE) 100332001f49Smrg exit (1); 100432001f49Smrg 100532001f49Smrg if (argc < 2) 100632001f49Smrg file = DEMOS_DATA_DIR "geartrain.dat"; 100732001f49Smrg else 100832001f49Smrg file = argv[1]; 100932001f49Smrg 101032001f49Smrg getdata (file); 101132001f49Smrg process (); 101232001f49Smrg init (); 101332001f49Smrg 101432001f49Smrg glutDisplayFunc (draw); 101532001f49Smrg glutReshapeFunc (reshape); 101632001f49Smrg glutKeyboardFunc (key); 101732001f49Smrg glutIdleFunc (idle); 101832001f49Smrg glutMainLoop (); 101932001f49Smrg return 0; 102032001f49Smrg} 1021