nuclear@0: #include nuclear@0: #include "opengl.h" nuclear@0: #include "particle.h" nuclear@0: #include "simworld.h" nuclear@0: nuclear@0: Particle::Particle() nuclear@0: : forces(0, 0, 0), pos(0, 0, 0), velocity(0, 0, 0) nuclear@0: { nuclear@0: rad = 1.0; nuclear@0: elast = 0.75; nuclear@0: mass = 1.0; nuclear@0: friction = 0.0; nuclear@0: } nuclear@0: nuclear@0: void Particle::add_ignore(const Particle *p) nuclear@0: { nuclear@0: ignorelist.insert(p); nuclear@0: } nuclear@0: nuclear@0: void Particle::set_radius(float rad) nuclear@0: { nuclear@0: this->rad = rad; nuclear@0: } nuclear@0: nuclear@0: float Particle::get_radius() const nuclear@0: { nuclear@0: return rad; nuclear@0: } nuclear@0: nuclear@0: void Particle::set_mass(float m) nuclear@0: { nuclear@0: mass = m; nuclear@0: } nuclear@0: nuclear@0: float Particle::get_mass() const nuclear@0: { nuclear@0: return mass; nuclear@0: } nuclear@0: nuclear@0: void Particle::set_elasticity(float e) nuclear@0: { nuclear@0: elast = e; nuclear@0: } nuclear@0: nuclear@0: float Particle::get_elasticity() const nuclear@0: { nuclear@0: return elast; nuclear@0: } nuclear@0: nuclear@0: void Particle::set_position(const Vector3 &pos) nuclear@0: { nuclear@0: this->pos = pos; nuclear@0: } nuclear@0: nuclear@0: void Particle::set_velocity(const Vector3 &vel) nuclear@0: { nuclear@0: velocity = vel; nuclear@0: } nuclear@0: nuclear@0: Vector3 &Particle::get_position() nuclear@0: { nuclear@0: return pos; nuclear@0: } nuclear@0: nuclear@0: const Vector3 &Particle::get_position() const nuclear@0: { nuclear@0: return pos; nuclear@0: } nuclear@0: nuclear@0: Vector3 &Particle::get_velocity() nuclear@0: { nuclear@0: return velocity; nuclear@0: } nuclear@0: nuclear@0: const Vector3 &Particle::get_velocity() const nuclear@0: { nuclear@0: return velocity; nuclear@0: } nuclear@0: nuclear@0: void Particle::set_friction(float frict) nuclear@0: { nuclear@0: friction = frict; nuclear@0: } nuclear@0: nuclear@0: float Particle::get_friction() const nuclear@0: { nuclear@0: return friction; nuclear@0: } nuclear@0: nuclear@0: void Particle::add_force(const Vector3 &fvec) nuclear@0: { nuclear@0: forces += fvec; nuclear@0: } nuclear@0: nuclear@0: void Particle::step(SimWorld *world, float dt) nuclear@0: { nuclear@0: Vector3 accel = forces / mass; nuclear@0: forces.x = forces.y = forces.z = 0.0f; nuclear@0: nuclear@0: velocity = velocity * world->damping + accel * dt - velocity * friction * dt; nuclear@0: nuclear@0: Vector3 newpos = pos + velocity * dt; nuclear@0: nuclear@0: Ray ray(pos, newpos - pos); nuclear@0: Collision col; nuclear@0: nuclear@0: if(world->collision(ray, rad, &col)) { nuclear@0: pos = col.pos; nuclear@0: velocity = -velocity.reflection(col.normal) * elast; nuclear@0: } else { nuclear@0: pos = newpos; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: bool Particle::collision(const Particle *p2, Collision *col) const nuclear@0: { nuclear@0: if(ignorelist.find(p2) != ignorelist.end()) { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: Vector3 v = p2->pos - pos; nuclear@0: float dist_sq = dot_product(v, v); nuclear@0: float radsum = rad + p2->rad; nuclear@0: nuclear@0: if(dist_sq < radsum * radsum) { nuclear@0: float rad_ratio = rad / p2->rad; nuclear@0: Vector3 dir = p2->pos - pos; nuclear@0: col->pos = pos + dir * rad_ratio; nuclear@0: col->normal = -dir.normalized(); nuclear@0: col->elast = elast * p2->elast; nuclear@0: return true; nuclear@0: } nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: void Particle::draw() const nuclear@0: { nuclear@0: float color[] = {0.3, 0.9, 0.2, 1}; nuclear@0: nuclear@0: glPushMatrix(); nuclear@0: glTranslatef(pos.x, pos.y, pos.z); nuclear@0: nuclear@0: glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); nuclear@0: nuclear@0: glutSolidSphere(rad, 16, 8); nuclear@0: nuclear@0: glPushAttrib(GL_ENABLE_BIT); nuclear@0: glDisable(GL_DEPTH_TEST); nuclear@0: glDisable(GL_LIGHTING); nuclear@0: glEnable(GL_BLEND); nuclear@0: glBlendFunc(GL_ONE, GL_ONE); nuclear@0: glLineWidth(2.0); nuclear@0: nuclear@0: glBegin(GL_LINES); nuclear@0: glColor3f(0.3, 0, 0); nuclear@0: glVertex3f(0, 0, 0); nuclear@0: glVertex3f(velocity.x, velocity.y, velocity.z); nuclear@0: nuclear@0: glColor3f(0, 0, 0.8); nuclear@0: glVertex3f(0, 0, 0); nuclear@0: glVertex3f(forces.x, forces.y, forces.z); nuclear@0: glEnd(); nuclear@0: nuclear@0: glPopAttrib(); nuclear@0: nuclear@0: glPopMatrix(); nuclear@0: }