static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *result, int framenr) { ClothVertex *verts = NULL; Cloth *cloth; ListBase *effectors = NULL; MVert *mvert; unsigned int i = 0; int ret = 0; /* simulate 1 frame forward */ cloth = clmd->clothObject; verts = cloth->verts; mvert = result->getVertArray(result); /* force any pinned verts to their constrained location. */ for (i = 0; i < clmd->clothObject->mvert_num; i++, verts++) { /* save the previous position. */ copy_v3_v3(verts->xold, verts->xconst); copy_v3_v3(verts->txold, verts->x); /* Get the current position. */ copy_v3_v3(verts->xconst, mvert[i].co); mul_m4_v3(ob->obmat, verts->xconst); } effectors = pdInitEffectors(clmd->scene, ob, NULL, clmd->sim_parms->effector_weights, true); if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH ) cloth_update_verts ( ob, clmd, result ); /* Support for dynamic vertex groups, changing from frame to frame */ cloth_apply_vgroup ( clmd, result ); if ( clmd->sim_parms->flags & (CLOTH_SIMSETTINGS_FLAG_SEW | CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH) ) cloth_update_spring_lengths ( clmd, result ); cloth_update_springs( clmd ); // TIMEIT_START(cloth_step) /* call the solver. */ ret = BPH_cloth_solve(ob, framenr, clmd, effectors); // TIMEIT_END(cloth_step) pdEndEffectors(&effectors); // printf ( "%f\n", ( float ) tval() ); return ret; }
static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float UNUSED(framenr), int first) { int i = 0; MVert *mvert = NULL; ClothVertex *verts = NULL; float (*shapekey_rest)[3]= NULL; float tnull[3] = {0,0,0}; Cloth *cloth = NULL; float maxdist = 0; // If we have a clothObject, free it. if ( clmd->clothObject != NULL ) { cloth_free_modifier ( clmd ); if(G.rt > 0) printf("cloth_free_modifier cloth_from_object\n"); } // Allocate a new cloth object. clmd->clothObject = MEM_callocN ( sizeof ( Cloth ), "cloth" ); if ( clmd->clothObject ) { clmd->clothObject->old_solver_type = 255; // clmd->clothObject->old_collision_type = 255; cloth = clmd->clothObject; clmd->clothObject->edgehash = NULL; } else if ( !clmd->clothObject ) { modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject." ); return 0; } // mesh input objects need DerivedMesh if ( !dm ) return 0; cloth_from_mesh ( clmd, dm ); // create springs clmd->clothObject->springs = NULL; clmd->clothObject->numsprings = -1; if( clmd->sim_parms->shapekey_rest ) shapekey_rest = dm->getVertDataArray ( dm, CD_CLOTH_ORCO ); mvert = dm->getVertArray ( dm ); verts = clmd->clothObject->verts; // set initial values for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ ) { if(first) { copy_v3_v3( verts->x, mvert[i].co ); mul_m4_v3( ob->obmat, verts->x ); if( shapekey_rest ) { verts->xrest= shapekey_rest[i]; mul_m4_v3( ob->obmat, verts->xrest ); } else verts->xrest = verts->x; } /* no GUI interface yet */ verts->mass = clmd->sim_parms->mass; verts->impulse_count = 0; if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) verts->goal= clmd->sim_parms->defgoal; else verts->goal= 0.0f; verts->flags = 0; copy_v3_v3 ( verts->xold, verts->x ); copy_v3_v3 ( verts->xconst, verts->x ); copy_v3_v3 ( verts->txold, verts->x ); copy_v3_v3 ( verts->tx, verts->x ); mul_v3_fl( verts->v, 0.0f ); verts->impulse_count = 0; copy_v3_v3 ( verts->impulse, tnull ); } // apply / set vertex groups // has to be happen before springs are build! cloth_apply_vgroup (clmd, dm); if ( !cloth_build_springs ( clmd, dm ) ) { cloth_free_modifier ( clmd ); modifier_setError ( & ( clmd->modifier ), "Can't build springs." ); printf("cloth_free_modifier cloth_build_springs\n"); return 0; } for ( i = 0; i < dm->getNumVerts(dm); i++) { if((!(cloth->verts[i].flags & CLOTH_VERT_FLAG_PINNED)) && (cloth->verts[i].goal > ALMOST_ZERO)) { cloth_add_spring (clmd, i, i, 0.0, CLOTH_SPRING_TYPE_GOAL); } } // init our solver if ( solvers [clmd->sim_parms->solver_type].init ) { solvers [clmd->sim_parms->solver_type].init ( ob, clmd ); } if(!first) implicit_set_positions(clmd); clmd->clothObject->bvhtree = bvhtree_build_from_cloth ( clmd, MAX2(clmd->coll_parms->epsilon, clmd->coll_parms->distance_repel) ); for(i = 0; i < dm->getNumVerts(dm); i++) { maxdist = MAX2(maxdist, clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len*2.0f)); } clmd->clothObject->bvhselftree = bvhselftree_build_from_cloth ( clmd, maxdist ); return 1; }