Blender  V3.3
SIM_mass_spring.cpp
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_meshdata_types.h"
12 #include "DNA_modifier_types.h"
13 #include "DNA_object_force_types.h"
14 #include "DNA_object_types.h"
15 #include "DNA_scene_types.h"
16 
17 #include "BLI_linklist.h"
18 #include "BLI_math.h"
19 #include "BLI_utildefines.h"
20 
21 #include "BKE_cloth.h"
22 #include "BKE_collision.h"
23 #include "BKE_effect.h"
24 
25 #include "SIM_mass_spring.h"
26 #include "implicit.h"
27 
28 #include "DEG_depsgraph.h"
29 #include "DEG_depsgraph_query.h"
30 
31 static float I3[3][3] = {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}};
32 
33 /* Number of off-diagonal non-zero matrix blocks.
34  * Basically there is one of these for each vertex-vertex interaction.
35  */
37 {
38  LinkNode *link;
39  int nondiag = 0;
40 
41  for (link = cloth->springs; link; link = link->next) {
42  ClothSpring *spring = (ClothSpring *)link->link;
43  switch (spring->type) {
45  /* angular bending combines 3 vertices */
46  nondiag += 3;
47  break;
48 
49  default:
50  /* all other springs depend on 2 vertices only */
51  nondiag += 1;
52  break;
53  }
54  }
55 
56  return nondiag;
57 }
58 
60  const MVertTri *vt,
61  float *r_weights)
62 {
63  /* We have custom vertex weights for pressure. */
64  if (clmd->sim_parms->vgroup_pressure > 0) {
65  Cloth *cloth = clmd->clothObject;
66  ClothVertex *verts = cloth->verts;
67 
68  for (unsigned int j = 0; j < 3; j++) {
69  r_weights[j] = verts[vt->tri[j]].pressure_factor;
70 
71  /* Skip the entire triangle if it has a zero weight. */
72  if (r_weights[j] == 0.0f) {
73  return false;
74  }
75  }
76  }
77 
78  return true;
79 }
80 
82  const float gradient_vector[3],
83  float *r_vertex_pressure)
84 {
85  Cloth *cloth = clmd->clothObject;
86  Implicit_Data *data = cloth->implicit;
87  unsigned int mvert_num = cloth->mvert_num;
88  float pt[3];
89 
90  for (unsigned int i = 0; i < mvert_num; i++) {
92  r_vertex_pressure[i] = dot_v3v3(pt, gradient_vector);
93  }
94 }
95 
97 {
98  /* Calculate the (closed) cloth volume. */
99  Cloth *cloth = clmd->clothObject;
100  const MVertTri *tri = cloth->tri;
101  Implicit_Data *data = cloth->implicit;
102  float weights[3] = {1.0f, 1.0f, 1.0f};
103  float vol = 0;
104 
105  /* Early exit for hair, as it never has volume. */
106  if (clmd->hairdata) {
107  return 0.0f;
108  }
109 
110  for (unsigned int i = 0; i < cloth->primitive_num; i++) {
111  const MVertTri *vt = &tri[i];
112 
113  if (cloth_get_pressure_weights(clmd, vt, weights)) {
114  vol += SIM_tri_tetra_volume_signed_6x(data, vt->tri[0], vt->tri[1], vt->tri[2]);
115  }
116  }
117 
118  /* We need to divide by 6 to get the actual volume. */
119  vol = vol / 6.0f;
120 
121  return vol;
122 }
123 
125 {
126  /* Calculate the (closed) cloth volume. */
127  Cloth *cloth = clmd->clothObject;
128  const MVertTri *tri = cloth->tri;
129  const ClothVertex *v = cloth->verts;
130  float weights[3] = {1.0f, 1.0f, 1.0f};
131  float vol = 0;
132 
133  /* Early exit for hair, as it never has volume. */
134  if (clmd->hairdata) {
135  return 0.0f;
136  }
137 
138  for (unsigned int i = 0; i < cloth->primitive_num; i++) {
139  const MVertTri *vt = &tri[i];
140 
141  if (cloth_get_pressure_weights(clmd, vt, weights)) {
143  v[vt->tri[0]].xrest, v[vt->tri[1]].xrest, v[vt->tri[2]].xrest);
144  }
145  }
146 
147  /* We need to divide by 6 to get the actual volume. */
148  vol = vol / 6.0f;
149 
150  return vol;
151 }
152 
153 static float cloth_calc_average_pressure(ClothModifierData *clmd, const float *vertex_pressure)
154 {
155  Cloth *cloth = clmd->clothObject;
156  const MVertTri *tri = cloth->tri;
157  Implicit_Data *data = cloth->implicit;
158  float weights[3] = {1.0f, 1.0f, 1.0f};
159  float total_force = 0;
160  float total_area = 0;
161 
162  for (unsigned int i = 0; i < cloth->primitive_num; i++) {
163  const MVertTri *vt = &tri[i];
164 
165  if (cloth_get_pressure_weights(clmd, vt, weights)) {
166  float area = SIM_tri_area(data, vt->tri[0], vt->tri[1], vt->tri[2]);
167 
168  total_force += (vertex_pressure[vt->tri[0]] + vertex_pressure[vt->tri[1]] +
169  vertex_pressure[vt->tri[2]]) *
170  area / 3.0f;
171  total_area += area;
172  }
173  }
174 
175  return total_force / total_area;
176 }
177 
179 {
180  Cloth *cloth = clmd->clothObject;
181  ClothVertex *verts = cloth->verts;
182  const float ZERO[3] = {0.0f, 0.0f, 0.0f};
183  Implicit_Data *id;
184  unsigned int i, nondiag;
185 
186  nondiag = cloth_count_nondiag_blocks(cloth);
187  cloth->implicit = id = SIM_mass_spring_solver_create(cloth->mvert_num, nondiag);
188 
189  for (i = 0; i < cloth->mvert_num; i++) {
191  }
192 
193  for (i = 0; i < cloth->mvert_num; i++) {
195  }
196 
197  return 1;
198 }
199 
201 {
203 }
204 
206 {
207  Cloth *cloth = clmd->clothObject;
208 
209  if (cloth->implicit) {
211  cloth->implicit = nullptr;
212  }
213 }
214 
216 {
217  Cloth *cloth = clmd->clothObject;
218  ClothVertex *verts = cloth->verts;
219  unsigned int mvert_num = cloth->mvert_num, i;
220  ClothHairData *cloth_hairdata = clmd->hairdata;
221  Implicit_Data *id = cloth->implicit;
222 
223  for (i = 0; i < mvert_num; i++) {
224  if (cloth_hairdata) {
225  ClothHairData *root = &cloth_hairdata[i];
227  }
228  else {
230  }
231 
233  }
234 }
235 
237 {
238  Cloth *cloth = clmd->clothObject;
239 
241 }
242 
243 /* Init constraint matrix
244  * This is part of the modified CG method suggested by Baraff/Witkin in
245  * "Large Steps in Cloth Simulation" (Siggraph 1998)
246  */
248 {
249  Cloth *cloth = clmd->clothObject;
250  Implicit_Data *data = cloth->implicit;
251  ClothVertex *verts = cloth->verts;
252  int mvert_num = cloth->mvert_num;
253  int v;
254 
255  const float ZERO[3] = {0.0f, 0.0f, 0.0f};
256 
258 
259  for (v = 0; v < mvert_num; v++) {
260  if (verts[v].flags & CLOTH_VERT_FLAG_PINNED) {
261  /* pinned vertex constraints */
262  SIM_mass_spring_add_constraint_ndof0(data, v, ZERO); /* velocity is defined externally */
263  }
264 
265  verts[v].impulse_count = 0;
266  }
267 }
268 
275  ClothModifierData *clmd,
276  float (*initial_cos)[3],
277  float UNUSED(step),
278  float dt)
279 {
280  Cloth *cloth = clmd->clothObject;
281  float(*cos)[3] = (float(*)[3])MEM_callocN(sizeof(float[3]) * cloth->mvert_num,
282  "cos cloth_calc_helper_forces");
283  float *masses = (float *)MEM_callocN(sizeof(float) * cloth->mvert_num,
284  "cos cloth_calc_helper_forces");
285  LinkNode *node;
286  ClothSpring *spring;
287  ClothVertex *cv;
288  int i, steps;
289 
290  cv = cloth->verts;
291  for (i = 0; i < cloth->mvert_num; i++, cv++) {
292  copy_v3_v3(cos[i], cv->tx);
293 
294  if (cv->goal == 1.0f || len_squared_v3v3(initial_cos[i], cv->tx) != 0.0f) {
295  masses[i] = 1e+10;
296  }
297  else {
298  masses[i] = cv->mass;
299  }
300  }
301 
302  steps = 55;
303  for (i = 0; i < steps; i++) {
304  for (node = cloth->springs; node; node = node->next) {
305  /* ClothVertex *cv1, *cv2; */ /* UNUSED */
306  int v1, v2;
307  float len, c, l, vec[3];
308 
309  spring = (ClothSpring *)node->link;
311  continue;
312  }
313 
314  v1 = spring->ij;
315  v2 = spring->kl;
316  /* cv1 = cloth->verts + v1; */ /* UNUSED */
317  /* cv2 = cloth->verts + v2; */ /* UNUSED */
318  len = len_v3v3(cos[v1], cos[v2]);
319 
320  sub_v3_v3v3(vec, cos[v1], cos[v2]);
321  normalize_v3(vec);
322 
323  c = (len - spring->restlen);
324  if (c == 0.0f) {
325  continue;
326  }
327 
328  l = c / ((1.0f / masses[v1]) + (1.0f / masses[v2]));
329 
330  mul_v3_fl(vec, -(1.0f / masses[v1]) * l);
331  add_v3_v3(cos[v1], vec);
332 
333  sub_v3_v3v3(vec, cos[v2], cos[v1]);
334  normalize_v3(vec);
335 
336  mul_v3_fl(vec, -(1.0f / masses[v2]) * l);
337  add_v3_v3(cos[v2], vec);
338  }
339  }
340 
341  cv = cloth->verts;
342  for (i = 0; i < cloth->mvert_num; i++, cv++) {
343  float vec[3];
344 
345  /* Compute forces. */
346  sub_v3_v3v3(vec, cos[i], cv->tx);
347  mul_v3_fl(vec, cv->mass * dt * 20.0f);
348  add_v3_v3(cv->tv, vec);
349  // copy_v3_v3(cv->tx, cos[i]);
350  }
351 
352  MEM_freeN(cos);
353  MEM_freeN(masses);
354 
355  return 1;
356 }
357 
359 {
360  Cloth *cloth = clmd->clothObject;
361  ClothSimSettings *parms = clmd->sim_parms;
362  Implicit_Data *data = cloth->implicit;
363  bool using_angular = parms->bending_model == CLOTH_BENDING_ANGULAR;
364  bool resist_compress = (parms->flags & CLOTH_SIMSETTINGS_FLAG_RESIST_SPRING_COMPRESS) &&
365  !using_angular;
366 
368 
369  /* Calculate force of bending springs. */
370  if ((s->type & CLOTH_SPRING_TYPE_BENDING) && using_angular) {
371 #ifdef CLOTH_FORCE_SPRING_BEND
372  float k, scaling;
373 
375 
376  scaling = parms->bending + s->ang_stiffness * fabsf(parms->max_bend - parms->bending);
377  k = scaling * s->restlen *
378  0.1f; /* Multiplying by 0.1, just to scale the forces to more reasonable values. */
379 
381  data, s->ij, s->kl, s->pa, s->pb, s->la, s->lb, s->restang, k, parms->bending_damping);
382 #endif
383  }
384 
385  /* Calculate force of structural + shear springs. */
386  if (s->type &
388 #ifdef CLOTH_FORCE_SPRING_STRUCTURAL
389  float k_tension, scaling_tension;
390 
392 
393  scaling_tension = parms->tension +
394  s->lin_stiffness * fabsf(parms->max_tension - parms->tension);
395  k_tension = scaling_tension / (parms->avg_spring_len + FLT_EPSILON);
396 
397  if (s->type & CLOTH_SPRING_TYPE_SEWING) {
398  /* TODO: verify, half verified (couldn't see error)
399  * sewing springs usually have a large distance at first so clamp the force so we don't get
400  * tunneling through collision objects. */
402  s->ij,
403  s->kl,
404  s->restlen,
405  k_tension,
406  parms->tension_damp,
407  0.0f,
408  0.0f,
409  false,
410  false,
411  parms->max_sewing);
412  }
413  else if (s->type & CLOTH_SPRING_TYPE_STRUCTURAL) {
414  float k_compression, scaling_compression;
415  scaling_compression = parms->compression +
416  s->lin_stiffness * fabsf(parms->max_compression - parms->compression);
417  k_compression = scaling_compression / (parms->avg_spring_len + FLT_EPSILON);
418 
420  s->ij,
421  s->kl,
422  s->restlen,
423  k_tension,
424  parms->tension_damp,
425  k_compression,
426  parms->compression_damp,
427  resist_compress,
428  using_angular,
429  0.0f);
430  }
431  else {
432  /* CLOTH_SPRING_TYPE_INTERNAL */
434 
435  scaling_tension = parms->internal_tension +
436  s->lin_stiffness *
438  k_tension = scaling_tension / (parms->avg_spring_len + FLT_EPSILON);
439  float scaling_compression = parms->internal_compression +
441  parms->internal_compression);
442  float k_compression = scaling_compression / (parms->avg_spring_len + FLT_EPSILON);
443 
444  float k_tension_damp = parms->tension_damp;
445  float k_compression_damp = parms->compression_damp;
446 
447  if (k_tension == 0.0f) {
448  /* No damping so it behaves as if no tension spring was there at all. */
449  k_tension_damp = 0.0f;
450  }
451 
452  if (k_compression == 0.0f) {
453  /* No damping so it behaves as if no compression spring was there at all. */
454  k_compression_damp = 0.0f;
455  }
456 
458  s->ij,
459  s->kl,
460  s->restlen,
461  k_tension,
462  k_tension_damp,
463  k_compression,
464  k_compression_damp,
465  resist_compress,
466  using_angular,
467  0.0f);
468  }
469 #endif
470  }
471  else if (s->type & CLOTH_SPRING_TYPE_SHEAR) {
472 #ifdef CLOTH_FORCE_SPRING_SHEAR
473  float k, scaling;
474 
476 
477  scaling = parms->shear + s->lin_stiffness * fabsf(parms->max_shear - parms->shear);
478  k = scaling / (parms->avg_spring_len + FLT_EPSILON);
479 
481  s->ij,
482  s->kl,
483  s->restlen,
484  k,
485  parms->shear_damp,
486  0.0f,
487  0.0f,
488  resist_compress,
489  false,
490  0.0f);
491 #endif
492  }
493  else if (s->type & CLOTH_SPRING_TYPE_BENDING) { /* calculate force of bending springs */
494 #ifdef CLOTH_FORCE_SPRING_BEND
495  float kb, cb, scaling;
496 
498 
499  scaling = parms->bending + s->lin_stiffness * fabsf(parms->max_bend - parms->bending);
500  kb = scaling / (20.0f * (parms->avg_spring_len + FLT_EPSILON));
501 
502  /* Fix for T45084 for cloth stiffness must have cb proportional to kb */
503  cb = kb * parms->bending_damping;
504 
506 #endif
507  }
508  else if (s->type & CLOTH_SPRING_TYPE_BENDING_HAIR) {
509 #ifdef CLOTH_FORCE_SPRING_BEND
510  float kb, cb, scaling;
511 
513 
514  /* XXX WARNING: angular bending springs for hair apply stiffness factor as an overall factor,
515  * unlike cloth springs! this is crap, but needed due to cloth/hair mixing ... max_bend factor
516  * is not even used for hair, so ...
517  */
518  scaling = s->lin_stiffness * parms->bending;
519  kb = scaling / (20.0f * (parms->avg_spring_len + FLT_EPSILON));
520 
521  /* Fix for T45084 for cloth stiffness must have cb proportional to kb */
522  cb = kb * parms->bending_damping;
523 
524  /* XXX assuming same restlen for ij and jk segments here,
525  * this can be done correctly for hair later. */
526  SIM_mass_spring_force_spring_bending_hair(data, s->ij, s->kl, s->mn, s->target, kb, cb);
527 
528 # if 0
529  {
530  float x_kl[3], x_mn[3], v[3], d[3];
531 
534 
535  BKE_sim_debug_data_add_dot(clmd->debug_data, x_kl, 0.9, 0.9, 0.9, "target", 7980, s->kl);
537  clmd->debug_data, x_kl, x_mn, 0.8, 0.8, 0.8, "target", 7981, s->kl);
538 
539  copy_v3_v3(d, s->target);
541  clmd->debug_data, x_kl, d, 0.8, 0.8, 0.2, "target", 7982, s->kl);
542 
543  // copy_v3_v3(d, s->target_ij);
544  // BKE_sim_debug_data_add_vector(clmd->debug_data, x, d, 1, 0.4, 0.4, "target", 7983, s->kl);
545  }
546 # endif
547 #endif
548  }
549 }
550 
551 static void hair_get_boundbox(ClothModifierData *clmd, float gmin[3], float gmax[3])
552 {
553  Cloth *cloth = clmd->clothObject;
554  Implicit_Data *data = cloth->implicit;
555  unsigned int mvert_num = cloth->mvert_num;
556  int i;
557 
558  INIT_MINMAX(gmin, gmax);
559  for (i = 0; i < mvert_num; i++) {
560  float x[3];
562  DO_MINMAX(x, gmin, gmax);
563  }
564 }
565 
566 static void cloth_calc_force(
567  Scene *scene, ClothModifierData *clmd, float UNUSED(frame), ListBase *effectors, float time)
568 {
569  /* Collect forces and derivatives: F, dFdX, dFdV */
570  Cloth *cloth = clmd->clothObject;
571  ClothSimSettings *parms = clmd->sim_parms;
572  Implicit_Data *data = cloth->implicit;
573  unsigned int i = 0;
574  float drag = clmd->sim_parms->Cvi * 0.01f; /* viscosity of air scaled in percent */
575  float gravity[3] = {0.0f, 0.0f, 0.0f};
576  const MVertTri *tri = cloth->tri;
577  unsigned int mvert_num = cloth->mvert_num;
578  ClothVertex *vert;
579 
580 #ifdef CLOTH_FORCE_GRAVITY
581  /* global acceleration (gravitation) */
583  /* scale gravity force */
584  mul_v3_v3fl(gravity,
586  0.001f * clmd->sim_parms->effector_weights->global_gravity);
587  }
588 
589  vert = cloth->verts;
590  for (i = 0; i < cloth->mvert_num; i++, vert++) {
591  SIM_mass_spring_force_gravity(data, i, vert->mass, gravity);
592 
593  /* Vertex goal springs */
594  if ((!(vert->flags & CLOTH_VERT_FLAG_PINNED)) && (vert->goal > FLT_EPSILON)) {
595  float goal_x[3], goal_v[3];
596  float k;
597 
598  /* divide by time_scale to prevent goal vertices' delta locations from being multiplied */
599  interp_v3_v3v3(goal_x, vert->xold, vert->xconst, time / clmd->sim_parms->time_scale);
600  sub_v3_v3v3(goal_v, vert->xconst, vert->xold); /* distance covered over dt==1 */
601 
602  k = vert->goal * clmd->sim_parms->goalspring /
603  (clmd->sim_parms->avg_spring_len + FLT_EPSILON);
604 
606  data, i, goal_x, goal_v, k, clmd->sim_parms->goalfrict * 0.01f);
607  }
608  }
609 #endif
610 
611  // cloth_calc_volume_force(clmd);
612 
613 #ifdef CLOTH_FORCE_DRAG
615 #endif
616  /* handle pressure forces (making sure that this never gets computed for hair). */
617  if ((parms->flags & CLOTH_SIMSETTINGS_FLAG_PRESSURE) && (clmd->hairdata == nullptr)) {
618  /* The difference in pressure between the inside and outside of the mesh. */
619  float pressure_difference = 0.0f;
620  float volume_factor = 1.0f;
621 
622  float init_vol;
624  init_vol = clmd->sim_parms->target_volume;
625  }
626  else {
627  init_vol = cloth->initial_mesh_volume;
628  }
629 
630  /* Check if we need to calculate the volume of the mesh. */
631  if (init_vol > 1E-6f) {
632  float f;
633  float vol = cloth_calc_volume(clmd);
634 
635  /* If the volume is the same don't apply any pressure. */
636  volume_factor = init_vol / vol;
637  pressure_difference = volume_factor - 1;
638 
639  /* Calculate an artificial maximum value for cloth pressure. */
640  f = fabs(clmd->sim_parms->uniform_pressure_force) + 200.0f;
641 
642  /* Clamp the cloth pressure to the calculated maximum value. */
643  CLAMP_MAX(pressure_difference, f);
644  }
645 
646  pressure_difference += clmd->sim_parms->uniform_pressure_force;
647  pressure_difference *= clmd->sim_parms->pressure_factor;
648 
649  /* Compute the hydrostatic pressure gradient if enabled. */
650  float fluid_density = clmd->sim_parms->fluid_density * 1000; /* kg/l -> kg/m3 */
651  float *hydrostatic_pressure = nullptr;
652 
653  if (fabs(fluid_density) > 1e-6f) {
654  float hydrostatic_vector[3];
655  copy_v3_v3(hydrostatic_vector, gravity);
656 
657  /* When the fluid is inside the object, factor in the acceleration of
658  * the object into the pressure field, as gravity is indistinguishable
659  * from acceleration from the inside. */
660  if (fluid_density > 0) {
661  sub_v3_v3(hydrostatic_vector, cloth->average_acceleration);
662 
663  /* Preserve the total mass by scaling density to match the change in volume. */
664  fluid_density *= volume_factor;
665  }
666 
667  mul_v3_fl(hydrostatic_vector, fluid_density);
668 
669  /* Compute an array of per-vertex hydrostatic pressure, and subtract the average. */
670  hydrostatic_pressure = (float *)MEM_mallocN(sizeof(float) * mvert_num,
671  "hydrostatic pressure gradient");
672 
673  cloth_calc_pressure_gradient(clmd, hydrostatic_vector, hydrostatic_pressure);
674 
675  pressure_difference -= cloth_calc_average_pressure(clmd, hydrostatic_pressure);
676  }
677 
678  /* Apply pressure. */
679  if (hydrostatic_pressure || fabs(pressure_difference) > 1E-6f) {
680  float weights[3] = {1.0f, 1.0f, 1.0f};
681 
682  for (i = 0; i < cloth->primitive_num; i++) {
683  const MVertTri *vt = &tri[i];
684 
685  if (cloth_get_pressure_weights(clmd, vt, weights)) {
687  vt->tri[0],
688  vt->tri[1],
689  vt->tri[2],
690  pressure_difference,
691  hydrostatic_pressure,
692  weights);
693  }
694  }
695  }
696 
697  if (hydrostatic_pressure) {
698  MEM_freeN(hydrostatic_pressure);
699  }
700  }
701 
702  /* handle external forces like wind */
703  if (effectors) {
704  bool is_not_hair = (clmd->hairdata == nullptr) && (cloth->primitive_num > 0);
705  bool has_wind = false, has_force = false;
706 
707  /* cache per-vertex forces to avoid redundant calculation */
708  float(*winvec)[3] = (float(*)[3])MEM_callocN(sizeof(float[3]) * mvert_num * 2,
709  "effector forces");
710  float(*forcevec)[3] = is_not_hair ? winvec + mvert_num : winvec;
711 
712  for (i = 0; i < cloth->mvert_num; i++) {
713  float x[3], v[3];
714  EffectedPoint epoint;
715 
717  pd_point_from_loc(scene, x, v, i, &epoint);
718  BKE_effectors_apply(effectors,
719  nullptr,
721  &epoint,
722  forcevec[i],
723  winvec[i],
724  nullptr);
725 
726  has_wind = has_wind || !is_zero_v3(winvec[i]);
727  has_force = has_force || !is_zero_v3(forcevec[i]);
728  }
729 
730  /* Hair has only edges. */
731  if (is_not_hair) {
732  for (i = 0; i < cloth->primitive_num; i++) {
733  const MVertTri *vt = &tri[i];
734  if (has_wind) {
735  SIM_mass_spring_force_face_wind(data, vt->tri[0], vt->tri[1], vt->tri[2], winvec);
736  }
737  if (has_force) {
738  SIM_mass_spring_force_face_extern(data, vt->tri[0], vt->tri[1], vt->tri[2], forcevec);
739  }
740  }
741  }
742  else {
743 #if 0
744  ClothHairData *hairdata = clmd->hairdata;
745  ClothHairData *hair_ij, *hair_kl;
746 
747  for (LinkNode *link = cloth->springs; link; link = link->next) {
748  ClothSpring *spring = (ClothSpring *)link->link;
749  if (spring->type == CLOTH_SPRING_TYPE_STRUCTURAL) {
750  if (hairdata) {
751  hair_ij = &hairdata[spring->ij];
752  hair_kl = &hairdata[spring->kl];
754  data, spring->ij, spring->kl, hair_ij->radius, hair_kl->radius, winvec);
755  }
756  else {
757  SIM_mass_spring_force_edge_wind(data, spring->ij, spring->kl, 1.0f, 1.0f, winvec);
758  }
759  }
760  }
761 #else
762  ClothHairData *hairdata = clmd->hairdata;
763 
764  vert = cloth->verts;
765  for (i = 0; i < cloth->mvert_num; i++, vert++) {
766  if (hairdata) {
767  ClothHairData *hair = &hairdata[i];
768  SIM_mass_spring_force_vertex_wind(data, i, hair->radius, winvec);
769  }
770  else {
771  SIM_mass_spring_force_vertex_wind(data, i, 1.0f, winvec);
772  }
773  }
774 #endif
775  }
776 
777  MEM_freeN(winvec);
778  }
779 
780  /* calculate spring forces */
781  for (LinkNode *link = cloth->springs; link; link = link->next) {
782  ClothSpring *spring = (ClothSpring *)link->link;
783  /* only handle active springs */
784  if (!(spring->flags & CLOTH_SPRING_FLAG_DEACTIVATE)) {
785  cloth_calc_spring_force(clmd, spring);
786  }
787  }
788 }
789 
790 /* returns vertices' motion state */
792  float cell_scale,
793  const float cell_offset[3],
794  int index,
795  float x[3],
796  float v[3])
797 {
800 
801  mul_v3_fl(x, cell_scale);
802  add_v3_v3(x, cell_offset);
803 }
804 
805 /* returns next spring forming a continuous hair sequence */
807 {
808  ClothSpring *spring = (ClothSpring *)spring_link->link;
809  LinkNode *next = spring_link->next;
810  if (next) {
811  ClothSpring *next_spring = (ClothSpring *)next->link;
812  if (next_spring->type == CLOTH_SPRING_TYPE_STRUCTURAL && next_spring->kl == spring->ij) {
813  return next;
814  }
815  }
816  return nullptr;
817 }
818 
819 /* XXX this is nasty: cloth meshes do not explicitly store
820  * the order of hair segments!
821  * We have to rely on the spring build function for now,
822  * which adds structural springs in reverse order:
823  * (3,4), (2,3), (1,2)
824  * This is currently the only way to figure out hair geometry inside this code ...
825  */
827  const float cell_scale,
828  const float cell_offset[3],
829  Cloth *cloth,
830  LinkNode *spring_link)
831 {
832  Implicit_Data *data = cloth->implicit;
833  LinkNode *next_spring_link = nullptr; /* return value */
834  ClothSpring *spring1, *spring2, *spring3;
835  // ClothVertex *verts = cloth->verts;
836  // ClothVertex *vert3, *vert4;
837  float x1[3], v1[3], x2[3], v2[3], x3[3], v3[3], x4[3], v4[3];
838  float dir1[3], dir2[3], dir3[3];
839 
840  spring1 = nullptr;
841  spring2 = nullptr;
842  spring3 = (ClothSpring *)spring_link->link;
843 
844  zero_v3(x1);
845  zero_v3(v1);
846  zero_v3(dir1);
847  zero_v3(x2);
848  zero_v3(v2);
849  zero_v3(dir2);
850 
851  // vert3 = &verts[spring3->kl];
852  cloth_get_grid_location(data, cell_scale, cell_offset, spring3->kl, x3, v3);
853  // vert4 = &verts[spring3->ij];
854  cloth_get_grid_location(data, cell_scale, cell_offset, spring3->ij, x4, v4);
855  sub_v3_v3v3(dir3, x4, x3);
856  normalize_v3(dir3);
857 
858  while (spring_link) {
859  /* move on */
860  spring1 = spring2;
861  spring2 = spring3;
862 
863  // vert3 = vert4;
864 
865  copy_v3_v3(x1, x2);
866  copy_v3_v3(v1, v2);
867  copy_v3_v3(x2, x3);
868  copy_v3_v3(v2, v3);
869  copy_v3_v3(x3, x4);
870  copy_v3_v3(v3, v4);
871 
872  copy_v3_v3(dir1, dir2);
873  copy_v3_v3(dir2, dir3);
874 
875  /* read next segment */
876  next_spring_link = spring_link->next;
877  spring_link = hair_spring_next(spring_link);
878 
879  if (spring_link) {
880  spring3 = (ClothSpring *)spring_link->link;
881  // vert4 = &verts[spring3->ij];
882  cloth_get_grid_location(data, cell_scale, cell_offset, spring3->ij, x4, v4);
883  sub_v3_v3v3(dir3, x4, x3);
884  normalize_v3(dir3);
885  }
886  else {
887  spring3 = nullptr;
888  // vert4 = NULL;
889  zero_v3(x4);
890  zero_v3(v4);
891  zero_v3(dir3);
892  }
893 
895  x1,
896  v1,
897  x2,
898  v2,
899  x3,
900  v3,
901  x4,
902  v4,
903  spring1 ? dir1 : nullptr,
904  dir2,
905  spring3 ? dir3 : nullptr);
906  }
907 
908  return next_spring_link;
909 }
910 
911 static void cloth_continuum_fill_grid(HairGrid *grid, Cloth *cloth)
912 {
913 #if 0
914  Implicit_Data *data = cloth->implicit;
915  int mvert_num = cloth->mvert_num;
916  ClothVertex *vert;
917  int i;
918 
919  for (i = 0, vert = cloth->verts; i < mvert_num; i++, vert++) {
920  float x[3], v[3];
921 
922  cloth_get_vertex_motion_state(data, vert, x, v);
924  }
925 #else
926  LinkNode *link;
927  float cellsize, gmin[3], cell_scale, cell_offset[3];
928 
929  /* scale and offset for transforming vertex locations into grid space
930  * (cell size is 0..1, gmin becomes origin)
931  */
932  SIM_hair_volume_grid_geometry(grid, &cellsize, nullptr, gmin, nullptr);
933  cell_scale = cellsize > 0.0f ? 1.0f / cellsize : 0.0f;
934  mul_v3_v3fl(cell_offset, gmin, cell_scale);
935  negate_v3(cell_offset);
936 
937  link = cloth->springs;
938  while (link) {
939  ClothSpring *spring = (ClothSpring *)link->link;
940  if (spring->type == CLOTH_SPRING_TYPE_STRUCTURAL) {
941  link = cloth_continuum_add_hair_segments(grid, cell_scale, cell_offset, cloth, link);
942  }
943  else {
944  link = link->next;
945  }
946  }
947 #endif
949 }
950 
951 static void cloth_continuum_step(ClothModifierData *clmd, float dt)
952 {
953  ClothSimSettings *parms = clmd->sim_parms;
954  Cloth *cloth = clmd->clothObject;
955  Implicit_Data *data = cloth->implicit;
956  int mvert_num = cloth->mvert_num;
957  ClothVertex *vert;
958 
959  const float fluid_factor = 0.95f; /* blend between PIC and FLIP methods */
960  float smoothfac = parms->velocity_smooth;
961  /* XXX FIXME arbitrary factor!!! this should be based on some intuitive value instead,
962  * like number of hairs per cell and time decay instead of "strength"
963  */
964  float density_target = parms->density_target;
965  float density_strength = parms->density_strength;
966  float gmin[3], gmax[3];
967  int i;
968 
969  /* clear grid info */
970  zero_v3_int(clmd->hair_grid_res);
971  zero_v3(clmd->hair_grid_min);
972  zero_v3(clmd->hair_grid_max);
973  clmd->hair_grid_cellsize = 0.0f;
974 
975  hair_get_boundbox(clmd, gmin, gmax);
976 
977  /* gather velocities & density */
978  if (smoothfac > 0.0f || density_strength > 0.0f) {
980  clmd->sim_parms->voxel_cell_size, gmin, gmax);
981 
982  cloth_continuum_fill_grid(grid, cloth);
983 
984  /* main hair continuum solver */
985  SIM_hair_volume_solve_divergence(grid, dt, density_target, density_strength);
986 
987  for (i = 0, vert = cloth->verts; i < mvert_num; i++, vert++) {
988  float x[3], v[3], nv[3];
989 
990  /* calculate volumetric velocity influence */
993 
994  SIM_hair_volume_grid_velocity(grid, x, v, fluid_factor, nv);
995 
996  interp_v3_v3v3(nv, v, nv, smoothfac);
997 
998  /* apply on hair data */
1000  }
1001 
1002  /* store basic grid info in the modifier data */
1004  &clmd->hair_grid_cellsize,
1005  clmd->hair_grid_res,
1006  clmd->hair_grid_min,
1007  clmd->hair_grid_max);
1008 
1009 #if 0 /* DEBUG hair velocity vector field */
1010  {
1011  const int size = 64;
1012  int i, j;
1013  float offset[3], a[3], b[3];
1014  const int axis = 0;
1015  const float shift = 0.0f;
1016 
1018  zero_v3(a);
1019  zero_v3(b);
1020 
1021  offset[axis] = shift * clmd->hair_grid_cellsize;
1022  a[(axis + 1) % 3] = clmd->hair_grid_max[(axis + 1) % 3] -
1023  clmd->hair_grid_min[(axis + 1) % 3];
1024  b[(axis + 2) % 3] = clmd->hair_grid_max[(axis + 2) % 3] -
1025  clmd->hair_grid_min[(axis + 2) % 3];
1026 
1027  BKE_sim_debug_data_clear_category(clmd->debug_data, "grid velocity");
1028  for (j = 0; j < size; j++) {
1029  for (i = 0; i < size; i++) {
1030  float x[3], v[3], gvel[3], gvel_smooth[3], gdensity;
1031 
1032  madd_v3_v3v3fl(x, offset, a, (float)i / (float)(size - 1));
1033  madd_v3_v3fl(x, b, (float)j / (float)(size - 1));
1034  zero_v3(v);
1035 
1036  SIM_hair_volume_grid_interpolate(grid, x, &gdensity, gvel, gvel_smooth, NULL, NULL);
1037 
1038 # if 0
1040  clmd->debug_data, x, gdensity, 0.7, 0.3, 1,
1041  "grid density", i, j, 3111);
1042 # endif
1043  if (!is_zero_v3(gvel) || !is_zero_v3(gvel_smooth)) {
1044  float dvel[3];
1045  sub_v3_v3v3(dvel, gvel_smooth, gvel);
1046 # if 0
1048  clmd->debug_data, x, gvel, 0.4, 0, 1,
1049  "grid velocity", i, j, 3112);
1051  clmd->debug_data, x, gvel_smooth, 0.6, 1, 1,
1052  "grid velocity", i, j, 3113);
1053 # endif
1055  clmd->debug_data, x, dvel, 0.4, 1, 0.7, "grid velocity", i, j, 3114);
1056 # if 0
1057  if (gdensity > 0.0f) {
1058  float col0[3] = {0.0, 0.0, 0.0};
1059  float col1[3] = {0.0, 1.0, 0.0};
1060  float col[3];
1061 
1062  interp_v3_v3v3(col, col0, col1,
1063  CLAMPIS(gdensity * clmd->sim_parms->density_strength, 0.0, 1.0));
1064 # if 0
1066  clmd->debug_data, x, gdensity * clmd->sim_parms->density_strength, 0, 1, 0.4,
1067  "grid velocity", i, j, 3115);
1069  clmd->debug_data, x, col[0], col[1], col[2],
1070  "grid velocity", i, j, 3115);
1071 # endif
1073  clmd->debug_data, x, 0.01f, col[0], col[1], col[2], "grid velocity", i, j, 3115);
1074  }
1075 # endif
1076  }
1077  }
1078  }
1079  }
1080 #endif
1081 
1083  }
1084 }
1085 
1086 #if 0
1087 static void cloth_calc_volume_force(ClothModifierData *clmd)
1088 {
1089  ClothSimSettings *parms = clmd->sim_parms;
1090  Cloth *cloth = clmd->clothObject;
1091  Implicit_Data *data = cloth->implicit;
1092  int mvert_num = cloth->mvert_num;
1093  ClothVertex *vert;
1094 
1095  /* 2.0f is an experimental value that seems to give good results */
1096  float smoothfac = 2.0f * parms->velocity_smooth;
1097  float collfac = 2.0f * parms->collider_friction;
1098  float pressfac = parms->pressure;
1099  float minpress = parms->pressure_threshold;
1100  float gmin[3], gmax[3];
1101  int i;
1102 
1103  hair_get_boundbox(clmd, gmin, gmax);
1104 
1105  /* gather velocities & density */
1106  if (smoothfac > 0.0f || pressfac > 0.0f) {
1107  HairVertexGrid *vertex_grid = SIM_hair_volume_create_vertex_grid(
1108  clmd->sim_parms->voxel_res, gmin, gmax);
1109 
1110  vert = cloth->verts;
1111  for (i = 0; i < mvert_num; i++, vert++) {
1112  float x[3], v[3];
1113 
1114  if (vert->solver_index < 0) {
1115  copy_v3_v3(x, vert->x);
1116  copy_v3_v3(v, vert->v);
1117  }
1118  else {
1119  SIM_mass_spring_get_motion_state(data, vert->solver_index, x, v);
1120  }
1121  SIM_hair_volume_add_vertex(vertex_grid, x, v);
1122  }
1124 
1125  vert = cloth->verts;
1126  for (i = 0; i < mvert_num; i++, vert++) {
1127  float x[3], v[3], f[3], dfdx[3][3], dfdv[3][3];
1128 
1129  if (vert->solver_index < 0) {
1130  continue;
1131  }
1132 
1133  /* calculate volumetric forces */
1134  SIM_mass_spring_get_motion_state(data, vert->solver_index, x, v);
1136  vertex_grid, x, v, smoothfac, pressfac, minpress, f, dfdx, dfdv);
1137  /* apply on hair data */
1138  SIM_mass_spring_force_extern(data, vert->solver_index, f, dfdx, dfdv);
1139  }
1140 
1141  SIM_hair_volume_free_vertex_grid(vertex_grid);
1142  }
1143 }
1144 #endif
1145 
1147 {
1148  Cloth *cloth = clmd->clothObject;
1149  Implicit_Data *data = cloth->implicit;
1150  int i, mvert_num = cloth->mvert_num;
1151  float total[3] = {0.0f, 0.0f, 0.0f};
1152 
1153  for (i = 0; i < mvert_num; i++) {
1154  float v[3], nv[3];
1155 
1158 
1159  sub_v3_v3(nv, v);
1160  add_v3_v3(total, nv);
1161  }
1162 
1163  mul_v3_fl(total, 1.0f / dt / mvert_num);
1164 
1165  /* Smooth the data using a running average to prevent instability.
1166  * This is effectively an abstraction of the wave propagation speed in fluid. */
1167  interp_v3_v3v3(cloth->average_acceleration, total, cloth->average_acceleration, powf(0.25f, dt));
1168 }
1169 
1171  Depsgraph *depsgraph, Object *ob, ClothModifierData *clmd, float step, float dt)
1172 {
1173  Cloth *cloth = clmd->clothObject;
1174  Implicit_Data *id = cloth->implicit;
1175  ClothVertex *verts = cloth->verts;
1176  int mvert_num = cloth->mvert_num;
1177  const float time_multiplier = 1.0f / (clmd->sim_parms->dt * clmd->sim_parms->timescale);
1178  int i;
1179 
1180  if (!(clmd->coll_parms->flags &
1182  return;
1183  }
1184 
1185  if (!clmd->clothObject->bvhtree) {
1186  return;
1187  }
1188 
1190 
1191  /* Update verts to current positions. */
1192  for (i = 0; i < mvert_num; i++) {
1194 
1195  sub_v3_v3v3(verts[i].tv, verts[i].tx, verts[i].txold);
1196  zero_v3(verts[i].dcvel);
1197  }
1198 
1200  ob,
1201  clmd,
1202  step / clmd->sim_parms->timescale,
1203  dt / clmd->sim_parms->timescale)) {
1204  for (i = 0; i < mvert_num; i++) {
1205  if ((clmd->sim_parms->vgroup_mass > 0) && (verts[i].flags & CLOTH_VERT_FLAG_PINNED)) {
1206  continue;
1207  }
1208 
1210  madd_v3_v3fl(verts[i].tv, verts[i].dcvel, time_multiplier);
1212  }
1213  }
1214 }
1215 
1217 {
1218  ClothSolverResult *sres = clmd->solver_result;
1219 
1220  sres->status = 0;
1221  sres->max_error = sres->min_error = sres->avg_error = 0.0f;
1222  sres->max_iterations = sres->min_iterations = 0;
1223  sres->avg_iterations = 0.0f;
1224 }
1225 
1227 {
1228  ClothSolverResult *sres = clmd->solver_result;
1229 
1230  if (sres->status) { /* already initialized ? */
1231  /* error only makes sense for successful iterations */
1232  if (result->status == SIM_SOLVER_SUCCESS) {
1233  sres->min_error = min_ff(sres->min_error, result->error);
1234  sres->max_error = max_ff(sres->max_error, result->error);
1235  sres->avg_error += result->error * dt;
1236  }
1237 
1238  sres->min_iterations = min_ii(sres->min_iterations, result->iterations);
1239  sres->max_iterations = max_ii(sres->max_iterations, result->iterations);
1240  sres->avg_iterations += (float)result->iterations * dt;
1241  }
1242  else {
1243  /* error only makes sense for successful iterations */
1244  if (result->status == SIM_SOLVER_SUCCESS) {
1245  sres->min_error = sres->max_error = result->error;
1246  sres->avg_error += result->error * dt;
1247  }
1248 
1249  sres->min_iterations = sres->max_iterations = result->iterations;
1250  sres->avg_iterations += (float)result->iterations * dt;
1251  }
1252 
1253  sres->status |= result->status;
1254 }
1255 
1257  Depsgraph *depsgraph, Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors)
1258 {
1259  /* Hair currently is a cloth sim in disguise ...
1260  * Collision detection and volumetrics work differently then.
1261  * Bad design, TODO
1262  */
1264  const bool is_hair = (clmd->hairdata != nullptr);
1265 
1266  unsigned int i = 0;
1267  float step = 0.0f, tf = clmd->sim_parms->timescale;
1268  Cloth *cloth = clmd->clothObject;
1269  ClothVertex *verts = cloth->verts /*, *cv*/;
1270  unsigned int mvert_num = cloth->mvert_num;
1271  float dt = clmd->sim_parms->dt * clmd->sim_parms->timescale;
1272  Implicit_Data *id = cloth->implicit;
1273 
1274  /* Hydrostatic pressure gradient of the fluid inside the object is affected by acceleration. */
1275  bool use_acceleration = (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_PRESSURE) &&
1276  (clmd->sim_parms->fluid_density > 0);
1277 
1278  BKE_sim_debug_data_clear_category("collision");
1279 
1280  if (!clmd->solver_result) {
1281  clmd->solver_result = MEM_cnew<ClothSolverResult>("cloth solver result");
1282  }
1283  cloth_clear_result(clmd);
1284 
1285  if (clmd->sim_parms->vgroup_mass > 0) { /* Do goal stuff. */
1286  for (i = 0; i < mvert_num; i++) {
1287  /* update velocities with constrained velocities from pinned verts */
1288  if (verts[i].flags & CLOTH_VERT_FLAG_PINNED) {
1289  float v[3];
1290  sub_v3_v3v3(v, verts[i].xconst, verts[i].xold);
1291  // mul_v3_fl(v, clmd->sim_parms->stepsPerFrame);
1292  /* divide by time_scale to prevent constrained velocities from being multiplied */
1293  mul_v3_fl(v, 1.0f / clmd->sim_parms->time_scale);
1295  }
1296  }
1297  }
1298 
1299  if (!use_acceleration) {
1300  zero_v3(cloth->average_acceleration);
1301  }
1302 
1303  while (step < tf) {
1305 
1306  /* setup vertex constraints for pinned vertices */
1308 
1309  /* initialize forces to zero */
1311 
1312  /* calculate forces */
1313  cloth_calc_force(scene, clmd, frame, effectors, step);
1314 
1315  /* calculate new velocity and position */
1317  cloth_record_result(clmd, &result, dt);
1318 
1319  /* Calculate collision impulses. */
1320  cloth_solve_collisions(depsgraph, ob, clmd, step, dt);
1321 
1322  if (is_hair) {
1323  cloth_continuum_step(clmd, dt);
1324  }
1325 
1326  if (use_acceleration) {
1328  }
1329 
1332 
1333  /* move pinned verts to correct position */
1334  for (i = 0; i < mvert_num; i++) {
1335  if (clmd->sim_parms->vgroup_mass > 0) {
1336  if (verts[i].flags & CLOTH_VERT_FLAG_PINNED) {
1337  float x[3];
1338  /* divide by time_scale to prevent pinned vertices'
1339  * delta locations from being multiplied */
1341  x, verts[i].xold, verts[i].xconst, (step + dt) / clmd->sim_parms->time_scale);
1343  }
1344  }
1345 
1346  SIM_mass_spring_get_motion_state(id, i, verts[i].txold, nullptr);
1347  }
1348 
1349  step += dt;
1350  }
1351 
1352  /* copy results back to cloth data */
1353  for (i = 0; i < mvert_num; i++) {
1355  copy_v3_v3(verts[i].txold, verts[i].x);
1356  }
1357 
1358  return 1;
1359 }
typedef float(TangentPoint)[2]
@ CLOTH_SPRING_TYPE_SEWING
Definition: BKE_cloth.h:187
@ CLOTH_SPRING_TYPE_SHEAR
Definition: BKE_cloth.h:184
@ CLOTH_SPRING_TYPE_BENDING_HAIR
Definition: BKE_cloth.h:188
@ CLOTH_SPRING_TYPE_STRUCTURAL
Definition: BKE_cloth.h:183
@ CLOTH_SPRING_TYPE_BENDING
Definition: BKE_cloth.h:185
@ CLOTH_SPRING_TYPE_INTERNAL
Definition: BKE_cloth.h:189
@ CLOTH_VERT_FLAG_PINNED
Definition: BKE_cloth.h:35
int cloth_bvh_collision(struct Depsgraph *depsgraph, struct Object *ob, struct ClothModifierData *clmd, float step, float dt)
Definition: collision.c:1541
@ CLOTH_SPRING_FLAG_DEACTIVATE
Definition: BKE_cloth.h:194
@ CLOTH_SPRING_FLAG_NEEDED
Definition: BKE_cloth.h:195
#define BKE_sim_debug_data_add_dot(p, r, g, b, category,...)
Definition: BKE_effect.h:238
void BKE_sim_debug_data_clear_category(const char *category)
Definition: effect.c:1378
#define BKE_sim_debug_data_add_vector(p, d, r, g, b, category,...)
Definition: BKE_effect.h:258
#define BKE_sim_debug_data_add_line(p1, p2, r, g, b, category,...)
Definition: BKE_effect.h:252
void BKE_effectors_apply(struct ListBase *effectors, struct ListBase *colliders, struct EffectorWeights *weights, struct EffectedPoint *point, float *force, float *wind_force, float *impulse)
Definition: effect.c:1114
#define BKE_sim_debug_data_add_circle(p, radius, r, g, b, category,...)
Definition: BKE_effect.h:245
void pd_point_from_loc(struct Scene *scene, float *loc, float *vel, int index, struct EffectedPoint *point)
Definition: effect.c:419
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_INLINE
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
float volume_tri_tetrahedron_signed_v3_6x(const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:255
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE float normalize_v3(float r[3])
MINLINE void sub_v3_v3(float r[3], const float a[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 bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
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 zero_v3_int(int r[3])
MINLINE void negate_v3(float r[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 mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
#define UNUSED_FUNCTION(x)
#define CLAMP_MAX(a, c)
#define INIT_MINMAX(min, max)
#define CLAMPIS(a, b, c)
#define DO_MINMAX(vec, min, max)
#define UNUSED(x)
#define ELEM(...)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ CLOTH_BENDING_ANGULAR
@ CLOTH_COLLSETTINGS_FLAG_ENABLED
@ CLOTH_COLLSETTINGS_FLAG_SELF
@ CLOTH_SIMSETTINGS_FLAG_PRESSURE_VOL
@ CLOTH_SIMSETTINGS_FLAG_PRESSURE
@ CLOTH_SIMSETTINGS_FLAG_RESIST_SPRING_COMPRESS
Object is a sort of wrapper for general info.
#define PHYS_GLOBAL_GRAVITY
_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 x2
_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.
void SIM_cloth_solver_free(ClothModifierData *clmd)
BLI_INLINE void cloth_get_grid_location(Implicit_Data *data, float cell_scale, const float cell_offset[3], int index, float x[3], float v[3])
static void cloth_continuum_step(ClothModifierData *clmd, float dt)
static bool cloth_get_pressure_weights(ClothModifierData *clmd, const MVertTri *vt, float *r_weights)
static void cloth_continuum_fill_grid(HairGrid *grid, Cloth *cloth)
static void cloth_clear_result(ClothModifierData *clmd)
static float cloth_calc_average_pressure(ClothModifierData *clmd, const float *vertex_pressure)
int SIM_cloth_solver_init(Object *UNUSED(ob), ClothModifierData *clmd)
static int UNUSED_FUNCTION() cloth_calc_helper_forces(Object *UNUSED(ob), ClothModifierData *clmd, float(*initial_cos)[3], float UNUSED(step), float dt)
static float cloth_calc_rest_volume(ClothModifierData *clmd)
static void cloth_calc_pressure_gradient(ClothModifierData *clmd, const float gradient_vector[3], float *r_vertex_pressure)
static int cloth_count_nondiag_blocks(Cloth *cloth)
static void hair_get_boundbox(ClothModifierData *clmd, float gmin[3], float gmax[3])
static LinkNode * cloth_continuum_add_hair_segments(HairGrid *grid, const float cell_scale, const float cell_offset[3], Cloth *cloth, LinkNode *spring_link)
static void cloth_calc_average_acceleration(ClothModifierData *clmd, float dt)
static void cloth_calc_force(Scene *scene, ClothModifierData *clmd, float UNUSED(frame), ListBase *effectors, float time)
static void cloth_record_result(ClothModifierData *clmd, ImplicitSolverResult *result, float dt)
BLI_INLINE LinkNode * hair_spring_next(LinkNode *spring_link)
BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s)
void SIM_cloth_solver_set_volume(ClothModifierData *clmd)
static void cloth_setup_constraints(ClothModifierData *clmd)
static float cloth_calc_volume(ClothModifierData *clmd)
void SIM_mass_spring_set_implicit_vertex_mass(Implicit_Data *data, int index, float mass)
static void cloth_solve_collisions(Depsgraph *depsgraph, Object *ob, ClothModifierData *clmd, float step, float dt)
void SIM_cloth_solver_set_positions(ClothModifierData *clmd)
static float I3[3][3]
int SIM_cloth_solve(Depsgraph *depsgraph, Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors)
@ SIM_SOLVER_SUCCESS
#define ZERO
Definition: StrokeRep.cpp:85
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
#define powf(x, y)
Definition: cuda/compat.h:103
OperationNode * node
double time
Scene scene
const Depsgraph * depsgraph
int len
Definition: draw_manager.c:108
static float verts[][3]
uint col
void SIM_hair_volume_grid_velocity(HairGrid *grid, const float x[3], const float v[3], float fluid_factor, float r_v[3])
void SIM_hair_volume_grid_interpolate(HairGrid *grid, const float x[3], float *density, float velocity[3], float velocity_smooth[3], float density_gradient[3], float velocity_gradient[3][3])
void SIM_hair_volume_grid_geometry(HairGrid *grid, float *cellsize, int res[3], float gmin[3], float gmax[3])
void SIM_hair_volume_free_vertex_grid(HairGrid *grid)
bool SIM_hair_volume_solve_divergence(HairGrid *grid, float, float target_density, float target_strength)
void SIM_hair_volume_add_vertex(HairGrid *grid, const float x[3], const float v[3])
void SIM_hair_volume_normalize_vertex_grid(HairGrid *grid)
void SIM_hair_volume_add_segment(HairGrid *grid, const float UNUSED(x1[3]), const float UNUSED(v1[3]), const float x2[3], const float v2[3], const float x3[3], const float v3[3], const float UNUSED(x4[3]), const float UNUSED(v4[3]), const float UNUSED(dir1[3]), const float UNUSED(dir2[3]), const float UNUSED(dir3[3]))
HairGrid * SIM_hair_volume_create_vertex_grid(float cellsize, const float gmin[3], const float gmax[3])
void SIM_hair_volume_vertex_grid_forces(HairGrid *grid, const float x[3], const float v[3], float smoothfac, float pressurefac, float minpressure, float f[3], float dfdx[3][3], float dfdv[3][3])
void SIM_mass_spring_force_vertex_wind(struct Implicit_Data *data, int v, float radius, const float(*winvec)[3])
float SIM_tri_tetra_volume_signed_6x(struct Implicit_Data *data, int v1, int v2, int v3)
void SIM_mass_spring_get_motion_state(struct Implicit_Data *data, int index, float x[3], float v[3])
void SIM_mass_spring_add_constraint_ndof0(struct Implicit_Data *data, int index, const float dV[3])
void SIM_mass_spring_force_edge_wind(struct Implicit_Data *data, int v1, int v2, float radius1, float radius2, const float(*winvec)[3])
void SIM_mass_spring_set_new_velocity(struct Implicit_Data *data, int index, const float v[3])
bool SIM_mass_spring_force_spring_goal(struct Implicit_Data *data, int i, const float goal_x[3], const float goal_v[3], float stiffness, float damping)
float SIM_tri_area(struct Implicit_Data *data, int v1, int v2, int v3)
void SIM_mass_spring_set_vertex_mass(struct Implicit_Data *data, int index, float mass)
void SIM_mass_spring_force_face_extern(struct Implicit_Data *data, int v1, int v2, int v3, const float(*forcevec)[3])
void SIM_mass_spring_get_velocity(struct Implicit_Data *data, int index, float v[3])
void SIM_mass_spring_set_motion_state(struct Implicit_Data *data, int index, const float x[3], const float v[3])
bool SIM_mass_spring_force_spring_linear(struct Implicit_Data *data, int i, int j, float restlen, float stiffness_tension, float damping_tension, float stiffness_compression, float damping_compression, bool resist_compress, bool new_compress, float clamp_force)
void SIM_mass_spring_get_new_position(struct Implicit_Data *data, int index, float x[3])
bool SIM_mass_spring_force_spring_bending(struct Implicit_Data *data, int i, int j, float restlen, float kb, float cb)
void SIM_mass_spring_apply_result(struct Implicit_Data *data)
void SIM_mass_spring_set_position(struct Implicit_Data *data, int index, const float x[3])
bool SIM_mass_spring_force_spring_bending_hair(struct Implicit_Data *data, int i, int j, int k, const float target[3], float stiffness, float damping)
void SIM_mass_spring_force_pressure(struct Implicit_Data *data, int v1, int v2, int v3, float common_pressure, const float *vertex_pressure, const float weights[3])
void SIM_mass_spring_force_face_wind(struct Implicit_Data *data, int v1, int v2, int v3, const float(*winvec)[3])
void SIM_mass_spring_get_position(struct Implicit_Data *data, int index, float x[3])
bool SIM_mass_spring_solve_velocities(struct Implicit_Data *data, float dt, struct ImplicitSolverResult *result)
void SIM_mass_spring_force_drag(struct Implicit_Data *data, float drag)
void SIM_mass_spring_clear_constraints(struct Implicit_Data *data)
bool SIM_mass_spring_solve_positions(struct Implicit_Data *data, float dt)
void SIM_mass_spring_get_new_velocity(struct Implicit_Data *data, int index, float v[3])
void SIM_mass_spring_set_velocity(struct Implicit_Data *data, int index, const float v[3])
bool SIM_mass_spring_force_spring_angular(struct Implicit_Data *data, int i, int j, int *i_a, int *i_b, int len_a, int len_b, float restang, float stiffness, float damping)
void SIM_mass_spring_force_extern(struct Implicit_Data *data, int i, const float f[3], float dfdx[3][3], float dfdv[3][3])
void SIM_mass_spring_force_gravity(struct Implicit_Data *data, int index, float mass, const float g[3])
void SIM_mass_spring_set_rest_transform(struct Implicit_Data *data, int index, float tfm[3][3])
void SIM_mass_spring_clear_forces(struct Implicit_Data *data)
Implicit_Data * SIM_mass_spring_solver_create(int numverts, int numsprings)
void SIM_mass_spring_solver_free(Implicit_Data *id)
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
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
static ulong * next
#define fabsf(x)
Definition: metal/compat.h:219
static unsigned c
Definition: RandGen.cpp:83
static unsigned a[3]
Definition: RandGen.cpp:78
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:319
static void area(int d1, int d2, int e1, int e2, float weights[2])
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static const int steps
Definition: sky_nishita.cpp:19
float rot[3][3]
Definition: BKE_cloth.h:42
float radius
Definition: BKE_cloth.h:44
struct ClothSolverResult * solver_result
struct ClothHairData * hairdata
struct Cloth * clothObject
struct ClothSimSettings * sim_parms
struct ClothCollSettings * coll_parms
struct EffectorWeights * effector_weights
float uniform_pressure_force
float max_internal_compression
float avg_iterations
Definition: BKE_cloth.h:52
float ang_stiffness
Definition: BKE_cloth.h:130
float lin_stiffness
Definition: BKE_cloth.h:129
int * pb
Definition: BKE_cloth.h:122
float target[3]
Definition: BKE_cloth.h:134
float restang
Definition: BKE_cloth.h:126
int * pa
Definition: BKE_cloth.h:121
float restlen
Definition: BKE_cloth.h:125
float mass
Definition: BKE_cloth.h:98
float tv[3]
Definition: BKE_cloth.h:97
float x[3]
Definition: BKE_cloth.h:93
float v[3]
Definition: BKE_cloth.h:91
float goal
Definition: BKE_cloth.h:99
float tx[3]
Definition: BKE_cloth.h:95
float xconst[3]
Definition: BKE_cloth.h:92
float xold[3]
Definition: BKE_cloth.h:94
struct LinkNode * springs
Definition: BKE_cloth.h:67
float initial_mesh_volume
Definition: BKE_cloth.h:80
float average_acceleration[3]
Definition: BKE_cloth.h:81
struct BVHTree * bvhtree
Definition: BKE_cloth.h:74
struct Implicit_Data * implicit
Definition: BKE_cloth.h:77
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
unsigned int primitive_num
Definition: BKE_cloth.h:70
void * link
Definition: BLI_linklist.h:24
struct LinkNode * next
Definition: BLI_linklist.h:23
unsigned int tri[3]
struct PhysicsSettings physics_settings