29 void Gear::attach(Gear *g)
32 if(g->supergear == this) {
35 g->supergear->detach(g);
38 subgears.push_back(g);
46 bool Gear::detach(Gear *g)
48 int nsubgears = (int)subgears.size();
49 for(int i=0; i<nsubgears; i++) {
50 if(subgears[i] == g) {
51 subgears.erase(subgears.begin() + i);
59 Gear *Gear::get_super() const
64 void Gear::set_angular_offset(float offs)
70 float Gear::get_angular_offset() const
75 void Gear::set_teeth(int nt, float tooth_pitch)
77 float circ = tooth_pitch * nt;
78 radius = circ / (2.0 * M_PI);
82 void Gear::set_axis(const Vec3 &axis)
84 this->axis = normalize(axis);
88 const Vec3 &Gear::get_axis() const
93 void Gear::set_position(const Vec3 &pos)
99 if(fabs(this->pos.z - pos.z) > 1e-5) {
106 const Vec3 &Gear::get_position() const
111 Vec3 Gear::get_global_position() const
113 const Mat4 &m = get_matrix();
114 return m * Vec3(0, 0, 0);
117 void Gear::set_angle(float angle)
123 float Gear::get_angle() const
128 float Gear::get_vis_rotation() const
130 return fmod(init_angle + angle, M_PI * 2.0);
133 const Mat4 &Gear::get_matrix() const
142 const Mat4 &Gear::get_dir_matrix() const
151 float Gear::get_angular_pitch() const
153 return 2.0 * M_PI / (float)nteeth;
156 void Gear::draw() const
159 if(!((Gear*)this)->gen_mesh()) {
167 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
170 glMultMatrixf(xform[0]);
172 if(opt_gear_wireframe) {
173 glPolygonOffset(1, 1);
174 glEnable(GL_POLYGON_OFFSET_FILL);
179 glDisable(GL_LIGHTING);
181 if(opt_gear_wireframe) {
182 glColor3f(0.2, 0.4, 1.0);
189 glVertex3f(0, 0, -10);
190 glVertex3f(0, 0, 10);
197 void Gear::draw_wire(float wire_width) const
200 if(!((Gear*)this)->gen_mesh()) {
208 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
209 glLineWidth(wire_width);
210 glDisable(GL_LIGHTING);
213 glMultMatrixf(xform[0]);
221 static Vec2 rev_pos(float u, float v, void *cls)
223 Gear *gear = (Gear*)cls;
225 float y = ((v - 1.0 / 3.0) / (1.0 / 3.0) - 0.5);
226 if(y < -0.5) y = -0.5;
228 y *= gear->thickness;
230 if(v < 0.001 || v > 0.999) {
234 float nt = (float)gear->nteeth * 4.0;
236 int part = (int)(u * nt) % 4; /* 4 parts to a tooth /#\_ */
237 float t = fmod(u * nt * 4.0, 1.0);
254 float inner_rad = gear->radius - gear->teeth_length;
255 return Vec2(inner_rad + offs * gear->teeth_length, -y);
258 bool Gear::gen_mesh()
261 gen_revol(mesh, nteeth * 4, 3, rev_pos, 0, this);
263 mesh->calc_face_normals();
265 float fix_tooth_up = get_angular_pitch() * 3.0 / 8.0;
268 rot.rotation_x(M_PI / 2.0);
269 rot.rotate_z(fix_tooth_up);
270 mesh->apply_xform(rot, rot);
272 mesh->set_vis_vecsize(6.0);
276 void Gear::calc_matrix() const
278 Vec3 up = Vec3(0, 1, 0);
279 if(1.0 - fabs(dot(up, axis)) < 1e-4) {
282 Vec3 right = normalize(cross(up, axis));
283 up = cross(axis, right);
285 dir_xform = Mat4(right, up, axis);
288 xform.rotate_z(get_vis_rotation());
289 xform.translate(pos);
291 axel_xform = dir_xform;
292 axel_xform.translate(pos);