Newer
Older
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
#include "chain.hpp"
void chain::initialize()
{
// Initial position and speed of particles
// ******************************************* //
n = 30;
f_spring.resize(n);
f_weight.resize(n);
f_damping.resize(n);
f.resize(n);
v.resize(n, { 0, 0, 0 });
p.resize(n);
for (int i = 0; i < n; i++) p[i] = { 0.0f, 0.35f * i, 4.0f };
L0 = 0.4f;
particle_sphere.initialize_data_on_gpu(mesh_primitive_sphere(0.05f));
segment.display_type = curve_drawable_display_type::Segments;
segment.initialize_data_on_gpu({ {0,0,0},{1,0,0} });
}
void chain::simulation_step(float dt, vec3 bird_pos)
{
// Simulation parameters
float m = 0.01f; // particle mass
float K = 5.0f; // spring stiffness
float mu = 0.01f; // damping coefficient
vec3 g = { 0,0,-9.81f }; // gravity
// 1st ball tracks bird
p[0] = bird_pos;
// Forces
for (int i = 1; i < n; i++) {
f_spring[i] = spring_force(p[i], p[i - 1], L0, K);
f_weight[i] = m * g;
f_damping[i] = -mu * v[i];
}
for (int i = 1; i < n - 1; i++) {
f[i] = f_spring[i] + f_weight[i] + f_damping[i] - f_spring[i + 1];
}
// Numerical Integration
for (int i = 1; i < n - 1; i++) {
v[i] = v[i] + dt * f[i] / m;
p[i] = p[i] + dt * v[i];
}
}
vec3 chain::spring_force(vec3 const& p_i, vec3 const& p_j, float L0, float K)
{
vec3 const p = p_i - p_j;
float const L = norm(p);
vec3 const u = p / L;
vec3 const F = -K * (L - L0) * u;
return F;
}