5 static void step(struct rsim_world *rsim, struct rsim_rope *rope, float dt);
7 int rsim_init(struct rsim_world *rsim)
10 cgm_vcons(&rsim->grav, 0, -9.807, 0);
15 void rsim_destroy(struct rsim_world *rsim)
18 struct rsim_rope *rope = rsim->ropes;
19 rsim->ropes = rsim->ropes->next;
24 int rsim_add_rope(struct rsim_world *rsim, struct rsim_rope *rope)
26 rope->next = rsim->ropes;
31 /* actual step function, called by rsim_step in a loop to microstep or once if
32 * microstepping is disabled
34 static void step(struct rsim_world *rsim, struct rsim_rope *rope, float dt)
38 cgm_vec3 npos, faccel, dir;
39 float inv_damp = rsim->damping == 0.0f ? 1.0f : (1.0f - rsim->damping);
40 struct rsim_mass *mass = rope->masses;
41 struct rsim_spring *spr = rope->springs;
43 /* accumulate forces from springs */
44 for(i=0; i<rope->num_springs; i++) {
45 dir = spr->mass[1]->p;
46 cgm_vsub(&dir, &spr->mass[0]->p);
48 len = cgm_vlength(&dir);
55 fmag = (len - spr->rest_len) * spr->k;
57 spr->mass[0]->f.x += dir.x * fmag / spr->mass[0]->m;
58 spr->mass[0]->f.y += dir.y * fmag / spr->mass[0]->m;
59 spr->mass[0]->f.z += dir.z * fmag / spr->mass[0]->m;
61 spr->mass[1]->f.x -= dir.x * fmag / spr->mass[1]->m;
62 spr->mass[1]->f.y -= dir.y * fmag / spr->mass[1]->m;
63 spr->mass[1]->f.z -= dir.z * fmag / spr->mass[1]->m;
69 for(i=0; i<rope->num_masses; i++) {
75 /* add constant forces to accumulated mass force */
76 cgm_vadd(&mass->f, &rsim->grav);
78 faccel = rsim->extforce;
79 cgm_vscale(&faccel, 1.0f / mass->m);
80 cgm_vadd(&mass->f, &rsim->extforce);
82 mass->v.x = (mass->v.x - mass->v.x * inv_damp * dt) + mass->f.x * dt;
83 mass->v.y = (mass->v.y - mass->v.y * inv_damp * dt) + mass->f.y * dt;
84 mass->v.z = (mass->v.z - mass->v.z * inv_damp * dt) + mass->f.z * dt;
86 /* zero out the accumulated forces for next iter */
87 mass->f.x = mass->f.y = mass->f.z = 0.0f;
90 npos.x = mass->p.x + mass->v.x * dt;
91 npos.y = mass->p.y + mass->v.y * dt;
92 npos.z = mass->p.z + mass->v.z * dt;
101 void rsim_step(struct rsim_world *rsim, float dt)
103 struct rsim_rope *rope = rsim->ropes;
105 if(rsim->udt > 0.0f) {
107 float dt_acc = rsim->udelta_acc;
111 step(rsim, rope, rsim->udt);
116 rsim->udelta_acc = dt_acc - dt;
119 step(rsim, rope, dt);
125 struct rsim_rope *rsim_alloc_rope(int nmasses, int nsprings)
127 struct rsim_rope *rope;
129 if(!(rope = malloc(sizeof *rope))) {
132 if(rsim_init_rope(rope, nmasses, nsprings) == -1) {
139 void rsim_free_rope(struct rsim_rope *rope)
141 rsim_destroy_rope(rope);
145 int rsim_init_rope(struct rsim_rope *rope, int nmasses, int nsprings)
147 memset(rope, 0, sizeof *rope);
149 if(!(rope->masses = calloc(nmasses, sizeof *rope->masses))) {
152 if(!(rope->springs = calloc(nsprings, sizeof *rope->springs))) {
156 rope->num_masses = nmasses;
157 rope->num_springs = nsprings;
161 void rsim_destroy_rope(struct rsim_rope *rope)
167 int rsim_freeze_rope_mass(struct rsim_rope *rope, struct rsim_mass *m)
169 if(m->fixed) return -1;
172 m->next = rope->fixedlist;
177 int rsim_unfreeze_rope_mass(struct rsim_rope *rope, struct rsim_mass *m)
179 struct rsim_mass *it, dummy;
181 if(!m->fixed) return -1;
183 dummy.next = rope->fixedlist;
194 rope->fixedlist = dummy.next;
196 return m->fixed ? -1 : 0;