nuclear@1: #include "opengl.h" nuclear@1: #include "ship.h" nuclear@6: #include "vein.h" nuclear@1: nuclear@6: Ship::Ship(Vein *vein) nuclear@1: { nuclear@9: friction = 0.95; nuclear@6: this->vein = vein; nuclear@1: } nuclear@1: nuclear@1: void Ship::accelerate(double a) nuclear@1: { nuclear@1: velocity += get_direction() * a; nuclear@1: } nuclear@1: nuclear@3: void Ship::accelerate_side(double a) nuclear@3: { nuclear@3: velocity += get_right() * a; nuclear@3: } nuclear@3: nuclear@1: void Ship::turn(double yaw, double pitch) nuclear@1: { nuclear@1: Quaternion qyaw(Vector3(0, 1, 0), yaw); nuclear@1: Quaternion qpitch(Vector3(1, 0, 0), pitch); nuclear@1: nuclear@1: rot *= qpitch; nuclear@1: rot *= qyaw; nuclear@1: } nuclear@1: nuclear@1: void Ship::update(time_sec_t dt) nuclear@1: { nuclear@6: Vector3 newpos = pos + velocity * dt; nuclear@1: velocity -= velocity * friction * dt; nuclear@6: nuclear@6: HitPoint hit; nuclear@6: if(collision(vein, pos, newpos, &hit)) { nuclear@6: newpos = hit.pos; nuclear@6: // TODO damp velocity along normal nuclear@6: } nuclear@6: nuclear@6: pos = newpos; nuclear@6: } nuclear@6: nuclear@6: #define SHIP_RAD 0.25 nuclear@6: bool Ship::collision(const Vein *vein, const Vector3 &start, const Vector3 &end, HitPoint *hit) const nuclear@6: { nuclear@6: Vector3 cent = vein->calc_center(end); nuclear@6: float rad = vein->get_radius(); nuclear@6: nuclear@6: Vector3 dir = end - cent; nuclear@6: float dist = dir.length(); nuclear@6: nuclear@6: if(dist < rad - SHIP_RAD) { nuclear@6: return false; nuclear@6: } nuclear@6: nuclear@6: if(hit) { nuclear@6: Vector3 dir_norm = dir / dist; nuclear@6: hit->pos = cent + dir_norm * (rad - SHIP_RAD); nuclear@6: hit->normal = -dir_norm; nuclear@6: } nuclear@6: return true; nuclear@1: } nuclear@1: nuclear@1: const Vector3 &Ship::get_position() const nuclear@1: { nuclear@1: return pos; nuclear@1: } nuclear@1: nuclear@1: Vector3 Ship::get_direction() const nuclear@1: { nuclear@6: static const Vector3 dir(0, 0, -1); nuclear@1: return dir.transformed(rot); nuclear@1: } nuclear@1: nuclear@3: Vector3 Ship::get_right() const nuclear@3: { nuclear@6: static const Vector3 dir(1, 0, 0); nuclear@3: return dir.transformed(rot); nuclear@3: } nuclear@3: nuclear@1: Matrix4x4 Ship::get_matrix() const nuclear@1: { nuclear@2: Matrix3x3 rmat = rot.get_rotation_matrix().transposed(); nuclear@2: Matrix4x4 tmat; nuclear@2: tmat.set_translation(pos); nuclear@2: nuclear@2: return tmat * Matrix4x4(rmat); nuclear@1: } nuclear@1: nuclear@1: void Ship::dbg_draw() const nuclear@1: { nuclear@1: glPushAttrib(GL_POINT_BIT | GL_ENABLE_BIT); nuclear@1: nuclear@1: glPointSize(3.0); nuclear@1: glDisable(GL_LIGHTING); nuclear@1: nuclear@1: glBegin(GL_LINES); nuclear@1: glColor3f(0, 0, 1); nuclear@1: glVertex3f(pos.x, pos.y, pos.z); nuclear@1: nuclear@1: Vector3 end = pos + get_direction(); nuclear@1: glVertex3f(end.x, end.y, end.z); nuclear@1: glEnd(); nuclear@1: nuclear@1: glBegin(GL_POINTS); nuclear@1: glColor3f(1, 0, 0); nuclear@1: glVertex3f(pos.x, pos.y, pos.z); nuclear@1: glEnd(); nuclear@1: nuclear@2: glMatrixMode(GL_MODELVIEW); nuclear@2: glPushMatrix(); nuclear@2: mult_gl_matrix(get_matrix()); nuclear@2: nuclear@2: glScalef(1, 1, -1); nuclear@2: glColor3f(1, 1, 0); nuclear@2: glutWireCone(0.1, 0.6, 12, 2); nuclear@2: nuclear@2: glPopMatrix(); nuclear@2: nuclear@1: glPopAttrib(); nuclear@1: }