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 }
|