meshing calculation for co-planar gears
[antikythera] / src / gear.cc
index 6450c65..6ce9d8a 100644 (file)
@@ -1,6 +1,7 @@
 #include <GL/glew.h>
 #include "gear.h"
 #include "meshgen.h"
+#include "app.h"
 
 Gear::Gear()
        : axis(0, 0, 1)
@@ -12,6 +13,8 @@ Gear::Gear()
        teeth_length = 5;
        thickness = 5;
        bevel = 1.5;
+       init_angle = 0;
+       xform_valid = false;
 
        mesh = 0;
 }
@@ -21,6 +24,75 @@ Gear::~Gear()
        delete mesh;
 }
 
+void Gear::set_teeth(int nt, float tooth_pitch)
+{
+       float circ = tooth_pitch * nt;
+       radius = circ / (2.0 * M_PI);
+       nteeth = nt;
+       init_angle = get_angular_pitch() * 3.0 / 8.0;
+}
+
+void Gear::set_axis(const Vec3 &axis)
+{
+       this->axis = normalize(axis);
+       xform_valid = false;
+}
+
+void Gear::set_position(const Vec3 &pos)
+{
+       this->pos = pos;
+       xform_valid = false;
+}
+
+const Vec3 &Gear::get_position() const
+{
+       return pos;
+}
+
+Vec3 Gear::get_global_position() const
+{
+       return pos;     // TODO
+}
+
+void Gear::set_angle(float angle)
+{
+       this->angle = angle;
+       xform_valid = false;
+}
+
+float Gear::get_angle() const
+{
+       return angle;
+}
+
+float Gear::get_vis_rotation() const
+{
+       return fmod(init_angle + angle, M_PI * 2.0);
+}
+
+const Mat4 &Gear::get_matrix() const
+{
+       if(!xform_valid) {
+               calc_matrix();
+               xform_valid = true;
+       }
+       return xform;
+}
+
+const Mat4 &Gear::get_dir_matrix() const
+{
+       if(!xform_valid) {
+               calc_matrix();
+               xform_valid = true;
+       }
+       return xform;
+}
+
+float Gear::get_angular_pitch() const
+{
+       return 2.0 * M_PI / (float)nteeth;
+}
+
 void Gear::draw() const
 {
        if(!mesh) {
@@ -30,20 +102,34 @@ void Gear::draw() const
        }
        calc_matrix();
 
+       glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
+
        glPushMatrix();
        glMultMatrixf(xform[0]);
 
+       if(opt_gear_wireframe) {
+               glPolygonOffset(1, 1);
+               glEnable(GL_POLYGON_OFFSET_FILL);
+       }
+
        mesh->draw();
 
-       /*
-       glPushAttrib(GL_ENABLE_BIT);
        glDisable(GL_LIGHTING);
-       glColor3f(0, 1, 0);
-       mesh->draw_normals();
-       glPopAttrib();
-       */
+
+       if(opt_gear_wireframe) {
+               glColor3f(0.2, 0.4, 1.0);
+               mesh->draw_wire();
+       }
+
+       glLineWidth(2.0);
+       glBegin(GL_LINES);
+       glColor3f(0, 0, 1);
+       glVertex3f(0, 0, -10);
+       glVertex3f(0, 0, 10);
+       glEnd();
 
        glPopMatrix();
+       glPopAttrib();
 }
 
 static Vec2 rev_pos(float u, float v, void *cls)
@@ -107,6 +193,9 @@ void Gear::calc_matrix() const
        Vec3 right = normalize(cross(up, axis));
        up = cross(axis, right);
 
-       xform = Mat4(right, up, axis);
+       dir_xform = Mat4(right, up, axis);
+
+       xform = dir_xform;
+       xform.rotate_z(get_vis_rotation());
        xform.translate(pos);
 }