cloth
annotate src/simworld.cc @ 3:28a31079dcdf
disc
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 04 Jan 2016 10:52:15 +0200 |
parents | 2eac424f58b2 |
children |
rev | line source |
---|---|
nuclear@2 | 1 #include <float.h> |
nuclear@0 | 2 #include "simworld.h" |
nuclear@0 | 3 |
nuclear@0 | 4 SimWorld::SimWorld() |
nuclear@0 | 5 { |
nuclear@0 | 6 grav = Vector3(0, -9.81, 0); |
nuclear@0 | 7 damping = 0.99; |
nuclear@0 | 8 } |
nuclear@0 | 9 |
nuclear@3 | 10 void SimWorld::add_object(Object *o) |
nuclear@3 | 11 { |
nuclear@3 | 12 objects.push_back(o); |
nuclear@3 | 13 } |
nuclear@3 | 14 |
nuclear@3 | 15 int SimWorld::get_object_count() const |
nuclear@3 | 16 { |
nuclear@3 | 17 return (int)objects.size(); |
nuclear@3 | 18 } |
nuclear@3 | 19 |
nuclear@3 | 20 Object *SimWorld::get_object(int idx) const |
nuclear@3 | 21 { |
nuclear@3 | 22 return objects[idx]; |
nuclear@3 | 23 } |
nuclear@3 | 24 |
nuclear@0 | 25 void SimWorld::add_particle(Particle *p) |
nuclear@0 | 26 { |
nuclear@0 | 27 part.push_back(p); |
nuclear@0 | 28 } |
nuclear@0 | 29 |
nuclear@0 | 30 bool SimWorld::collision(const Ray &ray, float rad, Collision *col) const |
nuclear@0 | 31 { |
nuclear@2 | 32 Collision nearest; |
nuclear@2 | 33 nearest.dist = FLT_MAX; |
nuclear@0 | 34 |
nuclear@2 | 35 for(auto obj : objects) { |
nuclear@2 | 36 Collision tmpcol; |
nuclear@2 | 37 if(obj->collision(ray, rad, &tmpcol) && tmpcol.dist < nearest.dist) { |
nuclear@2 | 38 nearest = tmpcol; |
nuclear@2 | 39 } |
nuclear@0 | 40 } |
nuclear@0 | 41 |
nuclear@2 | 42 *col = nearest; |
nuclear@2 | 43 return true; |
nuclear@0 | 44 } |
nuclear@0 | 45 |
nuclear@0 | 46 void SimWorld::step(float dt) |
nuclear@0 | 47 { |
nuclear@0 | 48 for(size_t i=0; i<part.size(); i++) { |
nuclear@0 | 49 // add gravity |
nuclear@0 | 50 part[i]->add_force(grav * part[i]->get_mass()); |
nuclear@0 | 51 |
nuclear@0 | 52 part[i]->step(this, dt); |
nuclear@0 | 53 |
nuclear@0 | 54 // handle collisions with other particles |
nuclear@0 | 55 for(size_t j=0; j<part.size(); j++) { |
nuclear@0 | 56 Collision col; |
nuclear@0 | 57 if(i != j && part[i]->collision(part[j], &col)) { |
nuclear@0 | 58 Vector3 rel_vel = part[j]->get_velocity() - part[i]->get_velocity(); |
nuclear@0 | 59 |
nuclear@0 | 60 float kn = 1.0 / part[i]->get_mass() + 1.0 / part[j]->get_mass(); |
nuclear@0 | 61 float imp = dot_product(rel_vel, col.normal) * (col.elast + 1) / kn; |
nuclear@0 | 62 |
nuclear@0 | 63 if(imp < 0.0) imp = 0.0; |
nuclear@0 | 64 |
nuclear@0 | 65 Vector3 v = part[i]->get_position() - part[j]->get_position(); |
nuclear@0 | 66 float dist_sq = v.length_sq(); |
nuclear@0 | 67 float pen_depth_sq = part[i]->get_radius() + part[j]->get_radius() - dist_sq; |
nuclear@0 | 68 if(pen_depth_sq < 0.0) pen_depth_sq = 0.0; |
nuclear@0 | 69 |
nuclear@0 | 70 part[i]->add_force(col.normal * imp * (1.0 / dt * pen_depth_sq + 1)); |
nuclear@0 | 71 } |
nuclear@0 | 72 } |
nuclear@0 | 73 } |
nuclear@0 | 74 } |
nuclear@0 | 75 |
nuclear@0 | 76 void SimWorld::draw_particles() const |
nuclear@0 | 77 { |
nuclear@0 | 78 for(size_t i=0; i<part.size(); i++) { |
nuclear@0 | 79 part[i]->draw(); |
nuclear@0 | 80 } |
nuclear@0 | 81 } |