Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/collision.c
| Context not available. | |||||
| // static collisions | // static collisions | ||||
| //////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////// | ||||
| // update cloth bvh | if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) { | ||||
| bvhtree_update_from_cloth ( clmd, 1 ); // 0 means STATIC, 1 means MOVING (see later in this function) | bvhtree_update_from_cloth(clmd, true); | ||||
| bvhselftree_update_from_cloth ( clmd, 0 ); // 0 means STATIC, 1 means MOVING (see later in this function) | |||||
| collobjs = BKE_collision_objects_create(depsgraph, ob, clmd->coll_parms->group, &numcollobj, eModifierType_Collision); | collobjs = BKE_collision_objects_create(depsgraph, ob, clmd->coll_parms->group, &numcollobj, eModifierType_Collision); | ||||
| if (!collobjs) | if (!collobjs) { | ||||
| return 0; | return 0; | ||||
| } | |||||
| /* move object to position (step) in time */ | /* Move object to position (step) in time. */ | ||||
| for (i = 0; i < numcollobj; i++) { | |||||
| Object *collob= collobjs[i]; | |||||
| CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType(collob, eModifierType_Collision); | |||||
| if (!collmd->bvhtree) | |||||
| continue; | |||||
| /* move object to position (step) in time */ | |||||
| collision_move_object ( collmd, step + dt, step ); | |||||
| } | |||||
| do { | |||||
| CollPair **collisions, **collisions_index; | |||||
| ret2 = 0; | |||||
| collisions = MEM_callocN(sizeof(CollPair *) *numcollobj, "CollPair"); | |||||
| collisions_index = MEM_callocN(sizeof(CollPair *) *numcollobj, "CollPair"); | |||||
| // check all collision objects | |||||
| for (i = 0; i < numcollobj; i++) { | for (i = 0; i < numcollobj; i++) { | ||||
| Object *collob= collobjs[i]; | Object *collob = collobjs[i]; | ||||
| CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType(collob, eModifierType_Collision); | CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType(collob, eModifierType_Collision); | ||||
| BVHTreeOverlap *overlap = NULL; | |||||
| unsigned int result = 0; | |||||
| if (!collmd->bvhtree) | if (!collmd->bvhtree) { | ||||
| continue; | continue; | ||||
| /* search for overlapping collision pairs */ | |||||
| overlap = BLI_bvhtree_overlap(cloth_bvh, collmd->bvhtree, &result, NULL, NULL); | |||||
| // go to next object if no overlap is there | |||||
| if ( result && overlap ) { | |||||
| /* check if collisions really happen (costly near check) */ | |||||
| cloth_bvh_objcollisions_nearcheck ( clmd, collmd, &collisions[i], | |||||
| &collisions_index[i], result, overlap, dt/(float)clmd->coll_parms->loop_count); | |||||
| // resolve nearby collisions | |||||
| ret += cloth_bvh_objcollisions_resolve ( clmd, collmd, collisions[i], collisions_index[i]); | |||||
| ret2 += ret; | |||||
| } | } | ||||
| if ( overlap ) | /* Move object to position (step) in time. */ | ||||
| MEM_freeN ( overlap ); | collision_move_object(collmd, step + dt, step); | ||||
| } | } | ||||
| rounds++; | } | ||||
| for (i = 0; i < numcollobj; i++) { | if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF) { | ||||
| if ( collisions[i] ) MEM_freeN ( collisions[i] ); | bvhselftree_update_from_cloth(clmd, false); | ||||
| } | } | ||||
| do { | |||||
| ret2 = 0; | |||||
| if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) { | |||||
| CollPair **collisions, **collisions_index; | |||||
| MEM_freeN(collisions); | collisions = MEM_callocN(sizeof(CollPair *) *numcollobj, "CollPair"); | ||||
| MEM_freeN(collisions_index); | collisions_index = MEM_callocN(sizeof(CollPair *) *numcollobj, "CollPair"); | ||||
| //////////////////////////////////////////////////////////// | /* Check all collision objects. */ | ||||
| // update positions | for (i = 0; i < numcollobj; i++) { | ||||
| // this is needed for bvh_calc_DOP_hull_moving() [kdop.c] | Object *collob= collobjs[i]; | ||||
| //////////////////////////////////////////////////////////// | CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType(collob, eModifierType_Collision); | ||||
| BVHTreeOverlap *overlap = NULL; | |||||
| unsigned int result = 0; | |||||
| /* verts come from clmd */ | if (!collmd->bvhtree) { | ||||
| for (i = 0; i < mvert_num; i++) { | |||||
| if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) { | |||||
| if ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) { | |||||
| continue; | continue; | ||||
| } | } | ||||
| /* Search for overlapping collision pairs. */ | |||||
| overlap = BLI_bvhtree_overlap(cloth_bvh, collmd->bvhtree, &result, NULL, NULL); | |||||
| /* Go to next object if no overlap is there. */ | |||||
| if (result && overlap) { | |||||
| /* Check if collisions really happen (costly near check). */ | |||||
| cloth_bvh_objcollisions_nearcheck(clmd, collmd, &collisions[i], &collisions_index[i], | |||||
| result, overlap, dt/(float)clmd->coll_parms->loop_count); | |||||
| /* Resolve nearby collisions. */ | |||||
| ret += cloth_bvh_objcollisions_resolve(clmd, collmd, collisions[i], collisions_index[i]); | |||||
| ret2 += ret; | |||||
| } | |||||
| MEM_SAFE_FREE(overlap); | |||||
| } | |||||
| for (i = 0; i < numcollobj; i++) { | |||||
| MEM_SAFE_FREE(collisions[i]); | |||||
| } | } | ||||
| VECADD ( verts[i].tx, verts[i].txold, verts[i].tv ); | MEM_freeN(collisions); | ||||
| MEM_freeN(collisions_index); | |||||
| //////////////////////////////////////////////////////////// | |||||
| // update positions | |||||
| // this is needed for bvh_calc_DOP_hull_moving() [kdop.c] | |||||
| //////////////////////////////////////////////////////////// | |||||
| /* Verts come from clmd. */ | |||||
| for (i = 0; i < mvert_num; i++) { | |||||
| if (clmd->sim_parms->vgroup_mass > 0) { | |||||
| if (verts [i].flags & CLOTH_VERT_FLAG_PINNED) { | |||||
| continue; | |||||
| } | |||||
| } | |||||
| VECADD(verts[i].tx, verts[i].txold, verts[i].tv); | |||||
| } | |||||
| //////////////////////////////////////////////////////////// | |||||
| } | } | ||||
| //////////////////////////////////////////////////////////// | |||||
| rounds++; | |||||
| //////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////// | ||||
| // Test on *simple* selfcollisions | // Test on *simple* selfcollisions | ||||
| Context not available. | |||||
| mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len ); | mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len ); | ||||
| if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) { | if (clmd->sim_parms->vgroup_mass > 0) { | ||||
| if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) && | if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) && | ||||
| ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) ) | ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) ) | ||||
| { | { | ||||
| Context not available. | |||||
| // verts come from clmd | // verts come from clmd | ||||
| for (i = 0; i < mvert_num; i++) { | for (i = 0; i < mvert_num; i++) { | ||||
| if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) { | if (clmd->sim_parms->vgroup_mass > 0) { | ||||
| if ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) { | if ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| Context not available. | |||||
| // verts come from clmd | // verts come from clmd | ||||
| for (i = 0; i < mvert_num; i++) { | for (i = 0; i < mvert_num; i++) { | ||||
| if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { | if (clmd->sim_parms->vgroup_mass > 0) { | ||||
| if (verts [i].flags & CLOTH_VERT_FLAG_PINNED) { | if (verts [i].flags & CLOTH_VERT_FLAG_PINNED) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| Context not available. | |||||