Blender  V2.93
collision.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) Blender Foundation
17  * All rights reserved.
18  */
19 
24 #include "MEM_guardedalloc.h"
25 
26 #include "DNA_cloth_types.h"
27 #include "DNA_collection_types.h"
28 #include "DNA_effect_types.h"
29 #include "DNA_meshdata_types.h"
30 #include "DNA_object_force_types.h"
31 #include "DNA_object_types.h"
32 #include "DNA_scene_types.h"
33 
34 #include "BLI_blenlib.h"
35 #include "BLI_edgehash.h"
36 #include "BLI_linklist.h"
37 #include "BLI_math.h"
38 #include "BLI_task.h"
39 #include "BLI_threads.h"
40 #include "BLI_utildefines.h"
41 
42 #include "BKE_cloth.h"
43 #include "BKE_collection.h"
44 #include "BKE_effect.h"
45 #include "BKE_layer.h"
46 #include "BKE_modifier.h"
47 #include "BKE_scene.h"
48 
49 #include "BKE_collision.h"
50 #include "BLI_kdopbvh.h"
51 
52 #include "DEG_depsgraph.h"
53 #include "DEG_depsgraph_physics.h"
54 #include "DEG_depsgraph_query.h"
55 
56 #ifdef WITH_ELTOPO
57 # include "eltopo-capi.h"
58 #endif
59 
60 typedef struct ColDetectData {
65  bool culling;
66  bool use_normal;
67  bool collided;
69 
70 typedef struct SelfColDetectData {
74  bool collided;
76 
77 /***********************************
78  * Collision modifier code start
79  ***********************************/
80 
81 /* step is limited from 0 (frame start position) to 1 (frame end position) */
83  const float step,
84  const float prevstep,
85  const bool moving_bvh)
86 {
87  unsigned int i = 0;
88 
89  /* the collider doesn't move this frame */
90  if (collmd->is_static) {
91  for (i = 0; i < collmd->mvert_num; i++) {
92  zero_v3(collmd->current_v[i].co);
93  }
94 
95  return;
96  }
97 
98  for (i = 0; i < collmd->mvert_num; i++) {
99  interp_v3_v3v3(collmd->current_x[i].co, collmd->x[i].co, collmd->xnew[i].co, prevstep);
100  interp_v3_v3v3(collmd->current_xnew[i].co, collmd->x[i].co, collmd->xnew[i].co, step);
101  sub_v3_v3v3(collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co);
102  }
103 
105  collmd->current_xnew,
106  collmd->current_x,
107  collmd->tri,
108  collmd->tri_num,
109  moving_bvh);
110 }
111 
113  const struct MVertTri *tri,
114  int tri_num,
115  float epsilon)
116 {
117  BVHTree *tree = BLI_bvhtree_new(tri_num, epsilon, 4, 26);
118 
119  /* fill tree */
120  int i;
121  const MVertTri *vt;
122  for (i = 0, vt = tri; i < tri_num; i++, vt++) {
123  float co[3][3];
124 
125  copy_v3_v3(co[0], mvert[vt->tri[0]].co);
126  copy_v3_v3(co[1], mvert[vt->tri[1]].co);
127  copy_v3_v3(co[2], mvert[vt->tri[2]].co);
128 
129  BLI_bvhtree_insert(tree, i, co[0], 3);
130  }
131 
132  /* balance tree */
134 
135  return tree;
136 }
137 
139  const MVert *mvert,
140  const MVert *mvert_moving,
141  const MVertTri *tri,
142  int tri_num,
143  bool moving)
144 {
145 
146  if ((bvhtree == NULL) || (mvert == NULL)) {
147  return;
148  }
149 
150  if (mvert_moving == NULL) {
151  moving = false;
152  }
153 
154  const MVertTri *vt;
155  int i;
156  for (i = 0, vt = tri; i < tri_num; i++, vt++) {
157  float co[3][3];
158  bool ret;
159 
160  copy_v3_v3(co[0], mvert[vt->tri[0]].co);
161  copy_v3_v3(co[1], mvert[vt->tri[1]].co);
162  copy_v3_v3(co[2], mvert[vt->tri[2]].co);
163 
164  /* copy new locations into array */
165  if (moving) {
166  float co_moving[3][3];
167  /* update moving positions */
168  copy_v3_v3(co_moving[0], mvert_moving[vt->tri[0]].co);
169  copy_v3_v3(co_moving[1], mvert_moving[vt->tri[1]].co);
170  copy_v3_v3(co_moving[2], mvert_moving[vt->tri[2]].co);
171 
172  ret = BLI_bvhtree_update_node(bvhtree, i, &co[0][0], &co_moving[0][0], 3);
173  }
174  else {
175  ret = BLI_bvhtree_update_node(bvhtree, i, &co[0][0], NULL, 3);
176  }
177 
178  /* check if tree is already full */
179  if (ret == false) {
180  break;
181  }
182  }
183 
184  BLI_bvhtree_update_tree(bvhtree);
185 }
186 
187 /* ***************************
188  * Collision modifier code end
189  * *************************** */
190 
192 {
193  return (++i < 3) ? i : 0;
194 }
195 
196 static float compute_collision_point_tri_tri(const float a1[3],
197  const float a2[3],
198  const float a3[3],
199  const float b1[3],
200  const float b2[3],
201  const float b3[3],
202  bool culling,
203  bool use_normal,
204  float r_a[3],
205  float r_b[3],
206  float r_vec[3])
207 {
208  float a[3][3];
209  float b[3][3];
210  float dist = FLT_MAX;
211  float tmp_co1[3], tmp_co2[3];
212  float isect_a[3], isect_b[3];
213  float tmp, tmp_vec[3];
214  float normal[3], cent[3];
215  bool backside = false;
216 
217  copy_v3_v3(a[0], a1);
218  copy_v3_v3(a[1], a2);
219  copy_v3_v3(a[2], a3);
220 
221  copy_v3_v3(b[0], b1);
222  copy_v3_v3(b[1], b2);
223  copy_v3_v3(b[2], b3);
224 
225  /* Find intersections. */
226  int tri_a_edge_isect_count;
227  const bool is_intersecting = isect_tri_tri_v3_ex(
228  a, b, isect_a, isect_b, &tri_a_edge_isect_count);
229 
230  /* Determine collision side. */
231  if (culling) {
232  normal_tri_v3(normal, b[0], b[1], b[2]);
233  mid_v3_v3v3v3(cent, b[0], b[1], b[2]);
234 
235  if (!is_intersecting) {
236  for (int i = 0; i < 3; i++) {
237  sub_v3_v3v3(tmp_vec, a[i], cent);
238  if (dot_v3v3(tmp_vec, normal) < 0.0f) {
239  backside = true;
240  break;
241  }
242  }
243  }
244  else if (tri_a_edge_isect_count != 1) {
245  /* It is not Edge intersection. */
246  backside = true;
247  }
248  }
249  else if (use_normal) {
250  normal_tri_v3(normal, b[0], b[1], b[2]);
251  }
252 
253  if (tri_a_edge_isect_count == 1) {
254  /* Edge intersection. */
255  copy_v3_v3(r_a, isect_a);
256  copy_v3_v3(r_b, isect_b);
257 
258  if (use_normal) {
259  copy_v3_v3(r_vec, normal);
260  }
261  else {
262  sub_v3_v3v3(r_vec, r_b, r_a);
263  }
264 
265  return 0.0f;
266  }
267 
268  if (backside) {
269  float maxdist = 0.0f;
270  bool found = false;
271 
272  /* Point projections. */
273  for (int i = 0; i < 3; i++) {
274  if (isect_ray_tri_v3(a[i], normal, b[0], b[1], b[2], &tmp, NULL)) {
275  if (tmp > maxdist) {
276  maxdist = tmp;
277  copy_v3_v3(r_a, a[i]);
278  madd_v3_v3v3fl(r_b, a[i], normal, tmp);
279  found = true;
280  }
281  }
282  }
283 
284  negate_v3(normal);
285 
286  for (int i = 0; i < 3; i++) {
287  if (isect_ray_tri_v3(b[i], normal, a[0], a[1], a[2], &tmp, NULL)) {
288  if (tmp > maxdist) {
289  maxdist = tmp;
290  madd_v3_v3v3fl(r_a, b[i], normal, tmp);
291  copy_v3_v3(r_b, b[i]);
292  found = true;
293  }
294  }
295  }
296 
297  negate_v3(normal);
298 
299  /* Edge projections. */
300  for (int i = 0; i < 3; i++) {
301  float dir[3];
302 
303  sub_v3_v3v3(tmp_vec, b[next_ind(i)], b[i]);
304  cross_v3_v3v3(dir, tmp_vec, normal);
305 
306  for (int j = 0; j < 3; j++) {
307  if (isect_line_plane_v3(tmp_co1, a[j], a[next_ind(j)], b[i], dir) &&
308  point_in_slice_seg(tmp_co1, a[j], a[next_ind(j)]) &&
309  point_in_slice_seg(tmp_co1, b[i], b[next_ind(i)])) {
310  closest_to_line_v3(tmp_co2, tmp_co1, b[i], b[next_ind(i)]);
311  sub_v3_v3v3(tmp_vec, tmp_co1, tmp_co2);
312  tmp = len_v3(tmp_vec);
313 
314  if ((tmp > maxdist) && (dot_v3v3(tmp_vec, normal) < 0.0f)) {
315  maxdist = tmp;
316  copy_v3_v3(r_a, tmp_co1);
317  copy_v3_v3(r_b, tmp_co2);
318  found = true;
319  }
320  }
321  }
322  }
323 
324  /* If no point is found, will fallback onto regular proximity test below. */
325  if (found) {
326  sub_v3_v3v3(r_vec, r_b, r_a);
327 
328  if (use_normal) {
329  if (dot_v3v3(normal, r_vec) >= 0.0f) {
330  copy_v3_v3(r_vec, normal);
331  }
332  else {
333  negate_v3_v3(r_vec, normal);
334  }
335  }
336 
337  return 0.0f;
338  }
339  }
340 
341  /* Closest point. */
342  for (int i = 0; i < 3; i++) {
343  closest_on_tri_to_point_v3(tmp_co1, a[i], b[0], b[1], b[2]);
344  tmp = len_squared_v3v3(tmp_co1, a[i]);
345 
346  if (tmp < dist) {
347  dist = tmp;
348  copy_v3_v3(r_a, a[i]);
349  copy_v3_v3(r_b, tmp_co1);
350  }
351  }
352 
353  for (int i = 0; i < 3; i++) {
354  closest_on_tri_to_point_v3(tmp_co1, b[i], a[0], a[1], a[2]);
355  tmp = len_squared_v3v3(tmp_co1, b[i]);
356 
357  if (tmp < dist) {
358  dist = tmp;
359  copy_v3_v3(r_a, tmp_co1);
360  copy_v3_v3(r_b, b[i]);
361  }
362  }
363 
364  /* Closest edge. */
365  if (!is_intersecting) {
366  for (int i = 0; i < 3; i++) {
367  for (int j = 0; j < 3; j++) {
368  isect_seg_seg_v3(a[i], a[next_ind(i)], b[j], b[next_ind(j)], tmp_co1, tmp_co2);
369  tmp = len_squared_v3v3(tmp_co1, tmp_co2);
370 
371  if (tmp < dist) {
372  dist = tmp;
373  copy_v3_v3(r_a, tmp_co1);
374  copy_v3_v3(r_b, tmp_co2);
375  }
376  }
377  }
378  }
379 
380  if (!is_intersecting) {
381  sub_v3_v3v3(r_vec, r_a, r_b);
382  dist = sqrtf(dist);
383  }
384  else {
385  sub_v3_v3v3(r_vec, r_b, r_a);
386  dist = 0.0f;
387  }
388 
389  if (culling && use_normal) {
390  copy_v3_v3(r_vec, normal);
391  }
392  else if (use_normal) {
393  if (dot_v3v3(normal, r_vec) >= 0.0f) {
394  copy_v3_v3(r_vec, normal);
395  }
396  else {
397  negate_v3_v3(r_vec, normal);
398  }
399  }
400  else if (culling && (dot_v3v3(r_vec, normal) < 0.0f)) {
401  return FLT_MAX;
402  }
403 
404  return dist;
405 }
406 
407 static float compute_collision_point_edge_tri(const float a1[3],
408  const float a2[3],
409  const float b1[3],
410  const float b2[3],
411  const float b3[3],
412  bool culling,
413  bool use_normal,
414  float r_a[3],
415  float r_b[3],
416  float r_vec[3])
417 {
418  float a[2][3];
419  float b[3][3];
420  float dist = FLT_MAX;
421  float tmp_co1[3], tmp_co2[3];
422  float isect_a[3];
423  bool isect = false;
424  float tmp, tmp_vec[3];
425  float normal[3], cent[3];
426  bool backside = false;
427 
428  copy_v3_v3(a[0], a1);
429  copy_v3_v3(a[1], a2);
430 
431  copy_v3_v3(b[0], b1);
432  copy_v3_v3(b[1], b2);
433  copy_v3_v3(b[2], b3);
434 
435  normal_tri_v3(normal, b[0], b[1], b[2]);
436 
437  /* Find intersection. */
438  if (isect_line_segment_tri_v3(a[0], a[1], b[0], b[1], b[2], &tmp, NULL)) {
439  interp_v3_v3v3(isect_a, a[0], a[1], tmp);
440  isect = true;
441  }
442 
443  /* Determine collision side. */
444  if (culling) {
445  if (isect) {
446  backside = true;
447  }
448  else {
449  mid_v3_v3v3v3(cent, b[0], b[1], b[2]);
450 
451  for (int i = 0; i < 2; i++) {
452  sub_v3_v3v3(tmp_vec, a[i], cent);
453  if (dot_v3v3(tmp_vec, normal) < 0.0f) {
454  backside = true;
455  break;
456  }
457  }
458  }
459  }
460 
461  if (isect) {
462  /* Edge intersection. */
463  copy_v3_v3(r_a, isect_a);
464  copy_v3_v3(r_b, isect_a);
465 
466  copy_v3_v3(r_vec, normal);
467 
468  return 0.0f;
469  }
470 
471  if (backside) {
472  float maxdist = 0.0f;
473  bool found = false;
474 
475  /* Point projections. */
476  for (int i = 0; i < 2; i++) {
477  if (isect_ray_tri_v3(a[i], normal, b[0], b[1], b[2], &tmp, NULL)) {
478  if (tmp > maxdist) {
479  maxdist = tmp;
480  copy_v3_v3(r_a, a[i]);
481  madd_v3_v3v3fl(r_b, a[i], normal, tmp);
482  found = true;
483  }
484  }
485  }
486 
487  /* Edge projections. */
488  for (int i = 0; i < 3; i++) {
489  float dir[3];
490 
491  sub_v3_v3v3(tmp_vec, b[next_ind(i)], b[i]);
492  cross_v3_v3v3(dir, tmp_vec, normal);
493 
494  if (isect_line_plane_v3(tmp_co1, a[0], a[1], b[i], dir) &&
495  point_in_slice_seg(tmp_co1, a[0], a[1]) &&
496  point_in_slice_seg(tmp_co1, b[i], b[next_ind(i)])) {
497  closest_to_line_v3(tmp_co2, tmp_co1, b[i], b[next_ind(i)]);
498  sub_v3_v3v3(tmp_vec, tmp_co1, tmp_co2);
499  tmp = len_v3(tmp_vec);
500 
501  if ((tmp > maxdist) && (dot_v3v3(tmp_vec, normal) < 0.0f)) {
502  maxdist = tmp;
503  copy_v3_v3(r_a, tmp_co1);
504  copy_v3_v3(r_b, tmp_co2);
505  found = true;
506  }
507  }
508  }
509 
510  /* If no point is found, will fallback onto regular proximity test below. */
511  if (found) {
512  sub_v3_v3v3(r_vec, r_b, r_a);
513 
514  if (use_normal) {
515  if (dot_v3v3(normal, r_vec) >= 0.0f) {
516  copy_v3_v3(r_vec, normal);
517  }
518  else {
519  negate_v3_v3(r_vec, normal);
520  }
521  }
522 
523  return 0.0f;
524  }
525  }
526 
527  /* Closest point. */
528  for (int i = 0; i < 2; i++) {
529  closest_on_tri_to_point_v3(tmp_co1, a[i], b[0], b[1], b[2]);
530  tmp = len_squared_v3v3(tmp_co1, a[i]);
531 
532  if (tmp < dist) {
533  dist = tmp;
534  copy_v3_v3(r_a, a[i]);
535  copy_v3_v3(r_b, tmp_co1);
536  }
537  }
538 
539  /* Closest edge. */
540  if (!isect) {
541  for (int j = 0; j < 3; j++) {
542  isect_seg_seg_v3(a[0], a[1], b[j], b[next_ind(j)], tmp_co1, tmp_co2);
543  tmp = len_squared_v3v3(tmp_co1, tmp_co2);
544 
545  if (tmp < dist) {
546  dist = tmp;
547  copy_v3_v3(r_a, tmp_co1);
548  copy_v3_v3(r_b, tmp_co2);
549  }
550  }
551  }
552 
553  if (isect) {
554  sub_v3_v3v3(r_vec, r_b, r_a);
555  dist = 0.0f;
556  }
557  else {
558  sub_v3_v3v3(r_vec, r_a, r_b);
559  dist = sqrtf(dist);
560  }
561 
562  if (culling && use_normal) {
563  copy_v3_v3(r_vec, normal);
564  }
565  else if (use_normal) {
566  if (dot_v3v3(normal, r_vec) >= 0.0f) {
567  copy_v3_v3(r_vec, normal);
568  }
569  else {
570  negate_v3_v3(r_vec, normal);
571  }
572  }
573  else if (culling && (dot_v3v3(r_vec, normal) < 0.0f)) {
574  return FLT_MAX;
575  }
576 
577  return dist;
578 }
579 
580 // w3 is not perfect
581 static void collision_compute_barycentric(const float pv[3],
582  const float p1[3],
583  const float p2[3],
584  const float p3[3],
585  float *w1,
586  float *w2,
587  float *w3)
588 {
589  /* dot_v3v3 */
590 #define INPR(v1, v2) ((v1)[0] * (v2)[0] + (v1)[1] * (v2)[1] + (v1)[2] * (v2)[2])
591 
592  double tempV1[3], tempV2[3], tempV4[3];
593  double a, b, c, d, e, f;
594 
595  sub_v3db_v3fl_v3fl(tempV1, p1, p3);
596  sub_v3db_v3fl_v3fl(tempV2, p2, p3);
597  sub_v3db_v3fl_v3fl(tempV4, pv, p3);
598 
599  a = INPR(tempV1, tempV1);
600  b = INPR(tempV1, tempV2);
601  c = INPR(tempV2, tempV2);
602  e = INPR(tempV1, tempV4);
603  f = INPR(tempV2, tempV4);
604 
605  d = (a * c - b * b);
606 
607  if (fabs(d) < (double)ALMOST_ZERO) {
608  *w1 = *w2 = *w3 = 1.0 / 3.0;
609  return;
610  }
611 
612  w1[0] = (float)((e * c - b * f) / d);
613 
614  if (w1[0] < 0) {
615  w1[0] = 0;
616  }
617 
618  w2[0] = (float)((f - b * (double)w1[0]) / c);
619 
620  if (w2[0] < 0) {
621  w2[0] = 0;
622  }
623 
624  w3[0] = 1.0f - w1[0] - w2[0];
625 
626 #undef INPR
627 }
628 
629 #ifdef __GNUC__
630 # pragma GCC diagnostic push
631 # pragma GCC diagnostic ignored "-Wdouble-promotion"
632 #endif
633 
635  const float v1[3],
636  const float v2[3],
637  const float v3[3],
638  const double w1,
639  const double w2,
640  const double w3)
641 {
642  zero_v3(to);
643  VECADDMUL(to, v1, w1);
644  VECADDMUL(to, v2, w2);
645  VECADDMUL(to, v3, w3);
646 }
647 
648 static void cloth_collision_impulse_vert(const float clamp_sq,
649  const float impulse[3],
650  struct ClothVertex *vert)
651 {
652  float impulse_len_sq = len_squared_v3(impulse);
653 
654  if ((clamp_sq > 0.0f) && (impulse_len_sq > clamp_sq)) {
655  return;
656  }
657 
658  if (fabsf(vert->impulse[0]) < fabsf(impulse[0])) {
659  vert->impulse[0] = impulse[0];
660  }
661 
662  if (fabsf(vert->impulse[1]) < fabsf(impulse[1])) {
663  vert->impulse[1] = impulse[1];
664  }
665 
666  if (fabsf(vert->impulse[2]) < fabsf(impulse[2])) {
667  vert->impulse[2] = impulse[2];
668  }
669 
670  vert->impulse_count++;
671 }
672 
674  CollisionModifierData *collmd,
675  Object *collob,
676  CollPair *collpair,
677  uint collision_count,
678  const float dt)
679 {
680  int result = 0;
681  Cloth *cloth = clmd->clothObject;
682  const float clamp_sq = square_f(clmd->coll_parms->clamp * dt);
683  const float time_multiplier = 1.0f / (clmd->sim_parms->dt * clmd->sim_parms->timescale);
684  const float epsilon2 = BLI_bvhtree_get_epsilon(collmd->bvhtree);
685  const float min_distance = (clmd->coll_parms->epsilon + epsilon2) * (8.0f / 9.0f);
686 
687  const bool is_hair = (clmd->hairdata != NULL);
688  for (int i = 0; i < collision_count; i++, collpair++) {
689  float i1[3], i2[3], i3[3];
690  float w1, w2, w3, u1, u2, u3;
691  float v1[3], v2[3], relativeVelocity[3];
692  zero_v3(i1);
693  zero_v3(i2);
694  zero_v3(i3);
695 
696  /* Only handle static collisions here. */
697  if (collpair->flag & (COLLISION_IN_FUTURE | COLLISION_INACTIVE)) {
698  continue;
699  }
700 
701  /* Compute barycentric coordinates and relative "velocity" for both collision points. */
702  if (is_hair) {
704  collpair->pa, cloth->verts[collpair->ap1].tx, cloth->verts[collpair->ap2].tx);
705 
706  w1 = 1.0f - w2;
707 
708  interp_v3_v3v3(v1, cloth->verts[collpair->ap1].tv, cloth->verts[collpair->ap2].tv, w2);
709  }
710  else {
712  cloth->verts[collpair->ap1].tx,
713  cloth->verts[collpair->ap2].tx,
714  cloth->verts[collpair->ap3].tx,
715  &w1,
716  &w2,
717  &w3);
718 
720  cloth->verts[collpair->ap1].tv,
721  cloth->verts[collpair->ap2].tv,
722  cloth->verts[collpair->ap3].tv,
723  w1,
724  w2,
725  w3);
726  }
727 
729  collmd->current_xnew[collpair->bp1].co,
730  collmd->current_xnew[collpair->bp2].co,
731  collmd->current_xnew[collpair->bp3].co,
732  &u1,
733  &u2,
734  &u3);
735 
737  collmd->current_v[collpair->bp1].co,
738  collmd->current_v[collpair->bp2].co,
739  collmd->current_v[collpair->bp3].co,
740  u1,
741  u2,
742  u3);
743 
744  sub_v3_v3v3(relativeVelocity, v2, v1);
745 
746  /* Calculate the normal component of the relative velocity
747  * (actually only the magnitude - the direction is stored in 'normal'). */
748  const float magrelVel = dot_v3v3(relativeVelocity, collpair->normal);
749  const float d = min_distance - collpair->distance;
750 
751  /* If magrelVel < 0 the edges are approaching each other. */
752  if (magrelVel > 0.0f) {
753  /* Calculate Impulse magnitude to stop all motion in normal direction. */
754  float magtangent = 0, repulse = 0;
755  double impulse = 0.0;
756  float vrel_t_pre[3];
757  float temp[3];
758 
759  /* Calculate tangential velocity. */
760  copy_v3_v3(temp, collpair->normal);
761  mul_v3_fl(temp, magrelVel);
762  sub_v3_v3v3(vrel_t_pre, relativeVelocity, temp);
763 
764  /* Decrease in magnitude of relative tangential velocity due to coulomb friction
765  * in original formula "magrelVel" should be the
766  * "change of relative velocity in normal direction". */
767  magtangent = min_ff(collob->pd->pdef_cfrict * 0.01f * magrelVel, len_v3(vrel_t_pre));
768 
769  /* Apply friction impulse. */
770  if (magtangent > ALMOST_ZERO) {
771  normalize_v3(vrel_t_pre);
772 
773  impulse = magtangent / 1.5;
774 
775  VECADDMUL(i1, vrel_t_pre, (double)w1 * impulse);
776  VECADDMUL(i2, vrel_t_pre, (double)w2 * impulse);
777 
778  if (!is_hair) {
779  VECADDMUL(i3, vrel_t_pre, (double)w3 * impulse);
780  }
781  }
782 
783  /* Apply velocity stopping impulse. */
784  impulse = magrelVel / 1.5f;
785 
786  VECADDMUL(i1, collpair->normal, (double)w1 * impulse);
787  VECADDMUL(i2, collpair->normal, (double)w2 * impulse);
788  if (!is_hair) {
789  VECADDMUL(i3, collpair->normal, (double)w3 * impulse);
790  }
791 
792  if ((magrelVel < 0.1f * d * time_multiplier) && (d > ALMOST_ZERO)) {
793  repulse = MIN2(d / time_multiplier, 0.1f * d * time_multiplier - magrelVel);
794 
795  /* Stay on the safe side and clamp repulse. */
796  if (impulse > ALMOST_ZERO) {
797  repulse = min_ff(repulse, 5.0f * impulse);
798  }
799 
800  repulse = max_ff(impulse, repulse);
801 
802  impulse = repulse / 1.5f;
803 
804  VECADDMUL(i1, collpair->normal, impulse);
805  VECADDMUL(i2, collpair->normal, impulse);
806  if (!is_hair) {
807  VECADDMUL(i3, collpair->normal, impulse);
808  }
809  }
810 
811  result = 1;
812  }
813  else if (d > ALMOST_ZERO) {
814  /* Stay on the safe side and clamp repulse. */
815  float repulse = d / time_multiplier;
816  float impulse = repulse / 4.5f;
817 
818  VECADDMUL(i1, collpair->normal, w1 * impulse);
819  VECADDMUL(i2, collpair->normal, w2 * impulse);
820 
821  if (!is_hair) {
822  VECADDMUL(i3, collpair->normal, w3 * impulse);
823  }
824 
825  result = 1;
826  }
827 
828  if (result) {
829  cloth_collision_impulse_vert(clamp_sq, i1, &cloth->verts[collpair->ap1]);
830  cloth_collision_impulse_vert(clamp_sq, i2, &cloth->verts[collpair->ap2]);
831  if (!is_hair) {
832  cloth_collision_impulse_vert(clamp_sq, i3, &cloth->verts[collpair->ap3]);
833  }
834  }
835  }
836 
837  return result;
838 }
839 
841  CollPair *collpair,
842  uint collision_count,
843  const float dt)
844 {
845  int result = 0;
846  Cloth *cloth = clmd->clothObject;
847  const float clamp_sq = square_f(clmd->coll_parms->self_clamp * dt);
848  const float time_multiplier = 1.0f / (clmd->sim_parms->dt * clmd->sim_parms->timescale);
849  const float min_distance = (2.0f * clmd->coll_parms->selfepsilon) * (8.0f / 9.0f);
850 
851  for (int i = 0; i < collision_count; i++, collpair++) {
852  float ia[3][3] = {{0.0f}};
853  float ib[3][3] = {{0.0f}};
854  float w1, w2, w3, u1, u2, u3;
855  float v1[3], v2[3], relativeVelocity[3];
856 
857  /* Only handle static collisions here. */
858  if (collpair->flag & (COLLISION_IN_FUTURE | COLLISION_INACTIVE)) {
859  continue;
860  }
861 
862  /* Compute barycentric coordinates for both collision points. */
864  cloth->verts[collpair->ap1].tx,
865  cloth->verts[collpair->ap2].tx,
866  cloth->verts[collpair->ap3].tx,
867  &w1,
868  &w2,
869  &w3);
870 
872  cloth->verts[collpair->bp1].tx,
873  cloth->verts[collpair->bp2].tx,
874  cloth->verts[collpair->bp3].tx,
875  &u1,
876  &u2,
877  &u3);
878 
879  /* Calculate relative "velocity". */
881  cloth->verts[collpair->ap1].tv,
882  cloth->verts[collpair->ap2].tv,
883  cloth->verts[collpair->ap3].tv,
884  w1,
885  w2,
886  w3);
887 
889  cloth->verts[collpair->bp1].tv,
890  cloth->verts[collpair->bp2].tv,
891  cloth->verts[collpair->bp3].tv,
892  u1,
893  u2,
894  u3);
895 
896  sub_v3_v3v3(relativeVelocity, v2, v1);
897 
898  /* Calculate the normal component of the relative velocity
899  * (actually only the magnitude - the direction is stored in 'normal'). */
900  const float magrelVel = dot_v3v3(relativeVelocity, collpair->normal);
901  const float d = min_distance - collpair->distance;
902 
903  /* TODO: Impulses should be weighed by mass as this is self col,
904  * this has to be done after mass distribution is implemented. */
905 
906  /* If magrelVel < 0 the edges are approaching each other. */
907  if (magrelVel > 0.0f) {
908  /* Calculate Impulse magnitude to stop all motion in normal direction. */
909  float magtangent = 0, repulse = 0;
910  double impulse = 0.0;
911  float vrel_t_pre[3];
912  float temp[3];
913 
914  /* Calculate tangential velocity. */
915  copy_v3_v3(temp, collpair->normal);
916  mul_v3_fl(temp, magrelVel);
917  sub_v3_v3v3(vrel_t_pre, relativeVelocity, temp);
918 
919  /* Decrease in magnitude of relative tangential velocity due to coulomb friction
920  * in original formula "magrelVel" should be the
921  * "change of relative velocity in normal direction". */
922  magtangent = min_ff(clmd->coll_parms->self_friction * 0.01f * magrelVel, len_v3(vrel_t_pre));
923 
924  /* Apply friction impulse. */
925  if (magtangent > ALMOST_ZERO) {
926  normalize_v3(vrel_t_pre);
927 
928  impulse = magtangent / 1.5;
929 
930  VECADDMUL(ia[0], vrel_t_pre, (double)w1 * impulse);
931  VECADDMUL(ia[1], vrel_t_pre, (double)w2 * impulse);
932  VECADDMUL(ia[2], vrel_t_pre, (double)w3 * impulse);
933 
934  VECADDMUL(ib[0], vrel_t_pre, (double)u1 * -impulse);
935  VECADDMUL(ib[1], vrel_t_pre, (double)u2 * -impulse);
936  VECADDMUL(ib[2], vrel_t_pre, (double)u3 * -impulse);
937  }
938 
939  /* Apply velocity stopping impulse. */
940  impulse = magrelVel / 3.0f;
941 
942  VECADDMUL(ia[0], collpair->normal, (double)w1 * impulse);
943  VECADDMUL(ia[1], collpair->normal, (double)w2 * impulse);
944  VECADDMUL(ia[2], collpair->normal, (double)w3 * impulse);
945 
946  VECADDMUL(ib[0], collpair->normal, (double)u1 * -impulse);
947  VECADDMUL(ib[1], collpair->normal, (double)u2 * -impulse);
948  VECADDMUL(ib[2], collpair->normal, (double)u3 * -impulse);
949 
950  if ((magrelVel < 0.1f * d * time_multiplier) && (d > ALMOST_ZERO)) {
951  repulse = MIN2(d / time_multiplier, 0.1f * d * time_multiplier - magrelVel);
952 
953  if (impulse > ALMOST_ZERO) {
954  repulse = min_ff(repulse, 5.0 * impulse);
955  }
956 
957  repulse = max_ff(impulse, repulse);
958  impulse = repulse / 1.5f;
959 
960  VECADDMUL(ia[0], collpair->normal, (double)w1 * impulse);
961  VECADDMUL(ia[1], collpair->normal, (double)w2 * impulse);
962  VECADDMUL(ia[2], collpair->normal, (double)w3 * impulse);
963 
964  VECADDMUL(ib[0], collpair->normal, (double)u1 * -impulse);
965  VECADDMUL(ib[1], collpair->normal, (double)u2 * -impulse);
966  VECADDMUL(ib[2], collpair->normal, (double)u3 * -impulse);
967  }
968 
969  result = 1;
970  }
971  else if (d > ALMOST_ZERO) {
972  /* Stay on the safe side and clamp repulse. */
973  float repulse = d * 1.0f / time_multiplier;
974  float impulse = repulse / 9.0f;
975 
976  VECADDMUL(ia[0], collpair->normal, w1 * impulse);
977  VECADDMUL(ia[1], collpair->normal, w2 * impulse);
978  VECADDMUL(ia[2], collpair->normal, w3 * impulse);
979 
980  VECADDMUL(ib[0], collpair->normal, u1 * -impulse);
981  VECADDMUL(ib[1], collpair->normal, u2 * -impulse);
982  VECADDMUL(ib[2], collpair->normal, u3 * -impulse);
983 
984  result = 1;
985  }
986 
987  if (result) {
988  cloth_collision_impulse_vert(clamp_sq, ia[0], &cloth->verts[collpair->ap1]);
989  cloth_collision_impulse_vert(clamp_sq, ia[1], &cloth->verts[collpair->ap2]);
990  cloth_collision_impulse_vert(clamp_sq, ia[2], &cloth->verts[collpair->ap3]);
991 
992  cloth_collision_impulse_vert(clamp_sq, ib[0], &cloth->verts[collpair->bp1]);
993  cloth_collision_impulse_vert(clamp_sq, ib[1], &cloth->verts[collpair->bp2]);
994  cloth_collision_impulse_vert(clamp_sq, ib[2], &cloth->verts[collpair->bp3]);
995  }
996  }
997 
998  return result;
999 }
1000 
1001 #ifdef __GNUC__
1002 # pragma GCC diagnostic pop
1003 #endif
1004 
1006  const Cloth *cloth,
1007  const MVertTri *tri_a)
1008 {
1009  const ClothVertex *verts = cloth->verts;
1010 
1011  /* Fully pinned triangles don't need collision processing. */
1012  const int flags_a = verts[tri_a->tri[0]].flags & verts[tri_a->tri[1]].flags &
1013  verts[tri_a->tri[2]].flags;
1014 
1016  return false;
1017  }
1018 
1019  return true;
1020 }
1021 
1022 static void cloth_collision(void *__restrict userdata,
1023  const int index,
1024  const TaskParallelTLS *__restrict UNUSED(tls))
1025 {
1026  ColDetectData *data = (ColDetectData *)userdata;
1027 
1028  ClothModifierData *clmd = data->clmd;
1029  CollisionModifierData *collmd = data->collmd;
1030  CollPair *collpair = data->collisions;
1031  const MVertTri *tri_a, *tri_b;
1032  ClothVertex *verts1 = clmd->clothObject->verts;
1033  float distance = 0.0f;
1034  float epsilon1 = clmd->coll_parms->epsilon;
1035  float epsilon2 = BLI_bvhtree_get_epsilon(collmd->bvhtree);
1036  float pa[3], pb[3], vect[3];
1037 
1038  tri_a = &clmd->clothObject->tri[data->overlap[index].indexA];
1039  tri_b = &collmd->tri[data->overlap[index].indexB];
1040 
1041  /* Compute distance and normal. */
1042  distance = compute_collision_point_tri_tri(verts1[tri_a->tri[0]].tx,
1043  verts1[tri_a->tri[1]].tx,
1044  verts1[tri_a->tri[2]].tx,
1045  collmd->current_xnew[tri_b->tri[0]].co,
1046  collmd->current_xnew[tri_b->tri[1]].co,
1047  collmd->current_xnew[tri_b->tri[2]].co,
1048  data->culling,
1049  data->use_normal,
1050  pa,
1051  pb,
1052  vect);
1053 
1054  if ((distance <= (epsilon1 + epsilon2 + ALMOST_ZERO)) && (len_squared_v3(vect) > ALMOST_ZERO)) {
1055  collpair[index].ap1 = tri_a->tri[0];
1056  collpair[index].ap2 = tri_a->tri[1];
1057  collpair[index].ap3 = tri_a->tri[2];
1058 
1059  collpair[index].bp1 = tri_b->tri[0];
1060  collpair[index].bp2 = tri_b->tri[1];
1061  collpair[index].bp3 = tri_b->tri[2];
1062 
1063  copy_v3_v3(collpair[index].pa, pa);
1064  copy_v3_v3(collpair[index].pb, pb);
1065  copy_v3_v3(collpair[index].vector, vect);
1066 
1067  normalize_v3_v3(collpair[index].normal, collpair[index].vector);
1068 
1069  collpair[index].distance = distance;
1070  collpair[index].flag = 0;
1071 
1072  data->collided = true;
1073  }
1074  else {
1075  collpair[index].flag = COLLISION_INACTIVE;
1076  }
1077 }
1078 
1080  const Cloth *cloth,
1081  const MVertTri *tri_a,
1082  const MVertTri *tri_b)
1083 {
1084  const ClothVertex *verts = cloth->verts;
1085 
1086  /* Skip when either triangle is excluded. */
1087  const int flags_a = verts[tri_a->tri[0]].flags & verts[tri_a->tri[1]].flags &
1088  verts[tri_a->tri[2]].flags;
1089  const int flags_b = verts[tri_b->tri[0]].flags & verts[tri_b->tri[1]].flags &
1090  verts[tri_b->tri[2]].flags;
1091 
1092  if ((flags_a | flags_b) & CLOTH_VERT_FLAG_NOSELFCOLL) {
1093  return false;
1094  }
1095 
1096  /* Skip when both triangles are pinned. */
1097  if ((flags_a & flags_b) & CLOTH_VERT_FLAG_PINNED) {
1098  return false;
1099  }
1100 
1101  /* Ignore overlap of neighboring triangles and triangles connected by a sewing edge. */
1102  bool sewing_active = (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SEW);
1103 
1104  for (uint i = 0; i < 3; i++) {
1105  for (uint j = 0; j < 3; j++) {
1106  if (tri_a->tri[i] == tri_b->tri[j]) {
1107  return false;
1108  }
1109 
1110  if (sewing_active) {
1111  if (BLI_edgeset_haskey(cloth->sew_edge_graph, tri_a->tri[i], tri_b->tri[j])) {
1112  return false;
1113  }
1114  }
1115  }
1116  }
1117 
1118  return true;
1119 }
1120 
1121 static void cloth_selfcollision(void *__restrict userdata,
1122  const int index,
1123  const TaskParallelTLS *__restrict UNUSED(tls))
1124 {
1125  SelfColDetectData *data = (SelfColDetectData *)userdata;
1126 
1127  ClothModifierData *clmd = data->clmd;
1128  CollPair *collpair = data->collisions;
1129  const MVertTri *tri_a, *tri_b;
1130  ClothVertex *verts1 = clmd->clothObject->verts;
1131  float distance = 0.0f;
1132  float epsilon = clmd->coll_parms->selfepsilon;
1133  float pa[3], pb[3], vect[3];
1134 
1135  tri_a = &clmd->clothObject->tri[data->overlap[index].indexA];
1136  tri_b = &clmd->clothObject->tri[data->overlap[index].indexB];
1137 
1138  BLI_assert(cloth_bvh_selfcollision_is_active(clmd, clmd->clothObject, tri_a, tri_b));
1139 
1140  /* Compute distance and normal. */
1141  distance = compute_collision_point_tri_tri(verts1[tri_a->tri[0]].tx,
1142  verts1[tri_a->tri[1]].tx,
1143  verts1[tri_a->tri[2]].tx,
1144  verts1[tri_b->tri[0]].tx,
1145  verts1[tri_b->tri[1]].tx,
1146  verts1[tri_b->tri[2]].tx,
1147  false,
1148  false,
1149  pa,
1150  pb,
1151  vect);
1152 
1153  if ((distance <= (epsilon * 2.0f + ALMOST_ZERO)) && (len_squared_v3(vect) > ALMOST_ZERO)) {
1154  collpair[index].ap1 = tri_a->tri[0];
1155  collpair[index].ap2 = tri_a->tri[1];
1156  collpair[index].ap3 = tri_a->tri[2];
1157 
1158  collpair[index].bp1 = tri_b->tri[0];
1159  collpair[index].bp2 = tri_b->tri[1];
1160  collpair[index].bp3 = tri_b->tri[2];
1161 
1162  copy_v3_v3(collpair[index].pa, pa);
1163  copy_v3_v3(collpair[index].pb, pb);
1164  copy_v3_v3(collpair[index].vector, vect);
1165 
1166  normalize_v3_v3(collpair[index].normal, collpair[index].vector);
1167 
1168  collpair[index].distance = distance;
1169  collpair[index].flag = 0;
1170 
1171  data->collided = true;
1172  }
1173  else {
1174  collpair[index].flag = COLLISION_INACTIVE;
1175  }
1176 }
1177 
1178 static void hair_collision(void *__restrict userdata,
1179  const int index,
1180  const TaskParallelTLS *__restrict UNUSED(tls))
1181 {
1182  ColDetectData *data = (ColDetectData *)userdata;
1183 
1184  ClothModifierData *clmd = data->clmd;
1185  CollisionModifierData *collmd = data->collmd;
1186  CollPair *collpair = data->collisions;
1187  const MVertTri *tri_coll;
1188  const MEdge *edge_coll;
1189  ClothVertex *verts1 = clmd->clothObject->verts;
1190  float distance = 0.0f;
1191  float epsilon1 = clmd->coll_parms->epsilon;
1192  float epsilon2 = BLI_bvhtree_get_epsilon(collmd->bvhtree);
1193  float pa[3], pb[3], vect[3];
1194 
1195  /* TODO: This is not efficient. Might be wise to instead build an array before iterating, to
1196  * avoid walking the list every time. */
1197  edge_coll = &clmd->clothObject->edges[data->overlap[index].indexA];
1198  tri_coll = &collmd->tri[data->overlap[index].indexB];
1199 
1200  /* Compute distance and normal. */
1201  distance = compute_collision_point_edge_tri(verts1[edge_coll->v1].tx,
1202  verts1[edge_coll->v2].tx,
1203  collmd->current_x[tri_coll->tri[0]].co,
1204  collmd->current_x[tri_coll->tri[1]].co,
1205  collmd->current_x[tri_coll->tri[2]].co,
1206  data->culling,
1207  data->use_normal,
1208  pa,
1209  pb,
1210  vect);
1211 
1212  if ((distance <= (epsilon1 + epsilon2 + ALMOST_ZERO)) && (len_squared_v3(vect) > ALMOST_ZERO)) {
1213  collpair[index].ap1 = edge_coll->v1;
1214  collpair[index].ap2 = edge_coll->v2;
1215 
1216  collpair[index].bp1 = tri_coll->tri[0];
1217  collpair[index].bp2 = tri_coll->tri[1];
1218  collpair[index].bp3 = tri_coll->tri[2];
1219 
1220  copy_v3_v3(collpair[index].pa, pa);
1221  copy_v3_v3(collpair[index].pb, pb);
1222  copy_v3_v3(collpair[index].vector, vect);
1223 
1224  normalize_v3_v3(collpair[index].normal, collpair[index].vector);
1225 
1226  collpair[index].distance = distance;
1227  collpair[index].flag = 0;
1228 
1229  data->collided = true;
1230  }
1231  else {
1232  collpair[index].flag = COLLISION_INACTIVE;
1233  }
1234 }
1235 
1236 static void add_collision_object(ListBase *relations,
1237  Object *ob,
1238  int level,
1239  unsigned int modifier_type)
1240 {
1241  /* only get objects with collision modifier */
1242  ModifierData *cmd = BKE_modifiers_findby_type(ob, modifier_type);
1243 
1244  if (cmd) {
1245  CollisionRelation *relation = MEM_callocN(sizeof(CollisionRelation), "CollisionRelation");
1246  relation->ob = ob;
1247  BLI_addtail(relations, relation);
1248  }
1249 
1250  /* objects in dupli groups, one level only for now */
1251  /* TODO: this doesn't really work, we are not taking into account the
1252  * dupli transforms and can get objects in the list multiple times. */
1253  if (ob->instance_collection && level == 0) {
1254  Collection *collection = ob->instance_collection;
1255 
1256  /* add objects */
1257  FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (collection, object) {
1258  add_collision_object(relations, object, level + 1, modifier_type);
1259  }
1261  }
1262 }
1263 
1264 /* Create list of collision relations in the collection or entire scene.
1265  * This is used by the depsgraph to build relations, as well as faster
1266  * lookup of colliders during evaluation. */
1268  Collection *collection,
1269  unsigned int modifier_type)
1270 {
1272  Base *base = BKE_collection_or_layer_objects(view_layer, collection);
1273  const bool for_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
1274  const int base_flag = (for_render) ? BASE_ENABLED_RENDER : BASE_ENABLED_VIEWPORT;
1275 
1276  ListBase *relations = MEM_callocN(sizeof(ListBase), "CollisionRelation list");
1277 
1278  for (; base; base = base->next) {
1279  if (base->flag & base_flag) {
1280  add_collision_object(relations, base->object, 0, modifier_type);
1281  }
1282  }
1283 
1284  return relations;
1285 }
1286 
1288 {
1289  if (relations) {
1290  BLI_freelistN(relations);
1291  MEM_freeN(relations);
1292  }
1293 }
1294 
1295 /* Create effective list of colliders from relations built beforehand.
1296  * Self will be excluded. */
1298  Object *self,
1299  Collection *collection,
1300  unsigned int *numcollobj,
1301  unsigned int modifier_type)
1302 {
1303  ListBase *relations = DEG_get_collision_relations(depsgraph, collection, modifier_type);
1304 
1305  if (!relations) {
1306  *numcollobj = 0;
1307  return NULL;
1308  }
1309 
1310  int maxnum = BLI_listbase_count(relations);
1311  int num = 0;
1312  Object **objects = MEM_callocN(sizeof(Object *) * maxnum, __func__);
1313 
1314  LISTBASE_FOREACH (CollisionRelation *, relation, relations) {
1315  /* Get evaluated object. */
1316  Object *ob = (Object *)DEG_get_evaluated_id(depsgraph, &relation->ob->id);
1317 
1318  if (modifier_type == eModifierType_Collision && !(ob->pd && ob->pd->deflect)) {
1319  continue;
1320  }
1321 
1322  if (ob != self) {
1323  objects[num] = ob;
1324  num++;
1325  }
1326  }
1327 
1328  if (num == 0) {
1329  MEM_freeN(objects);
1330  objects = NULL;
1331  }
1332 
1333  *numcollobj = num;
1334  return objects;
1335 }
1336 
1338 {
1339  if (objects) {
1340  MEM_freeN(objects);
1341  }
1342 }
1343 
1344 /* Create effective list of colliders from relations built beforehand.
1345  * Self will be excluded. */
1347 {
1349  depsgraph, collection, eModifierType_Collision);
1350  ListBase *cache = NULL;
1351 
1352  if (!relations) {
1353  return NULL;
1354  }
1355 
1356  LISTBASE_FOREACH (CollisionRelation *, relation, relations) {
1357  /* Get evaluated object. */
1358  Object *ob = (Object *)DEG_get_evaluated_id(depsgraph, &relation->ob->id);
1359 
1360  if (ob == self) {
1361  continue;
1362  }
1363 
1366  if (cmd && cmd->bvhtree) {
1367  if (cache == NULL) {
1368  cache = MEM_callocN(sizeof(ListBase), "ColliderCache array");
1369  }
1370 
1371  ColliderCache *col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
1372  col->ob = ob;
1373  col->collmd = cmd;
1374  /* make sure collider is properly set up */
1375  collision_move_object(cmd, 1.0, 0.0, true);
1376  BLI_addtail(cache, col);
1377  }
1378  }
1379 
1380  return cache;
1381 }
1382 
1384 {
1385  if (*colliders) {
1386  BLI_freelistN(*colliders);
1387  MEM_freeN(*colliders);
1388  *colliders = NULL;
1389  }
1390 }
1391 
1393  CollisionModifierData *collmd,
1394  CollPair **collisions,
1395  int numresult,
1396  BVHTreeOverlap *overlap,
1397  bool culling,
1398  bool use_normal)
1399 {
1400  const bool is_hair = (clmd->hairdata != NULL);
1401  *collisions = (CollPair *)MEM_mallocN(sizeof(CollPair) * numresult, "collision array");
1402 
1403  ColDetectData data = {
1404  .clmd = clmd,
1405  .collmd = collmd,
1406  .overlap = overlap,
1407  .collisions = *collisions,
1408  .culling = culling,
1409  .use_normal = use_normal,
1410  .collided = false,
1411  };
1412 
1413  TaskParallelSettings settings;
1415  settings.use_threading = true;
1417  0, numresult, &data, is_hair ? hair_collision : cloth_collision, &settings);
1418 
1419  return data.collided;
1420 }
1421 
1423  CollPair *collisions,
1424  int numresult,
1425  BVHTreeOverlap *overlap)
1426 {
1428  .clmd = clmd,
1429  .overlap = overlap,
1430  .collisions = collisions,
1431  .collided = false,
1432  };
1433 
1434  TaskParallelSettings settings;
1436  settings.use_threading = true;
1437  BLI_task_parallel_range(0, numresult, &data, cloth_selfcollision, &settings);
1438 
1439  return data.collided;
1440 }
1441 
1443  Object **collobjs,
1444  CollPair **collisions,
1445  uint *collision_counts,
1446  const uint numcollobj,
1447  const float dt)
1448 {
1449  Cloth *cloth = clmd->clothObject;
1450  int i = 0, j = 0, mvert_num = 0;
1451  ClothVertex *verts = NULL;
1452  int ret = 0;
1453  int result = 0;
1454 
1455  mvert_num = clmd->clothObject->mvert_num;
1456  verts = cloth->verts;
1457 
1458  result = 1;
1459 
1460  for (j = 0; j < 2; j++) {
1461  result = 0;
1462 
1463  for (i = 0; i < numcollobj; i++) {
1464  Object *collob = collobjs[i];
1466  collob, eModifierType_Collision);
1467 
1468  if (collmd->bvhtree) {
1470  clmd, collmd, collob, collisions[i], collision_counts[i], dt);
1471  }
1472  }
1473 
1474  /* Apply impulses in parallel. */
1475  if (result) {
1476  for (i = 0; i < mvert_num; i++) {
1477  // calculate "velocities" (just xnew = xold + v; no dt in v)
1478  if (verts[i].impulse_count) {
1479  add_v3_v3(verts[i].tv, verts[i].impulse);
1480  add_v3_v3(verts[i].dcvel, verts[i].impulse);
1481  zero_v3(verts[i].impulse);
1482  verts[i].impulse_count = 0;
1483 
1484  ret++;
1485  }
1486  }
1487  }
1488  else {
1489  break;
1490  }
1491  }
1492  return ret;
1493 }
1494 
1496  CollPair *collisions,
1497  int collision_count,
1498  const float dt)
1499 {
1500  Cloth *cloth = clmd->clothObject;
1501  int i = 0, j = 0, mvert_num = 0;
1502  ClothVertex *verts = NULL;
1503  int ret = 0;
1504  int result = 0;
1505 
1506  mvert_num = clmd->clothObject->mvert_num;
1507  verts = cloth->verts;
1508 
1509  for (j = 0; j < 2; j++) {
1510  result = 0;
1511 
1512  result += cloth_selfcollision_response_static(clmd, collisions, collision_count, dt);
1513 
1514  /* Apply impulses in parallel. */
1515  if (result) {
1516  for (i = 0; i < mvert_num; i++) {
1517  if (verts[i].impulse_count) {
1518  // VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count );
1519  add_v3_v3(verts[i].tv, verts[i].impulse);
1520  add_v3_v3(verts[i].dcvel, verts[i].impulse);
1521  zero_v3(verts[i].impulse);
1522  verts[i].impulse_count = 0;
1523 
1524  ret++;
1525  }
1526  }
1527  }
1528 
1529  if (!result) {
1530  break;
1531  }
1532  }
1533  return ret;
1534 }
1535 
1536 static bool cloth_bvh_obj_overlap_cb(void *userdata,
1537  int index_a,
1538  int UNUSED(index_b),
1539  int UNUSED(thread))
1540 {
1541  ClothModifierData *clmd = (ClothModifierData *)userdata;
1542  struct Cloth *clothObject = clmd->clothObject;
1543  const MVertTri *tri_a = &clothObject->tri[index_a];
1544 
1545  return cloth_bvh_collision_is_active(clmd, clothObject, tri_a);
1546 }
1547 
1548 static bool cloth_bvh_self_overlap_cb(void *userdata, int index_a, int index_b, int UNUSED(thread))
1549 {
1550  /* No need for equal combinations (eg. (0,1) & (1,0)). */
1551  if (index_a < index_b) {
1552  ClothModifierData *clmd = (ClothModifierData *)userdata;
1553  struct Cloth *clothObject = clmd->clothObject;
1554  const MVertTri *tri_a, *tri_b;
1555  tri_a = &clothObject->tri[index_a];
1556  tri_b = &clothObject->tri[index_b];
1557 
1558  if (cloth_bvh_selfcollision_is_active(clmd, clothObject, tri_a, tri_b)) {
1559  return true;
1560  }
1561  }
1562  return false;
1563 }
1564 
1566  Depsgraph *depsgraph, Object *ob, ClothModifierData *clmd, float step, float dt)
1567 {
1568  Cloth *cloth = clmd->clothObject;
1569  BVHTree *cloth_bvh = cloth->bvhtree;
1570  uint i = 0, mvert_num = 0;
1571  int rounds = 0;
1572  ClothVertex *verts = NULL;
1573  int ret = 0, ret2 = 0;
1574  Object **collobjs = NULL;
1575  unsigned int numcollobj = 0;
1576  uint *coll_counts_obj = NULL;
1577  BVHTreeOverlap **overlap_obj = NULL;
1578  uint coll_count_self = 0;
1579  BVHTreeOverlap *overlap_self = NULL;
1580 
1581  if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || cloth_bvh == NULL) {
1582  return 0;
1583  }
1584 
1585  verts = cloth->verts;
1586  mvert_num = cloth->mvert_num;
1587 
1589  bvhtree_update_from_cloth(clmd, false, false);
1590 
1591  /* Enable self collision if this is a hair sim */
1592  const bool is_hair = (clmd->hairdata != NULL);
1593 
1595  is_hair ? NULL : ob,
1596  clmd->coll_parms->group,
1597  &numcollobj,
1599 
1600  if (collobjs) {
1601  coll_counts_obj = MEM_callocN(sizeof(uint) * numcollobj, "CollCounts");
1602  overlap_obj = MEM_callocN(sizeof(*overlap_obj) * numcollobj, "BVHOverlap");
1603 
1604  for (i = 0; i < numcollobj; i++) {
1605  Object *collob = collobjs[i];
1607  collob, eModifierType_Collision);
1608 
1609  if (!collmd->bvhtree) {
1610  continue;
1611  }
1612 
1613  /* Move object to position (step) in time. */
1614  collision_move_object(collmd, step + dt, step, false);
1615 
1616  overlap_obj[i] = BLI_bvhtree_overlap(cloth_bvh,
1617  collmd->bvhtree,
1618  &coll_counts_obj[i],
1619  is_hair ? NULL : cloth_bvh_obj_overlap_cb,
1620  clmd);
1621  }
1622  }
1623  }
1624 
1626  bvhtree_update_from_cloth(clmd, false, true);
1627 
1628  overlap_self = BLI_bvhtree_overlap(
1629  cloth->bvhselftree, cloth->bvhselftree, &coll_count_self, cloth_bvh_self_overlap_cb, clmd);
1630  }
1631 
1632  do {
1633  ret2 = 0;
1634 
1635  /* Object collisions. */
1636  if ((clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) && collobjs) {
1637  CollPair **collisions;
1638  bool collided = false;
1639 
1640  collisions = MEM_callocN(sizeof(CollPair *) * numcollobj, "CollPair");
1641 
1642  for (i = 0; i < numcollobj; i++) {
1643  Object *collob = collobjs[i];
1645  collob, eModifierType_Collision);
1646 
1647  if (!collmd->bvhtree) {
1648  continue;
1649  }
1650 
1651  if (coll_counts_obj[i] && overlap_obj[i]) {
1653  clmd,
1654  collmd,
1655  &collisions[i],
1656  coll_counts_obj[i],
1657  overlap_obj[i],
1658  (collob->pd->flag & PFIELD_CLOTH_USE_CULLING),
1659  (collob->pd->flag & PFIELD_CLOTH_USE_NORMAL)) ||
1660  collided;
1661  }
1662  }
1663 
1664  if (collided) {
1666  clmd, collobjs, collisions, coll_counts_obj, numcollobj, dt);
1667  ret2 += ret;
1668  }
1669 
1670  for (i = 0; i < numcollobj; i++) {
1671  MEM_SAFE_FREE(collisions[i]);
1672  }
1673 
1674  MEM_freeN(collisions);
1675  }
1676 
1677  /* Self collisions. */
1679  CollPair *collisions = NULL;
1680 
1681  verts = cloth->verts;
1682  mvert_num = cloth->mvert_num;
1683 
1684  if (cloth->bvhselftree) {
1685  if (coll_count_self && overlap_self) {
1686  collisions = (CollPair *)MEM_mallocN(sizeof(CollPair) * coll_count_self,
1687  "collision array");
1688 
1690  clmd, collisions, coll_count_self, overlap_self)) {
1691  ret += cloth_bvh_selfcollisions_resolve(clmd, collisions, coll_count_self, dt);
1692  ret2 += ret;
1693  }
1694  }
1695  }
1696 
1697  MEM_SAFE_FREE(collisions);
1698  }
1699 
1700  /* Apply all collision resolution. */
1701  if (ret2) {
1702  for (i = 0; i < mvert_num; i++) {
1703  if (clmd->sim_parms->vgroup_mass > 0) {
1704  if (verts[i].flags & CLOTH_VERT_FLAG_PINNED) {
1705  continue;
1706  }
1707  }
1708 
1709  add_v3_v3v3(verts[i].tx, verts[i].txold, verts[i].tv);
1710  }
1711  }
1712 
1713  rounds++;
1714  } while (ret2 && (clmd->coll_parms->loop_count > rounds));
1715 
1716  if (overlap_obj) {
1717  for (i = 0; i < numcollobj; i++) {
1718  MEM_SAFE_FREE(overlap_obj[i]);
1719  }
1720 
1721  MEM_freeN(overlap_obj);
1722  }
1723 
1724  MEM_SAFE_FREE(coll_counts_obj);
1725 
1726  MEM_SAFE_FREE(overlap_self);
1727 
1728  BKE_collision_objects_free(collobjs);
1729 
1730  return MIN2(ret, 1);
1731 }
1732 
1733 BLI_INLINE void max_v3_v3v3(float r[3], const float a[3], const float b[3])
1734 {
1735  r[0] = max_ff(a[0], b[0]);
1736  r[1] = max_ff(a[1], b[1]);
1737  r[2] = max_ff(a[2], b[2]);
1738 }
1739 
1740 void collision_get_collider_velocity(float vel_old[3],
1741  float vel_new[3],
1742  CollisionModifierData *collmd,
1743  CollPair *collpair)
1744 {
1745  float u1, u2, u3;
1746 
1747  /* compute barycentric coordinates */
1749  collmd->current_x[collpair->bp1].co,
1750  collmd->current_x[collpair->bp2].co,
1751  collmd->current_x[collpair->bp3].co,
1752  &u1,
1753  &u2,
1754  &u3);
1755 
1757  collmd->current_v[collpair->bp1].co,
1758  collmd->current_v[collpair->bp2].co,
1759  collmd->current_v[collpair->bp3].co,
1760  u1,
1761  u2,
1762  u3);
1763  /* XXX assume constant velocity of the collider for now */
1764  copy_v3_v3(vel_old, vel_new);
1765 }
typedef float(TangentPoint)[2]
void bvhtree_update_from_cloth(struct ClothModifierData *clmd, bool moving, bool self)
Definition: cloth.c:134
#define DO_INLINE
Definition: BKE_cloth.h:40
@ CLOTH_VERT_FLAG_PINNED
Definition: BKE_cloth.h:51
@ CLOTH_VERT_FLAG_NOSELFCOLL
Definition: BKE_cloth.h:52
@ CLOTH_VERT_FLAG_NOOBJCOLL
Definition: BKE_cloth.h:53
#define VECADDMUL(v1, v2, aS)
Definition: BKE_cloth.h:189
#define ALMOST_ZERO
Definition: BKE_cloth.h:47
#define FOREACH_COLLECTION_OBJECT_RECURSIVE_END
#define FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(_collection, _object)
struct Base * BKE_collection_or_layer_objects(const struct ViewLayer *view_layer, struct Collection *collection)
@ COLLISION_INACTIVE
Definition: BKE_collision.h:48
@ COLLISION_IN_FUTURE
Definition: BKE_collision.h:43
struct ModifierData * BKE_modifiers_findby_type(const struct Object *ob, ModifierType type)
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define BLI_INLINE
bool BLI_edgeset_haskey(EdgeSet *es, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT
Definition: edgehash.c:611
BVHTreeOverlap * BLI_bvhtree_overlap(const BVHTree *tree1, const BVHTree *tree2, unsigned int *r_overlap_tot, BVHTree_OverlapCallback callback, void *userdata)
Definition: BLI_kdopbvh.c:1401
void BLI_bvhtree_balance(BVHTree *tree)
Definition: BLI_kdopbvh.c:956
BVHTree * BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
Definition: BLI_kdopbvh.c:873
void BLI_bvhtree_update_tree(BVHTree *tree)
Definition: BLI_kdopbvh.c:1044
void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints)
Definition: BLI_kdopbvh.c:998
bool BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints)
Definition: BLI_kdopbvh.c:1017
float BLI_bvhtree_get_epsilon(const BVHTree *tree)
Definition: BLI_kdopbvh.c:1074
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
MINLINE float square_f(float a)
bool isect_ray_tri_v3(const float ray_origin[3], const float ray_direction[3], const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float r_uv[2])
Definition: math_geom.c:1751
void isect_seg_seg_v3(const float a0[3], const float a1[3], const float b0[3], const float b1[3], float r_a[3], float r_b[3])
Definition: math_geom.c:1174
bool point_in_slice_seg(float p[3], float l1[3], float l2[3])
Definition: math_geom.c:3580
void closest_on_tri_to_point_v3(float r[3], const float p[3], const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:1023
bool isect_tri_tri_v3_ex(const float tri_a[3][3], const float tri_b[3][3], float r_i1[3], float r_i2[3], int *r_tri_a_edge_isect_count)
Definition: math_geom.c:2384
float line_point_factor_v3(const float p[3], const float l1[3], const float l2[3])
Definition: math_geom.c:3449
float closest_to_line_v3(float r_close[3], const float p[3], const float l1[3], const float l2[3])
Definition: math_geom.c:3364
bool isect_line_plane_v3(float r_isect_co[3], const float l1[3], const float l2[3], const float plane_co[3], const float plane_no[3]) ATTR_WARN_UNUSED_RESULT
Definition: math_geom.c:2191
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:51
bool isect_line_segment_tri_v3(const float p1[3], const float p2[3], const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float r_uv[2])
Definition: math_geom.c:1645
MINLINE void sub_v3db_v3fl_v3fl(double r[3], const float a[3], const float b[3])
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], const float t)
Definition: math_vector.c:49
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3(float r[3])
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void negate_v3(float r[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3])
Definition: math_vector.c:289
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
unsigned int uint
Definition: BLI_sys_types.h:83
void BLI_task_parallel_range(const int start, const int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:110
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Definition: BLI_task.h:231
#define UNUSED(x)
#define MIN2(a, b)
typedef double(DMatrix)[4][4]
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
@ DAG_EVAL_RENDER
Definition: DEG_depsgraph.h:62
struct ListBase * DEG_get_collision_relations(const struct Depsgraph *depsgraph, struct Collection *collection, unsigned int modifier_type)
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
struct ID * DEG_get_evaluated_id(const struct Depsgraph *depsgraph, struct ID *id)
struct ViewLayer * DEG_get_input_view_layer(const Depsgraph *graph)
@ CLOTH_COLLSETTINGS_FLAG_ENABLED
@ CLOTH_COLLSETTINGS_FLAG_SELF
@ CLOTH_SIMSETTINGS_FLAG_SEW
@ CLOTH_SIMSETTINGS_FLAG_COLLOBJ
Object groups, one object can be in many groups at once.
@ BASE_ENABLED_RENDER
@ BASE_ENABLED_VIEWPORT
@ eModifierType_Collision
#define PFIELD_CLOTH_USE_NORMAL
#define PFIELD_CLOTH_USE_CULLING
Object is a sort of wrapper for general info.
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble u2
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble u1
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint i1
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
static void cloth_selfcollision(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict UNUSED(tls))
Definition: collision.c:1121
#define INPR(v1, v2)
struct SelfColDetectData SelfColDetectData
ListBase * BKE_collider_cache_create(Depsgraph *depsgraph, Object *self, Collection *collection)
Definition: collision.c:1346
void BKE_collider_cache_free(ListBase **colliders)
Definition: collision.c:1383
static bool cloth_bvh_collision_is_active(const ClothModifierData *UNUSED(clmd), const Cloth *cloth, const MVertTri *tri_a)
Definition: collision.c:1005
static int cloth_collision_response_static(ClothModifierData *clmd, CollisionModifierData *collmd, Object *collob, CollPair *collpair, uint collision_count, const float dt)
Definition: collision.c:673
static bool cloth_bvh_selfcollisions_nearcheck(ClothModifierData *clmd, CollPair *collisions, int numresult, BVHTreeOverlap *overlap)
Definition: collision.c:1422
static float compute_collision_point_tri_tri(const float a1[3], const float a2[3], const float a3[3], const float b1[3], const float b2[3], const float b3[3], bool culling, bool use_normal, float r_a[3], float r_b[3], float r_vec[3])
Definition: collision.c:196
BLI_INLINE void max_v3_v3v3(float r[3], const float a[3], const float b[3])
Definition: collision.c:1733
static int cloth_bvh_objcollisions_resolve(ClothModifierData *clmd, Object **collobjs, CollPair **collisions, uint *collision_counts, const uint numcollobj, const float dt)
Definition: collision.c:1442
static int cloth_bvh_selfcollisions_resolve(ClothModifierData *clmd, CollPair *collisions, int collision_count, const float dt)
Definition: collision.c:1495
static bool cloth_bvh_selfcollision_is_active(const ClothModifierData *clmd, const Cloth *cloth, const MVertTri *tri_a, const MVertTri *tri_b)
Definition: collision.c:1079
Object ** BKE_collision_objects_create(Depsgraph *depsgraph, Object *self, Collection *collection, unsigned int *numcollobj, unsigned int modifier_type)
Definition: collision.c:1297
static bool cloth_bvh_self_overlap_cb(void *userdata, int index_a, int index_b, int UNUSED(thread))
Definition: collision.c:1548
DO_INLINE void collision_interpolateOnTriangle(float to[3], const float v1[3], const float v2[3], const float v3[3], const double w1, const double w2, const double w3)
Definition: collision.c:634
static void collision_compute_barycentric(const float pv[3], const float p1[3], const float p2[3], const float p3[3], float *w1, float *w2, float *w3)
Definition: collision.c:581
void BKE_collision_relations_free(ListBase *relations)
Definition: collision.c:1287
static void cloth_collision(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict UNUSED(tls))
Definition: collision.c:1022
static void hair_collision(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict UNUSED(tls))
Definition: collision.c:1178
BVHTree * bvhtree_build_from_mvert(const MVert *mvert, const struct MVertTri *tri, int tri_num, float epsilon)
Definition: collision.c:112
static bool cloth_bvh_objcollisions_nearcheck(ClothModifierData *clmd, CollisionModifierData *collmd, CollPair **collisions, int numresult, BVHTreeOverlap *overlap, bool culling, bool use_normal)
Definition: collision.c:1392
void collision_get_collider_velocity(float vel_old[3], float vel_new[3], CollisionModifierData *collmd, CollPair *collpair)
Definition: collision.c:1740
void BKE_collision_objects_free(Object **objects)
Definition: collision.c:1337
BLI_INLINE int next_ind(int i)
Definition: collision.c:191
static bool cloth_bvh_obj_overlap_cb(void *userdata, int index_a, int UNUSED(index_b), int UNUSED(thread))
Definition: collision.c:1536
ListBase * BKE_collision_relations_create(Depsgraph *depsgraph, Collection *collection, unsigned int modifier_type)
Definition: collision.c:1267
void bvhtree_update_from_mvert(BVHTree *bvhtree, const MVert *mvert, const MVert *mvert_moving, const MVertTri *tri, int tri_num, bool moving)
Definition: collision.c:138
int cloth_bvh_collision(Depsgraph *depsgraph, Object *ob, ClothModifierData *clmd, float step, float dt)
Definition: collision.c:1565
static void cloth_collision_impulse_vert(const float clamp_sq, const float impulse[3], struct ClothVertex *vert)
Definition: collision.c:648
static void add_collision_object(ListBase *relations, Object *ob, int level, unsigned int modifier_type)
Definition: collision.c:1236
static float compute_collision_point_edge_tri(const float a1[3], const float a2[3], const float b1[3], const float b2[3], const float b3[3], bool culling, bool use_normal, float r_a[3], float r_b[3], float r_vec[3])
Definition: collision.c:407
void collision_move_object(CollisionModifierData *collmd, const float step, const float prevstep, const bool moving_bvh)
Definition: collision.c:82
struct ColDetectData ColDetectData
static int cloth_selfcollision_response_static(ClothModifierData *clmd, CollPair *collpair, uint collision_count, const float dt)
Definition: collision.c:840
const Depsgraph * depsgraph
void * tree
static float verts[][3]
uint col
IconTextureDrawCall normal
#define fabsf(x)
#define sqrtf(x)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static unsigned c
Definition: RandGen.cpp:97
static unsigned a[3]
Definition: RandGen.cpp:92
double epsilon2
power or 2 of epsilon
Definition: utility.cpp:23
static double epsilon
return ret
struct Base * next
short flag
struct Object * object
struct Collection * group
struct ClothHairData * hairdata
struct Cloth * clothObject
struct ClothSimSettings * sim_parms
struct ClothCollSettings * coll_parms
float impulse[3]
Definition: BKE_cloth.h:116
float tv[3]
Definition: BKE_cloth.h:113
unsigned int impulse_count
Definition: BKE_cloth.h:119
float tx[3]
Definition: BKE_cloth.h:111
struct EdgeSet * sew_edge_graph
Definition: BKE_cloth.h:99
struct BVHTree * bvhtree
Definition: BKE_cloth.h:90
struct BVHTree * bvhselftree
Definition: BKE_cloth.h:91
unsigned int mvert_num
Definition: BKE_cloth.h:85
struct ClothVertex * verts
Definition: BKE_cloth.h:82
struct MVertTri * tri
Definition: BKE_cloth.h:92
struct MEdge * edges
Definition: BKE_cloth.h:98
CollPair * collisions
Definition: collision.c:64
CollisionModifierData * collmd
Definition: collision.c:62
BVHTreeOverlap * overlap
Definition: collision.c:63
bool collided
Definition: collision.c:67
bool use_normal
Definition: collision.c:66
bool culling
Definition: collision.c:65
ClothModifierData * clmd
Definition: collision.c:61
float distance
Definition: BKE_collision.h:58
float pa[3]
Definition: BKE_collision.h:61
float pb[3]
Definition: BKE_collision.h:61
float normal[3]
Definition: BKE_collision.h:59
struct BVHTree * bvhtree
struct Object * ob
unsigned int v1
unsigned int v2
unsigned int tri[3]
float co[3]
struct Collection * instance_collection
struct PartDeflect * pd
CollPair * collisions
Definition: collision.c:73
ClothModifierData * clmd
Definition: collision.c:71
BVHTreeOverlap * overlap
Definition: collision.c:72
ccl_device_inline float distance(const float2 &a, const float2 &b)
ccl_device_inline float2 fabs(const float2 &a)