diff options
author | Daniel Genrich <daniel.genrich@gmx.net> | 2008-03-03 22:02:01 +0300 |
---|---|---|
committer | Daniel Genrich <daniel.genrich@gmx.net> | 2008-03-03 22:02:01 +0300 |
commit | 156d24646242a442cda1f53a1df8d4b9d4eea966 (patch) | |
tree | a5da3207b3e0a078986d2f24bbf58ac5b74cfb20 /source/blender/blenkernel/intern/collision.c | |
parent | b26a76792307be3a1406d2c8786a6f4fdac7352e (diff) |
Cloth bugfix for linked deflector groups (reported by alchibal on #blendercoders incl. source) - please verify
Diffstat (limited to 'source/blender/blenkernel/intern/collision.c')
-rw-r--r-- | source/blender/blenkernel/intern/collision.c | 319 |
1 files changed, 102 insertions, 217 deletions
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 32c5c3b16d6..65583a6c9c4 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -36,6 +36,7 @@ #include "MEM_guardedalloc.h" /* types */ #include "DNA_curve_types.h" +#include "DNA_group_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" #include "DNA_cloth_types.h" @@ -957,20 +958,85 @@ void cloth_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clm cloth_collision_moving_tris(coll_clmd, clmd, tree2, tree1); } -void cloth_collision_self_static(ModifierData *md1, ModifierData *md2, CollisionTree *tree1, CollisionTree *tree2) +void cloth_free_collision_list(ClothModifierData *clmd) { -/* - ClothModifierData *clmd = (ClothModifierData *)md1; - CollisionModifierData *collmd = (CollisionModifierData *)md2; - CollPair *collpair = NULL; - Cloth *cloth1=NULL; - MFace *face1=NULL, *face2=NULL; - ClothVertex *verts1=NULL; - double distance = 0; - float epsilon = clmd->coll_parms->epsilon; - unsigned int i = 0; -*/ + // free collision list + if(clmd->coll_parms->collision_list) + { + LinkNode *search = clmd->coll_parms->collision_list; + while(search) + { + CollPair *coll_pair = search->link; + + MEM_freeN(coll_pair); + search = search->next; + } + BLI_linklist_free(clmd->coll_parms->collision_list,NULL); + + clmd->coll_parms->collision_list = NULL; + } +} + +int cloth_bvh_objcollisions_do(ClothModifierData * clmd, CollisionModifierData *collmd, float step, float dt) +{ + Cloth *cloth = clmd->clothObject; + BVH *cloth_bvh=(BVH *) cloth->tree; + long i=0, j = 0, numfaces = 0, numverts = 0; + ClothVertex *verts = NULL; + int ret = 0; + unsigned int result = 0; + float tnull[3] = {0,0,0}; + + numfaces = clmd->clothObject->numfaces; + numverts = clmd->clothObject->numverts; + + verts = cloth->verts; + + if (collmd->tree) + { + BVH *coll_bvh = collmd->tree; + + collision_move_object(collmd, step + dt, step); + + bvh_traverse((ModifierData *)clmd, (ModifierData *)collmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_static, 0); + } + else + { + if(G.rt > 0) + printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + } + + // process all collisions (calculate impulses, TODO: also repulses if distance too short) + result = 1; + for(j = 0; j < 5; j++) // 5 is just a value that ensures convergence + { + result = 0; + + if (collmd->tree) + result += cloth_collision_response_static(clmd, collmd); + + // apply impulses in parallel + if(result) + for(i = 0; i < numverts; i++) + { + // calculate "velocities" (just xnew = xold + v; no dt in v) + if(verts[i].impulse_count) + { + VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); + VECCOPY(verts[i].impulse, tnull); + verts[i].impulse_count = 0; + + ret++; + } + } + + if(!result) + break; + } + + cloth_free_collision_list(clmd); + return ret; } // cloth - object collisions @@ -982,9 +1048,8 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) Object *coll_ob=NULL; BVH *cloth_bvh=NULL; long i=0, j = 0, numfaces = 0, numverts = 0; - unsigned int result = 0, ic = 0, rounds = 0; // result counts applied collisions; ic is for debug output; + unsigned int result = 0, rounds = 0; // result counts applied collisions; ic is for debug output; ClothVertex *verts = NULL; - float tnull[3] = {0,0,0}; int ret = 0; ClothModifierData *tclmd; int collisions = 0, count = 0; @@ -1010,7 +1075,6 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) do { result = 0; - ic = 0; clmd->coll_parms->collision_list = NULL; // check all collision objects @@ -1020,67 +1084,36 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) collmd = (CollisionModifierData *) modifiers_findByType (coll_ob, eModifierType_Collision); if (!collmd) - continue; - - tclmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); - if(tclmd == clmd) - continue; - - if (collmd->tree) - { - BVH *coll_bvh = collmd->tree; - - collision_move_object(collmd, step + dt, step); - - bvh_traverse((ModifierData *)clmd, (ModifierData *)collmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_static, 0); - } - else - { - if(G.rt > 0) - printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); - } - - - // process all collisions (calculate impulses, TODO: also repulses if distance too short) - result = 1; - for(j = 0; j < 5; j++) // 5 is just a value that ensures convergence { - result = 0; - - if (collmd->tree) - result += cloth_collision_response_static(clmd, collmd); - - // apply impulses in parallel - ic=0; - for(i = 0; i < numverts; i++) + if(coll_ob->dup_group) { - // calculate "velocities" (just xnew = xold + v; no dt in v) - if(verts[i].impulse_count) + GroupObject *go; + Group *group = coll_ob->dup_group; + + for(go= group->gobject.first; go; go= go->next) { - VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); - VECCOPY(verts[i].impulse, tnull); - verts[i].impulse_count = 0; - - ic++; - ret++; + coll_ob = go->ob; + + collmd = (CollisionModifierData *) modifiers_findByType (coll_ob, eModifierType_Collision); + + if (!collmd) + continue; + + tclmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + if(tclmd == clmd) + continue; + + ret += cloth_bvh_objcollisions_do(clmd, collmd, step, dt); } } } - - // free collision list - if(clmd->coll_parms->collision_list) + else { - LinkNode *search = clmd->coll_parms->collision_list; - while(search) - { - CollPair *coll_pair = search->link; - - MEM_freeN(coll_pair); - search = search->next; - } - BLI_linklist_free(clmd->coll_parms->collision_list,NULL); - - clmd->coll_parms->collision_list = NULL; + tclmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + if(tclmd == clmd) + continue; + + ret += cloth_bvh_objcollisions_do(clmd, collmd, step, dt); } } rounds++; @@ -1203,153 +1236,5 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) } while(result && (clmd->coll_parms->loop_count>rounds)); - //////////////////////////////////////////////////////////// - // moving collisions - // - // response code is just missing itm - //////////////////////////////////////////////////////////// - - /* - // update cloth bvh - bvh_update_from_cloth(clmd, 1); // 0 means STATIC, 1 means MOVING - - // update moving bvh for collision object once - for (base = G.scene->base.first; base; base = base->next) - { - - coll_ob = base->object; - coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); - if (!coll_clmd) - continue; - - if(!coll_clmd->clothObject) - continue; - - // if collision object go on - if (coll_clmd->clothObject && coll_clmd->clothObject->tree) - { - BVH *coll_bvh = coll_clmd->clothObject->tree; - - bvh_update_from_cloth(coll_clmd, 1); // 0 means STATIC, 1 means MOVING -} -} - - - do - { - result = 0; - ic = 0; - clmd->coll_parms->collision_list = NULL; - - // check all collision objects - for (base = G.scene->base.first; base; base = base->next) - { - coll_ob = base->object; - coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); - - if (!coll_clmd) - continue; - - // if collision object go on - if (coll_clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) - { - if (coll_clmd->clothObject && coll_clmd->clothObject->tree) - { - BVH *coll_bvh = coll_clmd->clothObject->tree; - - bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_moving, 0); -} - else - printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); -} -} - - // process all collisions (calculate impulses, TODO: also repulses if distance too short) - result = 1; - for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence - { - result = 0; - - // handle all collision objects - for (base = G.scene->base.first; base; base = base->next) - { - - coll_ob = base->object; - coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); - - if (!coll_clmd) - continue; - - // if collision object go on - if (coll_clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) - { - if (coll_clmd->clothObject) - result += cloth_collision_response_moving_tris(clmd, coll_clmd); - else - printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); -} -} - - // apply impulses in parallel - ic=0; - for(i = 0; i < numverts; i++) - { - // calculate "velocities" (just xnew = xold + v; no dt in v) - if(verts[i].impulse_count) - { - VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); - VECCOPY(verts[i].impulse, tnull); - verts[i].impulse_count = 0; - - ic++; - ret++; -} -} -} - - - // verts come from clmd - for(i = 0; i < numverts; i++) - { - VECADD(verts[i].tx, verts[i].txold, verts[i].tv); -} - - // update cloth bvh - bvh_update_from_cloth(clmd, 1); // 0 means STATIC, 1 means MOVING - - - // free collision list - if(clmd->coll_parms->collision_list) - { - LinkNode *search = clmd->coll_parms->collision_list; - while(search) - { - CollPair *coll_pair = search->link; - - MEM_freeN(coll_pair); - search = search->next; -} - BLI_linklist_free(clmd->coll_parms->collision_list,NULL); - - clmd->coll_parms->collision_list = NULL; -} - - // printf("ic: %d\n", ic); - rounds++; -} - while(result && (CLOTH_MAX_THRESHOLD>rounds)); - - //////////////////////////////////////////////////////////// - // update positions + velocities - //////////////////////////////////////////////////////////// - - // verts come from clmd - for(i = 0; i < numverts; i++) - { - VECADD(verts[i].tx, verts[i].txold, verts[i].tv); -} - //////////////////////////////////////////////////////////// - */ - return MIN2(ret, 1); } |