#include <GL/gl.h>
#include "tool.h"
static void draw_disc(const Vector3 &p, const Vector3 &axis, Real r, bool flip = false, int segments = 16) {
Vector3 n = axis.norm();
Vector3 vx = n.perp().norm();
Vector3 vy = vx.cross(n);
if (flip) glNormal3d(-n.x, -n.y, -n.z); else glNormal3dv(n.c);
glBegin(GL_TRIANGLE_FAN);
glVertex3dv(p.c);
for(int i = 0; i <= segments; ++i) {
Real a = 2*M_PI*(flip ? segments - i - 1 : i)/segments;
Vector3 n = vx*cos(a) + vy*sin(a);
glVertex3dv((p + n*r).c);
}
glEnd();
}
static void draw_cone(const Vector3 &p0, const Vector3 &p1, Real r0, Real r1, bool flip = false, int segments = 16) {
Vector3 dir = (p1 - p0).norm();
Vector3 vx = dir.perp().norm();
Vector3 vy = vx.cross(dir);
glBegin(GL_TRIANGLE_STRIP);
for(int i = 0; i <= segments; ++i) {
Real a = 2*M_PI*i/segments;
Vector3 n = vx*cos(a) + vy*sin(a);
if (flip) {
glNormal3d(-n.x, -n.y, -n.z);
glVertex3dv((p1 + n*r1).c);
glVertex3dv((p0 + n*r0).c);
} else {
glNormal3dv(n.c);
glVertex3dv((p0 + n*r0).c);
glVertex3dv((p1 + n*r1).c);
}
}
glEnd();
}
void FlatTool::draw(const Vector3 &pos, const Vector3 &dir) const {
Vector3 p0 = pos - dir.norm()*10*radius;
glEnable(GL_LIGHTING);
glColor4d(1, 1, 0, 0.25);
draw_cone(p0, pos, radius, radius);
draw_disc(p0, pos - p0, radius, true);
draw_disc(pos, pos - p0, radius);
glDisable(GL_LIGHTING);
glPopMatrix();
}
void ConeTool::draw(const Vector3 &pos, const Vector3 &dir) const {
glEnable(GL_LIGHTING);
glColor4d(1, 1, 0, 0.25);
Real r = fabs(radius);
Real cr = fabs(cut_radius);
Real h = fabs(height);
Real cl = 10*r;
Vector3 p1 = pos;
if (h > precision && cr < r - precision) {
p1 = pos - dir.norm()*h;
draw_cone(p1, pos, r, cr);
if (cr > precision)
draw_disc(pos, pos - p1, cr);
cl = std::max(2*r, cl - h);
}
Vector3 p0 = p1 - dir.norm()*cl;
draw_cone(p0, p1, r, r);
draw_disc(p0, p1 - p0, r, true);
glDisable(GL_LIGHTING);
glPopMatrix();
}