X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=antikythera;a=blobdiff_plain;f=src%2Fgear.cc;h=697610d9440cdb3d157f36e34e62992fd1236dbb;hp=865679c155c0aab3d9234ec1f0ebe168f64cc5fd;hb=080d7a779d43f549fc16c44e709cbf5989180fdf;hpb=a88a9ac53952e1bb3768b147a043c19392e3d5d1 diff --git a/src/gear.cc b/src/gear.cc index 865679c..697610d 100644 --- a/src/gear.cc +++ b/src/gear.cc @@ -1,6 +1,7 @@ #include #include "gear.h" #include "meshgen.h" +#include "app.h" Gear::Gear() : axis(0, 0, 1) @@ -13,6 +14,9 @@ Gear::Gear() thickness = 5; bevel = 1.5; init_angle = 0; + xform_valid = false; + + supergear = 0; mesh = 0; } @@ -22,19 +26,128 @@ Gear::~Gear() delete mesh; } +void Gear::attach(Gear *g) +{ + if(g->supergear) { + if(g->supergear == this) { + return; + } + g->supergear->detach(g); + } + g->supergear = this; + subgears.push_back(g); + + // make co-axial + g->axis = axis; + g->pos.x = pos.x; + g->pos.y = pos.y; +} + +bool Gear::detach(Gear *g) +{ + int nsubgears = (int)subgears.size(); + for(int i=0; isupergear = 0; + return true; + } + } + return false; +} + +Gear *Gear::get_super() const +{ + return supergear; +} + +void Gear::set_angular_offset(float offs) +{ + init_angle = offs; + xform_valid = false; +} + +float Gear::get_angular_offset() const +{ + return init_angle; +} + 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; } -float Gear::get_rotation() const +void Gear::set_axis(const Vec3 &axis) +{ + this->axis = normalize(axis); + xform_valid = false; +} + +const Vec3 &Gear::get_axis() const +{ + return axis; +} + +void Gear::set_position(const Vec3 &pos) +{ + if(!supergear) { + this->pos = pos; + xform_valid = false; + } else { + if(fabs(this->pos.z - pos.z) > 1e-5) { + this->pos.z = pos.z; + xform_valid = false; + } + } +} + +const Vec3 &Gear::get_position() const +{ + return pos; +} + +Vec3 Gear::get_global_position() const +{ + const Mat4 &m = get_matrix(); + return m * Vec3(0, 0, 0); +} + +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 dir_xform; +} + float Gear::get_angular_pitch() const { return 2.0 * M_PI / (float)nteeth; @@ -47,25 +160,62 @@ void Gear::draw() const abort(); } } - calc_matrix(); + if(!xform_valid) { + 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(); + + glPopMatrix(); glPopAttrib(); +} + +void Gear::draw_wire(float wire_width) const +{ + if(!mesh) { + if(!((Gear*)this)->gen_mesh()) { + abort(); + } + } + if(!xform_valid) { + calc_matrix(); + } + + glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT); + glLineWidth(wire_width); + glDisable(GL_LIGHTING); + + glPushMatrix(); + glMultMatrixf(xform[0]); + + mesh->draw_wire(); glPopMatrix(); + glPopAttrib(); } static Vec2 rev_pos(float u, float v, void *cls) @@ -112,8 +262,11 @@ bool Gear::gen_mesh() mesh->explode(); mesh->calc_face_normals(); + float fix_tooth_up = get_angular_pitch() * 3.0 / 8.0; + Mat4 rot; rot.rotation_x(M_PI / 2.0); + rot.rotate_z(fix_tooth_up); mesh->apply_xform(rot, rot); mesh->set_vis_vecsize(6.0); @@ -129,7 +282,12 @@ 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); + + axel_xform = dir_xform; + axel_xform.translate(pos); }