--- /dev/null
+#ifndef GEAR_H_
+#define GEAR_H_
+
+#include <vector>
+#include <string>
+#include <gmath/gmath.h>
+#include "mesh.h"
+
+/* distance unit: millimeters
+ * angle unit: radians
+ */
+
+class Gear;
+struct GearPin;
+struct GearSlot;
+
+struct GearPin {
+ float radius;
+ float height;
+
+ Gear *parent;
+ /* position in polar coordinates on the parent gear */
+ float pos_dist, pos_angle;
+
+ GearSlot *conn_slot; /* slot connection */
+};
+
+struct GearSlot {
+ float radius, length;
+
+ Gear *parent;
+ /* position in polar coordinates on the parent gear */
+ float pos_dist_min, pos_dist_max, pos_angle;
+
+ GearPin *conn_pin; /* pin connection */
+};
+
+class Gear {
+private:
+ Mesh *mesh;
+
+ mutable Mat4 xform, dir_xform, axel_xform;
+ mutable bool xform_valid;
+ void calc_matrix() const;
+
+ float contour(float u);
+
+public:
+
+ /* TODO hide most of this shit, especially the stuff which invalidate
+ * the transformation matrices
+ */
+ std::string name;
+ Vec3 pos, axis; // implicitly defines a plane eqn.
+ float pdist; // derived: distance of plane from origin
+
+ float init_angle; // initial starting angle
+ float angle; // current angle of the gear
+
+ int nteeth; // number of teeth
+ float tooth_pitch;
+
+ float radius; // total radius of the gear, including teeth
+ float teeth_length; // how far teeth extend past the radius
+ float thickness; // thickness of the gear along the Z axis
+
+ float bevel; // bevel size
+
+ // visual surface properties
+ Vec3 color;
+ float roughness;
+ bool metallic;
+
+ Gear *supergear;
+ std::vector<Gear*> subgears;
+ std::vector<GearPin> pins;
+ std::vector<GearSlot> slots;
+
+ Gear();
+ ~Gear();
+
+ void attach(Gear *g);
+ bool detach(Gear *g);
+ Gear *get_super() const;
+
+ void set_angular_offset(float offs);
+ float get_angular_offset() const;
+
+ // sets the supplied number of teeth, and calculates the radius
+ // of the gear, to achieve the required tooth pitch
+ void set_teeth(int nt, float tooth_pitch = 0.0f);
+ void set_axis(const Vec3 &axis);
+ const Vec3 &get_axis() const;
+ void set_position(const Vec3 &pos);
+ const Vec3 &get_position() const;
+ Vec3 get_global_position() const; // taking parent gear into account
+
+ Vec3 get_planar_position() const; // 2D pos of gear on its plane
+
+ void set_angle(float angle);
+ float get_angle() const;
+
+ float get_vis_rotation() const;
+ const Mat4 &get_matrix() const;
+ const Mat4 &get_dir_matrix() const;
+
+ // returns the angle (in radians) from one tooth to the next
+ float get_angular_pitch() const;
+
+ void draw() const;
+ void draw_wire(float line_width = 1.0f) const;
+
+ bool gen_mesh();
+};
+
+#endif // GEAR_H_