cloth

annotate src/particle.cc @ 3:28a31079dcdf

disc
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 04 Jan 2016 10:52:15 +0200
parents
children
rev   line source
nuclear@0 1 #include <vector>
nuclear@0 2 #include "opengl.h"
nuclear@0 3 #include "particle.h"
nuclear@0 4 #include "simworld.h"
nuclear@0 5
nuclear@0 6 Particle::Particle()
nuclear@0 7 : forces(0, 0, 0), pos(0, 0, 0), velocity(0, 0, 0)
nuclear@0 8 {
nuclear@0 9 rad = 1.0;
nuclear@0 10 elast = 0.75;
nuclear@0 11 mass = 1.0;
nuclear@0 12 friction = 0.0;
nuclear@0 13 }
nuclear@0 14
nuclear@0 15 void Particle::add_ignore(const Particle *p)
nuclear@0 16 {
nuclear@0 17 ignorelist.insert(p);
nuclear@0 18 }
nuclear@0 19
nuclear@0 20 void Particle::set_radius(float rad)
nuclear@0 21 {
nuclear@0 22 this->rad = rad;
nuclear@0 23 }
nuclear@0 24
nuclear@0 25 float Particle::get_radius() const
nuclear@0 26 {
nuclear@0 27 return rad;
nuclear@0 28 }
nuclear@0 29
nuclear@0 30 void Particle::set_mass(float m)
nuclear@0 31 {
nuclear@0 32 mass = m;
nuclear@0 33 }
nuclear@0 34
nuclear@0 35 float Particle::get_mass() const
nuclear@0 36 {
nuclear@0 37 return mass;
nuclear@0 38 }
nuclear@0 39
nuclear@0 40 void Particle::set_elasticity(float e)
nuclear@0 41 {
nuclear@0 42 elast = e;
nuclear@0 43 }
nuclear@0 44
nuclear@0 45 float Particle::get_elasticity() const
nuclear@0 46 {
nuclear@0 47 return elast;
nuclear@0 48 }
nuclear@0 49
nuclear@0 50 void Particle::set_position(const Vector3 &pos)
nuclear@0 51 {
nuclear@0 52 this->pos = pos;
nuclear@0 53 }
nuclear@0 54
nuclear@0 55 void Particle::set_velocity(const Vector3 &vel)
nuclear@0 56 {
nuclear@0 57 velocity = vel;
nuclear@0 58 }
nuclear@0 59
nuclear@0 60 Vector3 &Particle::get_position()
nuclear@0 61 {
nuclear@0 62 return pos;
nuclear@0 63 }
nuclear@0 64
nuclear@0 65 const Vector3 &Particle::get_position() const
nuclear@0 66 {
nuclear@0 67 return pos;
nuclear@0 68 }
nuclear@0 69
nuclear@0 70 Vector3 &Particle::get_velocity()
nuclear@0 71 {
nuclear@0 72 return velocity;
nuclear@0 73 }
nuclear@0 74
nuclear@0 75 const Vector3 &Particle::get_velocity() const
nuclear@0 76 {
nuclear@0 77 return velocity;
nuclear@0 78 }
nuclear@0 79
nuclear@0 80 void Particle::set_friction(float frict)
nuclear@0 81 {
nuclear@0 82 friction = frict;
nuclear@0 83 }
nuclear@0 84
nuclear@0 85 float Particle::get_friction() const
nuclear@0 86 {
nuclear@0 87 return friction;
nuclear@0 88 }
nuclear@0 89
nuclear@0 90 void Particle::add_force(const Vector3 &fvec)
nuclear@0 91 {
nuclear@0 92 forces += fvec;
nuclear@0 93 }
nuclear@0 94
nuclear@0 95 void Particle::step(SimWorld *world, float dt)
nuclear@0 96 {
nuclear@0 97 Vector3 accel = forces / mass;
nuclear@0 98 forces.x = forces.y = forces.z = 0.0f;
nuclear@0 99
nuclear@0 100 velocity = velocity * world->damping + accel * dt - velocity * friction * dt;
nuclear@0 101
nuclear@0 102 Vector3 newpos = pos + velocity * dt;
nuclear@0 103
nuclear@0 104 Ray ray(pos, newpos - pos);
nuclear@0 105 Collision col;
nuclear@0 106
nuclear@0 107 if(world->collision(ray, rad, &col)) {
nuclear@0 108 pos = col.pos;
nuclear@0 109 velocity = -velocity.reflection(col.normal) * elast;
nuclear@0 110 } else {
nuclear@0 111 pos = newpos;
nuclear@0 112 }
nuclear@0 113 }
nuclear@0 114
nuclear@0 115 bool Particle::collision(const Particle *p2, Collision *col) const
nuclear@0 116 {
nuclear@0 117 if(ignorelist.find(p2) != ignorelist.end()) {
nuclear@0 118 return false;
nuclear@0 119 }
nuclear@0 120
nuclear@0 121 Vector3 v = p2->pos - pos;
nuclear@0 122 float dist_sq = dot_product(v, v);
nuclear@0 123 float radsum = rad + p2->rad;
nuclear@0 124
nuclear@0 125 if(dist_sq < radsum * radsum) {
nuclear@0 126 float rad_ratio = rad / p2->rad;
nuclear@0 127 Vector3 dir = p2->pos - pos;
nuclear@0 128 col->pos = pos + dir * rad_ratio;
nuclear@0 129 col->normal = -dir.normalized();
nuclear@0 130 col->elast = elast * p2->elast;
nuclear@0 131 return true;
nuclear@0 132 }
nuclear@0 133 return false;
nuclear@0 134 }
nuclear@0 135
nuclear@0 136 void Particle::draw() const
nuclear@0 137 {
nuclear@0 138 float color[] = {0.3, 0.9, 0.2, 1};
nuclear@0 139
nuclear@0 140 glPushMatrix();
nuclear@0 141 glTranslatef(pos.x, pos.y, pos.z);
nuclear@0 142
nuclear@0 143 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
nuclear@0 144
nuclear@0 145 glutSolidSphere(rad, 16, 8);
nuclear@0 146
nuclear@0 147 glPushAttrib(GL_ENABLE_BIT);
nuclear@0 148 glDisable(GL_DEPTH_TEST);
nuclear@0 149 glDisable(GL_LIGHTING);
nuclear@0 150 glEnable(GL_BLEND);
nuclear@0 151 glBlendFunc(GL_ONE, GL_ONE);
nuclear@0 152 glLineWidth(2.0);
nuclear@0 153
nuclear@0 154 glBegin(GL_LINES);
nuclear@0 155 glColor3f(0.3, 0, 0);
nuclear@0 156 glVertex3f(0, 0, 0);
nuclear@0 157 glVertex3f(velocity.x, velocity.y, velocity.z);
nuclear@0 158
nuclear@0 159 glColor3f(0, 0, 0.8);
nuclear@0 160 glVertex3f(0, 0, 0);
nuclear@0 161 glVertex3f(forces.x, forces.y, forces.z);
nuclear@0 162 glEnd();
nuclear@0 163
nuclear@0 164 glPopAttrib();
nuclear@0 165
nuclear@0 166 glPopMatrix();
nuclear@0 167 }