+
+ for(i=0; i<sizeof meshes / sizeof *meshes; i++) {
+ int idx;
+ if((idx = cmesh_find_submesh(scn, meshnames[i])) == -1) {
+ fprintf(stderr, "failed to locate required submesh (%s)\n", meshnames[i]);
+ return -1;
+ }
+ if(!(*meshes[i] = cmesh_alloc()) || cmesh_clone_submesh(*meshes[i], scn, idx) == -1) {
+ fprintf(stderr, "failed to clone submesh\n");
+ return -1;
+ }
+ cmesh_remove_submesh(scn, idx);
+ }
+
+ rsim_init(&rsim);
+ rsim.damping = 0.3;
+
+ if(!(rope = rsim_alloc_rope(ROPE_MASSES * 4))) {
+ fprintf(stderr, "failed to allocate rope\n");
+ return -1;
+ }
+ rsim_add_rope(&rsim, rope);
+
+ /* anchor points on the inner gimbal */
+ for(i=0; i<4; i++) {
+ ganchor[i].x = (float)(((i & 1) << 1) - 1) * 1.5f;
+ ganchor[i].y = (float)((i & 2) - 1) * 1.5f;
+ ganchor[i].z = 0;
+
+ manchor[i] = ganchor[i];
+ cgm_vscale(manchor + i, 0.32);
+
+
+
+ manchor[i].y += 0.15;
+
+ for(j=0; j<ROPE_MASSES; j++) {
+ int midx = i * ROPE_MASSES + j;
+ struct rsim_mass *mass = rope->masses + midx;
+
+ float t = (float)j / (float)(ROPE_MASSES - 1.0f);
+ cgm_vlerp(&mass->p, ganchor + i, manchor + i, t);
+ mass->m = ROPE_MASSES_MASS;
+
+ if(j == 0) {
+ rsim_freeze_rope_mass(rope, rope->masses + i * ROPE_MASSES); /* freeze first mass */
+ } else {
+ rsim_set_rope_spring(rope, midx, midx - 1, ROPE_K, RSIM_RLEN_DEFAULT);
+ }
+ }
+ }
+