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, force, 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 force.x = rsim->grav.x + rsim->extforce.x;
44 force.y = rsim->grav.y + rsim->extforce.y;
45 force.z = rsim->grav.z + rsim->extforce.z;
47 /* accumulate forces from springs */
48 for(i=0; i<rope->num_springs; i++) {
49 dir = spr->mass[1]->p;
50 cgm_vsub(&dir, &spr->mass[0]->p);
52 len = cgm_vlength(&dir);
59 fmag = (len - spr->rest_len) * spr->k;
61 cgm_vscale(&dir, fmag);
62 cgm_vadd(&spr->mass[0]->f, &dir);
63 cgm_vsub(&spr->mass[1]->f, &dir);
69 for(i=0; i<rope->num_masses; i++) {
75 /* add constant forces to accumulated mass force */
76 cgm_vadd(&mass->f, &force);
78 mass->v.x = (mass->v.x - mass->v.x * inv_damp * dt) + mass->f.x * dt;
79 mass->v.y = (mass->v.y - mass->v.y * inv_damp * dt) + mass->f.y * dt;
80 mass->v.z = (mass->v.z - mass->v.z * inv_damp * dt) + mass->f.z * dt;
82 /* zero out the accumulated forces for next iter */
83 mass->f.x = mass->f.y = mass->f.z = 0.0f;
86 npos.x = mass->p.x + mass->v.x * dt;
87 npos.y = mass->p.y + mass->v.y * dt;
88 npos.z = mass->p.z + mass->v.z * dt;
97 void rsim_step(struct rsim_world *rsim, float dt)
99 struct rsim_rope *rope = rsim->ropes;
101 if(rsim->udt > 0.0f) {
103 float dt_acc = rsim->udelta_acc;
107 step(rsim, rope, rsim->udt);
112 rsim->udelta_acc = dt_acc - dt;
115 step(rsim, rope, dt);
121 struct rsim_rope *rsim_alloc_rope(int nmasses, int nsprings)
123 struct rsim_rope *rope;
125 if(!(rope = malloc(sizeof *rope))) {
128 if(rsim_init_rope(rope, nmasses, nsprings) == -1) {
135 void rsim_free_rope(struct rsim_rope *rope)
137 rsim_destroy_rope(rope);
141 int rsim_init_rope(struct rsim_rope *rope, int nmasses, int nsprings)
143 memset(rope, 0, sizeof *rope);
145 if(!(rope->masses = calloc(nmasses, sizeof *rope->masses))) {
148 if(!(rope->springs = calloc(nsprings, sizeof *rope->springs))) {
152 rope->num_masses = nmasses;
153 rope->num_springs = nsprings;
157 void rsim_destroy_rope(struct rsim_rope *rope)
163 int rsim_freeze_rope_mass(struct rsim_rope *rope, struct rsim_mass *m)
165 if(m->fixed) return -1;
168 m->next = rope->fixedlist;
173 int rsim_unfreeze_rope_mass(struct rsim_rope *rope, struct rsim_mass *m)
175 struct rsim_mass *it, dummy;
177 if(!m->fixed) return -1;
179 dummy.next = rope->fixedlist;
190 rope->fixedlist = dummy.next;
192 return m->fixed ? -1 : 0;