diff options
Diffstat (limited to 'source/blender/blenkernel/intern/collision.c')
-rw-r--r-- | source/blender/blenkernel/intern/collision.c | 61 |
1 files changed, 36 insertions, 25 deletions
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index ffd504f5945..af12d23b2c2 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -37,9 +37,15 @@ #include "DNA_object_types.h" #include "DNA_object_force.h" #include "DNA_scene_types.h" +#include "DNA_meshdata_types.h" + +#include "BLI_blenlib.h" +#include "BLI_math.h" +#include "BLI_edgehash.h" #include "BKE_DerivedMesh.h" #include "BKE_global.h" +#include "BKE_scene.h" #include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_modifier.h" @@ -59,7 +65,7 @@ Collision modifier code start /* step is limited from 0 (frame start position) to 1 (frame end position) */ void collision_move_object ( CollisionModifierData *collmd, float step, float prevstep ) { - float tv[3] = {0,0,0}; + float tv[3] = {0, 0, 0}; unsigned int i = 0; for ( i = 0; i < collmd->numverts; i++ ) @@ -69,6 +75,7 @@ void collision_move_object ( CollisionModifierData *collmd, float step, float pr VECADDS ( collmd->current_xnew[i].co, collmd->x[i].co, tv, step ); VECSUB ( collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co ); } + bvhtree_update_from_mvert ( collmd->bvhtree, collmd->mfaces, collmd->numfaces, collmd->current_x, collmd->current_xnew, collmd->numverts, 1 ); } @@ -527,7 +534,7 @@ int cloth_collision_response_static ( ClothModifierData *clmd, CollisionModifier float magtangent = 0, repulse = 0, d = 0; double impulse = 0.0; float vrel_t_pre[3]; - float temp[3]; + float temp[3], spf; // calculate tangential velocity VECCOPY ( temp, collpair->normal ); @@ -565,10 +572,12 @@ int cloth_collision_response_static ( ClothModifierData *clmd, CollisionModifier // Apply repulse impulse if distance too short // I_r = -min(dt*kd, m(0,1d/dt - v_n)) + spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale; + d = clmd->coll_parms->epsilon*8.0/9.0 + epsilon2*8.0/9.0 - collpair->distance; - if ( ( magrelVel < 0.1*d*clmd->sim_parms->stepsPerFrame ) && ( d > ALMOST_ZERO ) ) + if ( ( magrelVel < 0.1*d*spf ) && ( d > ALMOST_ZERO ) ) { - repulse = MIN2 ( d*1.0/clmd->sim_parms->stepsPerFrame, 0.1*d*clmd->sim_parms->stepsPerFrame - magrelVel ); + repulse = MIN2 ( d*1.0/spf, 0.1*d*spf - magrelVel ); // stay on the safe side and clamp repulse if ( impulse > ALMOST_ZERO ) @@ -587,7 +596,7 @@ int cloth_collision_response_static ( ClothModifierData *clmd, CollisionModifier return result; } -//Determines collisions on overlap, collisions are writen to collpair[i] and collision+number_collision_found is returned +//Determines collisions on overlap, collisions are written to collpair[i] and collision+number_collision_found is returned CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTreeOverlap *overlap, CollPair *collpair ) { ClothModifierData *clmd = ( ClothModifierData * ) md1; @@ -682,8 +691,7 @@ CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTreeOverlap if ( distance <= ( epsilon1 + epsilon2 + ALMOST_ZERO ) ) { - VECCOPY ( collpair->normal, collpair->vector ); - normalize_v3( collpair->normal ); + normalize_v3_v3( collpair->normal, collpair->vector ); collpair->distance = distance; collpair->flag = 0; @@ -1350,10 +1358,13 @@ Object **get_collisionobjects(Scene *scene, Object *self, Group *group, int *num add_collision_object(&objs, &numobj, &maxobj, go->ob, self, 0); } else { + Scene *sce; /* for SETLOOPER macro */ /* add objects in same layer in scene */ - for(base = scene->base.first; base; base = base->next) - if(base->lay & self->lay) + for(SETLOOPER(scene, base)) { + if(base->lay & self->lay) add_collision_object(&objs, &numobj, &maxobj, base->object, self, 0); + + } } *numcollobj= numobj; @@ -1397,7 +1408,6 @@ static void add_collider_cache_object(ListBase **objs, Object *ob, Object *self, ListBase *get_collider_cache(Scene *scene, Object *self, Group *group) { - Base *base; GroupObject *go; ListBase *objs= NULL; @@ -1407,9 +1417,15 @@ ListBase *get_collider_cache(Scene *scene, Object *self, Group *group) add_collider_cache_object(&objs, go->ob, self, 0); } else { - for(base = scene->base.first; base; base = base->next) - if(!self || (base->lay & self->lay)) + Scene *sce; /* for SETLOOPER macro */ + Base *base; + + /* add objects in same layer in scene */ + for(SETLOOPER(scene, base)) { + if(!self || (base->lay & self->lay)) add_collider_cache_object(&objs, base->object, self, 0); + + } } return objs; @@ -1541,20 +1557,15 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl overlap = BLI_bvhtree_overlap ( cloth_bvh, collmd->bvhtree, &result ); // go to next object if no overlap is there - if(!result || !overlap) - { - if ( overlap ) - MEM_freeN ( overlap ); - continue; - } - - /* check if collisions really happen (costly near check) */ - cloth_bvh_objcollisions_nearcheck ( clmd, collmd, &collisions[i], &collisions_index[i], result, overlap); - - // resolve nearby collisions - ret += cloth_bvh_objcollisions_resolve ( clmd, collmd, collisions[i], collisions_index[i]); - ret2 += ret; + if( result && overlap ) { + /* check if collisions really happen (costly near check) */ + cloth_bvh_objcollisions_nearcheck ( clmd, collmd, &collisions[i], &collisions_index[i], result, overlap); + // resolve nearby collisions + ret += cloth_bvh_objcollisions_resolve ( clmd, collmd, collisions[i], collisions_index[i]); + ret2 += ret; + } + if ( overlap ) MEM_freeN ( overlap ); } |