meshing calculation for co-planar gears
[antikythera] / src / main.cc
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4 #include <GL/glew.h>
5 #ifdef __APPLE__
6 #include <GLUT/glut.h>
7 #else
8 #include <GL/glut.h>
9 #endif
10 #include "app.h"
11 #include "machine.h"
12
13 bool init();
14 void cleanup();
15 void display();
16 void idle();
17 void draw_gears();
18 void reshape(int x, int y);
19 void keyb(unsigned char key, int x, int y);
20 void mouse(int bn, int st, int x, int y);
21 void motion(int x, int y);
22
23 static float cam_dist = 0.5;
24 static float cam_theta, cam_phi;
25 static int prev_mx, prev_my;
26 static bool bnstate[8];
27
28 static unsigned int start_time, prev_msec;
29 static Machine *machine;
30
31 int main(int argc, char **argv)
32 {
33         glutInitWindowSize(1024, 768);
34         glutInit(&argc, argv);
35         glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | GLUT_MULTISAMPLE);
36         glutCreateWindow("Antikythera");
37
38         glutDisplayFunc(display);
39         glutIdleFunc(idle);
40         glutReshapeFunc(reshape);
41         glutKeyboardFunc(keyb);
42         glutMouseFunc(mouse);
43         glutMotionFunc(motion);
44
45         if(!init()) {
46                 return 1;
47         }
48         atexit(cleanup);
49
50         glutMainLoop();
51         return 0;
52 }
53
54 bool init()
55 {
56         glewInit();
57
58         glEnable(GL_MULTISAMPLE);
59         glEnable(GL_DEPTH_TEST);
60         glEnable(GL_CULL_FACE);
61         glEnable(GL_LIGHTING);
62         glEnable(GL_LIGHT0);
63         glEnable(GL_NORMALIZE);
64
65         Mesh::use_custom_sdr_attr = false;
66
67         machine = new Machine;
68
69         const float pitch = 10.0f;
70
71         Gear *gear1 = new Gear;
72         gear1->pos = Vec3(-50, 0, 0);
73         gear1->set_teeth(16, pitch);
74         gear1->gen_mesh();
75         machine->add_gear(gear1);
76
77         Gear *gear2 = new Gear;
78         gear2->set_teeth(32, pitch);
79         gear2->pos = gear1->pos + Vec3(gear1->radius + gear2->radius - gear1->teeth_length * 0.75, 0, 0);
80         gear2->thickness = 5;
81         gear2->gen_mesh();
82         machine->add_gear(gear2);
83
84         Gear *gear3 = new Gear;
85         gear3->set_teeth(8, pitch);
86         gear3->pos = gear2->pos + Vec3(0, gear2->radius + gear3->radius - gear2->teeth_length * 0.75, 0);
87         gear3->gen_mesh();
88         machine->add_gear(gear3);
89
90         machine->add_motor(0, 1.0);
91         machine->calc_meshing();
92
93         start_time = glutGet(GLUT_ELAPSED_TIME);
94         return true;
95 }
96
97 void cleanup()
98 {
99         delete machine;
100 }
101
102 void display()
103 {
104         unsigned int msec = glutGet(GLUT_ELAPSED_TIME) - start_time;
105         float dt = (float)(msec - prev_msec) / 1000.0f;
106         prev_msec = msec;
107
108         machine->update(dt);
109
110         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
111
112         glMatrixMode(GL_MODELVIEW);
113         glLoadIdentity();
114         glTranslatef(0, 0, -cam_dist);
115         glRotatef(cam_phi, 1, 0, 0);
116         glRotatef(cam_theta, 0, 1, 0);
117
118         draw_gears();
119
120         glutSwapBuffers();
121         assert(glGetError() == GL_NO_ERROR);
122 }
123
124 void idle()
125 {
126         glutPostRedisplay();
127 }
128
129 void draw_gears()
130 {
131         /* world scale is in meters, gears are in millimeters, scale by 1/1000 */
132         glPushMatrix();
133         glScalef(0.001, 0.001, 0.001);
134
135         machine->draw();
136
137         glPopMatrix();
138 }
139
140 void reshape(int x, int y)
141 {
142         glViewport(0, 0, x, y);
143
144         glMatrixMode(GL_PROJECTION);
145         glLoadIdentity();
146         gluPerspective(50.0, (float)x / (float)y, 0.01, 100.0);
147 }
148
149 void keyb(unsigned char key, int x, int y)
150 {
151         switch(key) {
152         case 27:
153                 exit(0);
154
155         case 'w':
156                 opt_gear_wireframe = !opt_gear_wireframe;
157                 glutPostRedisplay();
158                 break;
159         }
160 }
161
162 void mouse(int bn, int st, int x, int y)
163 {
164         prev_mx = x;
165         prev_my = y;
166         bnstate[bn - GLUT_LEFT_BUTTON] = st == GLUT_DOWN;
167 }
168
169 void motion(int x, int y)
170 {
171         int dx = x - prev_mx;
172         int dy = y - prev_my;
173         prev_mx = x;
174         prev_my = y;
175
176         if(!dx && !dy) return;
177
178         if(bnstate[0]) {
179                 cam_theta += dx * 0.5;
180                 cam_phi += dy * 0.5;
181
182                 if(cam_phi < -90) cam_phi = -90;
183                 if(cam_phi > 90) cam_phi = 90;
184                 glutPostRedisplay();
185         }
186         if(bnstate[2]) {
187                 cam_dist += dy * 0.01;
188                 if(cam_dist < 0.0) cam_dist = 0.0;
189                 glutPostRedisplay();
190         }
191 }