24 color = Vec3(0.6, 0.6, 0.6);
34 void Gear::attach(Gear *g)
37 if(g->supergear == this) {
40 g->supergear->detach(g);
43 subgears.push_back(g);
51 bool Gear::detach(Gear *g)
53 int nsubgears = (int)subgears.size();
54 for(int i=0; i<nsubgears; i++) {
55 if(subgears[i] == g) {
56 subgears.erase(subgears.begin() + i);
64 Gear *Gear::get_super() const
69 void Gear::set_angular_offset(float offs)
75 float Gear::get_angular_offset() const
80 void Gear::set_teeth(int nt, float tooth_pitch)
82 float circ = tooth_pitch * nt;
83 radius = circ / (2.0 * M_PI);
87 void Gear::set_axis(const Vec3 &axis)
89 this->axis = normalize(axis);
93 const Vec3 &Gear::get_axis() const
98 void Gear::set_position(const Vec3 &pos)
103 this->pos = supergear->pos;
108 for(int i=0; i<(int)subgears.size(); i++) {
109 Vec3 subpos = this->pos;
110 subpos.z = subgears[i]->pos.z;
111 subgears[i]->set_position(subpos);
115 const Vec3 &Gear::get_position() const
120 Vec3 Gear::get_global_position() const
122 const Mat4 &m = get_matrix();
123 return m * Vec3(0, 0, 0);
126 void Gear::set_angle(float angle)
132 float Gear::get_angle() const
137 float Gear::get_vis_rotation() const
139 return fmod(init_angle + angle, M_PI * 2.0);
142 const Mat4 &Gear::get_matrix() const
151 const Mat4 &Gear::get_dir_matrix() const
160 float Gear::get_angular_pitch() const
162 return 2.0 * M_PI / (float)nteeth;
165 void Gear::draw() const
168 if(!((Gear*)this)->gen_mesh()) {
176 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_LIGHTING_BIT);
179 glMultMatrixf(xform[0]);
181 if(opt_gear_wireframe) {
182 glPolygonOffset(1, 1);
183 glEnable(GL_POLYGON_OFFSET_FILL);
186 Vec3 diffuse = metallic ? Vec3(0, 0, 0) : color;
187 float col[] = {diffuse.x, diffuse.y, diffuse.z, 1.0};
188 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
190 Vec3 specular = (metallic ? color : Vec3(1, 1, 1)) * (1.0 - roughness);
191 float scol[] = {specular.x, specular.y, specular.z, 1.0};
192 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, scol);
193 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 1.0 + (1.0 - roughness) * 60.0);
197 glDisable(GL_LIGHTING);
199 if(opt_gear_wireframe) {
200 glColor3f(0.2, 0.4, 1.0);
208 void Gear::draw_wire(float wire_width) const
211 if(!((Gear*)this)->gen_mesh()) {
219 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
220 glLineWidth(wire_width);
221 glDisable(GL_LIGHTING);
224 glMultMatrixf(xform[0]);
232 static Vec2 rev_pos(float u, float v, void *cls)
234 Gear *gear = (Gear*)cls;
236 float y = ((v - 1.0 / 3.0) / (1.0 / 3.0) - 0.5);
237 if(y < -0.5) y = -0.5;
239 y *= gear->thickness;
241 if(v < 0.001 || v > 0.999) {
245 float nt = (float)gear->nteeth * 4.0;
247 int part = (int)(u * nt) % 4; /* 4 parts to a tooth /#\_ */
248 float t = fmod(u * nt * 4.0, 1.0);
265 float inner_rad = gear->radius - gear->teeth_length;
266 return Vec2(inner_rad + offs * gear->teeth_length, -y);
269 bool Gear::gen_mesh()
272 gen_revol(mesh, nteeth * 4, 3, rev_pos, 0, this);
274 mesh->calc_face_normals();
276 float fix_tooth_up = get_angular_pitch() * 3.0 / 8.0;
279 rot.rotation_x(M_PI / 2.0);
280 rot.rotate_z(fix_tooth_up);
281 mesh->apply_xform(rot, rot);
283 mesh->set_vis_vecsize(6.0);
287 void Gear::calc_matrix() const
289 Vec3 up = Vec3(0, 1, 0);
290 if(1.0 - fabs(dot(up, axis)) < 1e-4) {
293 Vec3 right = normalize(cross(up, axis));
294 up = cross(axis, right);
296 dir_xform = Mat4(right, up, axis);
299 xform.rotate_z(get_vis_rotation());
300 xform.translate(pos);
302 axel_xform = dir_xform;
303 axel_xform.translate(pos);