Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

geartrain.c 30KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066
  1. /* $Id: geartrain.c,v 1.7 2000/11/30 01:44:24 gareth Exp $ */
  2. /*
  3. * GearTrain Simulator * Version: 1.00
  4. *
  5. * 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.
  25. */
  26. #include <math.h>
  27. #include <stdlib.h>
  28. #include <GL/glut.h>
  29. #include <string.h>
  30. #include <stdio.h>
  31. #define min(x, y) ( x < y ? x : y )
  32. #ifndef M_PI
  33. #define M_PI 3.14159265
  34. #endif /* */
  35. typedef GLfloat TDA[4];
  36. TDA background;
  37. struct AXLE
  38. {
  39. char name[20];
  40. GLint id;
  41. GLfloat radius;
  42. GLint axis;
  43. TDA color;
  44. TDA position;
  45. GLfloat length;
  46. GLint motored;
  47. GLfloat angular_velocity;
  48. GLint direction;
  49. };
  50. struct GEAR
  51. {
  52. char name[20];
  53. char type[7];
  54. GLint face;
  55. GLint id;
  56. GLfloat radius;
  57. GLfloat width;
  58. GLint teeth;
  59. GLfloat tooth_depth;
  60. GLfloat angle;
  61. GLfloat angular_velocity;
  62. TDA color;
  63. GLint relative_position;
  64. TDA position;
  65. char axle_name[20];
  66. GLint axis;
  67. GLint direction;
  68. GLint motored;
  69. };
  70. struct BELT
  71. {
  72. char name[20];
  73. GLint id;
  74. char gear1_name[20];
  75. char gear2_name[20];
  76. };
  77. FILE * mainfile;
  78. struct GEAR g[10];
  79. struct AXLE a[10];
  80. struct BELT b[10];
  81. int number_of_gears;
  82. int number_of_axles;
  83. int number_of_belts;
  84. char Buf1[256], Buf2[256], Buf3[256], Buf4[256], Buf5[256];
  85. static GLint T0 = 0;
  86. static GLint Frames = 0;
  87. static void
  88. strset (char buf[], char ch)
  89. {
  90. int i;
  91. for (i = 0; i < strlen (buf); i++)
  92. buf[i] = ch;
  93. }
  94. static void
  95. Clear_Buffers ()
  96. {
  97. strset (Buf1, 0);
  98. strset (Buf2, 0);
  99. strset (Buf3, 0);
  100. strset (Buf4, 0);
  101. strset (Buf5, 0);
  102. }
  103. static void
  104. LoadTriplet (TDA A)
  105. {
  106. Clear_Buffers ();
  107. fscanf (mainfile, "%s %s %s %s", Buf1, Buf2, Buf3, Buf4);
  108. A[0] = atof (Buf2);
  109. A[1] = atof (Buf3);
  110. A[2] = atof (Buf4);
  111. }
  112. static void
  113. LoadReal (float *a)
  114. {
  115. Clear_Buffers ();
  116. fscanf (mainfile, "%s %s", Buf1, Buf2);
  117. *a = atof (Buf2);
  118. }
  119. static void
  120. LoadInteger (int *a)
  121. {
  122. Clear_Buffers ();
  123. fscanf (mainfile, "%s %s", Buf1, Buf2);
  124. *a = atoi (Buf2);
  125. }
  126. static void
  127. LoadText (char *a)
  128. {
  129. Clear_Buffers ();
  130. fscanf (mainfile, "%s %s", Buf1, Buf2);
  131. strcpy (a, Buf2);
  132. }
  133. static void
  134. getdata (char filename[])
  135. {
  136. int gear_count = 0, axle_count = 0, belt_count = 0, i;
  137. mainfile = fopen (filename, "r");
  138. if (!mainfile) {
  139. printf("Error: couldn't open %s\n", filename);
  140. exit(-1);
  141. }
  142. do
  143. {
  144. Clear_Buffers ();
  145. fscanf (mainfile, "%s", Buf1);
  146. if (ferror (mainfile))
  147. {
  148. printf ("\nError opening file !\n");
  149. exit (1);
  150. }
  151. if (!(strcmp (Buf1, "BACKGROUND")))
  152. LoadTriplet (background);
  153. if (!(strcmp (Buf1, "ANAME")))
  154. {
  155. LoadText (a[axle_count].name);
  156. axle_count++;
  157. }
  158. if (!(strcmp (Buf1, "ARADIUS")))
  159. LoadReal (&a[axle_count - 1].radius);
  160. if (!(strcmp (Buf1, "AAXIS")))
  161. LoadInteger (&a[axle_count - 1].axis);
  162. if (!(strcmp (Buf1, "ACOLOR")))
  163. LoadTriplet (a[axle_count - 1].color);
  164. if (!(strcmp (Buf1, "APOSITION")))
  165. LoadTriplet (a[axle_count - 1].position);
  166. if (!(strcmp (Buf1, "ALENGTH")))
  167. LoadReal (&a[axle_count - 1].length);
  168. if (!(strcmp (Buf1, "AMOTORED")))
  169. LoadInteger (&a[axle_count - 1].motored);
  170. if (!(strcmp (Buf1, "AANGULARVELOCITY")))
  171. LoadReal (&a[axle_count - 1].angular_velocity);
  172. if (!(strcmp (Buf1, "ADIRECTION")))
  173. LoadInteger (&a[axle_count - 1].direction);
  174. if (!(strcmp (Buf1, "GNAME")))
  175. {
  176. LoadText (g[gear_count].name);
  177. gear_count++;
  178. }
  179. if (!(strcmp (Buf1, "GTYPE")))
  180. LoadText (g[gear_count - 1].type);
  181. if (!(strcmp (Buf1, "GFACE")))
  182. LoadInteger (&g[gear_count - 1].face);
  183. if (!(strcmp (Buf1, "GRADIUS")))
  184. LoadReal (&g[gear_count - 1].radius);
  185. if (!(strcmp (Buf1, "GWIDTH")))
  186. LoadReal (&g[gear_count - 1].width);
  187. if (!(strcmp (Buf1, "GTEETH")))
  188. LoadInteger (&g[gear_count - 1].teeth);
  189. if (!(strcmp (Buf1, "GTOOTHDEPTH")))
  190. LoadReal (&g[gear_count - 1].tooth_depth);
  191. if (!(strcmp (Buf1, "GCOLOR")))
  192. LoadTriplet (g[gear_count - 1].color);
  193. if (!(strcmp (Buf1, "GAXLE")))
  194. LoadText (g[gear_count - 1].axle_name);
  195. if (!(strcmp (Buf1, "GPOSITION")))
  196. LoadInteger (&g[gear_count - 1].relative_position);
  197. if (!(strcmp (Buf1, "BELTNAME")))
  198. {
  199. LoadText (b[belt_count].name);
  200. belt_count++;
  201. }
  202. if (!(strcmp (Buf1, "GEAR1NAME")))
  203. LoadText (b[belt_count - 1].gear1_name);
  204. if (!(strcmp (Buf1, "GEAR2NAME")))
  205. LoadText (b[belt_count - 1].gear2_name);
  206. }
  207. while (Buf1[0] != 0);
  208. for (i = 0; i < number_of_gears; i++)
  209. {
  210. g[i].axis = -1;
  211. g[i].direction = 0;
  212. g[i].angular_velocity = 0.0;
  213. }
  214. number_of_gears = gear_count;
  215. number_of_axles = axle_count;
  216. number_of_belts = belt_count;
  217. fclose (mainfile);
  218. }
  219. static void
  220. axle (GLint j, GLfloat radius, GLfloat length)
  221. {
  222. GLfloat angle, rad, incr = 10.0 * M_PI / 180.0;
  223. /* draw main cylinder */
  224. glBegin (GL_QUADS);
  225. for (angle = 0.0; angle < 360.0; angle += 5.0)
  226. {
  227. rad = angle * M_PI / 180.0;
  228. glNormal3f (cos (rad), sin (rad), 0.0);
  229. glVertex3f (radius * cos (rad), radius * sin (rad), length / 2);
  230. glVertex3f (radius * cos (rad), radius * sin (rad), -length / 2);
  231. glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), -length / 2);
  232. glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), length / 2);
  233. }
  234. glEnd ();
  235. /* draw front face */
  236. glNormal3f (0.0, 0.0, 1.0);
  237. glBegin (GL_TRIANGLES);
  238. for (angle = 0.0; angle < 360.0; angle += 5.0)
  239. {
  240. rad = angle * M_PI / 180.0;
  241. glVertex3f (0.0, 0.0, length / 2);
  242. glVertex3f (radius * cos (rad), radius * sin (rad), length / 2);
  243. glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), length / 2);
  244. glVertex3f (0.0, 0.0, length / 2);
  245. }
  246. glEnd ();
  247. /* draw back face */
  248. glNormal3f (0.0, 0.0, -1.0);
  249. glBegin (GL_TRIANGLES);
  250. for (angle = 0.0; angle <= 360.0; angle += 5.0)
  251. {
  252. rad = angle * M_PI / 180.0;
  253. glVertex3f (0.0, 0.0, -length / 2);
  254. glVertex3f (radius * cos (rad), radius * sin (rad), -length / 2);
  255. glVertex3f (radius * cos (rad + incr), radius * sin (rad + incr), -length / 2);
  256. glVertex3f (0.0, 0.0, -length / 2);
  257. }
  258. glEnd ();
  259. }
  260. static void
  261. gear (GLint j, char type[], GLfloat radius, GLfloat width,
  262. GLint teeth, GLfloat tooth_depth)
  263. {
  264. GLint i;
  265. GLfloat r1, r2;
  266. GLfloat angle, da;
  267. GLfloat u, v, len, fraction = 0.5;
  268. GLfloat n = 1.0;
  269. r1 = radius - tooth_depth;
  270. r2 = radius;
  271. da = 2.0 * M_PI / teeth / 4.0;
  272. if (!g[j].face)
  273. {
  274. fraction = -0.5;
  275. n = -1.0;
  276. }
  277. if (!(strcmp (type, "NORMAL")))
  278. {
  279. fraction = 0.5;
  280. n = 1.0;
  281. }
  282. /* draw front face */
  283. if (!(strcmp (type, "NORMAL")))
  284. {
  285. glNormal3f (0.0, 0.0, 1.0 * n);
  286. glBegin (GL_QUAD_STRIP);
  287. for (i = 0; i <= teeth; i++)
  288. {
  289. angle = i * 2.0 * M_PI / teeth;
  290. glVertex3f (0.0, 0.0, width * fraction);
  291. glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
  292. glVertex3f (0.0, 0.0, width * fraction);
  293. glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
  294. }
  295. glEnd ();
  296. }
  297. else
  298. {
  299. glNormal3f (0.0, 0.0, 1.0 * n);
  300. glBegin (GL_QUAD_STRIP);
  301. for (i = 0; i <= teeth; i++)
  302. {
  303. angle = i * 2.0 * M_PI / teeth;
  304. glVertex3f (0.0, 0.0, width * fraction);
  305. glVertex3f ((r2 - width) * cos (angle), (r2 - width) * sin (angle), width * fraction);
  306. glVertex3f (0.0, 0.0, width * fraction);
  307. glVertex3f ((r2 - width) * cos (angle + 3 * da), (r2 - width) * sin (angle + 3 * da), width * fraction);
  308. }
  309. glEnd ();
  310. }
  311. /* draw front sides of teeth */
  312. if (!(strcmp (type, "NORMAL")))
  313. {
  314. glNormal3f (0.0, 0.0, 1.0 * n);
  315. glBegin (GL_QUADS);
  316. da = 2.0 * M_PI / teeth / 4.0;
  317. for (i = 0; i < teeth; i++)
  318. {
  319. angle = i * 2.0 * M_PI / teeth;
  320. glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
  321. glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), width * fraction);
  322. glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), width * fraction);
  323. glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
  324. }
  325. glEnd ();
  326. }
  327. glNormal3f (0.0, 0.0, -1.0 * n);
  328. /* draw back face */
  329. glBegin (GL_QUAD_STRIP);
  330. for (i = 0; i <= teeth; i++)
  331. {
  332. angle = i * 2.0 * M_PI / teeth;
  333. glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
  334. glVertex3f (0.0, 0.0, -width * fraction);
  335. glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
  336. glVertex3f (0.0, 0.0, -width * fraction);
  337. }
  338. glEnd ();
  339. /* draw back sides of teeth */
  340. glNormal3f (0.0, 0.0, -1.0 * n);
  341. glBegin (GL_QUADS);
  342. da = 2.0 * M_PI / teeth / 4.0;
  343. for (i = 0; i < teeth; i++)
  344. {
  345. angle = i * 2.0 * M_PI / teeth;
  346. glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
  347. glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
  348. glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
  349. glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
  350. }
  351. glEnd ();
  352. /* draw outward faces of teeth */
  353. if (!(strcmp (type, "NORMAL")))
  354. {
  355. glBegin (GL_QUAD_STRIP);
  356. for (i = 0; i < teeth; i++)
  357. {
  358. angle = i * 2.0 * M_PI / teeth;
  359. glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
  360. glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
  361. u = r2 * cos (angle + da) - r1 * cos (angle);
  362. v = r2 * sin (angle + da) - r1 * sin (angle);
  363. len = sqrt (u * u + v * v);
  364. u /= len;
  365. v /= len;
  366. glNormal3f (v, -u, 0.0);
  367. glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), width * fraction);
  368. glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
  369. glNormal3f (cos (angle), sin (angle), 0.0);
  370. glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), width * fraction);
  371. glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
  372. u = r1 * cos (angle + 3 * da) - r2 * cos (angle + 2 * da);
  373. v = r1 * sin (angle + 3 * da) - r2 * sin (angle + 2 * da);
  374. glNormal3f (v, -u, 0.0);
  375. glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
  376. glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
  377. glNormal3f (cos (angle), sin (angle), 0.0);
  378. }
  379. }
  380. else
  381. {
  382. glBegin (GL_QUAD_STRIP);
  383. for (i = 0; i < teeth; i++)
  384. {
  385. angle = i * 2.0 * M_PI / teeth;
  386. glVertex3f (r1 * cos (angle), r1 * sin (angle), width * fraction);
  387. glVertex3f (r1 * cos (angle), r1 * sin (angle), -width * fraction);
  388. u = r2 * cos (angle + da) - r1 * cos (angle);
  389. v = r2 * sin (angle + da) - r1 * sin (angle);
  390. len = sqrt (u * u + v * v);
  391. u /= len;
  392. v /= len;
  393. glNormal3f (v, -u, 0.0);
  394. glVertex3f ((r2 - width) * cos (angle + da), (r2 - width) * sin (angle + da), width * fraction);
  395. glVertex3f (r2 * cos (angle + da), r2 * sin (angle + da), -width * fraction);
  396. glNormal3f (cos (angle), sin (angle), n);
  397. glVertex3f ((r2 - width) * cos (angle + 2 * da), (r2 - width) * sin (angle + 2 * da), width * fraction);
  398. glVertex3f (r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da), -width * fraction);
  399. u = r1 * cos (angle + 3 * da) - r2 * cos (angle + 2 * da);
  400. v = r1 * sin (angle + 3 * da) - r2 * sin (angle + 2 * da);
  401. glNormal3f (v, -u, 0.0);
  402. glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), width * fraction);
  403. glVertex3f (r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da), -width * fraction);
  404. glNormal3f (cos (angle), sin (angle), n);
  405. }
  406. }
  407. glVertex3f (r1 * cos (0), r1 * sin (0), width * fraction);
  408. glVertex3f (r1 * cos (0), r1 * sin (0), -width * fraction);
  409. glEnd ();
  410. }
  411. static void
  412. belt (struct GEAR g1, struct GEAR g2)
  413. {
  414. GLfloat D, alpha, phi, angle, incr, width;
  415. GLint indexes[3] =
  416. {
  417. 0, 0, 0
  418. };
  419. GLfloat col[3] =
  420. {
  421. 0.0, 0.0, 0.0
  422. };
  423. width = min (g1.width, g2.width);
  424. 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));
  425. alpha = acos ((g2.position[0] - g1.position[0]) / D);
  426. phi = acos ((g1.radius - g2.radius) / D);
  427. glBegin (GL_QUADS);
  428. glColor3fv (col);
  429. glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
  430. incr = 1.2 * 360.0 / g1.teeth * M_PI / 180.00;
  431. for (angle = alpha + phi; angle <= 2 * M_PI - phi + alpha; angle += 360.0 / g1.teeth * M_PI / 180.00)
  432. {
  433. glNormal3f (cos (angle), sin (angle), 0.0);
  434. glVertex3f (g1.radius * cos (angle), g1.radius * sin (angle), width * 0.5);
  435. glVertex3f (g1.radius * cos (angle), g1.radius * sin (angle), -width * 0.5);
  436. glVertex3f (g1.radius * cos (angle + incr), g1.radius * sin (angle + incr), -width * 0.5);
  437. glVertex3f (g1.radius * cos (angle + incr), g1.radius * sin (angle + incr), width * 0.5);
  438. }
  439. glEnd ();
  440. glBegin (GL_QUADS);
  441. glColor3fv (col);
  442. glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
  443. incr = 1.2 * 360.0 / g2.teeth * M_PI / 180.00;
  444. for (angle = -phi + alpha; angle <= phi + alpha; angle += 360.0 / g1.teeth * M_PI / 180.0)
  445. {
  446. glNormal3f (cos (angle), sin (angle), 0.0);
  447. glVertex3f (g2.radius * cos (angle) + g2.position[0] - g1.position[0], g2.radius * sin (angle) + g2.position[1] - g1.position[1], width * 0.5);
  448. glVertex3f (g2.radius * cos (angle) + g2.position[0] - g1.position[0], g2.radius * sin (angle) + g2.position[1] - g1.position[1], width * -0.5);
  449. 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);
  450. 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);
  451. }
  452. glEnd ();
  453. glBegin (GL_QUADS);
  454. glColor3fv (col);
  455. glMaterialiv (GL_FRONT, GL_COLOR_INDEXES, indexes);
  456. glVertex3f (g1.radius * cos (alpha + phi), g1.radius * sin (alpha + phi), width * 0.5);
  457. glVertex3f (g1.radius * cos (alpha + phi), g1.radius * sin (alpha + phi), width * -0.5);
  458. 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);
  459. 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);
  460. glVertex3f (g1.radius * cos (alpha - phi), g1.radius * sin (alpha - phi), width * 0.5);
  461. glVertex3f (g1.radius * cos (alpha - phi), g1.radius * sin (alpha - phi), width * -0.5);
  462. 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);
  463. 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);
  464. glEnd ();
  465. }
  466. static int
  467. axle_find (char axle_name[])
  468. {
  469. int i;
  470. for (i = 0; i < number_of_axles; i++)
  471. {
  472. if (!(strcmp (axle_name, a[i].name)))
  473. break;
  474. }
  475. return i;
  476. }
  477. static int
  478. gear_find (char gear_name[])
  479. {
  480. int i;
  481. for (i = 0; i < number_of_gears; i++)
  482. {
  483. if (!(strcmp (gear_name, g[i].name)))
  484. break;
  485. }
  486. return i;
  487. }
  488. static void
  489. process ()
  490. {
  491. GLfloat x, y, z, D, dist;
  492. GLint axle_index, i, j, g1, g2, k;
  493. char error[80];
  494. for (i = 0; i < number_of_gears; i++)
  495. {
  496. x = 0.0;
  497. y = 0.0;
  498. z = 0.0;
  499. axle_index = axle_find (g[i].axle_name);
  500. g[i].axis = a[axle_index].axis;
  501. g[i].motored = a[axle_index].motored;
  502. if (a[axle_index].motored)
  503. {
  504. g[i].direction = a[axle_index].direction;
  505. g[i].angular_velocity = a[axle_index].angular_velocity;
  506. }
  507. if (g[i].axis == 0)
  508. x = 1.0;
  509. else if (g[i].axis == 1)
  510. y = 1.0;
  511. else
  512. z = 1.0;
  513. g[i].position[0] = a[axle_index].position[0] + x * g[i].relative_position;
  514. g[i].position[1] = a[axle_index].position[1] + y * g[i].relative_position;
  515. g[i].position[2] = a[axle_index].position[2] + z * g[i].relative_position;
  516. }
  517. for (k = 0; k < number_of_axles; k++)
  518. {
  519. for (i = 0; i < number_of_gears - 1; i++)
  520. {
  521. for (j = 0; j < number_of_gears; j++)
  522. {
  523. 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))
  524. {
  525. 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));
  526. if (D < 1.1 * (g[i].radius - g[i].tooth_depth + g[j].radius - g[j].tooth_depth))
  527. {
  528. printf (error, "Gear %s and %s are too close to each other.", g[i].name, g[j].name);
  529. /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
  530. exit (1);
  531. }
  532. if (g[i].axis == 0)
  533. {
  534. dist = g[i].position[0] - g[j].position[0];
  535. }
  536. else if (g[i].axis == 1)
  537. {
  538. dist = g[i].position[1] - g[j].position[1];
  539. }
  540. else
  541. dist = g[i].position[2] - g[j].position[2];
  542. dist = fabs (dist);
  543. if (dist < (g[i].width / 2 + g[j].width / 2))
  544. {
  545. if ((g[i].motored) && (!(g[j].motored)) && (D < 0.95 * (g[i].radius + g[j].radius)))
  546. {
  547. axle_index = axle_find (g[j].axle_name);
  548. 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))
  549. {
  550. printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
  551. /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
  552. exit (1);
  553. }
  554. g[j].motored = (a[axle_index].motored = 1);
  555. g[j].direction = (a[axle_index].direction = -g[i].direction);
  556. a[axle_index].angular_velocity = g[i].angular_velocity * g[i].teeth / g[j].teeth;
  557. g[j].angular_velocity = (a[axle_index].angular_velocity *= g[i].radius / g[j].radius);
  558. }
  559. if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * (g[i].radius + g[j].radius)))
  560. {
  561. axle_index = axle_find (g[i].axle_name);
  562. 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))
  563. {
  564. printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
  565. /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
  566. exit (1);
  567. }
  568. g[i].motored = (a[axle_index].motored = 1);
  569. g[i].direction = (a[axle_index].direction = -g[j].direction);
  570. a[axle_index].angular_velocity = g[j].angular_velocity * g[j].teeth / g[i].teeth;
  571. g[i].angular_velocity = (a[axle_index].angular_velocity *= g[j].radius / g[i].radius);
  572. }
  573. }
  574. }
  575. 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))
  576. {
  577. 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));
  578. if ((g[i].motored) && (!(g[j].motored)) && (D < 0.95 * sqrt (g[i].radius * g[i].radius + g[j].radius * g[j].radius)))
  579. {
  580. axle_index = axle_find (g[j].axle_name);
  581. 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))
  582. {
  583. printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
  584. /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
  585. exit (1);
  586. }
  587. g[j].motored = (a[axle_index].motored = 1);
  588. g[j].direction = (a[axle_index].direction = -g[i].direction);
  589. a[axle_index].angular_velocity = g[i].angular_velocity * g[i].teeth / g[j].teeth;
  590. g[j].angular_velocity = (a[axle_index].angular_velocity *= g[i].radius / g[j].radius);
  591. }
  592. if ((!(g[i].motored)) && (g[j].motored) && (D < 0.95 * sqrt (g[i].radius * g[i].radius + g[j].radius * g[j].radius)))
  593. {
  594. axle_index = axle_find (g[i].axle_name);
  595. 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))
  596. {
  597. printf (error, "Error in tooth linkage of gears %s and %s.", g[i].name, g[j].name);
  598. /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
  599. exit (1);
  600. }
  601. g[i].motored = (a[axle_index].motored = 1);
  602. g[i].direction = (a[axle_index].direction = -g[j].direction);
  603. a[axle_index].angular_velocity = g[j].angular_velocity * g[j].teeth / g[i].teeth;
  604. g[i].angular_velocity = (a[axle_index].angular_velocity *= g[j].radius / g[i].radius);
  605. }
  606. }
  607. }
  608. }
  609. for (i = 0; i < number_of_gears; i++)
  610. {
  611. axle_index = axle_find (g[i].axle_name);
  612. g[i].motored = a[axle_index].motored;
  613. if (a[axle_index].motored)
  614. {
  615. g[i].direction = a[axle_index].direction;
  616. g[i].angular_velocity = a[axle_index].angular_velocity;
  617. }
  618. }
  619. for (i = 0; i < number_of_belts; i++)
  620. {
  621. g1 = gear_find (b[i].gear1_name);
  622. g2 = gear_find (b[i].gear2_name);
  623. 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));
  624. if (!((g[g1].axis == g[g2].axis) && (!strcmp (g[g1].type, g[g2].type)) && (!strcmp (g[g1].type, "NORMAL"))))
  625. {
  626. printf (error, "Belt %s invalid.", b[i].name);
  627. /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
  628. exit (1);
  629. }
  630. if ((g[g1].axis == g[g2].axis) && (!strcmp (g[g1].type, g[g2].type)) && (!strcmp (g[g1].type, "NORMAL")))
  631. {
  632. /*
  633. if((g[g1].motored)&&(g[g2].motored))
  634. if(g[g2].angular_velocity!=(g[g1].angular_velocity*g[g1].radius/g[g2].radius))
  635. {
  636. printf(error,"Error in belt linkage of gears %s and %s".,g[g1].name,g[g2].name);
  637. MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);
  638. exit(1);
  639. }
  640. */
  641. if (g[g1].axis == 0)
  642. {
  643. dist = g[g1].position[0] - g[g2].position[0];
  644. }
  645. else if (g[i].axis == 1)
  646. {
  647. dist = g[g1].position[1] - g[g2].position[1];
  648. }
  649. else
  650. dist = g[g1].position[2] - g[g2].position[2];
  651. dist = fabs (dist);
  652. if (dist > (g[g1].width / 2 + g[g2].width / 2))
  653. {
  654. printf (error, "Belt %s invalid.", b[i].name);
  655. /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
  656. exit (1);
  657. }
  658. if (dist < (g[g1].width / 2 + g[g2].width / 2))
  659. {
  660. if (D < g[g1].radius + g[g2].radius)
  661. {
  662. printf (error, "Gears %s and %s too close to be linked with belts", g[g1].name, g[g2].name);
  663. /*MessageBox(NULL,error,windowName,MB_ICONEXCLAMATION|MB_OK);*/
  664. exit (1);
  665. }
  666. if ((g[g1].motored) && (!(g[g2].motored)))
  667. {
  668. axle_index = axle_find (g[g2].axle_name);
  669. g[g2].motored = (a[axle_index].motored = 1);
  670. g[g2].direction = (a[axle_index].direction = g[g1].direction);
  671. g[g2].angular_velocity = (a[axle_index].angular_velocity = g[g1].angular_velocity * g[g1].radius / g[g2].radius);
  672. }
  673. if ((!(g[g1].motored)) && (g[g2].motored))
  674. {
  675. axle_index = axle_find (g[g1].axle_name);
  676. g[g1].motored = (a[axle_index].motored = 1);
  677. g[g1].direction = (a[axle_index].direction = g[g2].direction);
  678. g[g1].angular_velocity = (a[axle_index].angular_velocity = g[g2].angular_velocity * g[g2].radius / g[g1].radius);
  679. }
  680. }
  681. }
  682. }
  683. for (i = 0; i < number_of_gears; i++)
  684. {
  685. axle_index = axle_find (g[i].axle_name);
  686. g[i].motored = a[axle_index].motored;
  687. if (a[axle_index].motored)
  688. {
  689. g[i].direction = a[axle_index].direction;
  690. g[i].angular_velocity = a[axle_index].angular_velocity;
  691. }
  692. }
  693. }
  694. }
  695. GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 10.0;
  696. static void
  697. draw (void)
  698. {
  699. int i;
  700. GLfloat x, y, z;
  701. int index;
  702. glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  703. glPushMatrix ();
  704. glRotatef (view_rotx, 1.0, 0.0, 0.0);
  705. glRotatef (view_roty, 0.0, 1.0, 0.0);
  706. glRotatef (view_rotz, 0.0, 0.0, 1.0);
  707. for (i = 0; i < number_of_gears; i++)
  708. {
  709. x = 0.0;
  710. y = 0.0;
  711. z = 0.0;
  712. glPushMatrix ();
  713. /*glTranslatef( -3.0, -2.0, 0.0 );*/
  714. glTranslatef (g[i].position[0], g[i].position[1], g[i].position[2]);
  715. if (g[i].axis == 0)
  716. y = 1.0;
  717. else if (g[i].axis == 1)
  718. x = 1.0;
  719. else
  720. z = 1.0;
  721. if (z != 1.0)
  722. glRotatef (90.0, x, y, z);
  723. glRotatef (g[i].direction * g[i].angle, 0.0, 0.0, 1.0);
  724. glCallList (g[i].id);
  725. glPopMatrix ();
  726. }
  727. for (i = 0; i < number_of_axles; i++)
  728. {
  729. x = 0.0;
  730. y = 0.0;
  731. z = 0.0;
  732. glPushMatrix ();
  733. glTranslatef (a[i].position[0], a[i].position[1], a[i].position[2]);
  734. if (a[i].axis == 0)
  735. y = 1.0;
  736. else if (a[i].axis == 1)
  737. x = 1.0;
  738. else
  739. z = 1.0;
  740. if (z != 1.0)
  741. glRotatef (90.0, x, y, z);
  742. glCallList (a[i].id);
  743. glPopMatrix ();
  744. }
  745. for (i = 0; i < number_of_belts; i++)
  746. {
  747. x = 0.0;
  748. y = 0.0;
  749. z = 0.0;
  750. glPushMatrix ();
  751. index = gear_find (b[i].gear1_name);
  752. glTranslatef (g[index].position[0], g[index].position[1], g[index].position[2]);
  753. if (g[index].axis == 0)
  754. y = 1.0;
  755. else if (g[index].axis == 1)
  756. x = 1.0;
  757. else
  758. z = 1.0;
  759. if (z != 1.0)
  760. glRotatef (90.0, x, y, z);
  761. glCallList (b[i].id);
  762. glPopMatrix ();
  763. }
  764. glPopMatrix ();
  765. glutSwapBuffers ();
  766. {
  767. GLint t = glutGet(GLUT_ELAPSED_TIME);
  768. Frames++;
  769. if (t - T0 >= 5000) {
  770. GLfloat seconds = (t - T0) / 1000.0;
  771. GLfloat fps = Frames / seconds;
  772. printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps);
  773. T0 = t;
  774. Frames = 0;
  775. }
  776. }
  777. }
  778. static void
  779. idle (void)
  780. {
  781. int i;
  782. for (i = 0; i < number_of_gears; i++)
  783. g[i].angle += g[i].angular_velocity;
  784. glutPostRedisplay();
  785. }
  786. /* change view angle, exit upon ESC */
  787. static void
  788. key (unsigned char k, int x, int y)
  789. {
  790. switch (k)
  791. {
  792. case 'x':
  793. view_rotx += 5.0;
  794. break;
  795. case 'X':
  796. view_rotx -= 5.0;
  797. break;
  798. case 'y':
  799. view_roty += 5.0;
  800. break;
  801. case 'Y':
  802. view_roty -= 5.0;
  803. break;
  804. case 'z':
  805. view_rotz += 5.0;
  806. break;
  807. case 'Z':
  808. view_rotz -= 5.0;
  809. break;
  810. case 0x1B:
  811. exit(0);
  812. }
  813. }
  814. /* new window size or exposure */
  815. static void
  816. reshape (int width, int height)
  817. {
  818. glViewport (0, 0, (GLint) width, (GLint) height);
  819. glMatrixMode (GL_PROJECTION);
  820. glLoadIdentity ();
  821. if (width > height)
  822. {
  823. GLfloat w = (GLfloat) width / (GLfloat) height;
  824. glFrustum (-w, w, -1.0, 1.0, 5.0, 60.0);
  825. }
  826. else
  827. {
  828. GLfloat h = (GLfloat) height / (GLfloat) width;
  829. glFrustum (-1.0, 1.0, -h, h, 5.0, 60.0);
  830. }
  831. glMatrixMode (GL_MODELVIEW);
  832. glLoadIdentity ();
  833. glTranslatef (0.0, 0.0, -40.0);
  834. glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  835. }
  836. static void
  837. init (void)
  838. {
  839. GLfloat matShine = 20.00F;
  840. GLfloat light0Pos[4] =
  841. {
  842. 0.70F, 0.70F, 1.25F, 0.50F
  843. };
  844. int i;
  845. glClearColor (background[0], background[1], background[2], 1.0F);
  846. glClearIndex ((GLfloat) 0.0);
  847. glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, matShine);
  848. glLightfv (GL_LIGHT0, GL_POSITION, light0Pos);
  849. glEnable (GL_LIGHT0);
  850. glEnable (GL_LIGHTING);
  851. glEnable (GL_DEPTH_TEST);
  852. for (i = 0; i < number_of_gears; i++)
  853. g[i].angle = 0.0;
  854. for (i = 0; i < number_of_gears; i++)
  855. {
  856. g[i].id = glGenLists (1);
  857. glNewList (g[i].id, GL_COMPILE);
  858. glColor3fv (g[i].color);
  859. glMaterialfv (GL_FRONT, GL_SPECULAR, g[i].color);
  860. gear (i, g[i].type, g[i].radius, g[i].width, g[i].teeth, g[i].tooth_depth);
  861. glEndList ();
  862. }
  863. for (i = 0; i < number_of_axles; i++)
  864. {
  865. a[i].id = glGenLists (1);
  866. glNewList (a[i].id, GL_COMPILE);
  867. glColor3fv (a[i].color);
  868. glMaterialfv (GL_FRONT, GL_SPECULAR, a[i].color);
  869. axle (i, a[i].radius, a[i].length);
  870. glEndList ();
  871. }
  872. for (i = 0; i < number_of_belts; i++)
  873. {
  874. b[i].id = glGenLists (1);
  875. glNewList (b[i].id, GL_COMPILE);
  876. belt (g[gear_find (b[i].gear1_name)], g[gear_find (b[i].gear2_name)]);
  877. glEndList ();
  878. }
  879. glEnable (GL_COLOR_MATERIAL);
  880. }
  881. int
  882. main (int argc, char *argv[])
  883. {
  884. char *file;
  885. if (argc < 2)
  886. file = "geartrain.dat";
  887. else
  888. file = argv[1];
  889. glutInitWindowPosition (0, 0);
  890. glutInitWindowSize(640,480);
  891. glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
  892. if (glutCreateWindow ("Gear Train Simulation") == GL_FALSE)
  893. exit (1);
  894. getdata (file);
  895. process ();
  896. init ();
  897. glutDisplayFunc (draw);
  898. glutReshapeFunc (reshape);
  899. glutKeyboardFunc (key);
  900. glutIdleFunc (idle);
  901. glutMainLoop ();
  902. return 0;
  903. }