cloth

view src/particle.cc @ 3:28a31079dcdf

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