X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=antikythera;a=blobdiff_plain;f=src%2Fgear.cc;h=e6a549115e838c56531972ad2e34fbd3aaf38310;hp=6ce9d8ac706151461e337f86d1c4fe7f1c9117a6;hb=1548fea8c64ebdfde728f33fd2d1537954ebf38b;hpb=84484521a697fe60f63bff077b9ba7475a45e54e diff --git a/src/gear.cc b/src/gear.cc index 6ce9d8a..e6a5491 100644 --- a/src/gear.cc +++ b/src/gear.cc @@ -1,3 +1,4 @@ +#include #include #include "gear.h" #include "meshgen.h" @@ -16,7 +17,13 @@ Gear::Gear() init_angle = 0; xform_valid = false; + supergear = 0; + mesh = 0; + + color = Vec3(0.6, 0.6, 0.6); + roughness = 1.0; + metallic = false; } Gear::~Gear() @@ -24,12 +31,57 @@ 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; } void Gear::set_axis(const Vec3 &axis) @@ -38,10 +90,26 @@ void Gear::set_axis(const Vec3 &axis) xform_valid = false; } +const Vec3 &Gear::get_axis() const +{ + return axis; +} + void Gear::set_position(const Vec3 &pos) { - this->pos = pos; + if(!supergear) { + this->pos = pos; + } else { + this->pos = supergear->pos; + this->pos.z = pos.z; + } xform_valid = false; + + for(int i=0; i<(int)subgears.size(); i++) { + Vec3 subpos = this->pos; + subpos.z = subgears[i]->pos.z; + subgears[i]->set_position(subpos); + } } const Vec3 &Gear::get_position() const @@ -51,7 +119,8 @@ const Vec3 &Gear::get_position() const Vec3 Gear::get_global_position() const { - return pos; // TODO + const Mat4 &m = get_matrix(); + return m * Vec3(0, 0, 0); } void Gear::set_angle(float angle) @@ -85,7 +154,7 @@ const Mat4 &Gear::get_dir_matrix() const calc_matrix(); xform_valid = true; } - return xform; + return dir_xform; } float Gear::get_angular_pitch() const @@ -100,9 +169,11 @@ void Gear::draw() const abort(); } } - calc_matrix(); + if(!xform_valid) { + calc_matrix(); + } - glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT); + glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_LIGHTING_BIT); glPushMatrix(); glMultMatrixf(xform[0]); @@ -112,6 +183,15 @@ void Gear::draw() const glEnable(GL_POLYGON_OFFSET_FILL); } + Vec3 diffuse = metallic ? Vec3(0, 0, 0) : color; + float col[] = {diffuse.x, diffuse.y, diffuse.z, 1.0}; + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col); + + Vec3 specular = (metallic ? color : Vec3(1, 1, 1)) * (1.0 - roughness); + float scol[] = {specular.x, specular.y, specular.z, 1.0}; + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, scol); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 1.0 + (1.0 - roughness) * 60.0); + mesh->draw(); glDisable(GL_LIGHTING); @@ -121,12 +201,29 @@ void Gear::draw() const 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(); @@ -176,8 +273,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); @@ -198,4 +298,7 @@ void Gear::calc_matrix() const xform = dir_xform; xform.rotate_z(get_vis_rotation()); xform.translate(pos); + + axel_xform = dir_xform; + axel_xform.translate(pos); }