-
Notifications
You must be signed in to change notification settings - Fork 0
/
RubberRope.cpp
78 lines (67 loc) · 2.04 KB
/
RubberRope.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//TODO: REIMPLEMENT!!
#include "RubberRope.h"
template <typename pos_t, typename mass_t>
Matrix<pos_t, 3, 1> RubberRope<pos_t, mass_t>::spring_force(const Vec3d& x, const Vec3d& reference)
{
Vec3d result(0, 0, 0);
Vec3d direction = (reference - x).normalized();
pos_t delta = (x - reference).norm() - rest_dist;
return delta*k*direction;
}
template <typename pos_t, typename mass_t>
RubberRope<pos_t, mass_t>::RubberRope(pos_t mass, const Vec3d& start, const Vec3d& end, unsigned num_links, double spring_k, double damp_k)
: Rope(mass, start, end, num_links), k(spring_k), d(damp_k)
{
rest_dist = (start - end).norm()/double(num_links);
}
template <typename pos_t, typename mass_t>
void RubberRope<pos_t, mass_t>::step(int millisecs)
{
Vec3d impulse;
double time = millisecs/1000.0;
/* Impulse from each spring */
if (links.size() > 1)
{
impulse = spring_force(links[0].pos, links[1].pos)*time;
addImpulseAt(impulse, 0);
}
for (size_t i = 1; i < links.size()-1; ++i)
{
impulse = spring_force(links[i].pos, links[i+1].pos)*time;
impulse += spring_force(links[i].pos, links[i-1].pos)*time;
addImpulseAt(impulse, i);
}
if(links.size() > 1)
{
impulse = spring_force(links[links.size()-1].pos, links[links.size()-2].pos)*time;
addImpulseAt(impulse, links.size()-1);
}
Rope::step(millisecs);
/* Damping each spring */
if (links.size() > 1)
{
Vec3d component = project(links[0].vel, links[1].pos - links[0].pos);
links[0].vel -= component;
component *= d;
links[0].vel += component;
}
for (size_t i = 1; i < links.size()-1; ++i)
{
Vec3d component = project(links[i].vel, links[i+1].pos - links[i].pos);
links[i].vel -= component;
component *= d;
links[i].vel += component;
component = project(links[i].vel, links[i-1].pos - links[i].pos);
links[i].vel -= component;
component *= d;
links[i].vel += component;
}
if(links.size() > 1)
{
size_t i = links.size()-1;
Vec3d component = project(links[i].vel, links[i-1].pos - links[i].pos);
links[i].vel -= component;
component *= d;
links[i].vel += component;
}
}