Blob Blame Raw

#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();
}