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