2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) Blender Foundation
19 * All rights reserved.
21 * The Original Code is: all of this file.
23 * Contributor(s): none yet.
25 * ***** END GPL LICENSE BLOCK *****
28 /** \file blender/blenkernel/intern/collision.c
33 #include "MEM_guardedalloc.h"
35 #include "BKE_cloth.h"
37 #include "DNA_cloth_types.h"
38 #include "DNA_group_types.h"
39 #include "DNA_mesh_types.h"
40 #include "DNA_object_types.h"
41 #include "DNA_object_force.h"
42 #include "DNA_scene_types.h"
43 #include "DNA_meshdata_types.h"
45 #include "BLI_utildefines.h"
46 #include "BLI_blenlib.h"
48 #include "BLI_edgehash.h"
49 #include "BLI_utildefines.h"
50 #include "BLI_ghash.h"
51 #include "BLI_memarena.h"
54 #include "BKE_DerivedMesh.h"
55 #include "BKE_global.h"
56 #include "BKE_scene.h"
58 #include "BKE_object.h"
59 #include "BKE_modifier.h"
61 #include "BKE_DerivedMesh.h"
63 #include "Bullet-C-Api.h"
65 #include "BLI_kdopbvh.h"
66 #include "BKE_collision.h"
69 #include "eltopo-capi.h"
73 /***********************************
74 Collision modifier code start
75 ***********************************/
77 /* step is limited from 0 (frame start position) to 1 (frame end position) */
78 void collision_move_object(CollisionModifierData *collmd, float step, float prevstep)
80 float tv[3] = {0, 0, 0};
83 for ( i = 0; i < collmd->numverts; i++ ) {
84 sub_v3_v3v3(tv, collmd->xnew[i].co, collmd->x[i].co);
85 VECADDS(collmd->current_x[i].co, collmd->x[i].co, tv, prevstep);
86 VECADDS(collmd->current_xnew[i].co, collmd->x[i].co, tv, step);
87 sub_v3_v3v3(collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co);
90 bvhtree_update_from_mvert ( collmd->bvhtree, collmd->mfaces, collmd->numfaces, collmd->current_x, collmd->current_xnew, collmd->numverts, 1 );
93 BVHTree *bvhtree_build_from_mvert ( MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int UNUSED(numverts), float epsilon )
98 MFace *tface = mfaces;
100 tree = BLI_bvhtree_new ( numfaces*2, epsilon, 4, 26 );
103 for ( i = 0; i < numfaces; i++, tface++ ) {
104 copy_v3_v3 ( &co[0*3], x[tface->v1].co );
105 copy_v3_v3 ( &co[1*3], x[tface->v2].co );
106 copy_v3_v3 ( &co[2*3], x[tface->v3].co );
108 copy_v3_v3 ( &co[3*3], x[tface->v4].co );
110 BLI_bvhtree_insert ( tree, i, co, ( mfaces->v4 ? 4 : 3 ) );
114 BLI_bvhtree_balance ( tree );
119 void bvhtree_update_from_mvert(BVHTree * bvhtree, MFace *faces, int numfaces, MVert *x, MVert *xnew, int UNUSED(numverts), int moving )
122 MFace *mfaces = faces;
123 float co[12], co_moving[12];
130 for ( i = 0; i < numfaces; i++, mfaces++ ) {
131 copy_v3_v3 ( &co[0*3], x[mfaces->v1].co );
132 copy_v3_v3 ( &co[1*3], x[mfaces->v2].co );
133 copy_v3_v3 ( &co[2*3], x[mfaces->v3].co );
135 copy_v3_v3 ( &co[3*3], x[mfaces->v4].co );
137 // copy new locations into array
138 if ( moving && xnew ) {
139 // update moving positions
140 copy_v3_v3 ( &co_moving[0*3], xnew[mfaces->v1].co );
141 copy_v3_v3 ( &co_moving[1*3], xnew[mfaces->v2].co );
142 copy_v3_v3 ( &co_moving[2*3], xnew[mfaces->v3].co );
144 copy_v3_v3 ( &co_moving[3*3], xnew[mfaces->v4].co );
146 ret = BLI_bvhtree_update_node ( bvhtree, i, co, co_moving, ( mfaces->v4 ? 4 : 3 ) );
149 ret = BLI_bvhtree_update_node ( bvhtree, i, co, NULL, ( mfaces->v4 ? 4 : 3 ) );
152 // check if tree is already full
157 BLI_bvhtree_update_tree ( bvhtree );
161 /***********************************
162 Collision modifier code end
163 ***********************************/
166 static void collision_compute_barycentric ( float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3 )
168 double tempV1[3], tempV2[3], tempV4[3];
169 double a, b, c, d, e, f;
171 VECSUB ( tempV1, p1, p3 );
172 VECSUB ( tempV2, p2, p3 );
173 VECSUB ( tempV4, pv, p3 );
175 a = INPR ( tempV1, tempV1 );
176 b = INPR ( tempV1, tempV2 );
177 c = INPR ( tempV2, tempV2 );
178 e = INPR ( tempV1, tempV4 );
179 f = INPR ( tempV2, tempV4 );
181 d = ( a * c - b * b );
183 if ( ABS ( d ) < (double)ALMOST_ZERO ) {
184 *w1 = *w2 = *w3 = 1.0 / 3.0;
188 w1[0] = ( float ) ( ( e * c - b * f ) / d );
193 w2[0] = ( float ) ( ( f - b * ( double ) w1[0] ) / c );
198 w3[0] = 1.0f - w1[0] - w2[0];
201 #pragma GCC diagnostic push
202 #pragma GCC diagnostic ignored "-Wdouble-promotion"
204 DO_INLINE void collision_interpolateOnTriangle ( float to[3], float v1[3], float v2[3], float v3[3], double w1, double w2, double w3 )
207 VECADDMUL(to, v1, w1);
208 VECADDMUL(to, v2, w2);
209 VECADDMUL(to, v3, w3);
212 static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end )
216 float w1, w2, w3, u1, u2, u3;
217 float v1[3], v2[3], relativeVelocity[3];
219 float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree );
221 cloth1 = clmd->clothObject;
223 for ( ; collpair != collision_end; collpair++ ) {
224 float i1[3], i2[3], i3[3];
230 /* only handle static collisions here */
231 if ( collpair->flag & COLLISION_IN_FUTURE )
234 /* compute barycentric coordinates for both collision points */
235 collision_compute_barycentric ( collpair->pa,
236 cloth1->verts[collpair->ap1].txold,
237 cloth1->verts[collpair->ap2].txold,
238 cloth1->verts[collpair->ap3].txold,
242 collision_compute_barycentric ( collpair->pb,
243 collmd->current_x[collpair->bp1].co,
244 collmd->current_x[collpair->bp2].co,
245 collmd->current_x[collpair->bp3].co,
248 /* Calculate relative "velocity". */
249 collision_interpolateOnTriangle ( v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3 );
251 collision_interpolateOnTriangle ( v2, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, collmd->current_v[collpair->bp3].co, u1, u2, u3 );
253 sub_v3_v3v3(relativeVelocity, v2, v1);
255 /* Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal'). */
256 magrelVel = dot_v3v3(relativeVelocity, collpair->normal);
258 /* printf("magrelVel: %f\n", magrelVel); */
260 /* Calculate masses of points.
263 /* If v_n_mag < 0 the edges are approaching each other. */
264 if ( magrelVel > ALMOST_ZERO ) {
265 /* Calculate Impulse magnitude to stop all motion in normal direction. */
266 float magtangent = 0, repulse = 0, d = 0;
267 double impulse = 0.0;
271 /* calculate tangential velocity */
272 copy_v3_v3 ( temp, collpair->normal );
273 mul_v3_fl(temp, magrelVel);
274 sub_v3_v3v3(vrel_t_pre, relativeVelocity, temp);
276 /* Decrease in magnitude of relative tangential velocity due to coulomb friction
277 * in original formula "magrelVel" should be the "change of relative velocity in normal direction" */
278 magtangent = min_ff(clmd->coll_parms->friction * 0.01f * magrelVel, sqrtf(dot_v3v3(vrel_t_pre, vrel_t_pre)));
280 /* Apply friction impulse. */
281 if ( magtangent > ALMOST_ZERO ) {
282 normalize_v3(vrel_t_pre);
284 impulse = magtangent / ( 1.0f + w1*w1 + w2*w2 + w3*w3 ); /* 2.0 * */
285 VECADDMUL ( i1, vrel_t_pre, w1 * impulse );
286 VECADDMUL ( i2, vrel_t_pre, w2 * impulse );
287 VECADDMUL ( i3, vrel_t_pre, w3 * impulse );
290 /* Apply velocity stopping impulse
291 * I_c = m * v_N / 2.0
292 * no 2.0 * magrelVel normally, but looks nicer DG */
293 impulse = magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3 );
295 VECADDMUL ( i1, collpair->normal, w1 * impulse );
296 cloth1->verts[collpair->ap1].impulse_count++;
298 VECADDMUL ( i2, collpair->normal, w2 * impulse );
299 cloth1->verts[collpair->ap2].impulse_count++;
301 VECADDMUL ( i3, collpair->normal, w3 * impulse );
302 cloth1->verts[collpair->ap3].impulse_count++;
304 /* Apply repulse impulse if distance too short
305 * I_r = -min(dt*kd, m(0, 1d/dt - v_n))
306 * DG: this formula ineeds to be changed for this code since we apply impulses/repulses like this:
307 * v += impulse; x_new = x + v;
309 * DG TODO: Fix usage of dt here! */
310 spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
312 d = clmd->coll_parms->epsilon*8.0f/9.0f + epsilon2*8.0f/9.0f - collpair->distance;
313 if ( ( magrelVel < 0.1f*d*spf ) && ( d > ALMOST_ZERO ) ) {
314 repulse = MIN2 ( d*1.0f/spf, 0.1f*d*spf - magrelVel );
316 /* stay on the safe side and clamp repulse */
317 if ( impulse > ALMOST_ZERO )
318 repulse = min_ff( repulse, 5.0*impulse );
319 repulse = max_ff(impulse, repulse);
321 impulse = repulse / ( 1.0f + w1*w1 + w2*w2 + w3*w3 ); /* original 2.0 / 0.25 */
322 VECADDMUL ( i1, collpair->normal, impulse );
323 VECADDMUL ( i2, collpair->normal, impulse );
324 VECADDMUL ( i3, collpair->normal, impulse );
330 /* Apply repulse impulse if distance too short
331 * I_r = -min(dt*kd, max(0, 1d/dt - v_n))
332 * DG: this formula ineeds to be changed for this code since we apply impulses/repulses like this:
333 * v += impulse; x_new = x + v;
334 * We don't use dt!! */
335 float spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
337 float d = clmd->coll_parms->epsilon*8.0f/9.0f + epsilon2*8.0f/9.0f - (float)collpair->distance;
338 if ( d > ALMOST_ZERO) {
339 /* stay on the safe side and clamp repulse */
340 float repulse = d*1.0f/spf;
342 float impulse = repulse / ( 3.0f * ( 1.0f + w1*w1 + w2*w2 + w3*w3 )); /* original 2.0 / 0.25 */
344 VECADDMUL ( i1, collpair->normal, impulse );
345 VECADDMUL ( i2, collpair->normal, impulse );
346 VECADDMUL ( i3, collpair->normal, impulse );
348 cloth1->verts[collpair->ap1].impulse_count++;
349 cloth1->verts[collpair->ap2].impulse_count++;
350 cloth1->verts[collpair->ap3].impulse_count++;
359 for (i = 0; i < 3; i++) {
360 if (cloth1->verts[collpair->ap1].impulse_count > 0 && ABS(cloth1->verts[collpair->ap1].impulse[i]) < ABS(i1[i]))
361 cloth1->verts[collpair->ap1].impulse[i] = i1[i];
363 if (cloth1->verts[collpair->ap2].impulse_count > 0 && ABS(cloth1->verts[collpair->ap2].impulse[i]) < ABS(i2[i]))
364 cloth1->verts[collpair->ap2].impulse[i] = i2[i];
366 if (cloth1->verts[collpair->ap3].impulse_count > 0 && ABS(cloth1->verts[collpair->ap3].impulse[i]) < ABS(i3[i]))
367 cloth1->verts[collpair->ap3].impulse[i] = i3[i];
374 #pragma GCC diagnostic pop
376 //Determines collisions on overlap, collisions are written to collpair[i] and collision+number_collision_found is returned
377 static CollPair* cloth_collision(ModifierData *md1, ModifierData *md2,
378 BVHTreeOverlap *overlap, CollPair *collpair, float UNUSED(dt))
380 ClothModifierData *clmd = (ClothModifierData *)md1;
381 CollisionModifierData *collmd = (CollisionModifierData *) md2;
382 /* Cloth *cloth = clmd->clothObject; */ /* UNUSED */
383 MFace *face1=NULL, *face2 = NULL;
385 ClothVertex *verts1 = clmd->clothObject->verts;
388 float epsilon1 = clmd->coll_parms->epsilon;
389 float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree );
392 face1 = & ( clmd->clothObject->mfaces[overlap->indexA] );
393 face2 = & ( collmd->mfaces[overlap->indexB] );
395 // check all 4 possible collisions
396 for ( i = 0; i < 4; i++ ) {
399 collpair->ap1 = face1->v1;
400 collpair->ap2 = face1->v2;
401 collpair->ap3 = face1->v3;
404 collpair->bp1 = face2->v1;
405 collpair->bp2 = face2->v2;
406 collpair->bp3 = face2->v3;
411 collpair->ap1 = face1->v1;
412 collpair->ap2 = face1->v3;
413 collpair->ap3 = face1->v4;
416 collpair->bp1 = face2->v1;
417 collpair->bp2 = face2->v2;
418 collpair->bp3 = face2->v3;
427 collpair->ap1 = face1->v1;
428 collpair->ap2 = face1->v2;
429 collpair->ap3 = face1->v3;
432 collpair->bp1 = face2->v1;
433 collpair->bp2 = face2->v4;
434 collpair->bp3 = face2->v3;
441 if ( face1->v4 && face2->v4 ) {
443 collpair->ap1 = face1->v1;
444 collpair->ap2 = face1->v3;
445 collpair->ap3 = face1->v4;
448 collpair->bp1 = face2->v1;
449 collpair->bp2 = face2->v3;
450 collpair->bp3 = face2->v4;
458 // calc distance + normal
459 distance = plNearestPoints (
460 verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, collmd->current_x[collpair->bp1].co, collmd->current_x[collpair->bp2].co, collmd->current_x[collpair->bp3].co, collpair->pa, collpair->pb, collpair->vector );
462 // just be sure that we don't add anything
463 distance = 2.0 * (double)( epsilon1 + epsilon2 + ALMOST_ZERO );
466 // distance -1 means no collision result
467 if (distance != -1.0 && (distance <= (double)(epsilon1 + epsilon2 + ALMOST_ZERO))) {
468 normalize_v3_v3(collpair->normal, collpair->vector);
470 collpair->distance = distance;
475 float w1, w2, w3, u1, u2, u3;
476 float v1[3], v2[3], relativeVelocity[3];
478 // calc relative velocity
480 // compute barycentric coordinates for both collision points
481 collision_compute_barycentric ( collpair->pa,
482 verts1[collpair->ap1].txold,
483 verts1[collpair->ap2].txold,
484 verts1[collpair->ap3].txold,
488 collision_compute_barycentric ( collpair->pb,
489 collmd->current_x[collpair->bp1].co,
490 collmd->current_x[collpair->bp2].co,
491 collmd->current_x[collpair->bp3].co,
494 // Calculate relative "velocity".
495 collision_interpolateOnTriangle ( v1, verts1[collpair->ap1].tv, verts1[collpair->ap2].tv, verts1[collpair->ap3].tv, w1, w2, w3 );
497 collision_interpolateOnTriangle ( v2, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, collmd->current_v[collpair->bp3].co, u1, u2, u3 );
499 sub_v3_v3v3(relativeVelocity, v2, v1);
501 if (sqrt(dot_v3v3(relativeVelocity, relativeVelocity)) >= distance)
503 // check for collision in the future
504 collpair->flag |= COLLISION_IN_FUTURE;
512 static void add_collision_object(Object ***objs, unsigned int *numobj, unsigned int *maxobj, Object *ob, Object *self, int level, unsigned int modifier_type)
514 CollisionModifierData *cmd= NULL;
519 /* only get objects with collision modifier */
520 if (((modifier_type == eModifierType_Collision) && ob->pd && ob->pd->deflect) || (modifier_type != eModifierType_Collision))
521 cmd= (CollisionModifierData *)modifiers_findByType(ob, modifier_type);
525 if (*numobj >= *maxobj) {
527 *objs= MEM_reallocN(*objs, sizeof(Object*)*(*maxobj));
530 (*objs)[*numobj] = ob;
534 /* objects in dupli groups, one level only for now */
535 if (ob->dup_group && level == 0) {
537 Group *group= ob->dup_group;
540 for (go= group->gobject.first; go; go= go->next)
541 add_collision_object(objs, numobj, maxobj, go->ob, self, level+1, modifier_type);
545 // return all collision objects in scene
546 // collision object will exclude self
547 Object **get_collisionobjects(Scene *scene, Object *self, Group *group, unsigned int *numcollobj, unsigned int modifier_type)
552 unsigned int numobj= 0, maxobj= 100;
554 objs= MEM_callocN(sizeof(Object *)*maxobj, "CollisionObjectsArray");
556 /* gather all collision objects */
558 /* use specified group */
559 for (go= group->gobject.first; go; go= go->next)
560 add_collision_object(&objs, &numobj, &maxobj, go->ob, self, 0, modifier_type);
564 /* add objects in same layer in scene */
565 for (SETLOOPER(scene, sce_iter, base)) {
566 if (base->lay & self->lay)
567 add_collision_object(&objs, &numobj, &maxobj, base->object, self, 0, modifier_type);
577 static void add_collider_cache_object(ListBase **objs, Object *ob, Object *self, int level)
579 CollisionModifierData *cmd= NULL;
585 if (ob->pd && ob->pd->deflect)
586 cmd =(CollisionModifierData *)modifiers_findByType(ob, eModifierType_Collision);
588 if (cmd && cmd->bvhtree) {
590 *objs = MEM_callocN(sizeof(ListBase), "ColliderCache array");
592 col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
595 /* make sure collider is properly set up */
596 collision_move_object(cmd, 1.0, 0.0);
597 BLI_addtail(*objs, col);
600 /* objects in dupli groups, one level only for now */
601 if (ob->dup_group && level == 0) {
603 Group *group= ob->dup_group;
606 for (go= group->gobject.first; go; go= go->next)
607 add_collider_cache_object(objs, go->ob, self, level+1);
611 ListBase *get_collider_cache(Scene *scene, Object *self, Group *group)
614 ListBase *objs= NULL;
616 /* add object in same layer in scene */
618 for (go= group->gobject.first; go; go= go->next)
619 add_collider_cache_object(&objs, go->ob, self, 0);
625 /* add objects in same layer in scene */
626 for (SETLOOPER(scene, sce_iter, base)) {
627 if (!self || (base->lay & self->lay))
628 add_collider_cache_object(&objs, base->object, self, 0);
636 void free_collider_cache(ListBase **colliders)
639 BLI_freelistN(*colliders);
640 MEM_freeN(*colliders);
646 static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd,
647 CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap, double dt)
651 *collisions = (CollPair *) MEM_mallocN(sizeof(CollPair) * numresult * 64, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision
652 *collisions_index = *collisions;
654 for ( i = 0; i < numresult; i++ ) {
655 *collisions_index = cloth_collision ( (ModifierData *)clmd, (ModifierData *)collmd,
656 overlap+i, *collisions_index, dt );
660 static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair *collisions, CollPair *collisions_index)
662 Cloth *cloth = clmd->clothObject;
663 int i=0, j = 0, /*numfaces = 0, */ numverts = 0;
664 ClothVertex *verts = NULL;
668 numverts = clmd->clothObject->numverts;
669 verts = cloth->verts;
671 // process all collisions (calculate impulses, TODO: also repulses if distance too short)
673 for ( j = 0; j < 2; j++ ) { /* 5 is just a value that ensures convergence */
676 if ( collmd->bvhtree ) {
677 result += cloth_collision_response_static ( clmd, collmd, collisions, collisions_index );
679 // apply impulses in parallel
681 for (i = 0; i < numverts; i++) {
682 // calculate "velocities" (just xnew = xold + v; no dt in v)
683 if (verts[i].impulse_count) {
684 // VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count );
685 VECADD ( verts[i].tv, verts[i].tv, verts[i].impulse);
686 zero_v3(verts[i].impulse);
687 verts[i].impulse_count = 0;
702 // cloth - object collisions
703 int cloth_bvh_objcollision(Object *ob, ClothModifierData * clmd, float step, float dt )
705 Cloth *cloth= clmd->clothObject;
706 BVHTree *cloth_bvh= cloth->bvhtree;
707 unsigned int i=0, /* numfaces = 0, */ /* UNUSED */ numverts = 0, k, l, j;
708 int rounds = 0; // result counts applied collisions; ic is for debug output;
709 ClothVertex *verts = NULL;
710 int ret = 0, ret2 = 0;
711 Object **collobjs = NULL;
712 unsigned int numcollobj = 0;
714 if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || cloth_bvh==NULL)
717 verts = cloth->verts;
718 /* numfaces = cloth->numfaces; */ /* UNUSED */
719 numverts = cloth->numverts;
721 ////////////////////////////////////////////////////////////
723 ////////////////////////////////////////////////////////////
726 bvhtree_update_from_cloth ( clmd, 1 ); // 0 means STATIC, 1 means MOVING (see later in this function)
727 bvhselftree_update_from_cloth ( clmd, 0 ); // 0 means STATIC, 1 means MOVING (see later in this function)
729 collobjs = get_collisionobjects(clmd->scene, ob, clmd->coll_parms->group, &numcollobj, eModifierType_Collision);
734 /* move object to position (step) in time */
735 for (i = 0; i < numcollobj; i++) {
736 Object *collob= collobjs[i];
737 CollisionModifierData *collmd = (CollisionModifierData*)modifiers_findByType(collob, eModifierType_Collision);
739 if (!collmd->bvhtree)
742 /* move object to position (step) in time */
743 collision_move_object ( collmd, step + dt, step );
747 CollPair **collisions, **collisions_index;
751 collisions = MEM_callocN(sizeof(CollPair *) *numcollobj, "CollPair");
752 collisions_index = MEM_callocN(sizeof(CollPair *) *numcollobj, "CollPair");
754 // check all collision objects
755 for (i = 0; i < numcollobj; i++) {
756 Object *collob= collobjs[i];
757 CollisionModifierData *collmd = (CollisionModifierData*)modifiers_findByType(collob, eModifierType_Collision);
758 BVHTreeOverlap *overlap = NULL;
759 unsigned int result = 0;
761 if (!collmd->bvhtree)
764 /* search for overlapping collision pairs */
765 overlap = BLI_bvhtree_overlap ( cloth_bvh, collmd->bvhtree, &result );
767 // go to next object if no overlap is there
768 if ( result && overlap ) {
769 /* check if collisions really happen (costly near check) */
770 cloth_bvh_objcollisions_nearcheck ( clmd, collmd, &collisions[i],
771 &collisions_index[i], result, overlap, dt/(float)clmd->coll_parms->loop_count);
773 // resolve nearby collisions
774 ret += cloth_bvh_objcollisions_resolve ( clmd, collmd, collisions[i], collisions_index[i]);
779 MEM_freeN ( overlap );
783 for (i = 0; i < numcollobj; i++) {
784 if ( collisions[i] ) MEM_freeN ( collisions[i] );
787 MEM_freeN(collisions);
788 MEM_freeN(collisions_index);
790 ////////////////////////////////////////////////////////////
792 // this is needed for bvh_calc_DOP_hull_moving() [kdop.c]
793 ////////////////////////////////////////////////////////////
795 // verts come from clmd
796 for ( i = 0; i < numverts; i++ ) {
797 if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) {
798 if ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) {
803 VECADD ( verts[i].tx, verts[i].txold, verts[i].tv );
805 ////////////////////////////////////////////////////////////
808 ////////////////////////////////////////////////////////////
809 // Test on *simple* selfcollisions
810 ////////////////////////////////////////////////////////////
811 if ( clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF ) {
812 for (l = 0; l < (unsigned int)clmd->coll_parms->self_loop_count; l++) {
813 /* TODO: add coll quality rounds again */
814 BVHTreeOverlap *overlap = NULL;
815 unsigned int result = 0;
818 verts = cloth->verts; // needed for openMP
820 /* numfaces = cloth->numfaces; */ /* UNUSED */
821 numverts = cloth->numverts;
823 verts = cloth->verts;
825 if ( cloth->bvhselftree ) {
826 // search for overlapping collision pairs
827 overlap = BLI_bvhtree_overlap ( cloth->bvhselftree, cloth->bvhselftree, &result );
829 // #pragma omp parallel for private(k, i, j) schedule(static)
830 for ( k = 0; k < result; k++ ) {
835 i = overlap[k].indexA;
836 j = overlap[k].indexB;
838 mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len );
840 if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) {
841 if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) &&
842 ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) )
848 if ((cloth->verts[i].flags & CLOTH_VERT_FLAG_NOSELFCOLL) ||
849 (cloth->verts[j].flags & CLOTH_VERT_FLAG_NOSELFCOLL))
854 sub_v3_v3v3(temp, verts[i].tx, verts[j].tx);
856 if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue;
858 // check for adjacent points (i must be smaller j)
859 if ( BLI_edgehash_haskey ( cloth->edgehash, MIN2(i, j), MAX2(i, j) ) ) {
863 length = normalize_v3(temp );
865 if ( length < mindistance ) {
866 float correction = mindistance - length;
868 if ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) {
869 mul_v3_fl(temp, -correction);
870 VECADD ( verts[j].tx, verts[j].tx, temp );
872 else if ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) {
873 mul_v3_fl(temp, correction);
874 VECADD ( verts[i].tx, verts[i].tx, temp );
877 mul_v3_fl(temp, correction * -0.5f);
878 VECADD ( verts[j].tx, verts[j].tx, temp );
880 sub_v3_v3v3(verts[i].tx, verts[i].tx, temp);
886 // check for approximated time collisions
891 MEM_freeN ( overlap );
895 ////////////////////////////////////////////////////////////
897 ////////////////////////////////////////////////////////////
898 // SELFCOLLISIONS: update velocities
899 ////////////////////////////////////////////////////////////
901 for ( i = 0; i < cloth->numverts; i++ ) {
902 if ( ! ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) ) {
903 sub_v3_v3v3(verts[i].tv, verts[i].tx, verts[i].txold);
907 ////////////////////////////////////////////////////////////
910 while ( ret2 && ( clmd->coll_parms->loop_count>rounds ) );
915 return 1|MIN2 ( ret, 1 );