cloth

view 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
line source
1 #include <float.h>
2 #include "simworld.h"
4 SimWorld::SimWorld()
5 {
6 grav = Vector3(0, -9.81, 0);
7 damping = 0.99;
8 }
10 void SimWorld::add_object(Object *o)
11 {
12 objects.push_back(o);
13 }
15 int SimWorld::get_object_count() const
16 {
17 return (int)objects.size();
18 }
20 Object *SimWorld::get_object(int idx) const
21 {
22 return objects[idx];
23 }
25 void SimWorld::add_particle(Particle *p)
26 {
27 part.push_back(p);
28 }
30 bool SimWorld::collision(const Ray &ray, float rad, Collision *col) const
31 {
32 Collision nearest;
33 nearest.dist = FLT_MAX;
35 for(auto obj : objects) {
36 Collision tmpcol;
37 if(obj->collision(ray, rad, &tmpcol) && tmpcol.dist < nearest.dist) {
38 nearest = tmpcol;
39 }
40 }
42 *col = nearest;
43 return true;
44 }
46 void SimWorld::step(float dt)
47 {
48 for(size_t i=0; i<part.size(); i++) {
49 // add gravity
50 part[i]->add_force(grav * part[i]->get_mass());
52 part[i]->step(this, dt);
54 // handle collisions with other particles
55 for(size_t j=0; j<part.size(); j++) {
56 Collision col;
57 if(i != j && part[i]->collision(part[j], &col)) {
58 Vector3 rel_vel = part[j]->get_velocity() - part[i]->get_velocity();
60 float kn = 1.0 / part[i]->get_mass() + 1.0 / part[j]->get_mass();
61 float imp = dot_product(rel_vel, col.normal) * (col.elast + 1) / kn;
63 if(imp < 0.0) imp = 0.0;
65 Vector3 v = part[i]->get_position() - part[j]->get_position();
66 float dist_sq = v.length_sq();
67 float pen_depth_sq = part[i]->get_radius() + part[j]->get_radius() - dist_sq;
68 if(pen_depth_sq < 0.0) pen_depth_sq = 0.0;
70 part[i]->add_force(col.normal * imp * (1.0 / dt * pen_depth_sq + 1));
71 }
72 }
73 }
74 }
76 void SimWorld::draw_particles() const
77 {
78 for(size_t i=0; i<part.size(); i++) {
79 part[i]->draw();
80 }
81 }