Blender  V3.3
softbody.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright Blender Foundation. All rights reserved. */
3 
25 #include <math.h>
26 #include <stdlib.h>
27 #include <string.h>
28 
29 #include "CLG_log.h"
30 
31 #include "MEM_guardedalloc.h"
32 
33 /* types */
34 #include "DNA_collection_types.h"
35 #include "DNA_curve_types.h"
36 #include "DNA_lattice_types.h"
37 #include "DNA_mesh_types.h"
38 #include "DNA_meshdata_types.h"
39 #include "DNA_object_force_types.h"
40 #include "DNA_object_types.h"
41 #include "DNA_scene_types.h"
42 
43 #include "BLI_ghash.h"
44 #include "BLI_listbase.h"
45 #include "BLI_math.h"
46 #include "BLI_threads.h"
47 #include "BLI_utildefines.h"
48 
49 #include "BKE_collection.h"
50 #include "BKE_collision.h"
51 #include "BKE_curve.h"
52 #include "BKE_deform.h"
53 #include "BKE_effect.h"
54 #include "BKE_global.h"
55 #include "BKE_layer.h"
56 #include "BKE_mesh.h"
57 #include "BKE_modifier.h"
58 #include "BKE_pointcache.h"
59 #include "BKE_scene.h"
60 #include "BKE_softbody.h"
61 
62 #include "DEG_depsgraph.h"
63 #include "DEG_depsgraph_query.h"
64 
65 #include "PIL_time.h"
66 
67 static CLG_LogRef LOG = {"bke.softbody"};
68 
69 /* callbacks for errors and interrupts and some goo */
71 
72 /* ********** soft body engine ******* */
73 
74 typedef enum { SB_EDGE = 1, SB_BEND = 2, SB_STIFFQUAD = 3, SB_HANDLE = 4 } type_spring;
75 
76 typedef struct BodySpring {
77  int v1, v2;
78  float len, cf, load;
79  float ext_force[3]; /* edges colliding and sailing */
81  short flag;
83 
84 typedef struct BodyFace {
85  int v1, v2, v3;
86  float ext_force[3]; /* faces colliding */
87  short flag;
89 
90 typedef struct ReferenceVert {
91  float pos[3]; /* position relative to com */
92  float mass; /* node mass */
94 
95 typedef struct ReferenceState {
96  float com[3]; /* Center of mass. */
97  ReferenceVert *ivert; /* List of initial values. */
99 
100 /* Private scratch pad for caching and other data only needed when alive. */
101 typedef struct SBScratch {
104  short flag;
106  int totface;
107  float aabbmin[3], aabbmax[3];
110 
111 typedef struct SB_thread_context {
114  float forcetime;
115  float timenow;
116  int ifirst;
117  int ilast;
120  float fieldfactor;
121  float windfactor;
122  int nr;
123  int tot;
125 
126 #define MID_PRESERVE 1
127 
128 #define SOFTGOALSNAP 0.999f
129 /* if bp-> goal is above make it a *forced follow original* and skip all ODE stuff for this bp
130  * removes *unnecessary* stiffness from ODE system
131  */
132 #define HEUNWARNLIMIT 1 /* 500 would be fine i think for detecting severe *stiff* stuff */
133 
134 #define BSF_INTERSECT 1 /* edge intersects collider face */
135 
136 /* private definitions for bodypoint states */
137 #define SBF_DOFUZZY 1 /* Bodypoint do fuzzy. */
138 #define SBF_OUTOFCOLLISION 2 /* Bodypoint does not collide. */
139 
140 #define BFF_INTERSECT 1 /* collider edge intrudes face. */
141 #define BFF_CLOSEVERT 2 /* collider vertex repulses face. */
142 
143 /* humm .. this should be calculated from sb parameters and sizes. */
144 static float SoftHeunTol = 1.0f;
145 
146 /* local prototypes */
147 static void free_softbody_intern(SoftBody *sb);
148 
149 /*+++ frame based timing +++ */
150 
151 /* Physical unit of force is `kg * m / sec^2`. */
152 
158 {
159  return (0.001f);
160 }
161 
167 {
168  return (0.01f);
169 }
170 
174 static float sb_time_scale(Object *ob)
175 {
176  SoftBody *sb = ob->soft; /* is supposed to be there */
177  if (sb) {
178  return (sb->physics_speed);
179  /* hrms .. this could be IPO as well :)
180  * estimated range [0.001 sluggish slug - 100.0 very fast (i hope ODE solver can handle that)]
181  * 1 approx = a unit 1 pendulum at g = 9.8 [earth conditions] has period 65 frames
182  * theory would give a 50 frames period .. so there must be something inaccurate ..
183  * looking for that (BM). */
184  }
185  return (1.0f);
186  /*
187  * this would be frames/sec independent timing assuming 25 fps is default
188  * but does not work very well with NLA
189  * return (25.0f/scene->r.frs_sec)
190  */
191 }
192 /*--- frame based timing ---*/
193 
194 /* helper functions for everything is animatable jow_go_for2_5 +++++++ */
195 /* introducing them here, because i know: steps in properties ( at frame timing )
196  * will cause unwanted responses of the softbody system (which does inter frame calculations )
197  * so first 'cure' would be: interpolate linear in time ..
198  * Q: why do i write this?
199  * A: because it happened once, that some eager coder 'streamlined' code to fail.
200  * We DO linear interpolation for goals .. and i think we should do on animated properties as well
201  */
202 
203 /* animate sb->maxgoal, sb->mingoal */
204 static float _final_goal(Object *ob, BodyPoint *bp) /* jow_go_for2_5 */
205 {
206  float f = -1999.99f;
207  if (ob) {
208  SoftBody *sb = ob->soft; /* is supposed to be there */
209  if (!(ob->softflag & OB_SB_GOAL)) {
210  return (0.0f);
211  }
212  if (sb && bp) {
213  if (bp->goal < 0.0f) {
214  return (0.0f);
215  }
216  f = sb->mingoal + bp->goal * fabsf(sb->maxgoal - sb->mingoal);
217  f = pow(f, 4.0f);
218  return f;
219  }
220  }
221  CLOG_ERROR(&LOG, "sb or bp == NULL");
222  return f; /* Using crude but spot able values some times helps debugging. */
223 }
224 
225 static float _final_mass(Object *ob, BodyPoint *bp)
226 {
227  if (ob) {
228  SoftBody *sb = ob->soft; /* is supposed to be there */
229  if (sb && bp) {
230  return (bp->mass * sb->nodemass);
231  }
232  }
233  CLOG_ERROR(&LOG, "sb or bp == NULL");
234  return 1.0f;
235 }
236 /* helper functions for everything is animateble jow_go_for2_5 ------*/
237 
238 /* +++ collider caching and dicing +++ */
239 
240 /*
241  * for each target object/face the axis aligned bounding box (AABB) is stored
242  * faces parallel to global axes
243  * so only simple "value" in [min, max] checks are used
244  * float operations still
245  */
246 
247 /* just an ID here to reduce the prob for killing objects
248  * ob->sumohandle points to we should not kill :)
249  */
250 static const int CCD_SAFETY = 190561;
251 
252 typedef struct ccdf_minmax {
253  float minx, miny, minz, maxx, maxy, maxz;
255 
256 typedef struct ccd_Mesh {
258  const MVert *mvert;
259  const MVert *mprevvert;
260  const MVertTri *tri;
261  int safety;
263  /* Axis Aligned Bounding Box AABB */
264  float bbmin[3];
265  float bbmax[3];
267 
269 {
271  ccd_Mesh *pccd_M = NULL;
272  ccdf_minmax *mima;
273  const MVertTri *vt;
274  float hull;
275  int i;
276 
278 
279  /* first some paranoia checks */
280  if (!cmd) {
281  return NULL;
282  }
283  if (!cmd->mvert_num || !cmd->tri_num) {
284  return NULL;
285  }
286 
287  pccd_M = MEM_mallocN(sizeof(ccd_Mesh), "ccd_Mesh");
288  pccd_M->mvert_num = cmd->mvert_num;
289  pccd_M->tri_num = cmd->tri_num;
290  pccd_M->safety = CCD_SAFETY;
291  pccd_M->bbmin[0] = pccd_M->bbmin[1] = pccd_M->bbmin[2] = 1e30f;
292  pccd_M->bbmax[0] = pccd_M->bbmax[1] = pccd_M->bbmax[2] = -1e30f;
293  pccd_M->mprevvert = NULL;
294 
295  /* Blow it up with force-field ranges. */
296  hull = max_ff(ob->pd->pdef_sbift, ob->pd->pdef_sboft);
297 
298  /* Allocate and copy verts. */
299  pccd_M->mvert = MEM_dupallocN(cmd->xnew);
300  /* note that xnew coords are already in global space, */
301  /* determine the ortho BB */
302  for (i = 0; i < pccd_M->mvert_num; i++) {
303  const float *v;
304 
305  /* evaluate limits */
306  v = pccd_M->mvert[i].co;
307  pccd_M->bbmin[0] = min_ff(pccd_M->bbmin[0], v[0] - hull);
308  pccd_M->bbmin[1] = min_ff(pccd_M->bbmin[1], v[1] - hull);
309  pccd_M->bbmin[2] = min_ff(pccd_M->bbmin[2], v[2] - hull);
310 
311  pccd_M->bbmax[0] = max_ff(pccd_M->bbmax[0], v[0] + hull);
312  pccd_M->bbmax[1] = max_ff(pccd_M->bbmax[1], v[1] + hull);
313  pccd_M->bbmax[2] = max_ff(pccd_M->bbmax[2], v[2] + hull);
314  }
315  /* Allocate and copy faces. */
316  pccd_M->tri = MEM_dupallocN(cmd->tri);
317 
318  /* OBBs for idea1 */
319  pccd_M->mima = MEM_mallocN(sizeof(ccdf_minmax) * pccd_M->tri_num, "ccd_Mesh_Faces_mima");
320 
321  /* anyhoo we need to walk the list of faces and find OBB they live in */
322  for (i = 0, mima = pccd_M->mima, vt = pccd_M->tri; i < pccd_M->tri_num; i++, mima++, vt++) {
323  const float *v;
324 
325  mima->minx = mima->miny = mima->minz = 1e30f;
326  mima->maxx = mima->maxy = mima->maxz = -1e30f;
327 
328  v = pccd_M->mvert[vt->tri[0]].co;
329  mima->minx = min_ff(mima->minx, v[0] - hull);
330  mima->miny = min_ff(mima->miny, v[1] - hull);
331  mima->minz = min_ff(mima->minz, v[2] - hull);
332  mima->maxx = max_ff(mima->maxx, v[0] + hull);
333  mima->maxy = max_ff(mima->maxy, v[1] + hull);
334  mima->maxz = max_ff(mima->maxz, v[2] + hull);
335 
336  v = pccd_M->mvert[vt->tri[1]].co;
337  mima->minx = min_ff(mima->minx, v[0] - hull);
338  mima->miny = min_ff(mima->miny, v[1] - hull);
339  mima->minz = min_ff(mima->minz, v[2] - hull);
340  mima->maxx = max_ff(mima->maxx, v[0] + hull);
341  mima->maxy = max_ff(mima->maxy, v[1] + hull);
342  mima->maxz = max_ff(mima->maxz, v[2] + hull);
343 
344  v = pccd_M->mvert[vt->tri[2]].co;
345  mima->minx = min_ff(mima->minx, v[0] - hull);
346  mima->miny = min_ff(mima->miny, v[1] - hull);
347  mima->minz = min_ff(mima->minz, v[2] - hull);
348  mima->maxx = max_ff(mima->maxx, v[0] + hull);
349  mima->maxy = max_ff(mima->maxy, v[1] + hull);
350  mima->maxz = max_ff(mima->maxz, v[2] + hull);
351  }
352 
353  return pccd_M;
354 }
355 static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
356 {
358  ccdf_minmax *mima;
359  const MVertTri *vt;
360  float hull;
361  int i;
362 
364 
365  /* first some paranoia checks */
366  if (!cmd) {
367  return;
368  }
369  if (!cmd->mvert_num || !cmd->tri_num) {
370  return;
371  }
372 
373  if ((pccd_M->mvert_num != cmd->mvert_num) || (pccd_M->tri_num != cmd->tri_num)) {
374  return;
375  }
376 
377  pccd_M->bbmin[0] = pccd_M->bbmin[1] = pccd_M->bbmin[2] = 1e30f;
378  pccd_M->bbmax[0] = pccd_M->bbmax[1] = pccd_M->bbmax[2] = -1e30f;
379 
380  /* blow it up with forcefield ranges */
381  hull = max_ff(ob->pd->pdef_sbift, ob->pd->pdef_sboft);
382 
383  /* rotate current to previous */
384  if (pccd_M->mprevvert) {
385  MEM_freeN((void *)pccd_M->mprevvert);
386  }
387  pccd_M->mprevvert = pccd_M->mvert;
388  /* Allocate and copy verts. */
389  pccd_M->mvert = MEM_dupallocN(cmd->xnew);
390  /* note that xnew coords are already in global space, */
391  /* determine the ortho BB */
392  for (i = 0; i < pccd_M->mvert_num; i++) {
393  const float *v;
394 
395  /* evaluate limits */
396  v = pccd_M->mvert[i].co;
397  pccd_M->bbmin[0] = min_ff(pccd_M->bbmin[0], v[0] - hull);
398  pccd_M->bbmin[1] = min_ff(pccd_M->bbmin[1], v[1] - hull);
399  pccd_M->bbmin[2] = min_ff(pccd_M->bbmin[2], v[2] - hull);
400 
401  pccd_M->bbmax[0] = max_ff(pccd_M->bbmax[0], v[0] + hull);
402  pccd_M->bbmax[1] = max_ff(pccd_M->bbmax[1], v[1] + hull);
403  pccd_M->bbmax[2] = max_ff(pccd_M->bbmax[2], v[2] + hull);
404 
405  /* evaluate limits */
406  v = pccd_M->mprevvert[i].co;
407  pccd_M->bbmin[0] = min_ff(pccd_M->bbmin[0], v[0] - hull);
408  pccd_M->bbmin[1] = min_ff(pccd_M->bbmin[1], v[1] - hull);
409  pccd_M->bbmin[2] = min_ff(pccd_M->bbmin[2], v[2] - hull);
410 
411  pccd_M->bbmax[0] = max_ff(pccd_M->bbmax[0], v[0] + hull);
412  pccd_M->bbmax[1] = max_ff(pccd_M->bbmax[1], v[1] + hull);
413  pccd_M->bbmax[2] = max_ff(pccd_M->bbmax[2], v[2] + hull);
414  }
415 
416  /* anyhoo we need to walk the list of faces and find OBB they live in */
417  for (i = 0, mima = pccd_M->mima, vt = pccd_M->tri; i < pccd_M->tri_num; i++, mima++, vt++) {
418  const float *v;
419 
420  mima->minx = mima->miny = mima->minz = 1e30f;
421  mima->maxx = mima->maxy = mima->maxz = -1e30f;
422 
423  /* mvert */
424  v = pccd_M->mvert[vt->tri[0]].co;
425  mima->minx = min_ff(mima->minx, v[0] - hull);
426  mima->miny = min_ff(mima->miny, v[1] - hull);
427  mima->minz = min_ff(mima->minz, v[2] - hull);
428  mima->maxx = max_ff(mima->maxx, v[0] + hull);
429  mima->maxy = max_ff(mima->maxy, v[1] + hull);
430  mima->maxz = max_ff(mima->maxz, v[2] + hull);
431 
432  v = pccd_M->mvert[vt->tri[1]].co;
433  mima->minx = min_ff(mima->minx, v[0] - hull);
434  mima->miny = min_ff(mima->miny, v[1] - hull);
435  mima->minz = min_ff(mima->minz, v[2] - hull);
436  mima->maxx = max_ff(mima->maxx, v[0] + hull);
437  mima->maxy = max_ff(mima->maxy, v[1] + hull);
438  mima->maxz = max_ff(mima->maxz, v[2] + hull);
439 
440  v = pccd_M->mvert[vt->tri[2]].co;
441  mima->minx = min_ff(mima->minx, v[0] - hull);
442  mima->miny = min_ff(mima->miny, v[1] - hull);
443  mima->minz = min_ff(mima->minz, v[2] - hull);
444  mima->maxx = max_ff(mima->maxx, v[0] + hull);
445  mima->maxy = max_ff(mima->maxy, v[1] + hull);
446  mima->maxz = max_ff(mima->maxz, v[2] + hull);
447 
448  /* mprevvert */
449  v = pccd_M->mprevvert[vt->tri[0]].co;
450  mima->minx = min_ff(mima->minx, v[0] - hull);
451  mima->miny = min_ff(mima->miny, v[1] - hull);
452  mima->minz = min_ff(mima->minz, v[2] - hull);
453  mima->maxx = max_ff(mima->maxx, v[0] + hull);
454  mima->maxy = max_ff(mima->maxy, v[1] + hull);
455  mima->maxz = max_ff(mima->maxz, v[2] + hull);
456 
457  v = pccd_M->mprevvert[vt->tri[1]].co;
458  mima->minx = min_ff(mima->minx, v[0] - hull);
459  mima->miny = min_ff(mima->miny, v[1] - hull);
460  mima->minz = min_ff(mima->minz, v[2] - hull);
461  mima->maxx = max_ff(mima->maxx, v[0] + hull);
462  mima->maxy = max_ff(mima->maxy, v[1] + hull);
463  mima->maxz = max_ff(mima->maxz, v[2] + hull);
464 
465  v = pccd_M->mprevvert[vt->tri[2]].co;
466  mima->minx = min_ff(mima->minx, v[0] - hull);
467  mima->miny = min_ff(mima->miny, v[1] - hull);
468  mima->minz = min_ff(mima->minz, v[2] - hull);
469  mima->maxx = max_ff(mima->maxx, v[0] + hull);
470  mima->maxy = max_ff(mima->maxy, v[1] + hull);
471  mima->maxz = max_ff(mima->maxz, v[2] + hull);
472  }
473 }
474 
475 static void ccd_mesh_free(ccd_Mesh *ccdm)
476 {
477  /* Make sure we're not nuking objects we don't know. */
478  if (ccdm && (ccdm->safety == CCD_SAFETY)) {
479  MEM_freeN((void *)ccdm->mvert);
480  MEM_freeN((void *)ccdm->tri);
481  if (ccdm->mprevvert) {
482  MEM_freeN((void *)ccdm->mprevvert);
483  }
484  MEM_freeN(ccdm->mima);
485  MEM_freeN(ccdm);
486  }
487 }
488 
490 {
491  /* only with deflecting set */
492  if (ob->pd && ob->pd->deflect) {
493  void **val_p;
494  if (!BLI_ghash_ensure_p(hash, ob, &val_p)) {
495  ccd_Mesh *ccdmesh = ccd_mesh_make(ob);
496  *val_p = ccdmesh;
497  }
498  }
499 }
500 
505  Collection *collection,
506  Object *vertexowner,
507  GHash *hash)
508 {
509  if (!hash) {
510  return;
511  }
512 
513  unsigned int numobjects;
515  depsgraph, vertexowner, collection, &numobjects, eModifierType_Collision);
516 
517  for (int i = 0; i < numobjects; i++) {
518  Object *ob = objects[i];
519 
520  if (ob->type == OB_MESH) {
522  }
523  }
524 
526 }
527 
529 {
530  if (ob->pd && ob->pd->deflect) {
531  ccd_Mesh *ccdmesh = BLI_ghash_lookup(hash, ob);
532  if (ccdmesh) {
533  ccd_mesh_update(ob, ccdmesh);
534  }
535  }
536 }
537 
542  Collection *collection,
543  Object *vertexowner,
544  GHash *hash)
545 {
546  if ((!hash) || (!vertexowner)) {
547  return;
548  }
549 
550  unsigned int numobjects;
552  depsgraph, vertexowner, collection, &numobjects, eModifierType_Collision);
553 
554  for (int i = 0; i < numobjects; i++) {
555  Object *ob = objects[i];
556 
557  if (ob->type == OB_MESH) {
559  }
560  }
561 
563 }
564 
565 /*--- collider caching and dicing ---*/
566 
567 static int count_mesh_quads(Mesh *me)
568 {
569  int a, result = 0;
570  const MPoly *mp = me->mpoly;
571 
572  if (mp) {
573  for (a = me->totpoly; a > 0; a--, mp++) {
574  if (mp->totloop == 4) {
575  result++;
576  }
577  }
578  }
579  return result;
580 }
581 
583 {
584  Mesh *me = ob->data;
585  // BodyPoint *bp; /* UNUSED */
586  int a;
587 
588  if (ob->soft) {
589  int nofquads;
590  // float s_shear = ob->soft->shearstiff*ob->soft->shearstiff;
591 
592  nofquads = count_mesh_quads(me);
593  if (nofquads) {
594  const MLoop *mloop = me->mloop;
595  const MPoly *mp = me->mpoly;
596  BodySpring *bs;
597 
598  /* resize spring-array to hold additional quad springs */
599  ob->soft->bspring = MEM_recallocN(ob->soft->bspring,
600  sizeof(BodySpring) * (ob->soft->totspring + nofquads * 2));
601 
602  /* fill the tail */
603  a = 0;
604  bs = &ob->soft->bspring[ob->soft->totspring];
605  // bp = ob->soft->bpoint; /* UNUSED */
606  for (a = me->totpoly; a > 0; a--, mp++) {
607  if (mp->totloop == 4) {
608  bs->v1 = mloop[mp->loopstart + 0].v;
609  bs->v2 = mloop[mp->loopstart + 2].v;
610  bs->springtype = SB_STIFFQUAD;
611  bs++;
612  bs->v1 = mloop[mp->loopstart + 1].v;
613  bs->v2 = mloop[mp->loopstart + 3].v;
614  bs->springtype = SB_STIFFQUAD;
615  bs++;
616  }
617  }
618 
619  /* now we can announce new springs */
620  ob->soft->totspring += nofquads * 2;
621  }
622  }
623 }
624 
625 static void add_2nd_order_roller(Object *ob, float UNUSED(stiffness), int *counter, int addsprings)
626 {
627  /* Assume we have a softbody. */
628  SoftBody *sb = ob->soft; /* is supposed to be there */
629  BodyPoint *bp, *bpo;
630  BodySpring *bs, *bs2, *bs3 = NULL;
631  int a, b, c, notthis = 0, v0;
632  if (!sb->bspring) {
633  return;
634  } /* we are 2nd order here so 1rst should have been build :) */
635  /* first run counting second run adding */
636  *counter = 0;
637  if (addsprings) {
638  bs3 = ob->soft->bspring + ob->soft->totspring;
639  }
640  for (a = sb->totpoint, bp = sb->bpoint; a > 0; a--, bp++) {
641  /* Scan for neighborhood. */
642  bpo = NULL;
643  v0 = (sb->totpoint - a);
644  for (b = bp->nofsprings; b > 0; b--) {
645  bs = sb->bspring + bp->springs[b - 1];
646  /* Nasty thing here that springs have two ends
647  * so here we have to make sure we examine the other */
648  if (v0 == bs->v1) {
649  bpo = sb->bpoint + bs->v2;
650  notthis = bs->v2;
651  }
652  else {
653  if (v0 == bs->v2) {
654  bpo = sb->bpoint + bs->v1;
655  notthis = bs->v1;
656  }
657  else {
658  CLOG_ERROR(&LOG, "oops we should not get here");
659  }
660  }
661  if (bpo) { /* so now we have a 2nd order humpdidump */
662  for (c = bpo->nofsprings; c > 0; c--) {
663  bs2 = sb->bspring + bpo->springs[c - 1];
664  if ((bs2->v1 != notthis) && (bs2->v1 > v0)) {
665  (*counter)++; /* hit */
666  if (addsprings) {
667  bs3->v1 = v0;
668  bs3->v2 = bs2->v1;
669  bs3->springtype = SB_BEND;
670  bs3++;
671  }
672  }
673  if ((bs2->v2 != notthis) && (bs2->v2 > v0)) {
674  (*counter)++; /* hit */
675  if (addsprings) {
676  bs3->v1 = v0;
677  bs3->v2 = bs2->v2;
678  bs3->springtype = SB_BEND;
679  bs3++;
680  }
681  }
682  }
683  }
684  }
685  /* Scan for neighborhood done. */
686  }
687 }
688 
689 static void add_2nd_order_springs(Object *ob, float stiffness)
690 {
691  int counter = 0;
692  BodySpring *bs_new;
693  stiffness *= stiffness;
694 
695  add_2nd_order_roller(ob, stiffness, &counter, 0); /* counting */
696  if (counter) {
697  /* resize spring-array to hold additional springs */
698  bs_new = MEM_callocN((ob->soft->totspring + counter) * sizeof(BodySpring), "bodyspring");
699  memcpy(bs_new, ob->soft->bspring, (ob->soft->totspring) * sizeof(BodySpring));
700 
701  if (ob->soft->bspring) {
702  MEM_freeN(ob->soft->bspring);
703  }
704  ob->soft->bspring = bs_new;
705 
706  add_2nd_order_roller(ob, stiffness, &counter, 1); /* adding */
707  ob->soft->totspring += counter;
708  }
709 }
710 
711 static void add_bp_springlist(BodyPoint *bp, int springID)
712 {
713  int *newlist;
714 
715  if (bp->springs == NULL) {
716  bp->springs = MEM_callocN(sizeof(int), "bpsprings");
717  bp->springs[0] = springID;
718  bp->nofsprings = 1;
719  }
720  else {
721  bp->nofsprings++;
722  newlist = MEM_callocN(bp->nofsprings * sizeof(int), "bpsprings");
723  memcpy(newlist, bp->springs, (bp->nofsprings - 1) * sizeof(int));
724  MEM_freeN(bp->springs);
725  bp->springs = newlist;
726  bp->springs[bp->nofsprings - 1] = springID;
727  }
728 }
729 
734 static void build_bps_springlist(Object *ob)
735 {
736  SoftBody *sb = ob->soft; /* is supposed to be there */
737  BodyPoint *bp;
738  BodySpring *bs;
739  int a, b;
740 
741  if (sb == NULL) {
742  return; /* paranoia check */
743  }
744 
745  for (a = sb->totpoint, bp = sb->bpoint; a > 0; a--, bp++) {
746  /* throw away old list */
747  if (bp->springs) {
748  MEM_freeN(bp->springs);
749  bp->springs = NULL;
750  }
751  /* scan for attached inner springs */
752  for (b = sb->totspring, bs = sb->bspring; b > 0; b--, bs++) {
753  if (((sb->totpoint - a) == bs->v1)) {
754  add_bp_springlist(bp, sb->totspring - b);
755  }
756  if (((sb->totpoint - a) == bs->v2)) {
757  add_bp_springlist(bp, sb->totspring - b);
758  }
759  } /* For springs. */
760  } /* For bp. */
761 }
762 
764 {
765  SoftBody *sb = ob->soft; /* is supposed to be there */
766  BodyPoint *bp;
767  BodySpring *bs;
768  int a, b, akku_count;
769  float min, max, akku;
770 
771  if (sb == NULL) {
772  return; /* paranoia check */
773  }
774 
775  for (a = sb->totpoint, bp = sb->bpoint; a > 0; a--, bp++) {
776  bp->colball = 0;
777  akku = 0.0f;
778  akku_count = 0;
779  min = 1e22f;
780  max = -1e22f;
781  /* first estimation based on attached */
782  for (b = bp->nofsprings; b > 0; b--) {
783  bs = sb->bspring + bp->springs[b - 1];
784  if (bs->springtype == SB_EDGE) {
785  akku += bs->len;
786  akku_count++;
787  min = min_ff(bs->len, min);
788  max = max_ff(bs->len, max);
789  }
790  }
791 
792  if (akku_count > 0) {
793  if (sb->sbc_mode == SBC_MODE_MANUAL) {
794  bp->colball = sb->colball;
795  }
796  if (sb->sbc_mode == SBC_MODE_AVG) {
797  bp->colball = akku / (float)akku_count * sb->colball;
798  }
799  if (sb->sbc_mode == SBC_MODE_MIN) {
800  bp->colball = min * sb->colball;
801  }
802  if (sb->sbc_mode == SBC_MODE_MAX) {
803  bp->colball = max * sb->colball;
804  }
805  if (sb->sbc_mode == SBC_MODE_AVGMINMAX) {
806  bp->colball = (min + max) / 2.0f * sb->colball;
807  }
808  }
809  else {
810  bp->colball = 0;
811  }
812  } /* For bp. */
813 }
814 
815 /* creates new softbody if didn't exist yet, makes new points and springs arrays */
816 static void renew_softbody(Object *ob, int totpoint, int totspring)
817 {
818  SoftBody *sb;
819  int i;
820  short softflag;
821  if (ob->soft == NULL) {
822  ob->soft = sbNew();
823  }
824  else {
826  }
827  sb = ob->soft;
828  softflag = ob->softflag;
829 
830  if (totpoint) {
831  sb->totpoint = totpoint;
832  sb->totspring = totspring;
833 
834  sb->bpoint = MEM_mallocN(totpoint * sizeof(BodyPoint), "bodypoint");
835  if (totspring) {
836  sb->bspring = MEM_mallocN(totspring * sizeof(BodySpring), "bodyspring");
837  }
838 
839  /* initialize BodyPoint array */
840  for (i = 0; i < totpoint; i++) {
841  BodyPoint *bp = &sb->bpoint[i];
842 
843  /* hum as far as i see this is overridden by _final_goal() now jow_go_for2_5 */
844  /* sadly breaks compatibility with older versions */
845  /* but makes goals behave the same for meshes, lattices and curves */
846  if (softflag & OB_SB_GOAL) {
847  bp->goal = sb->defgoal;
848  }
849  else {
850  bp->goal = 0.0f;
851  /* so this will definily be below SOFTGOALSNAP */
852  }
853 
854  bp->nofsprings = 0;
855  bp->springs = NULL;
856  bp->choke = 0.0f;
857  bp->choke2 = 0.0f;
858  bp->frozen = 1.0f;
859  bp->colball = 0.0f;
860  bp->loc_flag = 0;
861  bp->springweight = 1.0f;
862  bp->mass = 1.0f;
863  }
864  }
865 }
866 
868 {
869  SBVertex *key;
870  int k;
871 
872  for (k = 0; k < sb->totkey; k++) {
873  key = *(sb->keys + k);
874  if (key) {
875  MEM_freeN(key);
876  }
877  }
878  MEM_SAFE_FREE(sb->keys);
879  sb->totkey = 0;
880 }
881 static void free_scratch(SoftBody *sb)
882 {
883  if (sb->scratch) {
884  /* TODO: make sure everything is cleaned up nicely. */
885  if (sb->scratch->colliderhash) {
887  NULL,
888  (GHashValFreeFP)ccd_mesh_free); /* This hopefully will free all caches. */
889  sb->scratch->colliderhash = NULL;
890  }
891  if (sb->scratch->bodyface) {
892  MEM_freeN(sb->scratch->bodyface);
893  }
894  if (sb->scratch->Ref.ivert) {
895  MEM_freeN(sb->scratch->Ref.ivert);
896  }
897  MEM_freeN(sb->scratch);
898  sb->scratch = NULL;
899  }
900 }
901 
902 /* only frees internal data */
904 {
905  if (sb) {
906  int a;
907  BodyPoint *bp;
908 
909  if (sb->bpoint) {
910  for (a = sb->totpoint, bp = sb->bpoint; a > 0; a--, bp++) {
911  /* free spring list */
912  if (bp->springs != NULL) {
913  MEM_freeN(bp->springs);
914  }
915  }
916  MEM_freeN(sb->bpoint);
917  }
918 
919  if (sb->bspring) {
920  MEM_freeN(sb->bspring);
921  }
922 
923  sb->totpoint = sb->totspring = 0;
924  sb->bpoint = NULL;
925  sb->bspring = NULL;
926 
927  free_scratch(sb);
929  }
930 }
931 
932 /* ************ dynamics ********** */
933 
934 /* the most general (micro physics correct) way to do collision
935  * (only needs the current particle position)
936  *
937  * it actually checks if the particle intrudes a short range force field generated
938  * by the faces of the target object and returns a force to drive the particle out
939  * the strength of the field grows exponentially if the particle is on the 'wrong' side of the face
940  * 'wrong' side : projection to the face normal is negative (all referred to a vertex in the face)
941  *
942  * flaw of this: 'fast' particles as well as 'fast' colliding faces
943  * give a 'tunnel' effect such that the particle passes through the force field
944  * without ever 'seeing' it
945  * this is fully compliant to heisenberg: h >= fuzzy(location) * fuzzy(time)
946  * besides our h is way larger than in QM because forces propagate way slower here
947  * we have to deal with fuzzy(time) in the range of 1/25 seconds (typical frame rate)
948  * yup collision targets are not known here any better
949  * and 1/25 second is very long compared to real collision events
950  * Q: why not use 'simple' collision here like bouncing back a particle
951  * --> reverting is velocity on the face normal
952  * A: because our particles are not alone here
953  * and need to tell their neighbors exactly what happens via spring forces
954  * unless sbObjectStep( .. ) is called on sub frame timing level
955  * BTW that also questions the use of a 'implicit' solvers on softbodies
956  * since that would only valid for 'slow' moving collision targets and ditto particles.
957  */
958 
959 /* +++ dependency information functions. */
960 
965 {
966  unsigned int numobjects;
968  depsgraph, NULL, collection, &numobjects, eModifierType_Collision);
970 
971  return (numobjects != 0);
972 }
973 /* --- dependency information functions. */
974 
975 /* +++ the aabb "force" section. */
976 static int sb_detect_aabb_collisionCached(float UNUSED(force[3]),
977  struct Object *vertexowner,
978  float UNUSED(time))
979 {
980  Object *ob;
981  SoftBody *sb = vertexowner->soft;
982  GHash *hash;
983  GHashIterator *ihash;
984  float aabbmin[3], aabbmax[3];
985  int deflected = 0;
986 #if 0
987  int a;
988 #endif
989 
990  if ((sb == NULL) || (sb->scratch == NULL)) {
991  return 0;
992  }
993  copy_v3_v3(aabbmin, sb->scratch->aabbmin);
994  copy_v3_v3(aabbmax, sb->scratch->aabbmax);
995 
996  hash = vertexowner->soft->scratch->colliderhash;
997  ihash = BLI_ghashIterator_new(hash);
998  while (!BLI_ghashIterator_done(ihash)) {
999 
1000  ccd_Mesh *ccdm = BLI_ghashIterator_getValue(ihash);
1001  ob = BLI_ghashIterator_getKey(ihash);
1002  {
1003  /* only with deflecting set */
1004  if (ob->pd && ob->pd->deflect) {
1005  if (ccdm) {
1006  if ((aabbmax[0] < ccdm->bbmin[0]) || (aabbmax[1] < ccdm->bbmin[1]) ||
1007  (aabbmax[2] < ccdm->bbmin[2]) || (aabbmin[0] > ccdm->bbmax[0]) ||
1008  (aabbmin[1] > ccdm->bbmax[1]) || (aabbmin[2] > ccdm->bbmax[2])) {
1009  /* boxes don't intersect */
1010  BLI_ghashIterator_step(ihash);
1011  continue;
1012  }
1013 
1014  /* so now we have the 2 boxes overlapping */
1015  /* forces actually not used */
1016  deflected = 2;
1017  }
1018  else {
1019  /* Aye that should be cached. */
1020  CLOG_ERROR(&LOG, "missing cache error");
1021  BLI_ghashIterator_step(ihash);
1022  continue;
1023  }
1024  } /* if (ob->pd && ob->pd->deflect) */
1025  BLI_ghashIterator_step(ihash);
1026  }
1027  } /* while () */
1028  BLI_ghashIterator_free(ihash);
1029  return deflected;
1030 }
1031 /* --- the aabb section. */
1032 
1033 /* +++ the face external section. */
1034 static int sb_detect_face_pointCached(const float face_v1[3],
1035  const float face_v2[3],
1036  const float face_v3[3],
1037  float *damp,
1038  float force[3],
1039  struct Object *vertexowner,
1040  float time)
1041 {
1042  Object *ob;
1043  GHash *hash;
1044  GHashIterator *ihash;
1045  float nv1[3], edge1[3], edge2[3], d_nvect[3], aabbmin[3], aabbmax[3];
1046  float facedist, outerfacethickness, tune = 10.0f;
1047  int a, deflected = 0;
1048 
1049  aabbmin[0] = min_fff(face_v1[0], face_v2[0], face_v3[0]);
1050  aabbmin[1] = min_fff(face_v1[1], face_v2[1], face_v3[1]);
1051  aabbmin[2] = min_fff(face_v1[2], face_v2[2], face_v3[2]);
1052  aabbmax[0] = max_fff(face_v1[0], face_v2[0], face_v3[0]);
1053  aabbmax[1] = max_fff(face_v1[1], face_v2[1], face_v3[1]);
1054  aabbmax[2] = max_fff(face_v1[2], face_v2[2], face_v3[2]);
1055 
1056  /* calculate face normal once again SIGH */
1057  sub_v3_v3v3(edge1, face_v1, face_v2);
1058  sub_v3_v3v3(edge2, face_v3, face_v2);
1059  cross_v3_v3v3(d_nvect, edge2, edge1);
1060  normalize_v3(d_nvect);
1061 
1062  hash = vertexowner->soft->scratch->colliderhash;
1063  ihash = BLI_ghashIterator_new(hash);
1064  while (!BLI_ghashIterator_done(ihash)) {
1065 
1066  ccd_Mesh *ccdm = BLI_ghashIterator_getValue(ihash);
1067  ob = BLI_ghashIterator_getKey(ihash);
1068  {
1069  /* only with deflecting set */
1070  if (ob->pd && ob->pd->deflect) {
1071  const MVert *mvert = NULL;
1072  const MVert *mprevvert = NULL;
1073  if (ccdm) {
1074  mvert = ccdm->mvert;
1075  a = ccdm->mvert_num;
1076  mprevvert = ccdm->mprevvert;
1077  outerfacethickness = ob->pd->pdef_sboft;
1078  if ((aabbmax[0] < ccdm->bbmin[0]) || (aabbmax[1] < ccdm->bbmin[1]) ||
1079  (aabbmax[2] < ccdm->bbmin[2]) || (aabbmin[0] > ccdm->bbmax[0]) ||
1080  (aabbmin[1] > ccdm->bbmax[1]) || (aabbmin[2] > ccdm->bbmax[2])) {
1081  /* boxes don't intersect */
1082  BLI_ghashIterator_step(ihash);
1083  continue;
1084  }
1085  }
1086  else {
1087  /* Aye that should be cached. */
1088  CLOG_ERROR(&LOG, "missing cache error");
1089  BLI_ghashIterator_step(ihash);
1090  continue;
1091  }
1092 
1093  /* Use mesh. */
1094  if (mvert) {
1095  while (a) {
1096  copy_v3_v3(nv1, mvert[a - 1].co);
1097  if (mprevvert) {
1098  mul_v3_fl(nv1, time);
1099  madd_v3_v3fl(nv1, mprevvert[a - 1].co, 1.0f - time);
1100  }
1101  /* Origin to face_v2. */
1102  sub_v3_v3(nv1, face_v2);
1103  facedist = dot_v3v3(nv1, d_nvect);
1104  if (fabsf(facedist) < outerfacethickness) {
1105  if (isect_point_tri_prism_v3(nv1, face_v1, face_v2, face_v3)) {
1106  float df;
1107  if (facedist > 0) {
1108  df = (outerfacethickness - facedist) / outerfacethickness;
1109  }
1110  else {
1111  df = (outerfacethickness + facedist) / outerfacethickness;
1112  }
1113 
1114  *damp = df * tune * ob->pd->pdef_sbdamp;
1115 
1116  df = 0.01f * expf(-100.0f * df);
1117  madd_v3_v3fl(force, d_nvect, -df);
1118  deflected = 3;
1119  }
1120  }
1121  a--;
1122  } /* while (a) */
1123  } /* if (mvert) */
1124  } /* if (ob->pd && ob->pd->deflect) */
1125  BLI_ghashIterator_step(ihash);
1126  }
1127  } /* while () */
1128  BLI_ghashIterator_free(ihash);
1129  return deflected;
1130 }
1131 
1132 static int sb_detect_face_collisionCached(const float face_v1[3],
1133  const float face_v2[3],
1134  const float face_v3[3],
1135  float *damp,
1136  float force[3],
1137  struct Object *vertexowner,
1138  float time)
1139 {
1140  Object *ob;
1141  GHash *hash;
1142  GHashIterator *ihash;
1143  float nv1[3], nv2[3], nv3[3], edge1[3], edge2[3], d_nvect[3], aabbmin[3], aabbmax[3];
1144  float t, tune = 10.0f;
1145  int a, deflected = 0;
1146 
1147  aabbmin[0] = min_fff(face_v1[0], face_v2[0], face_v3[0]);
1148  aabbmin[1] = min_fff(face_v1[1], face_v2[1], face_v3[1]);
1149  aabbmin[2] = min_fff(face_v1[2], face_v2[2], face_v3[2]);
1150  aabbmax[0] = max_fff(face_v1[0], face_v2[0], face_v3[0]);
1151  aabbmax[1] = max_fff(face_v1[1], face_v2[1], face_v3[1]);
1152  aabbmax[2] = max_fff(face_v1[2], face_v2[2], face_v3[2]);
1153 
1154  hash = vertexowner->soft->scratch->colliderhash;
1155  ihash = BLI_ghashIterator_new(hash);
1156  while (!BLI_ghashIterator_done(ihash)) {
1157 
1158  ccd_Mesh *ccdm = BLI_ghashIterator_getValue(ihash);
1159  ob = BLI_ghashIterator_getKey(ihash);
1160  {
1161  /* only with deflecting set */
1162  if (ob->pd && ob->pd->deflect) {
1163  const MVert *mvert = NULL;
1164  const MVert *mprevvert = NULL;
1165  const MVertTri *vt = NULL;
1166  const ccdf_minmax *mima = NULL;
1167 
1168  if (ccdm) {
1169  mvert = ccdm->mvert;
1170  vt = ccdm->tri;
1171  mprevvert = ccdm->mprevvert;
1172  mima = ccdm->mima;
1173  a = ccdm->tri_num;
1174 
1175  if ((aabbmax[0] < ccdm->bbmin[0]) || (aabbmax[1] < ccdm->bbmin[1]) ||
1176  (aabbmax[2] < ccdm->bbmin[2]) || (aabbmin[0] > ccdm->bbmax[0]) ||
1177  (aabbmin[1] > ccdm->bbmax[1]) || (aabbmin[2] > ccdm->bbmax[2])) {
1178  /* boxes don't intersect */
1179  BLI_ghashIterator_step(ihash);
1180  continue;
1181  }
1182  }
1183  else {
1184  /* Aye that should be cached. */
1185  CLOG_ERROR(&LOG, "missing cache error");
1186  BLI_ghashIterator_step(ihash);
1187  continue;
1188  }
1189 
1190  /* Use mesh. */
1191  while (a--) {
1192  if ((aabbmax[0] < mima->minx) || (aabbmin[0] > mima->maxx) ||
1193  (aabbmax[1] < mima->miny) || (aabbmin[1] > mima->maxy) ||
1194  (aabbmax[2] < mima->minz) || (aabbmin[2] > mima->maxz)) {
1195  mima++;
1196  vt++;
1197  continue;
1198  }
1199 
1200  if (mvert) {
1201 
1202  copy_v3_v3(nv1, mvert[vt->tri[0]].co);
1203  copy_v3_v3(nv2, mvert[vt->tri[1]].co);
1204  copy_v3_v3(nv3, mvert[vt->tri[2]].co);
1205 
1206  if (mprevvert) {
1207  mul_v3_fl(nv1, time);
1208  madd_v3_v3fl(nv1, mprevvert[vt->tri[0]].co, 1.0f - time);
1209 
1210  mul_v3_fl(nv2, time);
1211  madd_v3_v3fl(nv2, mprevvert[vt->tri[1]].co, 1.0f - time);
1212 
1213  mul_v3_fl(nv3, time);
1214  madd_v3_v3fl(nv3, mprevvert[vt->tri[2]].co, 1.0f - time);
1215  }
1216  }
1217 
1218  /* Switch origin to be nv2. */
1219  sub_v3_v3v3(edge1, nv1, nv2);
1220  sub_v3_v3v3(edge2, nv3, nv2);
1221  cross_v3_v3v3(d_nvect, edge2, edge1);
1222  normalize_v3(d_nvect);
1223  if (isect_line_segment_tri_v3(nv1, nv2, face_v1, face_v2, face_v3, &t, NULL) ||
1224  isect_line_segment_tri_v3(nv2, nv3, face_v1, face_v2, face_v3, &t, NULL) ||
1225  isect_line_segment_tri_v3(nv3, nv1, face_v1, face_v2, face_v3, &t, NULL)) {
1226  madd_v3_v3fl(force, d_nvect, -0.5f);
1227  *damp = tune * ob->pd->pdef_sbdamp;
1228  deflected = 2;
1229  }
1230  mima++;
1231  vt++;
1232  } /* while a */
1233  } /* if (ob->pd && ob->pd->deflect) */
1234  BLI_ghashIterator_step(ihash);
1235  }
1236  } /* while () */
1237  BLI_ghashIterator_free(ihash);
1238  return deflected;
1239 }
1240 
1241 static void scan_for_ext_face_forces(Object *ob, float timenow)
1242 {
1243  SoftBody *sb = ob->soft;
1244  BodyFace *bf;
1245  int a;
1246  float damp = 0.0f, choke = 1.0f;
1247  float tune = -10.0f;
1248  float feedback[3];
1249 
1250  if (sb && sb->scratch->totface) {
1251 
1252  bf = sb->scratch->bodyface;
1253  for (a = 0; a < sb->scratch->totface; a++, bf++) {
1254  bf->ext_force[0] = bf->ext_force[1] = bf->ext_force[2] = 0.0f;
1255  /*+++edges intruding. */
1256  bf->flag &= ~BFF_INTERSECT;
1257  zero_v3(feedback);
1259  sb->bpoint[bf->v2].pos,
1260  sb->bpoint[bf->v3].pos,
1261  &damp,
1262  feedback,
1263  ob,
1264  timenow)) {
1265  madd_v3_v3fl(sb->bpoint[bf->v1].force, feedback, tune);
1266  madd_v3_v3fl(sb->bpoint[bf->v2].force, feedback, tune);
1267  madd_v3_v3fl(sb->bpoint[bf->v3].force, feedback, tune);
1268  // madd_v3_v3fl(bf->ext_force, feedback, tune);
1269  bf->flag |= BFF_INTERSECT;
1270  choke = min_ff(max_ff(damp, choke), 1.0f);
1271  }
1272  /*---edges intruding. */
1273 
1274  /*+++ close vertices. */
1275  if ((bf->flag & BFF_INTERSECT) == 0) {
1276  bf->flag &= ~BFF_CLOSEVERT;
1277  tune = -1.0f;
1278  zero_v3(feedback);
1279  if (sb_detect_face_pointCached(sb->bpoint[bf->v1].pos,
1280  sb->bpoint[bf->v2].pos,
1281  sb->bpoint[bf->v3].pos,
1282  &damp,
1283  feedback,
1284  ob,
1285  timenow)) {
1286  madd_v3_v3fl(sb->bpoint[bf->v1].force, feedback, tune);
1287  madd_v3_v3fl(sb->bpoint[bf->v2].force, feedback, tune);
1288  madd_v3_v3fl(sb->bpoint[bf->v3].force, feedback, tune);
1289  // madd_v3_v3fl(bf->ext_force, feedback, tune);
1290  bf->flag |= BFF_CLOSEVERT;
1291  choke = min_ff(max_ff(damp, choke), 1.0f);
1292  }
1293  }
1294  /*--- close vertices. */
1295  }
1296  bf = sb->scratch->bodyface;
1297  for (a = 0; a < sb->scratch->totface; a++, bf++) {
1298  if ((bf->flag & BFF_INTERSECT) || (bf->flag & BFF_CLOSEVERT)) {
1299  sb->bpoint[bf->v1].choke2 = max_ff(sb->bpoint[bf->v1].choke2, choke);
1300  sb->bpoint[bf->v2].choke2 = max_ff(sb->bpoint[bf->v2].choke2, choke);
1301  sb->bpoint[bf->v3].choke2 = max_ff(sb->bpoint[bf->v3].choke2, choke);
1302  }
1303  }
1304  }
1305 }
1306 
1307 /* --- the face external section. */
1308 
1309 /* +++ the spring external section. */
1310 
1311 static int sb_detect_edge_collisionCached(const float edge_v1[3],
1312  const float edge_v2[3],
1313  float *damp,
1314  float force[3],
1315  struct Object *vertexowner,
1316  float time)
1317 {
1318  Object *ob;
1319  GHash *hash;
1320  GHashIterator *ihash;
1321  float nv1[3], nv2[3], nv3[3], edge1[3], edge2[3], d_nvect[3], aabbmin[3], aabbmax[3];
1322  float t, el;
1323  int a, deflected = 0;
1324 
1325  minmax_v3v3_v3(aabbmin, aabbmax, edge_v1);
1326  minmax_v3v3_v3(aabbmin, aabbmax, edge_v2);
1327 
1328  el = len_v3v3(edge_v1, edge_v2);
1329 
1330  hash = vertexowner->soft->scratch->colliderhash;
1331  ihash = BLI_ghashIterator_new(hash);
1332  while (!BLI_ghashIterator_done(ihash)) {
1333 
1334  ccd_Mesh *ccdm = BLI_ghashIterator_getValue(ihash);
1335  ob = BLI_ghashIterator_getKey(ihash);
1336  {
1337  /* only with deflecting set */
1338  if (ob->pd && ob->pd->deflect) {
1339  const MVert *mvert = NULL;
1340  const MVert *mprevvert = NULL;
1341  const MVertTri *vt = NULL;
1342  const ccdf_minmax *mima = NULL;
1343 
1344  if (ccdm) {
1345  mvert = ccdm->mvert;
1346  mprevvert = ccdm->mprevvert;
1347  vt = ccdm->tri;
1348  mima = ccdm->mima;
1349  a = ccdm->tri_num;
1350 
1351  if ((aabbmax[0] < ccdm->bbmin[0]) || (aabbmax[1] < ccdm->bbmin[1]) ||
1352  (aabbmax[2] < ccdm->bbmin[2]) || (aabbmin[0] > ccdm->bbmax[0]) ||
1353  (aabbmin[1] > ccdm->bbmax[1]) || (aabbmin[2] > ccdm->bbmax[2])) {
1354  /* boxes don't intersect */
1355  BLI_ghashIterator_step(ihash);
1356  continue;
1357  }
1358  }
1359  else {
1360  /* Aye that should be cached. */
1361  CLOG_ERROR(&LOG, "missing cache error");
1362  BLI_ghashIterator_step(ihash);
1363  continue;
1364  }
1365 
1366  /* Use mesh. */
1367  while (a--) {
1368  if ((aabbmax[0] < mima->minx) || (aabbmin[0] > mima->maxx) ||
1369  (aabbmax[1] < mima->miny) || (aabbmin[1] > mima->maxy) ||
1370  (aabbmax[2] < mima->minz) || (aabbmin[2] > mima->maxz)) {
1371  mima++;
1372  vt++;
1373  continue;
1374  }
1375 
1376  if (mvert) {
1377 
1378  copy_v3_v3(nv1, mvert[vt->tri[0]].co);
1379  copy_v3_v3(nv2, mvert[vt->tri[1]].co);
1380  copy_v3_v3(nv3, mvert[vt->tri[2]].co);
1381 
1382  if (mprevvert) {
1383  mul_v3_fl(nv1, time);
1384  madd_v3_v3fl(nv1, mprevvert[vt->tri[0]].co, 1.0f - time);
1385 
1386  mul_v3_fl(nv2, time);
1387  madd_v3_v3fl(nv2, mprevvert[vt->tri[1]].co, 1.0f - time);
1388 
1389  mul_v3_fl(nv3, time);
1390  madd_v3_v3fl(nv3, mprevvert[vt->tri[2]].co, 1.0f - time);
1391  }
1392  }
1393 
1394  /* Switch origin to be nv2. */
1395  sub_v3_v3v3(edge1, nv1, nv2);
1396  sub_v3_v3v3(edge2, nv3, nv2);
1397 
1398  cross_v3_v3v3(d_nvect, edge2, edge1);
1399  normalize_v3(d_nvect);
1400  if (isect_line_segment_tri_v3(edge_v1, edge_v2, nv1, nv2, nv3, &t, NULL)) {
1401  float v1[3], v2[3];
1402  float intrusiondepth, i1, i2;
1403  sub_v3_v3v3(v1, edge_v1, nv2);
1404  sub_v3_v3v3(v2, edge_v2, nv2);
1405  i1 = dot_v3v3(v1, d_nvect);
1406  i2 = dot_v3v3(v2, d_nvect);
1407  intrusiondepth = -min_ff(i1, i2) / el;
1408  madd_v3_v3fl(force, d_nvect, intrusiondepth);
1409  *damp = ob->pd->pdef_sbdamp;
1410  deflected = 2;
1411  }
1412 
1413  mima++;
1414  vt++;
1415  } /* while a */
1416  } /* if (ob->pd && ob->pd->deflect) */
1417  BLI_ghashIterator_step(ihash);
1418  }
1419  } /* while () */
1420  BLI_ghashIterator_free(ihash);
1421  return deflected;
1422 }
1423 
1425  Scene *scene, Object *ob, float timenow, int ifirst, int ilast, struct ListBase *effectors)
1426 {
1427  SoftBody *sb = ob->soft;
1428  int a;
1429  float damp;
1430  float feedback[3];
1431 
1432  if (sb && sb->totspring) {
1433  for (a = ifirst; a < ilast; a++) {
1434  BodySpring *bs = &sb->bspring[a];
1435  bs->ext_force[0] = bs->ext_force[1] = bs->ext_force[2] = 0.0f;
1436  feedback[0] = feedback[1] = feedback[2] = 0.0f;
1437  bs->flag &= ~BSF_INTERSECT;
1438 
1439  if (bs->springtype == SB_EDGE) {
1440  /* +++ springs colliding */
1441  if (ob->softflag & OB_SB_EDGECOLL) {
1443  sb->bpoint[bs->v1].pos, sb->bpoint[bs->v2].pos, &damp, feedback, ob, timenow)) {
1444  add_v3_v3(bs->ext_force, feedback);
1445  bs->flag |= BSF_INTERSECT;
1446  // bs->cf=damp;
1447  bs->cf = sb->choke * 0.01f;
1448  }
1449  }
1450  /* ---- springs colliding */
1451 
1452  /* +++ springs seeing wind ... n stuff depending on their orientation. */
1453  /* NOTE: we don't use `sb->mediafrict` but use `sb->aeroedge` for magnitude of effect. */
1454  if (sb->aeroedge) {
1455  float vel[3], sp[3], pr[3], force[3];
1456  float f, windfactor = 0.25f;
1457  /* See if we have wind. */
1458  if (effectors) {
1459  EffectedPoint epoint;
1460  float speed[3] = {0.0f, 0.0f, 0.0f};
1461  float pos[3];
1462  mid_v3_v3v3(pos, sb->bpoint[bs->v1].pos, sb->bpoint[bs->v2].pos);
1463  mid_v3_v3v3(vel, sb->bpoint[bs->v1].vec, sb->bpoint[bs->v2].vec);
1464  pd_point_from_soft(scene, pos, vel, -1, &epoint);
1466  effectors, NULL, sb->effector_weights, &epoint, force, NULL, speed);
1467 
1468  mul_v3_fl(speed, windfactor);
1469  add_v3_v3(vel, speed);
1470  }
1471  /* media in rest */
1472  else {
1473  add_v3_v3v3(vel, sb->bpoint[bs->v1].vec, sb->bpoint[bs->v2].vec);
1474  }
1475  f = normalize_v3(vel);
1476  f = -0.0001f * f * f * sb->aeroedge;
1477  /* (todo) add a nice angle dependent function done for now BUT */
1478  /* still there could be some nice drag/lift function, but who needs it */
1479 
1480  sub_v3_v3v3(sp, sb->bpoint[bs->v1].pos, sb->bpoint[bs->v2].pos);
1481  project_v3_v3v3(pr, vel, sp);
1482  sub_v3_v3(vel, pr);
1483  normalize_v3(vel);
1484  if (ob->softflag & OB_SB_AERO_ANGLE) {
1485  normalize_v3(sp);
1486  madd_v3_v3fl(bs->ext_force, vel, f * (1.0f - fabsf(dot_v3v3(vel, sp))));
1487  }
1488  else {
1489  madd_v3_v3fl(bs->ext_force, vel, f); /* to keep compatible with 2.45 release files */
1490  }
1491  }
1492  /* --- springs seeing wind */
1493  }
1494  }
1495  }
1496 }
1497 
1499 {
1502  pctx->scene, pctx->ob, pctx->timenow, pctx->ifirst, pctx->ilast, pctx->effectors);
1503  return NULL;
1504 }
1505 
1507  Scene *scene,
1508  struct Object *ob,
1509  float timenow,
1510  int totsprings,
1511  int *UNUSED(ptr_to_break_func(void)))
1512 {
1513  ListBase threads;
1514  SB_thread_context *sb_threads;
1515  int i, totthread, left, dec;
1516 
1517  /* wild guess .. may increase with better thread management 'above'
1518  * or even be UI option sb->spawn_cf_threads_nopts */
1519  int lowsprings = 100;
1520 
1521  ListBase *effectors = BKE_effectors_create(
1522  depsgraph, ob, NULL, ob->soft->effector_weights, false);
1523 
1524  /* figure the number of threads while preventing pretty pointless threading overhead */
1525  totthread = BKE_scene_num_threads(scene);
1526  /* What if we got zillions of CPUs running but less to spread. */
1527  while ((totsprings / totthread < lowsprings) && (totthread > 1)) {
1528  totthread--;
1529  }
1530 
1531  sb_threads = MEM_callocN(sizeof(SB_thread_context) * totthread, "SBSpringsThread");
1532  memset(sb_threads, 0, sizeof(SB_thread_context) * totthread);
1533  left = totsprings;
1534  dec = totsprings / totthread + 1;
1535  for (i = 0; i < totthread; i++) {
1536  sb_threads[i].scene = scene;
1537  sb_threads[i].ob = ob;
1538  sb_threads[i].forcetime = 0.0; /* not used here */
1539  sb_threads[i].timenow = timenow;
1540  sb_threads[i].ilast = left;
1541  left = left - dec;
1542  if (left > 0) {
1543  sb_threads[i].ifirst = left;
1544  }
1545  else {
1546  sb_threads[i].ifirst = 0;
1547  }
1548  sb_threads[i].effectors = effectors;
1549  sb_threads[i].do_deflector = false; /* not used here */
1550  sb_threads[i].fieldfactor = 0.0f; /* not used here */
1551  sb_threads[i].windfactor = 0.0f; /* not used here */
1552  sb_threads[i].nr = i;
1553  sb_threads[i].tot = totthread;
1554  }
1555  if (totthread > 1) {
1557 
1558  for (i = 0; i < totthread; i++) {
1559  BLI_threadpool_insert(&threads, &sb_threads[i]);
1560  }
1561 
1563  }
1564  else {
1565  exec_scan_for_ext_spring_forces(&sb_threads[0]);
1566  }
1567  /* clean up */
1568  MEM_freeN(sb_threads);
1569 
1570  BKE_effectors_free(effectors);
1571 }
1572 
1573 /* --- the spring external section. */
1574 
1575 static int choose_winner(
1576  float *w, float *pos, float *a, float *b, float *c, float *ca, float *cb, float *cc)
1577 {
1578  float mindist, cp;
1579  int winner = 1;
1580  mindist = fabsf(dot_v3v3(pos, a));
1581 
1582  cp = fabsf(dot_v3v3(pos, b));
1583  if (mindist < cp) {
1584  mindist = cp;
1585  winner = 2;
1586  }
1587 
1588  cp = fabsf(dot_v3v3(pos, c));
1589  if (mindist < cp) {
1590  mindist = cp;
1591  winner = 3;
1592  }
1593  switch (winner) {
1594  case 1:
1595  copy_v3_v3(w, ca);
1596  break;
1597  case 2:
1598  copy_v3_v3(w, cb);
1599  break;
1600  case 3:
1601  copy_v3_v3(w, cc);
1602  }
1603  return winner;
1604 }
1605 
1606 static int sb_detect_vertex_collisionCached(float opco[3],
1607  float facenormal[3],
1608  float *damp,
1609  float force[3],
1610  struct Object *vertexowner,
1611  float time,
1612  float vel[3],
1613  float *intrusion)
1614 {
1615  Object *ob = NULL;
1616  GHash *hash;
1617  GHashIterator *ihash;
1618  float nv1[3], nv2[3], nv3[3], edge1[3], edge2[3], d_nvect[3], dv1[3], ve[3],
1619  avel[3] = {0.0, 0.0, 0.0}, vv1[3], vv2[3], vv3[3], coledge[3] = {0.0f, 0.0f, 0.0f},
1620  mindistedge = 1000.0f, outerforceaccu[3], innerforceaccu[3], facedist,
1621  /* n_mag, */ /* UNUSED */ force_mag_norm, minx, miny, minz, maxx, maxy, maxz,
1622  innerfacethickness = -0.5f, outerfacethickness = 0.2f, ee = 5.0f, ff = 0.1f, fa = 1;
1623  int a, deflected = 0, cavel = 0, ci = 0;
1624  /* init */
1625  *intrusion = 0.0f;
1626  hash = vertexowner->soft->scratch->colliderhash;
1627  ihash = BLI_ghashIterator_new(hash);
1628  outerforceaccu[0] = outerforceaccu[1] = outerforceaccu[2] = 0.0f;
1629  innerforceaccu[0] = innerforceaccu[1] = innerforceaccu[2] = 0.0f;
1630  /* go */
1631  while (!BLI_ghashIterator_done(ihash)) {
1632 
1633  ccd_Mesh *ccdm = BLI_ghashIterator_getValue(ihash);
1634  ob = BLI_ghashIterator_getKey(ihash);
1635  {
1636  /* only with deflecting set */
1637  if (ob->pd && ob->pd->deflect) {
1638  const MVert *mvert = NULL;
1639  const MVert *mprevvert = NULL;
1640  const MVertTri *vt = NULL;
1641  const ccdf_minmax *mima = NULL;
1642 
1643  if (ccdm) {
1644  mvert = ccdm->mvert;
1645  mprevvert = ccdm->mprevvert;
1646  vt = ccdm->tri;
1647  mima = ccdm->mima;
1648  a = ccdm->tri_num;
1649 
1650  minx = ccdm->bbmin[0];
1651  miny = ccdm->bbmin[1];
1652  minz = ccdm->bbmin[2];
1653 
1654  maxx = ccdm->bbmax[0];
1655  maxy = ccdm->bbmax[1];
1656  maxz = ccdm->bbmax[2];
1657 
1658  if ((opco[0] < minx) || (opco[1] < miny) || (opco[2] < minz) || (opco[0] > maxx) ||
1659  (opco[1] > maxy) || (opco[2] > maxz)) {
1660  /* Outside the padded bound-box -> collision object is too far away. */
1661  BLI_ghashIterator_step(ihash);
1662  continue;
1663  }
1664  }
1665  else {
1666  /* Aye that should be cached. */
1667  CLOG_ERROR(&LOG, "missing cache error");
1668  BLI_ghashIterator_step(ihash);
1669  continue;
1670  }
1671 
1672  /* do object level stuff */
1673  /* need to have user control for that since it depends on model scale */
1674  innerfacethickness = -ob->pd->pdef_sbift;
1675  outerfacethickness = ob->pd->pdef_sboft;
1676  fa = (ff * outerfacethickness - outerfacethickness);
1677  fa *= fa;
1678  fa = 1.0f / fa;
1679  avel[0] = avel[1] = avel[2] = 0.0f;
1680  /* Use mesh. */
1681  while (a--) {
1682  if ((opco[0] < mima->minx) || (opco[0] > mima->maxx) || (opco[1] < mima->miny) ||
1683  (opco[1] > mima->maxy) || (opco[2] < mima->minz) || (opco[2] > mima->maxz)) {
1684  mima++;
1685  vt++;
1686  continue;
1687  }
1688 
1689  if (mvert) {
1690 
1691  copy_v3_v3(nv1, mvert[vt->tri[0]].co);
1692  copy_v3_v3(nv2, mvert[vt->tri[1]].co);
1693  copy_v3_v3(nv3, mvert[vt->tri[2]].co);
1694 
1695  if (mprevvert) {
1696  /* Grab the average speed of the collider vertices before we spoil nvX
1697  * humm could be done once a SB steps but then we' need to store that too
1698  * since the AABB reduced probability to get here drastically
1699  * it might be a nice tradeoff CPU <--> memory.
1700  */
1701  sub_v3_v3v3(vv1, nv1, mprevvert[vt->tri[0]].co);
1702  sub_v3_v3v3(vv2, nv2, mprevvert[vt->tri[1]].co);
1703  sub_v3_v3v3(vv3, nv3, mprevvert[vt->tri[2]].co);
1704 
1705  mul_v3_fl(nv1, time);
1706  madd_v3_v3fl(nv1, mprevvert[vt->tri[0]].co, 1.0f - time);
1707 
1708  mul_v3_fl(nv2, time);
1709  madd_v3_v3fl(nv2, mprevvert[vt->tri[1]].co, 1.0f - time);
1710 
1711  mul_v3_fl(nv3, time);
1712  madd_v3_v3fl(nv3, mprevvert[vt->tri[2]].co, 1.0f - time);
1713  }
1714  }
1715 
1716  /* Switch origin to be nv2. */
1717  sub_v3_v3v3(edge1, nv1, nv2);
1718  sub_v3_v3v3(edge2, nv3, nv2);
1719  /* Abuse dv1 to have vertex in question at *origin* of triangle. */
1720  sub_v3_v3v3(dv1, opco, nv2);
1721 
1722  cross_v3_v3v3(d_nvect, edge2, edge1);
1723  /* n_mag = */ /* UNUSED */ normalize_v3(d_nvect);
1724  facedist = dot_v3v3(dv1, d_nvect);
1725  /* so rules are */
1726 
1727  if ((facedist > innerfacethickness) && (facedist < outerfacethickness)) {
1728  if (isect_point_tri_prism_v3(opco, nv1, nv2, nv3)) {
1729  force_mag_norm = (float)exp(-ee * facedist);
1730  if (facedist > outerfacethickness * ff) {
1731  force_mag_norm = (float)force_mag_norm * fa * (facedist - outerfacethickness) *
1732  (facedist - outerfacethickness);
1733  }
1734  *damp = ob->pd->pdef_sbdamp;
1735  if (facedist > 0.0f) {
1736  *damp *= (1.0f - facedist / outerfacethickness);
1737  madd_v3_v3fl(outerforceaccu, d_nvect, force_mag_norm);
1738  deflected = 3;
1739  }
1740  else {
1741  madd_v3_v3fl(innerforceaccu, d_nvect, force_mag_norm);
1742  if (deflected < 2) {
1743  deflected = 2;
1744  }
1745  }
1746  if ((mprevvert) && (*damp > 0.0f)) {
1747  choose_winner(ve, opco, nv1, nv2, nv3, vv1, vv2, vv3);
1748  add_v3_v3(avel, ve);
1749  cavel++;
1750  }
1751  *intrusion += facedist;
1752  ci++;
1753  }
1754  }
1755 
1756  mima++;
1757  vt++;
1758  } /* while a */
1759  } /* if (ob->pd && ob->pd->deflect) */
1760  BLI_ghashIterator_step(ihash);
1761  }
1762  } /* while () */
1763 
1764  if (deflected == 1) { /* no face but 'outer' edge cylinder sees vert */
1765  force_mag_norm = (float)exp(-ee * mindistedge);
1766  if (mindistedge > outerfacethickness * ff) {
1767  force_mag_norm = (float)force_mag_norm * fa * (mindistedge - outerfacethickness) *
1768  (mindistedge - outerfacethickness);
1769  }
1770  madd_v3_v3fl(force, coledge, force_mag_norm);
1771  *damp = ob->pd->pdef_sbdamp;
1772  if (mindistedge > 0.0f) {
1773  *damp *= (1.0f - mindistedge / outerfacethickness);
1774  }
1775  }
1776  if (deflected == 2) { /* face inner detected */
1777  add_v3_v3(force, innerforceaccu);
1778  }
1779  if (deflected == 3) { /* face outer detected */
1780  add_v3_v3(force, outerforceaccu);
1781  }
1782 
1783  BLI_ghashIterator_free(ihash);
1784  if (cavel) {
1785  mul_v3_fl(avel, 1.0f / (float)cavel);
1786  }
1787  copy_v3_v3(vel, avel);
1788  if (ci) {
1789  *intrusion /= ci;
1790  }
1791  if (deflected) {
1792  normalize_v3_v3(facenormal, force);
1793  }
1794  return deflected;
1795 }
1796 
1797 /* sandbox to plug in various deflection algos */
1798 static int sb_deflect_face(Object *ob,
1799  float *actpos,
1800  float *facenormal,
1801  float *force,
1802  float *cf,
1803  float time,
1804  float *vel,
1805  float *intrusion)
1806 {
1807  float s_actpos[3];
1808  int deflected;
1809  copy_v3_v3(s_actpos, actpos);
1811  s_actpos, facenormal, cf, force, ob, time, vel, intrusion);
1812 #if 0
1813  deflected = sb_detect_vertex_collisionCachedEx(
1814  s_actpos, facenormal, cf, force, ob, time, vel, intrusion);
1815 #endif
1816  return deflected;
1817 }
1818 
1819 /* hiding this for now .. but the jacobian may pop up on other tasks .. so i'd like to keep it */
1820 #if 0
1821 static void dfdx_spring(int ia, int ic, int op, float dir[3], float L, float len, float factor)
1822 {
1823  float m, delta_ij;
1824  int i, j;
1825  if (L < len) {
1826  for (i = 0; i < 3; i++) {
1827  for (j = 0; j < 3; j++) {
1828  delta_ij = (i == j ? (1.0f) : (0.0f));
1829  m = factor * (dir[i] * dir[j] + (1 - L / len) * (delta_ij - dir[i] * dir[j]));
1830  EIG_linear_solver_matrix_add(ia + i, op + ic + j, m);
1831  }
1832  }
1833  }
1834  else {
1835  for (i = 0; i < 3; i++) {
1836  for (j = 0; j < 3; j++) {
1837  m = factor * dir[i] * dir[j];
1838  EIG_linear_solver_matrix_add(ia + i, op + ic + j, m);
1839  }
1840  }
1841  }
1842 }
1843 
1844 static void dfdx_goal(int ia, int ic, int op, float factor)
1845 {
1846  int i;
1847  for (i = 0; i < 3; i++) {
1848  EIG_linear_solver_matrix_add(ia + i, op + ic + i, factor);
1849  }
1850 }
1851 
1852 static void dfdv_goal(int ia, int ic, float factor)
1853 {
1854  int i;
1855  for (i = 0; i < 3; i++) {
1856  EIG_linear_solver_matrix_add(ia + i, ic + i, factor);
1857  }
1858 }
1859 #endif /* if 0 */
1860 
1861 static void sb_spring_force(
1862  Object *ob, int bpi, BodySpring *bs, float iks, float UNUSED(forcetime))
1863 {
1864  SoftBody *sb = ob->soft; /* is supposed to be there */
1865  BodyPoint *bp1, *bp2;
1866 
1867  float dir[3], dvel[3];
1868  float distance, forcefactor, kd, absvel, projvel, kw;
1869 #if 0 /* UNUSED */
1870  int ia, ic;
1871 #endif
1872  /* prepare depending on which side of the spring we are on */
1873  if (bpi == bs->v1) {
1874  bp1 = &sb->bpoint[bs->v1];
1875  bp2 = &sb->bpoint[bs->v2];
1876 #if 0 /* UNUSED */
1877  ia = 3 * bs->v1;
1878  ic = 3 * bs->v2;
1879 #endif
1880  }
1881  else if (bpi == bs->v2) {
1882  bp1 = &sb->bpoint[bs->v2];
1883  bp2 = &sb->bpoint[bs->v1];
1884 #if 0 /* UNUSED */
1885  ia = 3 * bs->v2;
1886  ic = 3 * bs->v1;
1887 #endif
1888  }
1889  else {
1890  /* TODO: make this debug option. */
1891  CLOG_WARN(&LOG, "bodypoint <bpi> is not attached to spring <*bs>");
1892  return;
1893  }
1894 
1895  /* do bp1 <--> bp2 elastic */
1896  sub_v3_v3v3(dir, bp1->pos, bp2->pos);
1897  distance = normalize_v3(dir);
1898  if (bs->len < distance) {
1899  iks = 1.0f / (1.0f - sb->inspring) - 1.0f; /* inner spring constants function */
1900  }
1901  else {
1902  iks = 1.0f / (1.0f - sb->inpush) - 1.0f; /* inner spring constants function */
1903  }
1904 
1905  if (bs->len > 0.0f) { /* check for degenerated springs */
1906  forcefactor = iks / bs->len;
1907  }
1908  else {
1909  forcefactor = iks;
1910  }
1911  kw = (bp1->springweight + bp2->springweight) / 2.0f;
1912  kw = kw * kw;
1913  kw = kw * kw;
1914  switch (bs->springtype) {
1915  case SB_EDGE:
1916  case SB_HANDLE:
1917  forcefactor *= kw;
1918  break;
1919  case SB_BEND:
1920  forcefactor *= sb->secondspring * kw;
1921  break;
1922  case SB_STIFFQUAD:
1923  forcefactor *= sb->shearstiff * sb->shearstiff * kw;
1924  break;
1925  default:
1926  break;
1927  }
1928 
1929  madd_v3_v3fl(bp1->force, dir, (bs->len - distance) * forcefactor);
1930 
1931  /* do bp1 <--> bp2 viscous */
1932  sub_v3_v3v3(dvel, bp1->vec, bp2->vec);
1933  kd = sb->infrict * sb_fric_force_scale(ob);
1934  absvel = normalize_v3(dvel);
1935  projvel = dot_v3v3(dir, dvel);
1936  kd *= absvel * projvel;
1937  madd_v3_v3fl(bp1->force, dir, -kd);
1938 }
1939 
1940 /* since this is definitely the most CPU consuming task here .. try to spread it */
1941 /* core function _softbody_calc_forces_slice_in_a_thread */
1942 /* result is int to be able to flag user break */
1944  Object *ob,
1945  float forcetime,
1946  float timenow,
1947  int ifirst,
1948  int ilast,
1949  int *UNUSED(ptr_to_break_func(void)),
1950  ListBase *effectors,
1951  int do_deflector,
1952  float fieldfactor,
1953  float windfactor)
1954 {
1955  float iks;
1956  int bb, do_selfcollision, do_springcollision, do_aero;
1957  int number_of_points_here = ilast - ifirst;
1958  SoftBody *sb = ob->soft; /* is supposed to be there */
1959  BodyPoint *bp;
1960 
1961  /* initialize */
1962  if (sb) {
1963  /* check conditions for various options */
1964  /* +++ could be done on object level to squeeze out the last bits of it */
1965  do_selfcollision = ((ob->softflag & OB_SB_EDGES) && (sb->bspring) &&
1966  (ob->softflag & OB_SB_SELF));
1967  do_springcollision = do_deflector && (ob->softflag & OB_SB_EDGES) &&
1968  (ob->softflag & OB_SB_EDGECOLL);
1969  do_aero = ((sb->aeroedge) && (ob->softflag & OB_SB_EDGES));
1970  /* --- could be done on object level to squeeze out the last bits of it */
1971  }
1972  else {
1973  CLOG_ERROR(&LOG, "expected a SB here");
1974  return 999;
1975  }
1976 
1977  /* Debugging. */
1978  if (sb->totpoint < ifirst) {
1979  printf("Aye 998");
1980  return 998;
1981  }
1982  /* Debugging. */
1983 
1984  bp = &sb->bpoint[ifirst];
1985  for (bb = number_of_points_here; bb > 0; bb--, bp++) {
1986  /* clear forces accumulator */
1987  bp->force[0] = bp->force[1] = bp->force[2] = 0.0;
1988  /* naive ball self collision */
1989  /* needs to be done if goal snaps or not */
1990  if (do_selfcollision) {
1991  int attached;
1992  BodyPoint *obp;
1993  BodySpring *bs;
1994  int c, b;
1995  float velcenter[3], dvel[3], def[3];
1996  float distance;
1997  float compare;
1998  float bstune = sb->ballstiff;
1999 
2000  /* Running in a slice we must not assume anything done with obp
2001  * neither alter the data of obp. */
2002  for (c = sb->totpoint, obp = sb->bpoint; c > 0; c--, obp++) {
2003  compare = (obp->colball + bp->colball);
2004  sub_v3_v3v3(def, bp->pos, obp->pos);
2005  /* rather check the AABBoxes before ever calculating the real distance */
2006  /* mathematically it is completely nuts, but performance is pretty much (3) times faster */
2007  if ((fabsf(def[0]) > compare) || (fabsf(def[1]) > compare) || (fabsf(def[2]) > compare)) {
2008  continue;
2009  }
2010  distance = normalize_v3(def);
2011  if (distance < compare) {
2012  /* exclude body points attached with a spring */
2013  attached = 0;
2014  for (b = obp->nofsprings; b > 0; b--) {
2015  bs = sb->bspring + obp->springs[b - 1];
2016  if (ELEM(ilast - bb, bs->v2, bs->v1)) {
2017  attached = 1;
2018  continue;
2019  }
2020  }
2021  if (!attached) {
2022  float f = bstune / (distance) + bstune / (compare * compare) * distance -
2023  2.0f * bstune / compare;
2024 
2025  mid_v3_v3v3(velcenter, bp->vec, obp->vec);
2026  sub_v3_v3v3(dvel, velcenter, bp->vec);
2027  mul_v3_fl(dvel, _final_mass(ob, bp));
2028 
2029  madd_v3_v3fl(bp->force, def, f * (1.0f - sb->balldamp));
2030  madd_v3_v3fl(bp->force, dvel, sb->balldamp);
2031  }
2032  }
2033  }
2034  }
2035  /* naive ball self collision done */
2036 
2037  if (_final_goal(ob, bp) < SOFTGOALSNAP) { /* omit this bp when it snaps */
2038  float auxvect[3];
2039  float velgoal[3];
2040 
2041  /* do goal stuff */
2042  if (ob->softflag & OB_SB_GOAL) {
2043  /* true elastic goal */
2044  float ks, kd;
2045  sub_v3_v3v3(auxvect, bp->pos, bp->origT);
2046  ks = 1.0f / (1.0f - _final_goal(ob, bp) * sb->goalspring) - 1.0f;
2047  bp->force[0] += -ks * (auxvect[0]);
2048  bp->force[1] += -ks * (auxvect[1]);
2049  bp->force[2] += -ks * (auxvect[2]);
2050 
2051  /* Calculate damping forces generated by goals. */
2052  sub_v3_v3v3(velgoal, bp->origS, bp->origE);
2053  kd = sb->goalfrict * sb_fric_force_scale(ob);
2054  add_v3_v3v3(auxvect, velgoal, bp->vec);
2055 
2056  if (forcetime >
2057  0.0f) { /* make sure friction does not become rocket motor on time reversal */
2058  bp->force[0] -= kd * (auxvect[0]);
2059  bp->force[1] -= kd * (auxvect[1]);
2060  bp->force[2] -= kd * (auxvect[2]);
2061  }
2062  else {
2063  bp->force[0] -= kd * (velgoal[0] - bp->vec[0]);
2064  bp->force[1] -= kd * (velgoal[1] - bp->vec[1]);
2065  bp->force[2] -= kd * (velgoal[2] - bp->vec[2]);
2066  }
2067  }
2068  /* done goal stuff */
2069 
2070  /* gravitation */
2072  float gravity[3];
2074 
2075  /* Individual mass of node here. */
2076  mul_v3_fl(gravity,
2077  sb_grav_force_scale(ob) * _final_mass(ob, bp) *
2079 
2080  add_v3_v3(bp->force, gravity);
2081  }
2082 
2083  /* particle field & vortex */
2084  if (effectors) {
2085  EffectedPoint epoint;
2086  float kd;
2087  float force[3] = {0.0f, 0.0f, 0.0f};
2088  float speed[3] = {0.0f, 0.0f, 0.0f};
2089 
2090  /* just for calling function once */
2091  float eval_sb_fric_force_scale = sb_fric_force_scale(ob);
2092 
2093  pd_point_from_soft(scene, bp->pos, bp->vec, sb->bpoint - bp, &epoint);
2094  BKE_effectors_apply(effectors, NULL, sb->effector_weights, &epoint, force, NULL, speed);
2095 
2096  /* Apply force-field. */
2097  mul_v3_fl(force, fieldfactor * eval_sb_fric_force_scale);
2098  add_v3_v3(bp->force, force);
2099 
2100  /* BP friction in moving media */
2101  kd = sb->mediafrict * eval_sb_fric_force_scale;
2102  bp->force[0] -= kd * (bp->vec[0] + windfactor * speed[0] / eval_sb_fric_force_scale);
2103  bp->force[1] -= kd * (bp->vec[1] + windfactor * speed[1] / eval_sb_fric_force_scale);
2104  bp->force[2] -= kd * (bp->vec[2] + windfactor * speed[2] / eval_sb_fric_force_scale);
2105  /* now we'll have nice centrifugal effect for vortex */
2106  }
2107  else {
2108  /* BP friction in media (not) moving. */
2109  float kd = sb->mediafrict * sb_fric_force_scale(ob);
2110  /* assume it to be proportional to actual velocity */
2111  bp->force[0] -= bp->vec[0] * kd;
2112  bp->force[1] -= bp->vec[1] * kd;
2113  bp->force[2] -= bp->vec[2] * kd;
2114  /* friction in media done */
2115  }
2116  /* +++cached collision targets */
2117  bp->choke = 0.0f;
2118  bp->choke2 = 0.0f;
2119  bp->loc_flag &= ~SBF_DOFUZZY;
2120  if (do_deflector && !(bp->loc_flag & SBF_OUTOFCOLLISION)) {
2121  float cfforce[3], defforce[3] = {0.0f, 0.0f, 0.0f}, vel[3] = {0.0f, 0.0f, 0.0f},
2122  facenormal[3], cf = 1.0f, intrusion;
2123  float kd = 1.0f;
2124 
2125  if (sb_deflect_face(ob, bp->pos, facenormal, defforce, &cf, timenow, vel, &intrusion)) {
2126  if (intrusion < 0.0f) {
2127  sb->scratch->flag |= SBF_DOFUZZY;
2128  bp->loc_flag |= SBF_DOFUZZY;
2129  bp->choke = sb->choke * 0.01f;
2130  }
2131 
2132  sub_v3_v3v3(cfforce, bp->vec, vel);
2133  madd_v3_v3fl(bp->force, cfforce, -cf * 50.0f);
2134 
2135  madd_v3_v3fl(bp->force, defforce, kd);
2136  }
2137  }
2138  /* ---cached collision targets */
2139 
2140  /* +++springs */
2141  iks = 1.0f / (1.0f - sb->inspring) - 1.0f; /* inner spring constants function */
2142  if (ob->softflag & OB_SB_EDGES) {
2143  if (sb->bspring) { /* Spring list exists at all? */
2144  int b;
2145  BodySpring *bs;
2146  for (b = bp->nofsprings; b > 0; b--) {
2147  bs = sb->bspring + bp->springs[b - 1];
2148  if (do_springcollision || do_aero) {
2149  add_v3_v3(bp->force, bs->ext_force);
2150  if (bs->flag & BSF_INTERSECT) {
2151  bp->choke = bs->cf;
2152  }
2153  }
2154  // sb_spring_force(Object *ob, int bpi, BodySpring *bs, float iks, float forcetime)
2155  sb_spring_force(ob, ilast - bb, bs, iks, forcetime);
2156  } /* loop springs. */
2157  } /* existing spring list. */
2158  } /* Any edges. */
2159  /* ---springs */
2160  } /* Omit on snap. */
2161  } /* Loop all bp's. */
2162  return 0; /* Done fine. */
2163 }
2164 
2165 static void *exec_softbody_calc_forces(void *data)
2166 {
2169  pctx->ob,
2170  pctx->forcetime,
2171  pctx->timenow,
2172  pctx->ifirst,
2173  pctx->ilast,
2174  NULL,
2175  pctx->effectors,
2176  pctx->do_deflector,
2177  pctx->fieldfactor,
2178  pctx->windfactor);
2179  return NULL;
2180 }
2181 
2183  Object *ob,
2184  float forcetime,
2185  float timenow,
2186  int totpoint,
2187  int *UNUSED(ptr_to_break_func(void)),
2188  struct ListBase *effectors,
2189  int do_deflector,
2190  float fieldfactor,
2191  float windfactor)
2192 {
2193  ListBase threads;
2194  SB_thread_context *sb_threads;
2195  int i, totthread, left, dec;
2196 
2197  /* wild guess .. may increase with better thread management 'above'
2198  * or even be UI option sb->spawn_cf_threads_nopts. */
2199  int lowpoints = 100;
2200 
2201  /* figure the number of threads while preventing pretty pointless threading overhead */
2202  totthread = BKE_scene_num_threads(scene);
2203  /* What if we got zillions of CPUs running but less to spread. */
2204  while ((totpoint / totthread < lowpoints) && (totthread > 1)) {
2205  totthread--;
2206  }
2207 
2208  // printf("sb_cf_threads_run spawning %d threads\n", totthread);
2209 
2210  sb_threads = MEM_callocN(sizeof(SB_thread_context) * totthread, "SBThread");
2211  memset(sb_threads, 0, sizeof(SB_thread_context) * totthread);
2212  left = totpoint;
2213  dec = totpoint / totthread + 1;
2214  for (i = 0; i < totthread; i++) {
2215  sb_threads[i].scene = scene;
2216  sb_threads[i].ob = ob;
2217  sb_threads[i].forcetime = forcetime;
2218  sb_threads[i].timenow = timenow;
2219  sb_threads[i].ilast = left;
2220  left = left - dec;
2221  if (left > 0) {
2222  sb_threads[i].ifirst = left;
2223  }
2224  else {
2225  sb_threads[i].ifirst = 0;
2226  }
2227  sb_threads[i].effectors = effectors;
2228  sb_threads[i].do_deflector = do_deflector;
2229  sb_threads[i].fieldfactor = fieldfactor;
2230  sb_threads[i].windfactor = windfactor;
2231  sb_threads[i].nr = i;
2232  sb_threads[i].tot = totthread;
2233  }
2234 
2235  if (totthread > 1) {
2237 
2238  for (i = 0; i < totthread; i++) {
2239  BLI_threadpool_insert(&threads, &sb_threads[i]);
2240  }
2241 
2243  }
2244  else {
2245  exec_softbody_calc_forces(&sb_threads[0]);
2246  }
2247  /* clean up */
2248  MEM_freeN(sb_threads);
2249 }
2250 
2252  struct Depsgraph *depsgraph, Scene *scene, Object *ob, float forcetime, float timenow)
2253 {
2254  /* rule we never alter free variables :bp->vec bp->pos in here !
2255  * this will ruin adaptive stepsize AKA heun! (BM)
2256  */
2257  SoftBody *sb = ob->soft; /* is supposed to be there */
2258  // BodyPoint *bproot; /* UNUSED */
2259  // float gravity; /* UNUSED */
2260  // float iks;
2261  float fieldfactor = -1.0f, windfactor = 0.25;
2262  int do_deflector /*, do_selfcollision */, do_springcollision, do_aero;
2263 
2264  // gravity = sb->grav * sb_grav_force_scale(ob); /* UNUSED */
2265 
2266  /* check conditions for various options */
2267  do_deflector = query_external_colliders(depsgraph, sb->collision_group);
2268 #if 0
2269  do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF));
2270 #endif
2271  do_springcollision = do_deflector && (ob->softflag & OB_SB_EDGES) &&
2272  (ob->softflag & OB_SB_EDGECOLL);
2273  do_aero = ((sb->aeroedge) && (ob->softflag & OB_SB_EDGES));
2274 
2275  // iks = 1.0f / (1.0f - sb->inspring) - 1.0f; /* Inner spring constants function. */ /* UNUSED */
2276  // bproot = sb->bpoint; /* Need this for proper spring addressing. */ /* UNUSED */
2277 
2278  if (do_springcollision || do_aero) {
2279  sb_sfesf_threads_run(depsgraph, scene, ob, timenow, sb->totspring, NULL);
2280  }
2281 
2282  /* After spring scan because it uses effectors too. */
2283  ListBase *effectors = BKE_effectors_create(depsgraph, ob, NULL, sb->effector_weights, false);
2284 
2285  if (do_deflector) {
2286  float defforce[3];
2287  do_deflector = sb_detect_aabb_collisionCached(defforce, ob, timenow);
2288  }
2289 
2291  ob,
2292  forcetime,
2293  timenow,
2294  sb->totpoint,
2295  NULL,
2296  effectors,
2297  do_deflector,
2298  fieldfactor,
2299  windfactor);
2300 
2301  /* finally add forces caused by face collision */
2302  if (ob->softflag & OB_SB_FACECOLL) {
2303  scan_for_ext_face_forces(ob, timenow);
2304  }
2305 
2306  /* finish matrix and solve */
2307  BKE_effectors_free(effectors);
2308 }
2309 
2310 static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *err, int mid_flags)
2311 {
2312  /* time evolution */
2313  /* actually does an explicit euler step mode == 0 */
2314  /* or heun ~ 2nd order runge-kutta steps, mode 1, 2 */
2315  SoftBody *sb = ob->soft; /* is supposed to be there */
2316  BodyPoint *bp;
2317  float dx[3] = {0}, dv[3], aabbmin[3], aabbmax[3], cm[3] = {0.0f, 0.0f, 0.0f};
2318  float timeovermass /*, freezeloc=0.00001f, freezeforce=0.00000000001f*/;
2319  float maxerrpos = 0.0f, maxerrvel = 0.0f;
2320  int a, fuzzy = 0;
2321 
2322  forcetime *= sb_time_scale(ob);
2323 
2324  aabbmin[0] = aabbmin[1] = aabbmin[2] = 1e20f;
2325  aabbmax[0] = aabbmax[1] = aabbmax[2] = -1e20f;
2326 
2327  /* old one with homogeneous masses */
2328  /* claim a minimum mass for vertex */
2329 #if 0
2330  if (sb->nodemass > 0.009999f) {
2331  timeovermass = forcetime / sb->nodemass;
2332  }
2333  else {
2334  timeovermass = forcetime / 0.009999f;
2335  }
2336 #endif
2337 
2338  for (a = sb->totpoint, bp = sb->bpoint; a > 0; a--, bp++) {
2339  /* Now we have individual masses. */
2340  /* claim a minimum mass for vertex */
2341  if (_final_mass(ob, bp) > 0.009999f) {
2342  timeovermass = forcetime / _final_mass(ob, bp);
2343  }
2344  else {
2345  timeovermass = forcetime / 0.009999f;
2346  }
2347 
2348  if (_final_goal(ob, bp) < SOFTGOALSNAP) {
2349  /* this makes t~ = t */
2350  if (mid_flags & MID_PRESERVE) {
2351  copy_v3_v3(dx, bp->vec);
2352  }
2353 
2368  mul_v3_fl(bp->force, timeovermass); /* individual mass of node here */
2369  /* some nasty if's to have heun in here too */
2370  copy_v3_v3(dv, bp->force);
2371 
2372  if (mode == 1) {
2373  copy_v3_v3(bp->prevvec, bp->vec);
2374  copy_v3_v3(bp->prevdv, dv);
2375  }
2376 
2377  if (mode == 2) {
2378  /* be optimistic and execute step */
2379  bp->vec[0] = bp->prevvec[0] + 0.5f * (dv[0] + bp->prevdv[0]);
2380  bp->vec[1] = bp->prevvec[1] + 0.5f * (dv[1] + bp->prevdv[1]);
2381  bp->vec[2] = bp->prevvec[2] + 0.5f * (dv[2] + bp->prevdv[2]);
2382  /* compare euler to heun to estimate error for step sizing */
2383  maxerrvel = max_ff(maxerrvel, fabsf(dv[0] - bp->prevdv[0]));
2384  maxerrvel = max_ff(maxerrvel, fabsf(dv[1] - bp->prevdv[1]));
2385  maxerrvel = max_ff(maxerrvel, fabsf(dv[2] - bp->prevdv[2]));
2386  }
2387  else {
2388  add_v3_v3(bp->vec, bp->force);
2389  }
2390 
2391  /* this makes t~ = t+dt */
2392  if (!(mid_flags & MID_PRESERVE)) {
2393  copy_v3_v3(dx, bp->vec);
2394  }
2395 
2396  /* So here is: `(x)'= v(elocity)`.
2397  * The euler step for location then becomes:
2398  * `x(t + dt) = x(t) + v(t~) * dt` */
2399  mul_v3_fl(dx, forcetime);
2400 
2401  /* the freezer coming sooner or later */
2402 #if 0
2403  if ((dot_v3v3(dx, dx) < freezeloc) && (dot_v3v3(bp->force, bp->force) < freezeforce)) {
2404  bp->frozen /= 2;
2405  }
2406  else {
2407  bp->frozen = min_ff(bp->frozen * 1.05f, 1.0f);
2408  }
2409  mul_v3_fl(dx, bp->frozen);
2410 #endif
2411  /* again some nasty if's to have heun in here too */
2412  if (mode == 1) {
2413  copy_v3_v3(bp->prevpos, bp->pos);
2414  copy_v3_v3(bp->prevdx, dx);
2415  }
2416 
2417  if (mode == 2) {
2418  bp->pos[0] = bp->prevpos[0] + 0.5f * (dx[0] + bp->prevdx[0]);
2419  bp->pos[1] = bp->prevpos[1] + 0.5f * (dx[1] + bp->prevdx[1]);
2420  bp->pos[2] = bp->prevpos[2] + 0.5f * (dx[2] + bp->prevdx[2]);
2421  maxerrpos = max_ff(maxerrpos, fabsf(dx[0] - bp->prevdx[0]));
2422  maxerrpos = max_ff(maxerrpos, fabsf(dx[1] - bp->prevdx[1]));
2423  maxerrpos = max_ff(maxerrpos, fabsf(dx[2] - bp->prevdx[2]));
2424 
2425  /* bp->choke is set when we need to pull a vertex or edge out of the collider.
2426  * the collider object signals to get out by pushing hard. on the other hand
2427  * we don't want to end up in deep space so we add some <viscosity>
2428  * to balance that out */
2429  if (bp->choke2 > 0.0f) {
2430  mul_v3_fl(bp->vec, (1.0f - bp->choke2));
2431  }
2432  if (bp->choke > 0.0f) {
2433  mul_v3_fl(bp->vec, (1.0f - bp->choke));
2434  }
2435  }
2436  else {
2437  add_v3_v3(bp->pos, dx);
2438  }
2439  } /*snap*/
2440  /* so while we are looping BPs anyway do statistics on the fly */
2441  minmax_v3v3_v3(aabbmin, aabbmax, bp->pos);
2442  if (bp->loc_flag & SBF_DOFUZZY) {
2443  fuzzy = 1;
2444  }
2445  } /*for*/
2446 
2447  if (sb->totpoint) {
2448  mul_v3_fl(cm, 1.0f / sb->totpoint);
2449  }
2450  if (sb->scratch) {
2451  copy_v3_v3(sb->scratch->aabbmin, aabbmin);
2452  copy_v3_v3(sb->scratch->aabbmax, aabbmax);
2453  }
2454 
2455  if (err) { /* so step size will be controlled by biggest difference in slope */
2456  if (sb->solverflags & SBSO_OLDERR) {
2457  *err = max_ff(maxerrpos, maxerrvel);
2458  }
2459  else {
2460  *err = maxerrpos;
2461  }
2462  // printf("EP %f EV %f\n", maxerrpos, maxerrvel);
2463  if (fuzzy) {
2464  *err /= sb->fuzzyness;
2465  }
2466  }
2467 }
2468 
2469 /* used by heun when it overshoots */
2471 {
2472  SoftBody *sb = ob->soft; /* is supposed to be there. */
2473  BodyPoint *bp;
2474  int a;
2475 
2476  for (a = sb->totpoint, bp = sb->bpoint; a > 0; a--, bp++) {
2477  copy_v3_v3(bp->vec, bp->prevvec);
2478  copy_v3_v3(bp->pos, bp->prevpos);
2479  }
2480 }
2481 
2482 #if 0
2483 static void softbody_store_step(Object *ob)
2484 {
2485  SoftBody *sb = ob->soft; /* is supposed to be there. */
2486  BodyPoint *bp;
2487  int a;
2488 
2489  for (a = sb->totpoint, bp = sb->bpoint; a > 0; a--, bp++) {
2490  copy_v3_v3(bp->prevvec, bp->vec);
2491  copy_v3_v3(bp->prevpos, bp->pos);
2492  }
2493 }
2494 
2495 /* used by predictors and correctors */
2496 static void softbody_store_state(Object *ob, float *ppos, float *pvel)
2497 {
2498  SoftBody *sb = ob->soft; /* is supposed to be there. */
2499  BodyPoint *bp;
2500  int a;
2501  float *pp = ppos, *pv = pvel;
2502 
2503  for (a = sb->totpoint, bp = sb->bpoint; a > 0; a--, bp++) {
2504 
2505  copy_v3_v3(pv, bp->vec);
2506  pv += 3;
2507 
2508  copy_v3_v3(pp, bp->pos);
2509  pp += 3;
2510  }
2511 }
2512 
2513 /* used by predictors and correctors */
2514 static void softbody_retrieve_state(Object *ob, float *ppos, float *pvel)
2515 {
2516  SoftBody *sb = ob->soft; /* is supposed to be there. */
2517  BodyPoint *bp;
2518  int a;
2519  float *pp = ppos, *pv = pvel;
2520 
2521  for (a = sb->totpoint, bp = sb->bpoint; a > 0; a--, bp++) {
2522 
2523  copy_v3_v3(bp->vec, pv);
2524  pv += 3;
2525 
2526  copy_v3_v3(bp->pos, pp);
2527  pp += 3;
2528  }
2529 }
2530 
2531 /* used by predictors and correctors */
2532 static void softbody_swap_state(Object *ob, float *ppos, float *pvel)
2533 {
2534  SoftBody *sb = ob->soft; /* is supposed to be there. */
2535  BodyPoint *bp;
2536  int a;
2537  float *pp = ppos, *pv = pvel;
2538  float temp[3];
2539 
2540  for (a = sb->totpoint, bp = sb->bpoint; a > 0; a--, bp++) {
2541 
2542  copy_v3_v3(temp, bp->vec);
2543  copy_v3_v3(bp->vec, pv);
2544  copy_v3_v3(pv, temp);
2545  pv += 3;
2546 
2547  copy_v3_v3(temp, bp->pos);
2548  copy_v3_v3(bp->pos, pp);
2549  copy_v3_v3(pp, temp);
2550  pp += 3;
2551  }
2552 }
2553 #endif
2554 
2555 /* care for bodypoints taken out of the 'ordinary' solver step
2556  * because they are screwed to goal by bolts
2557  * they just need to move along with the goal in time
2558  * we need to adjust them on sub frame timing in solver
2559  * so now when frame is done .. put 'em to the position at the end of frame
2560  */
2562 {
2563  SoftBody *sb = ob->soft; /* is supposed to be there */
2564  BodyPoint *bp;
2565  int a;
2566 
2567  for (a = sb->totpoint, bp = sb->bpoint; a > 0; a--, bp++) {
2568  if (_final_goal(ob, bp) >= SOFTGOALSNAP) {
2569  copy_v3_v3(bp->prevpos, bp->pos);
2570  copy_v3_v3(bp->pos, bp->origT);
2571  }
2572  }
2573 }
2574 
2575 static void apply_spring_memory(Object *ob)
2576 {
2577  SoftBody *sb = ob->soft;
2578  BodySpring *bs;
2579  BodyPoint *bp1, *bp2;
2580  int a;
2581  float b, l, r;
2582 
2583  if (sb && sb->totspring) {
2584  b = sb->plastic;
2585  for (a = 0; a < sb->totspring; a++) {
2586  bs = &sb->bspring[a];
2587  bp1 = &sb->bpoint[bs->v1];
2588  bp2 = &sb->bpoint[bs->v2];
2589  l = len_v3v3(bp1->pos, bp2->pos);
2590  r = bs->len / l;
2591  if ((r > 1.05f) || (r < 0.95f)) {
2592  bs->len = ((100.0f - b) * bs->len + b * l) / 100.0f;
2593  }
2594  }
2595  }
2596 }
2597 
2598 /* expects full initialized softbody */
2599 static void interpolate_exciter(Object *ob, int timescale, int time)
2600 {
2601  SoftBody *sb = ob->soft;
2602  BodyPoint *bp;
2603  float f;
2604  int a;
2605 
2606  f = (float)time / (float)timescale;
2607 
2608  for (a = sb->totpoint, bp = sb->bpoint; a > 0; a--, bp++) {
2609  bp->origT[0] = bp->origS[0] + f * (bp->origE[0] - bp->origS[0]);
2610  bp->origT[1] = bp->origS[1] + f * (bp->origE[1] - bp->origS[1]);
2611  bp->origT[2] = bp->origS[2] + f * (bp->origE[2] - bp->origS[2]);
2612  if (_final_goal(ob, bp) >= SOFTGOALSNAP) {
2613  bp->vec[0] = bp->origE[0] - bp->origS[0];
2614  bp->vec[1] = bp->origE[1] - bp->origS[1];
2615  bp->vec[2] = bp->origE[2] - bp->origS[2];
2616  }
2617  }
2618 }
2619 
2620 /* ************ converters ********** */
2621 
2622 /* for each object type we need;
2623  * - xxxx_to_softbody(Object *ob) : a full (new) copy, creates SB geometry
2624  */
2625 
2626 /* Resetting a Mesh SB object's springs */
2627 /* Spring length are calculated from 'raw' mesh vertices that are NOT altered by modifier stack. */
2628 static void springs_from_mesh(Object *ob)
2629 {
2630  SoftBody *sb;
2631  Mesh *me = ob->data;
2632  BodyPoint *bp;
2633  int a;
2634  float scale = 1.0f;
2635 
2636  sb = ob->soft;
2637  if (me && sb) {
2638  /* using bp->origS as a container for spring calculations here
2639  * will be overwritten sbObjectStep() to receive
2640  * actual modifier stack positions
2641  */
2642  if (me->totvert) {
2643  bp = ob->soft->bpoint;
2644  for (a = 0; a < me->totvert; a++, bp++) {
2645  copy_v3_v3(bp->origS, me->mvert[a].co);
2646  mul_m4_v3(ob->obmat, bp->origS);
2647  }
2648  }
2649  /* recalculate spring length for meshes here */
2650  /* public version shrink to fit */
2651  if (sb->springpreload != 0) {
2652  scale = sb->springpreload / 100.0f;
2653  }
2654  for (a = 0; a < sb->totspring; a++) {
2655  BodySpring *bs = &sb->bspring[a];
2656  bs->len = scale * len_v3v3(sb->bpoint[bs->v1].origS, sb->bpoint[bs->v2].origS);
2657  }
2658  }
2659 }
2660 
2661 /* makes totally fresh start situation */
2662 static void mesh_to_softbody(Object *ob)
2663 {
2664  SoftBody *sb;
2665  Mesh *me = ob->data;
2666  MEdge *medge = me->medge;
2667  BodyPoint *bp;
2668  BodySpring *bs;
2669  int a, totedge;
2670  int defgroup_index, defgroup_index_mass, defgroup_index_spring;
2671 
2672  if (ob->softflag & OB_SB_EDGES) {
2673  totedge = me->totedge;
2674  }
2675  else {
2676  totedge = 0;
2677  }
2678 
2679  /* renew ends with ob->soft with points and edges, also checks & makes ob->soft */
2680  renew_softbody(ob, me->totvert, totedge);
2681 
2682  /* we always make body points */
2683  sb = ob->soft;
2684  bp = sb->bpoint;
2685 
2686  defgroup_index = me->dvert ? (sb->vertgroup - 1) : -1;
2687  defgroup_index_mass = me->dvert ? BKE_id_defgroup_name_index(&me->id, sb->namedVG_Mass) : -1;
2688  defgroup_index_spring = me->dvert ? BKE_id_defgroup_name_index(&me->id, sb->namedVG_Spring_K) :
2689  -1;
2690 
2691  for (a = 0; a < me->totvert; a++, bp++) {
2692  /* get scalar values needed *per vertex* from vertex group functions,
2693  * so we can *paint* them nicely ..
2694  * they are normalized [0.0..1.0] so may be we need amplitude for scale
2695  * which can be done by caller but still .. i'd like it to go this way
2696  */
2697 
2698  if (ob->softflag & OB_SB_GOAL) {
2699  BLI_assert(bp->goal == sb->defgoal);
2700  }
2701  if ((ob->softflag & OB_SB_GOAL) && (defgroup_index != -1)) {
2702  bp->goal *= BKE_defvert_find_weight(&me->dvert[a], defgroup_index);
2703  }
2704 
2705  /* to proof the concept
2706  * this enables per vertex *mass painting*
2707  */
2708 
2709  if (defgroup_index_mass != -1) {
2710  bp->mass *= BKE_defvert_find_weight(&me->dvert[a], defgroup_index_mass);
2711  }
2712 
2713  if (defgroup_index_spring != -1) {
2714  bp->springweight *= BKE_defvert_find_weight(&me->dvert[a], defgroup_index_spring);
2715  }
2716  }
2717 
2718  /* but we only optionally add body edge springs */
2719  if (ob->softflag & OB_SB_EDGES) {
2720  if (medge) {
2721  bs = sb->bspring;
2722  for (a = me->totedge; a > 0; a--, medge++, bs++) {
2723  bs->v1 = medge->v1;
2724  bs->v2 = medge->v2;
2725  bs->springtype = SB_EDGE;
2726  }
2727 
2728  /* insert *diagonal* springs in quads if desired */
2729  if (ob->softflag & OB_SB_QUADS) {
2731  }
2732 
2733  build_bps_springlist(ob); /* scan for springs attached to bodypoints ONCE */
2734  /* insert *other second order* springs if desired */
2735  if (sb->secondspring > 0.0000001f) {
2736  /* Exploits the first run of `build_bps_springlist(ob)`. */
2738  /* yes we need to do it again. */
2740  }
2741  springs_from_mesh(ob); /* write the 'rest'-length of the springs */
2742  if (ob->softflag & OB_SB_SELF) {
2744  }
2745  }
2746  }
2747 }
2748 
2750 {
2751  SoftBody *sb = ob->soft;
2752  const Mesh *me = ob->data;
2753  MLoopTri *looptri, *lt;
2754  BodyFace *bodyface;
2755  int a;
2756  /* Allocate and copy faces. */
2757 
2758  sb->scratch->totface = poly_to_tri_count(me->totpoly, me->totloop);
2759  looptri = lt = MEM_mallocN(sizeof(*looptri) * sb->scratch->totface, __func__);
2760  BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri);
2761 
2762  bodyface = sb->scratch->bodyface = MEM_mallocN(sizeof(BodyFace) * sb->scratch->totface,
2763  "SB_body_Faces");
2764 
2765  for (a = 0; a < sb->scratch->totface; a++, lt++, bodyface++) {
2766  bodyface->v1 = me->mloop[lt->tri[0]].v;
2767  bodyface->v2 = me->mloop[lt->tri[1]].v;
2768  bodyface->v3 = me->mloop[lt->tri[2]].v;
2769  zero_v3(bodyface->ext_force);
2770  bodyface->ext_force[0] = bodyface->ext_force[1] = bodyface->ext_force[2] = 0.0f;
2771  bodyface->flag = 0;
2772  }
2773 
2774  MEM_freeN(looptri);
2775 }
2777 {
2778  SoftBody *sb = ob->soft;
2779  ReferenceVert *rp;
2780  BodyPoint *bp;
2781  float accu_pos[3] = {0.0f, 0.0f, 0.0f};
2782  float accu_mass = 0.0f;
2783  int a;
2784 
2785  sb->scratch->Ref.ivert = MEM_mallocN(sizeof(ReferenceVert) * sb->totpoint, "SB_Reference");
2786  bp = ob->soft->bpoint;
2787  rp = sb->scratch->Ref.ivert;
2788  for (a = 0; a < sb->totpoint; a++, rp++, bp++) {
2789  copy_v3_v3(rp->pos, bp->pos);
2790  add_v3_v3(accu_pos, bp->pos);
2791  accu_mass += _final_mass(ob, bp);
2792  }
2793  mul_v3_fl(accu_pos, 1.0f / accu_mass);
2794  copy_v3_v3(sb->scratch->Ref.com, accu_pos);
2795  // printf("reference_to_scratch\n");
2796 }
2797 
2798 /*
2799  * helper function to get proper spring length
2800  * when object is rescaled
2801  */
2802 static float globallen(float *v1, float *v2, Object *ob)
2803 {
2804  float p1[3], p2[3];
2805  copy_v3_v3(p1, v1);
2806  mul_m4_v3(ob->obmat, p1);
2807  copy_v3_v3(p2, v2);
2808  mul_m4_v3(ob->obmat, p2);
2809  return len_v3v3(p1, p2);
2810 }
2811 
2812 static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff, Object *ob)
2813 {
2814  BPoint *bp = lt->def, *bpu;
2815  int u, v, w, dv, dw, bpc = 0, bpuc;
2816 
2817  dv = lt->pntsu;
2818  dw = dv * lt->pntsv;
2819 
2820  for (w = 0; w < lt->pntsw; w++) {
2821 
2822  for (v = 0; v < lt->pntsv; v++) {
2823 
2824  for (u = 0, bpuc = 0, bpu = NULL; u < lt->pntsu; u++, bp++, bpc++) {
2825 
2826  if (w) {
2827  bs->v1 = bpc;
2828  bs->v2 = bpc - dw;
2829  bs->springtype = SB_EDGE;
2830  bs->len = globallen((bp - dw)->vec, bp->vec, ob);
2831  bs++;
2832  }
2833  if (v) {
2834  bs->v1 = bpc;
2835  bs->v2 = bpc - dv;
2836  bs->springtype = SB_EDGE;
2837  bs->len = globallen((bp - dv)->vec, bp->vec, ob);
2838  bs++;
2839  }
2840  if (u) {
2841  bs->v1 = bpuc;
2842  bs->v2 = bpc;
2843  bs->springtype = SB_EDGE;
2844  bs->len = globallen((bpu)->vec, bp->vec, ob);
2845  bs++;
2846  }
2847 
2848  if (dostiff) {
2849 
2850  if (w) {
2851  if (v && u) {
2852  bs->v1 = bpc;
2853  bs->v2 = bpc - dw - dv - 1;
2854  bs->springtype = SB_BEND;
2855  bs->len = globallen((bp - dw - dv - 1)->vec, bp->vec, ob);
2856  bs++;
2857  }
2858  if ((v < lt->pntsv - 1) && (u != 0)) {
2859  bs->v1 = bpc;
2860  bs->v2 = bpc - dw + dv - 1;
2861  bs->springtype = SB_BEND;
2862  bs->len = globallen((bp - dw + dv - 1)->vec, bp->vec, ob);
2863  bs++;
2864  }
2865  }
2866 
2867  if (w < lt->pntsw - 1) {
2868  if (v && u) {
2869  bs->v1 = bpc;
2870  bs->v2 = bpc + dw - dv - 1;
2871  bs->springtype = SB_BEND;
2872  bs->len = globallen((bp + dw - dv - 1)->vec, bp->vec, ob);
2873  bs++;
2874  }
2875  if ((v < lt->pntsv - 1) && (u != 0)) {
2876  bs->v1 = bpc;
2877  bs->v2 = bpc + dw + dv - 1;
2878  bs->springtype = SB_BEND;
2879  bs->len = globallen((bp + dw + dv - 1)->vec, bp->vec, ob);
2880  bs++;
2881  }
2882  }
2883  }
2884  bpu = bp;
2885  bpuc = bpc;
2886  }
2887  }
2888  }
2889 }
2890 
2891 /* makes totally fresh start situation */
2892 static void lattice_to_softbody(Object *ob)
2893 {
2894  Lattice *lt = ob->data;
2895  SoftBody *sb;
2896  int totvert, totspring = 0, a;
2897  BodyPoint *bp;
2898  BPoint *bpnt = lt->def;
2899  int defgroup_index, defgroup_index_mass, defgroup_index_spring;
2900 
2901  totvert = lt->pntsu * lt->pntsv * lt->pntsw;
2902 
2903  if (ob->softflag & OB_SB_EDGES) {
2904  totspring = ((lt->pntsu - 1) * lt->pntsv + (lt->pntsv - 1) * lt->pntsu) * lt->pntsw +
2905  lt->pntsu * lt->pntsv * (lt->pntsw - 1);
2906  if (ob->softflag & OB_SB_QUADS) {
2907  totspring += 4 * (lt->pntsu - 1) * (lt->pntsv - 1) * (lt->pntsw - 1);
2908  }
2909  }
2910 
2911  /* renew ends with ob->soft with points and edges, also checks & makes ob->soft */
2912  renew_softbody(ob, totvert, totspring);
2913  sb = ob->soft; /* can be created in renew_softbody() */
2914  bp = sb->bpoint;
2915 
2916  defgroup_index = lt->dvert ? (sb->vertgroup - 1) : -1;
2917  defgroup_index_mass = lt->dvert ? BKE_id_defgroup_name_index(&lt->id, sb->namedVG_Mass) : -1;
2918  defgroup_index_spring = lt->dvert ? BKE_id_defgroup_name_index(&lt->id, sb->namedVG_Spring_K) :
2919  -1;
2920 
2921  /* same code used as for mesh vertices */
2922  for (a = 0; a < totvert; a++, bp++, bpnt++) {
2923 
2924  if (ob->softflag & OB_SB_GOAL) {
2925  BLI_assert(bp->goal == sb->defgoal);
2926  }
2927 
2928  if ((ob->softflag & OB_SB_GOAL) && (defgroup_index != -1)) {
2929  bp->goal *= BKE_defvert_find_weight(&lt->dvert[a], defgroup_index);
2930  }
2931  else {
2932  bp->goal *= bpnt->weight;
2933  }
2934 
2935  if (defgroup_index_mass != -1) {
2936  bp->mass *= BKE_defvert_find_weight(&lt->dvert[a], defgroup_index_mass);
2937  }
2938 
2939  if (defgroup_index_spring != -1) {
2940  bp->springweight *= BKE_defvert_find_weight(&lt->dvert[a], defgroup_index_spring);
2941  }
2942  }
2943 
2944  /* create some helper edges to enable SB lattice to be useful at all */
2945  if (ob->softflag & OB_SB_EDGES) {
2946  makelatticesprings(lt, ob->soft->bspring, ob->softflag & OB_SB_QUADS, ob);
2947  build_bps_springlist(ob); /* link bps to springs */
2948  if (ob->softflag & OB_SB_SELF) {
2950  }
2951  }
2952 }
2953 
2954 /* makes totally fresh start situation */
2956 {
2957  Curve *cu = ob->data;
2958  SoftBody *sb;
2959  BodyPoint *bp;
2960  BodySpring *bs;
2961  Nurb *nu;
2962  BezTriple *bezt;
2963  BPoint *bpnt;
2964  int a, curindex = 0;
2965  int totvert, totspring = 0, setgoal = 0;
2966 
2967  totvert = BKE_nurbList_verts_count(&cu->nurb);
2968 
2969  if (ob->softflag & OB_SB_EDGES) {
2970  if (ob->type == OB_CURVES_LEGACY) {
2971  totspring = totvert - BLI_listbase_count(&cu->nurb);
2972  }
2973  }
2974 
2975  /* renew ends with ob->soft with points and edges, also checks & makes ob->soft */
2976  renew_softbody(ob, totvert, totspring);
2977  sb = ob->soft; /* can be created in renew_softbody() */
2978 
2979  /* set vars now */
2980  bp = sb->bpoint;
2981  bs = sb->bspring;
2982 
2983  /* Weights from bpoints, same code used as for mesh vertices. */
2984  /* if ((ob->softflag & OB_SB_GOAL) && sb->vertgroup) 2.4x hack. */
2985  /* new! take the weights from curve vertex anyhow */
2986  if (ob->softflag & OB_SB_GOAL) {
2987  setgoal = 1;
2988  }
2989 
2990  for (nu = cu->nurb.first; nu; nu = nu->next) {
2991  if (nu->bezt) {
2992  /* Bezier case; this is nicely said naive; who ever wrote this part,
2993  * it was not me (JOW) :).
2994  *
2995  * a: never ever make tangent handles (sub) and or (ob)ject to collision.
2996  * b: rather calculate them using some C2
2997  * (C2= continuous in second derivative -> no jump in bending ) condition.
2998  *
2999  * Not too hard to do, but needs some more code to care for;
3000  * some one may want look at it (JOW 2010/06/12). */
3001  for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++, bp += 3, curindex += 3) {
3002  if (setgoal) {
3003  bp->goal *= bezt->weight;
3004 
3005  /* All three triples. */
3006  (bp + 1)->goal = bp->goal;
3007  (bp + 2)->goal = bp->goal;
3008  /* Do not collide handles. */
3009  (bp + 1)->loc_flag |= SBF_OUTOFCOLLISION;
3010  (bp + 2)->loc_flag |= SBF_OUTOFCOLLISION;
3011  }
3012 
3013  if (totspring) {
3014  if (a > 0) {
3015  bs->v1 = curindex - 3;
3016  bs->v2 = curindex;
3017  bs->springtype = SB_HANDLE;
3018  bs->len = globallen((bezt - 1)->vec[0], bezt->vec[0], ob);
3019  bs++;
3020  }
3021  bs->v1 = curindex;
3022  bs->v2 = curindex + 1;
3023  bs->springtype = SB_HANDLE;
3024  bs->len = globallen(bezt->vec[0], bezt->vec[1], ob);
3025  bs++;
3026 
3027  bs->v1 = curindex + 1;
3028  bs->v2 = curindex + 2;
3029  bs->springtype = SB_HANDLE;
3030  bs->len = globallen(bezt->vec[1], bezt->vec[2], ob);
3031  bs++;
3032  }
3033  }
3034  }
3035  else {
3036  for (bpnt = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bpnt++, bp++, curindex++) {
3037  if (setgoal) {
3038  bp->goal *= bpnt->weight;
3039  }
3040  if (totspring && a > 0) {
3041  bs->v1 = curindex - 1;
3042  bs->v2 = curindex;
3043  bs->springtype = SB_EDGE;
3044  bs->len = globallen((bpnt - 1)->vec, bpnt->vec, ob);
3045  bs++;
3046  }
3047  }
3048  }
3049  }
3050 
3051  if (totspring) {
3052  build_bps_springlist(ob); /* link bps to springs */
3053  if (ob->softflag & OB_SB_SELF) {
3055  }
3056  }
3057 }
3058 
3059 /* copies softbody result back in object */
3060 static void softbody_to_object(Object *ob, float (*vertexCos)[3], int numVerts, int local)
3061 {
3062  SoftBody *sb = ob->soft;
3063  if (sb) {
3064  BodyPoint *bp = sb->bpoint;
3065  int a;
3066  if (sb->solverflags & SBSO_ESTIMATEIPO) {
3067  SB_estimate_transform(ob, sb->lcom, sb->lrot, sb->lscale);
3068  }
3069  /* Inverse matrix is not up to date. */
3070  invert_m4_m4(ob->imat, ob->obmat);
3071 
3072  for (a = 0; a < numVerts; a++, bp++) {
3073  copy_v3_v3(vertexCos[a], bp->pos);
3074  if (local == 0) {
3075  mul_m4_v3(ob->imat, vertexCos[a]); /* softbody is in global coords, baked optionally not */
3076  }
3077  }
3078  }
3079 }
3080 
3081 /* +++ ************ maintaining scratch *************** */
3082 static void sb_new_scratch(SoftBody *sb)
3083 {
3084  if (!sb) {
3085  return;
3086  }
3087  sb->scratch = MEM_callocN(sizeof(SBScratch), "SBScratch");
3088  sb->scratch->colliderhash = BLI_ghash_ptr_new("sb_new_scratch gh");
3089  sb->scratch->bodyface = NULL;
3090  sb->scratch->totface = 0;
3091  sb->scratch->aabbmax[0] = sb->scratch->aabbmax[1] = sb->scratch->aabbmax[2] = 1.0e30f;
3092  sb->scratch->aabbmin[0] = sb->scratch->aabbmin[1] = sb->scratch->aabbmin[2] = -1.0e30f;
3093  sb->scratch->Ref.ivert = NULL;
3094 }
3095 /* --- ************ maintaining scratch *************** */
3096 
3097 /* ************ Object level, exported functions *************** */
3098 
3100 {
3101  SoftBody *sb;
3102 
3103  sb = MEM_callocN(sizeof(SoftBody), "softbody");
3104 
3105  sb->mediafrict = 0.5f;
3106  sb->nodemass = 1.0f;
3107  sb->grav = 9.8f;
3108  sb->physics_speed = 1.0f;
3109  sb->rklimit = 0.1f;
3110 
3111  sb->goalspring = 0.5f;
3112  sb->goalfrict = 0.0f;
3113  sb->mingoal = 0.0f;
3114  sb->maxgoal = 1.0f;
3115  sb->defgoal = 0.7f;
3116 
3117  sb->inspring = 0.5f;
3118  sb->infrict = 0.5f;
3119  /* TODO: backward file compat should copy `inspring` to `inpush` while reading old files. */
3120  sb->inpush = 0.5f;
3121 
3122  sb->colball = 0.49f;
3123  sb->balldamp = 0.50f;
3124  sb->ballstiff = 1.0f;
3125  sb->sbc_mode = 1;
3126 
3127  sb->minloops = 10;
3128  sb->maxloops = 300;
3129 
3130  sb->choke = 3;
3131  sb_new_scratch(sb);
3132  /* TODO: backward file compat should set `sb->shearstiff = 1.0f` while reading old files. */
3133  sb->shearstiff = 1.0f;
3134  sb->solverflags |= SBSO_OLDERR;
3135 
3136  sb->shared = MEM_callocN(sizeof(*sb->shared), "SoftBody_Shared");
3138 
3139  if (!sb->effector_weights) {
3141  }
3142 
3143  sb->last_frame = MINFRAME - 1;
3144 
3145  return sb;
3146 }
3147 
3148 void sbFree(Object *ob)
3149 {
3150  SoftBody *sb = ob->soft;
3151  if (sb == NULL) {
3152  return;
3153  }
3154 
3155  const bool is_orig = (ob->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0;
3156 
3158 
3159  if (is_orig) {
3160  /* Only free shared data on non-CoW copies */
3162  sb->shared->pointcache = NULL;
3163  MEM_freeN(sb->shared);
3164  }
3165  if (sb->effector_weights) {
3167  }
3168  MEM_freeN(sb);
3169 
3170  ob->soft = NULL;
3171 }
3172 
3174 {
3176 }
3177 
3179 {
3180  // ob->softflag |= OB_SB_REDO;
3181 
3183 }
3184 
3185 static bool object_has_edges(const Object *ob)
3186 {
3187  if (ob->type == OB_MESH) {
3188  return ((Mesh *)ob->data)->totedge;
3189  }
3190  if (ob->type == OB_LATTICE) {
3191  return true;
3192  }
3193 
3194  return false;
3195 }
3196 
3197 void sbSetInterruptCallBack(int (*f)(void))
3198 {
3200 }
3201 
3203  SoftBody *sb,
3204  float (*vertexCos)[3],
3205  int numVerts)
3206 {
3207  BodyPoint *bp;
3208  int a;
3209 
3210  if (!sb || !sb->bpoint) {
3211  return;
3212  }
3213 
3214  for (a = 0, bp = sb->bpoint; a < numVerts; a++, bp++) {
3215  /* store where goals are now */
3216  copy_v3_v3(bp->origS, bp->origE);
3217  /* copy the position of the goals at desired end time */
3218  copy_v3_v3(bp->origE, vertexCos[a]);
3219  /* vertexCos came from local world, go global */
3220  mul_m4_v3(ob->obmat, bp->origE);
3221  /* just to be save give bp->origT a defined value
3222  * will be calculated in interpolate_exciter() */
3223  copy_v3_v3(bp->origT, bp->origE);
3224  }
3225 }
3226 
3227 void SB_estimate_transform(Object *ob, float lloc[3], float lrot[3][3], float lscale[3][3])
3228 {
3229  BodyPoint *bp;
3230  ReferenceVert *rp;
3231  SoftBody *sb = NULL;
3232  float(*opos)[3];
3233  float(*rpos)[3];
3234  float com[3], rcom[3];
3235  int a;
3236 
3237  if (!ob || !ob->soft) {
3238  return; /* why did we get here ? */
3239  }
3240  sb = ob->soft;
3241  if (!sb || !sb->bpoint) {
3242  return;
3243  }
3244  opos = MEM_callocN(sizeof(float[3]) * sb->totpoint, "SB_OPOS");
3245  rpos = MEM_callocN(sizeof(float[3]) * sb->totpoint, "SB_RPOS");
3246  /* might filter vertex selection with a vertex group */
3247  for (a = 0, bp = sb->bpoint, rp = sb->scratch->Ref.ivert; a < sb->totpoint; a++, bp++, rp++) {
3248  copy_v3_v3(rpos[a], rp->pos);
3249  copy_v3_v3(opos[a], bp->pos);
3250  }
3251 
3252  vcloud_estimate_transform_v3(sb->totpoint, opos, NULL, rpos, NULL, com, rcom, lrot, lscale);
3253  // sub_v3_v3(com, rcom);
3254  if (lloc) {
3255  copy_v3_v3(lloc, com);
3256  }
3257  copy_v3_v3(sb->lcom, com);
3258  if (lscale) {
3259  copy_m3_m3(sb->lscale, lscale);
3260  }
3261  if (lrot) {
3262  copy_m3_m3(sb->lrot, lrot);
3263  }
3264 
3265  MEM_freeN(opos);
3266  MEM_freeN(rpos);
3267 }
3268 
3269 static void softbody_reset(Object *ob, SoftBody *sb, float (*vertexCos)[3], int numVerts)
3270 {
3271  BodyPoint *bp;
3272  int a;
3273 
3274  for (a = 0, bp = sb->bpoint; a < numVerts; a++, bp++) {
3275  copy_v3_v3(bp->pos, vertexCos[a]);
3276  mul_m4_v3(ob->obmat, bp->pos); /* Yep, soft-body is global coords. */
3277  copy_v3_v3(bp->origS, bp->pos);
3278  copy_v3_v3(bp->origE, bp->pos);
3279  copy_v3_v3(bp->origT, bp->pos);
3280  bp->vec[0] = bp->vec[1] = bp->vec[2] = 0.0f;
3281 
3282  /* the bp->prev*'s are for rolling back from a canceled try to propagate in time
3283  * adaptive step size algorithm in a nutshell:
3284  * 1. set scheduled time step to new dtime
3285  * 2. try to advance the scheduled time step, being optimistic execute it
3286  * 3. check for success
3287  * 3.a we 're fine continue, may be we can increase scheduled time again ?? if so, do so!
3288  * 3.b we did exceed error limit --> roll back, shorten the scheduled time and try again at 2.
3289  * 4. check if we did reach dtime
3290  * 4.a nope we need to do some more at 2.
3291  * 4.b yup we're done
3292  */
3293 
3294  copy_v3_v3(bp->prevpos, bp->pos);
3295  copy_v3_v3(bp->prevvec, bp->vec);
3296  copy_v3_v3(bp->prevdx, bp->vec);
3297  copy_v3_v3(bp->prevdv, bp->vec);
3298  }
3299 
3300  /* make a nice clean scratch struct */
3301  free_scratch(sb); /* clear if any */
3302  sb_new_scratch(sb); /* make a new */
3303  sb->scratch->needstobuildcollider = 1;
3304  zero_v3(sb->lcom);
3305  unit_m3(sb->lrot);
3306  unit_m3(sb->lscale);
3307 
3308  /* copy some info to scratch */
3309  /* we only need that if we want to reconstruct IPO */
3310  if (1) {
3314  }
3315  switch (ob->type) {
3316  case OB_MESH:
3317  if (ob->softflag & OB_SB_FACECOLL) {
3319  }
3320  break;
3321  case OB_LATTICE:
3322  break;
3323  case OB_CURVES_LEGACY:
3324  case OB_SURF:
3325  break;
3326  default:
3327  break;
3328  }
3329 }
3330 
3331 static void softbody_step(
3332  struct Depsgraph *depsgraph, Scene *scene, Object *ob, SoftBody *sb, float dtime)
3333 {
3334  /* the simulator */
3335  float forcetime;
3336  double sct, sst;
3337 
3338  sst = PIL_check_seconds_timer();
3339  /* Integration back in time is possible in theory, but pretty useless here.
3340  * So we refuse to do so. Since we do not know anything about 'outside' changes
3341  * especially colliders we refuse to go more than 10 frames.
3342  */
3343  if (dtime < 0 || dtime > 10.5f) {
3344  return;
3345  }
3346 
3348 
3349  if (sb->scratch->needstobuildcollider) {
3351  sb->scratch->needstobuildcollider = 0;
3352  }
3353 
3354  if (sb->solver_ID < 2) {
3355  /* special case of 2nd order Runge-Kutta type AKA Heun */
3356  int mid_flags = 0;
3357  float err = 0;
3358  /* Set defaults guess we shall do one frame */
3359  float forcetimemax = 1.0f;
3360  /* Set defaults guess 1/100 is tight enough */
3361  float forcetimemin = 0.01f;
3362  /* How far did we get without violating error condition. */
3363  float timedone = 0.0;
3364  /* Loops = counter for emergency brake we don't want to lock up the system if physics fail. */
3365  int loops = 0;
3366 
3367  SoftHeunTol = sb->rklimit; /* humm .. this should be calculated from sb parameters and sizes */
3368  /* adjust loop limits */
3369  if (sb->minloops > 0) {
3370  forcetimemax = dtime / sb->minloops;
3371  }
3372  if (sb->maxloops > 0) {
3373  forcetimemin = dtime / sb->maxloops;
3374  }
3375 
3376  if (sb->solver_ID > 0) {
3377  mid_flags |= MID_PRESERVE;
3378  }
3379 
3380  forcetime = forcetimemax; /* hope for integrating in one step */
3381  while ((fabsf(timedone) < fabsf(dtime)) && (loops < 2000)) {
3382  /* set goals in time */
3383  interpolate_exciter(ob, 200, (int)(200.0f * (timedone / dtime)));
3384 
3385  sb->scratch->flag &= ~SBF_DOFUZZY;
3386  /* do predictive euler step */
3387  softbody_calc_forces(depsgraph, scene, ob, forcetime, timedone / dtime);
3388 
3389  softbody_apply_forces(ob, forcetime, 1, NULL, mid_flags);
3390 
3391  /* crop new slope values to do averaged slope step */
3392  softbody_calc_forces(depsgraph, scene, ob, forcetime, timedone / dtime);
3393 
3394  softbody_apply_forces(ob, forcetime, 2, &err, mid_flags);
3396 
3397  if (err > SoftHeunTol) { /* error needs to be scaled to some quantity */
3398 
3399  if (forcetime > forcetimemin) {
3400  forcetime = max_ff(forcetime / 2.0f, forcetimemin);
3402  // printf("down, ");
3403  }
3404  else {
3405  timedone += forcetime;
3406  }
3407  }
3408  else {
3409  float newtime = forcetime * 1.1f; /* hope for 1.1 times better conditions in next step */
3410 
3411  if (sb->scratch->flag & SBF_DOFUZZY) {
3412  // /* stay with this stepsize unless err really small */
3413  // if (err > SoftHeunTol/(2.0f*sb->fuzzyness)) {
3414  newtime = forcetime;
3415  // }
3416  }
3417  else {
3418  if (err > SoftHeunTol / 2.0f) { /* stay with this stepsize unless err really small */
3419  newtime = forcetime;
3420  }
3421  }
3422  timedone += forcetime;
3423  newtime = min_ff(forcetimemax, max_ff(newtime, forcetimemin));
3424  // if (newtime > forcetime) printf("up, ");
3425  if (forcetime > 0.0f) {
3426  forcetime = min_ff(dtime - timedone, newtime);
3427  }
3428  else {
3429  forcetime = max_ff(dtime - timedone, newtime);
3430  }
3431  }
3432  loops++;
3433  if (sb->solverflags & SBSO_MONITOR) {
3434  sct = PIL_check_seconds_timer();
3435  if (sct - sst > 0.5) {
3436  printf("%3.0f%% \r", 100.0f * timedone / dtime);
3437  }
3438  }
3439  /* ask for user break */
3441  break;
3442  }
3443  }
3444  /* move snapped to final position */
3445  interpolate_exciter(ob, 2, 2);
3447 
3448  // if (G.debug & G_DEBUG) {
3449  if (sb->solverflags & SBSO_MONITOR) {
3450  if (loops > HEUNWARNLIMIT) { /* monitor high loop counts */
3451  printf("\r needed %d steps/frame", loops);
3452  }
3453  }
3454  }
3455  else if (sb->solver_ID == 2) {
3456  /* do semi "fake" implicit euler */
3457  /* removed */
3458  } /* SOLVER SELECT */
3459  else if (sb->solver_ID == 4) {
3460  /* do semi "fake" implicit euler */
3461  } /* SOLVER SELECT */
3462  else if (sb->solver_ID == 3) {
3463  /* do "stupid" semi "fake" implicit euler */
3464  /* removed */
3465 
3466  } /* SOLVER SELECT */
3467  else {
3468  CLOG_ERROR(&LOG, "softbody no valid solver ID!");
3469  } /* SOLVER SELECT */
3470  if (sb->plastic) {
3471  apply_spring_memory(ob);
3472  }
3473 
3474  if (sb->solverflags & SBSO_MONITOR) {
3475  sct = PIL_check_seconds_timer();
3476  if ((sct - sst > 0.5) || (G.debug & G_DEBUG)) {
3477  printf(" solver time %f sec %s\n", sct - sst, ob->id.name);
3478  }
3479  }
3480 }
3481 
3482 static void sbStoreLastFrame(struct Depsgraph *depsgraph, Object *object, float framenr)
3483 {
3484  if (!DEG_is_active(depsgraph)) {
3485  return;
3486  }
3487  Object *object_orig = DEG_get_original_object(object);
3488  object->soft->last_frame = framenr;
3489  object_orig->soft->last_frame = framenr;
3490 }
3491 
3493  Scene *scene,
3494  Object *ob,
3495  float cfra,
3496  float (*vertexCos)[3],
3497  int numVerts)
3498 {
3499  SoftBody *sb = ob->soft;
3500  PointCache *cache;
3501  PTCacheID pid;
3502  float dtime, timescale;
3503  int framedelta, framenr, startframe, endframe;
3504  int cache_result;
3505  cache = sb->shared->pointcache;
3506 
3507  framenr = (int)cfra;
3508  framedelta = framenr - cache->simframe;
3509 
3510  BKE_ptcache_id_from_softbody(&pid, ob, sb);
3511  BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, &timescale);
3512 
3513  /* check for changes in mesh, should only happen in case the mesh
3514  * structure changes during an animation */
3515  if (sb->bpoint && numVerts != sb->totpoint) {
3516  BKE_ptcache_invalidate(cache);
3517  return;
3518  }
3519 
3520  /* clamp frame ranges */
3521  if (framenr < startframe) {
3522  BKE_ptcache_invalidate(cache);
3523  return;
3524  }
3525  if (framenr > endframe) {
3526  framenr = endframe;
3527  }
3528 
3529  /* verify if we need to create the softbody data */
3530  if (sb->bpoint == NULL ||
3531  ((ob->softflag & OB_SB_EDGES) && !ob->soft->bspring && object_has_edges(ob))) {
3532 
3533  switch (ob->type) {
3534  case OB_MESH:
3535  mesh_to_softbody(ob);
3536  break;
3537  case OB_LATTICE:
3538  lattice_to_softbody(ob);
3539  break;
3540  case OB_CURVES_LEGACY:
3541  case OB_SURF:
3543  break;
3544  default:
3545  renew_softbody(ob, numVerts, 0);
3546  break;
3547  }
3548 
3549  softbody_update_positions(ob, sb, vertexCos, numVerts);
3550  softbody_reset(ob, sb, vertexCos, numVerts);
3551  }
3552 
3553  /* still no points? go away */
3554  if (sb->totpoint == 0) {
3555  return;
3556  }
3557  if (framenr == startframe) {
3559 
3560  /* first frame, no simulation to do, just set the positions */
3561  softbody_update_positions(ob, sb, vertexCos, numVerts);
3562 
3563  BKE_ptcache_validate(cache, framenr);
3564  cache->flag &= ~PTCACHE_REDO_NEEDED;
3565 
3566  sbStoreLastFrame(depsgraph, ob, framenr);
3567 
3568  return;
3569  }
3570 
3571  /* try to read from cache */
3572  bool can_write_cache = DEG_is_active(depsgraph);
3573  bool can_simulate = (framenr == sb->last_frame + 1) && !(cache->flag & PTCACHE_BAKED) &&
3574  can_write_cache;
3575 
3576  cache_result = BKE_ptcache_read(&pid, (float)framenr + scene->r.subframe, can_simulate);
3577 
3578  if (cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED ||
3579  (!can_simulate && cache_result == PTCACHE_READ_OLD)) {
3580  softbody_to_object(ob, vertexCos, numVerts, sb->local);
3581 
3582  BKE_ptcache_validate(cache, framenr);
3583 
3584  if (cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED &&
3585  can_write_cache) {
3586  BKE_ptcache_write(&pid, framenr);
3587  }
3588 
3589  sbStoreLastFrame(depsgraph, ob, framenr);
3590 
3591  return;
3592  }
3593  if (cache_result == PTCACHE_READ_OLD) {
3594  /* pass */
3595  }
3596  else if (/*ob->id.lib || */
3597  /* "library linking & pointcaches" has to be solved properly at some point */
3598  (cache->flag & PTCACHE_BAKED)) {
3599  /* if baked and nothing in cache, do nothing */
3600  if (can_write_cache) {
3601  BKE_ptcache_invalidate(cache);
3602  }
3603  return;
3604  }
3605 
3606  if (!can_simulate) {
3607  return;
3608  }
3609 
3610  /* if on second frame, write cache for first frame */
3611  if (cache->simframe == startframe &&
3612  (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0)) {
3613  BKE_ptcache_write(&pid, startframe);
3614  }
3615 
3616  softbody_update_positions(ob, sb, vertexCos, numVerts);
3617 
3618  /* checking time: */
3619  dtime = framedelta * timescale;
3620 
3621  /* do simulation */
3622  softbody_step(depsgraph, scene, ob, sb, dtime);
3623 
3624  softbody_to_object(ob, vertexCos, numVerts, 0);
3625 
3626  BKE_ptcache_validate(cache, framenr);
3627  BKE_ptcache_write(&pid, framenr);
3628 
3629  sbStoreLastFrame(depsgraph, ob, framenr);
3630 }
typedef float(TangentPoint)[2]
struct Object ** BKE_collision_objects_create(struct Depsgraph *depsgraph, struct Object *self, struct Collection *collection, unsigned int *numcollobj, unsigned int modifier_type)
Definition: collision.c:1275
void BKE_collision_objects_free(struct Object **objects)
Definition: collision.c:1315
int BKE_nurbList_verts_count(const struct ListBase *nurb)
support for deformation groups and hooks.
float BKE_defvert_find_weight(const struct MDeformVert *dvert, int defgroup)
Definition: deform.c:704
int BKE_id_defgroup_name_index(const struct ID *id, const char *name)
void BKE_effectors_free(struct ListBase *lb)
Definition: effect.c:369
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
void pd_point_from_soft(struct Scene *scene, float *loc, float *vel, int index, struct EffectedPoint *point)
Definition: effect.c:434
struct EffectorWeights * BKE_effector_add_weights(struct Collection *collection)
Definition: effect.c:58
struct ListBase * BKE_effectors_create(struct Depsgraph *depsgraph, struct Object *ob_src, struct ParticleSystem *psys_src, struct EffectorWeights *weights, bool use_rotation)
Definition: effect.c:314
@ G_DEBUG
Definition: BKE_global.h:174
void BKE_mesh_recalc_looptri(const struct MLoop *mloop, const struct MPoly *mpoly, const struct MVert *mvert, int totloop, int totpoly, struct MLoopTri *mlooptri)
struct ModifierData * BKE_modifiers_findby_type(const struct Object *ob, ModifierType type)
void BKE_ptcache_id_time(PTCacheID *pid, struct Scene *scene, float cfra, int *startframe, int *endframe, float *timescale)
Definition: pointcache.c:2773
void BKE_ptcache_validate(struct PointCache *cache, int framenr)
Definition: pointcache.c:3789
void BKE_ptcache_id_from_softbody(PTCacheID *pid, struct Object *ob, struct SoftBody *sb)
Definition: pointcache.c:864
#define PTCACHE_READ_INTERPOLATED
int BKE_ptcache_id_reset(struct Scene *scene, PTCacheID *id, int mode)
Definition: pointcache.c:2870
#define PTCACHE_READ_OLD
struct PointCache * BKE_ptcache_add(struct ListBase *ptcaches)
Definition: pointcache.c:3014
int BKE_ptcache_read(PTCacheID *pid, float cfra, bool no_extrapolate_old)
Definition: pointcache.c:2280
int BKE_ptcache_write(PTCacheID *pid, unsigned int cfra)
Definition: pointcache.c:2540
void BKE_ptcache_free_list(struct ListBase *ptcaches)
Definition: pointcache.c:3052
#define PTCACHE_RESET_OUTDATED
void BKE_ptcache_invalidate(struct PointCache *cache)
Definition: pointcache.c:3796
#define PTCACHE_READ_EXACT
int BKE_scene_num_threads(const struct Scene *scene)
#define BLI_assert(a)
Definition: BLI_assert.h:46
BLI_INLINE void * BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:298
void BLI_ghashIterator_step(GHashIterator *ghi)
Definition: BLI_ghash.c:914
void BLI_ghashIterator_free(GHashIterator *ghi)
Definition: BLI_ghash.c:928
BLI_INLINE void * BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:302
void(* GHashValFreeFP)(void *val)
Definition: BLI_ghash.h:38
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:734
GHashIterator * BLI_ghashIterator_new(GHash *gh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:891
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:863
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:755
BLI_INLINE bool BLI_ghashIterator_done(const GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:310
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float max_fff(float a, float b, float c)
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
MINLINE float min_fff(float a, float b, float c)
MINLINE int poly_to_tri_count(int poly_count, int corner_count)
void vcloud_estimate_transform_v3(int list_size, const float(*pos)[3], const float *weight, const float(*rpos)[3], const float *rweight, float lloc[3], float rloc[3], float lrot[3][3], float lscale[3][3])
Definition: math_geom.c:5141
bool isect_line_segment_tri_v3(const float p1[3], const float p2[3], const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float r_uv[2])
Definition: math_geom.c:1561
bool isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:3380
void copy_m3_m3(float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:71
void unit_m3(float m[3][3])
Definition: math_matrix.c:40
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1287
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:729
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
Definition: math_vector.c:867
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 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])
void project_v3_v3v3(float out[3], const float p[3], const float v_proj[3])
Definition: math_vector.c:600
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
Definition: math_vector.c:237
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
void BLI_threadpool_init(struct ListBase *threadbase, void *(*do_thread)(void *), int tot)
Definition: threads.cc:134
void BLI_threadpool_end(struct ListBase *threadbase)
Definition: threads.cc:262
void BLI_threadpool_insert(struct ListBase *threadbase, void *callerdata)
Definition: threads.cc:212
#define UNUSED(x)
#define ELEM(...)
#define CLOG_ERROR(clg_ref,...)
Definition: CLG_log.h:190
#define CLOG_WARN(clg_ref,...)
Definition: CLG_log.h:189
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
bool DEG_is_active(const struct Depsgraph *depsgraph)
Definition: depsgraph.cc:312
struct Object * DEG_get_original_object(struct Object *object)
@ LIB_TAG_COPIED_ON_WRITE
Definition: DNA_ID.h:720
Object groups, one object can be in many groups at once.
@ eModifierType_Collision
#define OB_SB_FACECOLL
#define OB_SB_EDGECOLL
#define SBC_MODE_MIN
#define OB_SB_EDGES
#define SBC_MODE_MANUAL
#define OB_SB_SELF
#define OB_SB_GOAL
#define SBC_MODE_AVG
#define SBSO_ESTIMATEIPO
#define SBC_MODE_AVGMINMAX
#define SBC_MODE_MAX
#define OB_SB_QUADS
#define SBSO_MONITOR
#define OB_SB_AERO_ANGLE
#define SBSO_OLDERR
Object is a sort of wrapper for general info.
@ OB_LATTICE
@ OB_SURF
@ OB_MESH
@ OB_CURVES_LEGACY
@ PTCACHE_BAKED
@ PTCACHE_OUTDATED
@ PTCACHE_REDO_NEEDED
#define MINFRAME
#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 GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint i1
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Read Guarded memory(de)allocation.
#define MEM_recallocN(vmemh, len)
#define MEM_SAFE_FREE(v)
Platform independent time functions.
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
#define expf(x)
Definition: cuda/compat.h:106
double time
Scene scene
const Depsgraph * depsgraph
SyclQueue void void size_t num_bytes void
int len
Definition: draw_manager.c:108
uint pos
BLI_INLINE void dfdx_spring(float to[3][3], const float dir[3], float length, float L, float k)
ccl_gpu_kernel_postfix ccl_global int * counter
void EIG_linear_solver_matrix_add(LinearSolver *solver, int row, int col, double value)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
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 float3 exp(float3 v)
Definition: math_float3.h:392
ccl_device_inline float3 pow(float3 v, float e)
Definition: math_float3.h:533
static int left
#define L
#define G(x, y, z)
#define fabsf(x)
Definition: metal/compat.h:219
static unsigned c
Definition: RandGen.cpp:83
static unsigned a[3]
Definition: RandGen.cpp:78
ListBase threads
list of all thread for every CPUDevice in cpudevices a thread exists.
T distance(const T &a, const T &b)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
#define hash
Definition: noise.c:153
#define BFF_INTERSECT
Definition: softbody.c:140
static void add_mesh_quad_diag_springs(Object *ob)
Definition: softbody.c:582
struct BodySpring BodySpring
static int count_mesh_quads(Mesh *me)
Definition: softbody.c:567
static int sb_detect_edge_collisionCached(const float edge_v1[3], const float edge_v2[3], float *damp, float force[3], struct Object *vertexowner, float time)
Definition: softbody.c:1311
static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float timenow, int totpoint, int *UNUSED(ptr_to_break_func(void)), struct ListBase *effectors, int do_deflector, float fieldfactor, float windfactor)
Definition: softbody.c:2182
static int query_external_colliders(Depsgraph *depsgraph, Collection *collection)
Definition: softbody.c:964
static void softbody_step(struct Depsgraph *depsgraph, Scene *scene, Object *ob, SoftBody *sb, float dtime)
Definition: softbody.c:3331
#define SBF_OUTOFCOLLISION
Definition: softbody.c:138
static ccd_Mesh * ccd_mesh_make(Object *ob)
Definition: softbody.c:268
static int sb_deflect_face(Object *ob, float *actpos, float *facenormal, float *force, float *cf, float time, float *vel, float *intrusion)
Definition: softbody.c:1798
void sbObjectStep(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float cfra, float(*vertexCos)[3], int numVerts)
Definition: softbody.c:3492
struct ReferenceVert ReferenceVert
static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, float forcetime, float timenow, int ifirst, int ilast, int *UNUSED(ptr_to_break_func(void)), ListBase *effectors, int do_deflector, float fieldfactor, float windfactor)
Definition: softbody.c:1943
static void ccd_mesh_free(ccd_Mesh *ccdm)
Definition: softbody.c:475
static int sb_detect_face_pointCached(const float face_v1[3], const float face_v2[3], const float face_v3[3], float *damp, float force[3], struct Object *vertexowner, float time)
Definition: softbody.c:1034
static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow, int ifirst, int ilast, struct ListBase *effectors)
Definition: softbody.c:1424
static float _final_mass(Object *ob, BodyPoint *bp)
Definition: softbody.c:225
static void mesh_faces_to_scratch(Object *ob)
Definition: softbody.c:2749
static void springs_from_mesh(Object *ob)
Definition: softbody.c:2628
static float _final_goal(Object *ob, BodyPoint *bp)
Definition: softbody.c:204
void sbObjectToSoftbody(Object *ob)
Definition: softbody.c:3178
static void ccd_build_deflector_hash_single(GHash *hash, Object *ob)
Definition: softbody.c:489
static void softbody_restore_prev_step(Object *ob)
Definition: softbody.c:2470
static float sb_grav_force_scale(Object *UNUSED(ob))
Definition: softbody.c:157
static void mesh_to_softbody(Object *ob)
Definition: softbody.c:2662
static void add_2nd_order_roller(Object *ob, float UNUSED(stiffness), int *counter, int addsprings)
Definition: softbody.c:625
static int(* SB_localInterruptCallBack)(void)
Definition: softbody.c:70
struct SBScratch SBScratch
static void curve_surf_to_softbody(Object *ob)
Definition: softbody.c:2955
static void softbody_apply_goalsnap(Object *ob)
Definition: softbody.c:2561
static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *err, int mid_flags)
Definition: softbody.c:2310
type_spring
Definition: softbody.c:74
@ SB_STIFFQUAD
Definition: softbody.c:74
@ SB_BEND
Definition: softbody.c:74
@ SB_HANDLE
Definition: softbody.c:74
@ SB_EDGE
Definition: softbody.c:74
static void ccd_build_deflector_hash(Depsgraph *depsgraph, Collection *collection, Object *vertexowner, GHash *hash)
Definition: softbody.c:504
struct SB_thread_context SB_thread_context
void sbFree(Object *ob)
Definition: softbody.c:3148
static void sb_spring_force(Object *ob, int bpi, BodySpring *bs, float iks, float UNUSED(forcetime))
Definition: softbody.c:1861
static void calculate_collision_balls(Object *ob)
Definition: softbody.c:763
static void build_bps_springlist(Object *ob)
Definition: softbody.c:734
static void add_bp_springlist(BodyPoint *bp, int springID)
Definition: softbody.c:711
static const int CCD_SAFETY
Definition: softbody.c:250
static void softbody_calc_forces(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float forcetime, float timenow)
Definition: softbody.c:2251
static int sb_detect_aabb_collisionCached(float UNUSED(force[3]), struct Object *vertexowner, float UNUSED(time))
Definition: softbody.c:976
static void * exec_scan_for_ext_spring_forces(void *data)
Definition: softbody.c:1498
static void softbody_reset(Object *ob, SoftBody *sb, float(*vertexCos)[3], int numVerts)
Definition: softbody.c:3269
static void renew_softbody(Object *ob, int totpoint, int totspring)
Definition: softbody.c:816
struct BodyFace BodyFace
static float globallen(float *v1, float *v2, Object *ob)
Definition: softbody.c:2802
static void softbody_to_object(Object *ob, float(*vertexCos)[3], int numVerts, int local)
Definition: softbody.c:3060
static void add_2nd_order_springs(Object *ob, float stiffness)
Definition: softbody.c:689
#define SBF_DOFUZZY
Definition: softbody.c:137
static void ccd_update_deflector_hash_single(GHash *hash, Object *ob)
Definition: softbody.c:528
static void free_softbody_intern(SoftBody *sb)
Definition: softbody.c:903
#define HEUNWARNLIMIT
Definition: softbody.c:132
void sbFreeSimulation(SoftBody *sb)
Definition: softbody.c:3173
#define MID_PRESERVE
Definition: softbody.c:126
SoftBody * sbNew(void)
Definition: softbody.c:3099
static float sb_fric_force_scale(Object *UNUSED(ob))
Definition: softbody.c:166
static void sb_new_scratch(SoftBody *sb)
Definition: softbody.c:3082
static CLG_LogRef LOG
Definition: softbody.c:67
#define SOFTGOALSNAP
Definition: softbody.c:128
static float sb_time_scale(Object *ob)
Definition: softbody.c:174
static void free_scratch(SoftBody *sb)
Definition: softbody.c:881
#define BFF_CLOSEVERT
Definition: softbody.c:141
static void interpolate_exciter(Object *ob, int timescale, int time)
Definition: softbody.c:2599
void SB_estimate_transform(Object *ob, float lloc[3], float lrot[3][3], float lscale[3][3])
Definition: softbody.c:3227
void sbSetInterruptCallBack(int(*f)(void))
Definition: softbody.c:3197
static void * exec_softbody_calc_forces(void *data)
Definition: softbody.c:2165
#define BSF_INTERSECT
Definition: softbody.c:134
static int choose_winner(float *w, float *pos, float *a, float *b, float *c, float *ca, float *cb, float *cc)
Definition: softbody.c:1575
static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff, Object *ob)
Definition: softbody.c:2812
static float SoftHeunTol
Definition: softbody.c:144
struct ccd_Mesh ccd_Mesh
static void reference_to_scratch(Object *ob)
Definition: softbody.c:2776
static bool object_has_edges(const Object *ob)
Definition: softbody.c:3185
static void free_softbody_baked(SoftBody *sb)
Definition: softbody.c:867
struct ReferenceState ReferenceState
struct ccdf_minmax ccdf_minmax
static void sbStoreLastFrame(struct Depsgraph *depsgraph, Object *object, float framenr)
Definition: softbody.c:3482
static void sb_sfesf_threads_run(struct Depsgraph *depsgraph, Scene *scene, struct Object *ob, float timenow, int totsprings, int *UNUSED(ptr_to_break_func(void)))
Definition: softbody.c:1506
static int sb_detect_face_collisionCached(const float face_v1[3], const float face_v2[3], const float face_v3[3], float *damp, float force[3], struct Object *vertexowner, float time)
Definition: softbody.c:1132
static void lattice_to_softbody(Object *ob)
Definition: softbody.c:2892
static void ccd_update_deflector_hash(Depsgraph *depsgraph, Collection *collection, Object *vertexowner, GHash *hash)
Definition: softbody.c:541
static void scan_for_ext_face_forces(Object *ob, float timenow)
Definition: softbody.c:1241
static void apply_spring_memory(Object *ob)
Definition: softbody.c:2575
static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *damp, float force[3], struct Object *vertexowner, float time, float vel[3], float *intrusion)
Definition: softbody.c:1606
static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
Definition: softbody.c:355
static void softbody_update_positions(Object *ob, SoftBody *sb, float(*vertexCos)[3], int numVerts)
Definition: softbody.c:3202
#define min(a, b)
Definition: sort.c:35
float weight
float vec[4]
float vec[3][3]
int v1
Definition: softbody.c:85
short flag
Definition: softbody.c:87
int v3
Definition: softbody.c:85
int v2
Definition: softbody.c:85
float ext_force[3]
Definition: softbody.c:86
float pos[3]
Definition: BKE_softbody.h:19
float force[3]
Definition: BKE_softbody.h:19
float origE[3]
Definition: BKE_softbody.h:19
float vec[3]
Definition: BKE_softbody.h:19
float prevdv[3]
Definition: BKE_softbody.h:21
float choke2
Definition: BKE_softbody.h:25
float goal
Definition: BKE_softbody.h:20
float prevdx[3]
Definition: BKE_softbody.h:21
int nofsprings
Definition: BKE_softbody.h:23
float mass
Definition: BKE_softbody.h:29
float prevvec[3]
Definition: BKE_softbody.h:21
float choke
Definition: BKE_softbody.h:25
float colball
Definition: BKE_softbody.h:26
short loc_flag
Definition: BKE_softbody.h:27
float prevpos[3]
Definition: BKE_softbody.h:21
int * springs
Definition: BKE_softbody.h:24
float origT[3]
Definition: BKE_softbody.h:19
float origS[3]
Definition: BKE_softbody.h:19
float frozen
Definition: BKE_softbody.h:25
float springweight
Definition: BKE_softbody.h:30
type_spring springtype
Definition: softbody.c:80
float ext_force[3]
Definition: softbody.c:79
float len
Definition: softbody.c:78
float load
Definition: softbody.c:78
short flag
Definition: softbody.c:81
float cf
Definition: softbody.c:78
int v1
Definition: softbody.c:77
int v2
Definition: softbody.c:77
ListBase nurb
int tag
Definition: DNA_ID.h:387
char name[66]
Definition: DNA_ID.h:378
struct MDeformVert * dvert
struct BPoint * def
void * first
Definition: DNA_listBase.h:31
unsigned int v1
unsigned int v2
unsigned int tri[3]
unsigned int v
unsigned int tri[3]
float co[3]
struct MEdge * medge
struct MVert * mvert
struct MDeformVert * dvert
int totedge
int totvert
struct MLoop * mloop
int totpoly
int totloop
struct MPoly * mpoly
struct Nurb * next
BezTriple * bezt
BPoint * bp
struct PartDeflect * pd
float imat[4][4]
struct SoftBody * soft
float obmat[4][4]
short softflag
void * data
float com[3]
Definition: softbody.c:96
ReferenceVert * ivert
Definition: softbody.c:97
float pos[3]
Definition: softbody.c:91
float mass
Definition: softbody.c:92
float aabbmin[3]
Definition: softbody.c:107
short flag
Definition: softbody.c:104
short needstobuildcollider
Definition: softbody.c:103
int totface
Definition: softbody.c:106
ReferenceState Ref
Definition: softbody.c:108
GHash * colliderhash
Definition: softbody.c:102
float aabbmax[3]
Definition: softbody.c:107
BodyFace * bodyface
Definition: softbody.c:105
ListBase * effectors
Definition: softbody.c:118
struct PhysicsSettings physics_settings
struct RenderData r
struct PointCache * pointcache
struct ListBase ptcaches
float lscale[3][3]
float lrot[3][3]
SBVertex ** keys
struct SoftBody_Shared * shared
struct Collection * collision_group
struct EffectorWeights * effector_weights
char namedVG_Spring_K[64]
struct BodySpring * bspring
struct SBScratch * scratch
struct BodyPoint * bpoint
const MVert * mprevvert
Definition: softbody.c:259
int safety
Definition: softbody.c:261
const MVert * mvert
Definition: softbody.c:258
int tri_num
Definition: softbody.c:257
const MVertTri * tri
Definition: softbody.c:260
ccdf_minmax * mima
Definition: softbody.c:262
float bbmin[3]
Definition: softbody.c:264
int mvert_num
Definition: softbody.c:257
float bbmax[3]
Definition: softbody.c:265
float maxx
Definition: softbody.c:253
float minx
Definition: softbody.c:253
float maxy
Definition: softbody.c:253
float miny
Definition: softbody.c:253
float minz
Definition: softbody.c:253
float maxz
Definition: softbody.c:253
double PIL_check_seconds_timer(void)
Definition: time.c:64
float max
static FT_Error err