meshing calculation for co-planar gears
[antikythera] / src / gear.cc
index 03a3b7d..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)
@@ -13,6 +14,7 @@ Gear::Gear()
        thickness = 5;
        bevel = 1.5;
        init_angle = 0;
+       xform_valid = false;
 
        mesh = 0;
 }
@@ -30,11 +32,62 @@ void Gear::set_teeth(int nt, float tooth_pitch)
        init_angle = get_angular_pitch() * 3.0 / 8.0;
 }
 
-float Gear::get_rotation() const
+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;
@@ -49,24 +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);
 
+       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();
-       glLineWidth(1.0);
-       glPopAttrib();
 
        glPopMatrix();
+       glPopAttrib();
 }
 
 static Vec2 rev_pos(float u, float v, void *cls)
@@ -130,7 +193,9 @@ void Gear::calc_matrix() const
        Vec3 right = normalize(cross(up, axis));
        up = cross(axis, right);
 
-       xform = Mat4(right, up, axis);
-       xform.rotate_z(get_rotation());
+       dir_xform = Mat4(right, up, axis);
+
+       xform = dir_xform;
+       xform.rotate_z(get_vis_rotation());
        xform.translate(pos);
 }