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