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 }