nuclear@6: #include nuclear@6: #include "opengl.h" nuclear@6: #include "dragon.h" nuclear@6: nuclear@6: Dragon::Dragon() nuclear@6: : pos(0, 0, 0), dir(0, 0, -1), head_pos(0, 0, -1), target(0, 0, -2) nuclear@6: { nuclear@6: set_head_limits(-1, 1, -1, 1); nuclear@6: } nuclear@6: nuclear@6: Dragon::~Dragon() nuclear@6: { nuclear@6: } nuclear@6: nuclear@6: void Dragon::set_position(const Vector3 &p) nuclear@6: { nuclear@6: pos = p; nuclear@6: } nuclear@6: nuclear@6: void Dragon::set_direction(const Vector3 &dir) nuclear@6: { nuclear@6: this->dir = dir.normalized(); nuclear@6: } nuclear@6: nuclear@6: void Dragon::set_target(const Vector3 &p) nuclear@6: { nuclear@6: target = p; nuclear@6: } nuclear@6: nuclear@6: void Dragon::set_head_limits(float xmin, float xmax, float ymin, float ymax) nuclear@6: { nuclear@6: head_xlim[0] = std::min(xmin, xmax); nuclear@6: head_xlim[1] = std::max(xmin, xmax); nuclear@6: head_ylim[0] = std::min(ymin, ymax); nuclear@6: head_ylim[1] = std::max(ymin, ymax); nuclear@6: } nuclear@6: nuclear@6: void Dragon::move_head(const Vector3 &p) nuclear@6: { nuclear@6: head_pos = p; nuclear@6: } nuclear@6: nuclear@6: static float clamp(float x, float low, float high) nuclear@6: { nuclear@6: return x < low ? low : (x > high ? high : x); nuclear@6: } nuclear@6: nuclear@6: void Dragon::move_head(float dx, float dy) nuclear@6: { nuclear@6: float newx = clamp(head_pos.x + dx, head_xlim[0], head_xlim[1]); nuclear@6: float newy = clamp(head_pos.y + dy, head_ylim[0], head_ylim[1]); nuclear@6: nuclear@6: dx = newx - head_pos.x; nuclear@6: dy = newy - head_pos.y; nuclear@6: head_pos.x = newx; nuclear@6: head_pos.y = newy; nuclear@6: nuclear@6: target.x += dx * 0.7; nuclear@6: target.y += dy * 0.5; nuclear@6: } nuclear@6: nuclear@6: const Vector3 &Dragon::head_position() const nuclear@6: { nuclear@6: return head_pos; nuclear@6: } nuclear@6: nuclear@6: Vector3 Dragon::breath_dir() const nuclear@6: { nuclear@6: return (target - head_pos).normalized(); nuclear@6: } nuclear@6: nuclear@6: void Dragon::update() nuclear@6: { nuclear@6: } nuclear@6: nuclear@6: static Vector3 bezier(const Vector3 &a, const Vector3 &b, const Vector3 &c, const Vector3 &d, float t) nuclear@6: { nuclear@6: float x = bezier(a.x, b.x, c.x, d.x, t); nuclear@6: float y = bezier(a.y, b.y, c.y, d.y, t); nuclear@6: float z = bezier(a.z, b.z, c.z, d.z, t); nuclear@6: return Vector3(x, y, z); nuclear@6: } nuclear@6: nuclear@6: void Dragon::draw() const nuclear@6: { nuclear@6: Vector3 bdir = breath_dir(); nuclear@6: Vector3 bezcp[] = { pos, pos + dir * 6.0, head_pos - bdir * 8.0, head_pos }; nuclear@6: nuclear@6: int cur_sdr; nuclear@6: glGetIntegerv(GL_CURRENT_PROGRAM, &cur_sdr); nuclear@6: glUseProgram(0); nuclear@6: nuclear@6: glPushAttrib(GL_ENABLE_BIT); nuclear@6: glDisable(GL_LIGHTING); nuclear@6: nuclear@6: glLineWidth(2.0); nuclear@6: glColor3f(0, 0, 1); nuclear@6: nuclear@6: glBegin(GL_LINE_STRIP); nuclear@6: for(int i=0; i<10; i++) { nuclear@6: float t = (float)i / 10.0f; nuclear@6: Vector3 p = bezier(bezcp[0], bezcp[1], bezcp[2], bezcp[3], t); nuclear@6: glVertex3f(p.x, p.y, p.z); nuclear@6: } nuclear@6: glEnd(); nuclear@6: glLineWidth(1); nuclear@6: nuclear@6: glPointSize(5.0); nuclear@6: glColor3f(0, 1, 0); nuclear@6: nuclear@6: glBegin(GL_POINTS); nuclear@6: for(int i=0; i<4; i++) { nuclear@6: glVertex3f(bezcp[i].x, bezcp[i].y, bezcp[i].z); nuclear@6: } nuclear@6: glEnd(); nuclear@6: nuclear@6: glPopAttrib(); nuclear@6: nuclear@6: glUseProgram(cur_sdr); nuclear@6: }