Clone of mesa.
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

geartrain.c 30KB

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