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