129#define MID_PRESERVE 1
131#define SOFTGOALSNAP 0.999f
135#define HEUNWARNLIMIT 1
137#define BSF_INTERSECT 1
141#define SBF_OUTOFCOLLISION 2
143#define BFF_INTERSECT 1
144#define BFF_CLOSEVERT 2
216 if (bp->
goal < 0.0f) {
421 mima->minx = mima->miny = mima->minz = 1e30f;
422 mima->maxx = mima->maxy = mima->maxz = -1e30f;
425 v = pccd_M->vert_positions[pccd_M->vert_tris[i][0]];
426 mima->minx = min_ff(mima->minx, v[0] - hull);
427 mima->miny = min_ff(mima->miny, v[1] - hull);
428 mima->minz = min_ff(mima->minz, v[2] - hull);
429 mima->maxx = max_ff(mima->maxx, v[0] + hull);
430 mima->maxy = max_ff(mima->maxy, v[1] + hull);
431 mima->maxz = max_ff(mima->maxz, v[2] + hull);
433 v = pccd_M->vert_positions[pccd_M->vert_tris[i][1]];
434 mima->minx = min_ff(mima->minx, v[0] - hull);
435 mima->miny = min_ff(mima->miny, v[1] - hull);
436 mima->minz = min_ff(mima->minz, v[2] - hull);
437 mima->maxx = max_ff(mima->maxx, v[0] + hull);
438 mima->maxy = max_ff(mima->maxy, v[1] + hull);
439 mima->maxz = max_ff(mima->maxz, v[2] + hull);
441 v = pccd_M->vert_positions[pccd_M->vert_tris[i][2]];
442 mima->minx = min_ff(mima->minx, v[0] - hull);
443 mima->miny = min_ff(mima->miny, v[1] - hull);
444 mima->minz = min_ff(mima->minz, v[2] - hull);
445 mima->maxx = max_ff(mima->maxx, v[0] + hull);
446 mima->maxy = max_ff(mima->maxy, v[1] + hull);
447 mima->maxz = max_ff(mima->maxz, v[2] + hull);
450 v = pccd_M->vert_positions_prev[pccd_M->vert_tris[i][0]];
451 mima->minx = min_ff(mima->minx, v[0] - hull);
452 mima->miny = min_ff(mima->miny, v[1] - hull);
453 mima->minz = min_ff(mima->minz, v[2] - hull);
454 mima->maxx = max_ff(mima->maxx, v[0] + hull);
455 mima->maxy = max_ff(mima->maxy, v[1] + hull);
456 mima->maxz = max_ff(mima->maxz, v[2] + hull);
458 v = pccd_M->vert_positions_prev[pccd_M->vert_tris[i][1]];
459 mima->minx = min_ff(mima->minx, v[0] - hull);
460 mima->miny = min_ff(mima->miny, v[1] - hull);
461 mima->minz = min_ff(mima->minz, v[2] - hull);
462 mima->maxx = max_ff(mima->maxx, v[0] + hull);
463 mima->maxy = max_ff(mima->maxy, v[1] + hull);
464 mima->maxz = max_ff(mima->maxz, v[2] + hull);
466 v = pccd_M->vert_positions_prev[pccd_M->vert_tris[i][2]];
467 mima->minx = min_ff(mima->minx, v[0] - hull);
468 mima->miny = min_ff(mima->miny, v[1] - hull);
469 mima->minz = min_ff(mima->minz, v[2] - hull);
470 mima->maxx = max_ff(mima->maxx, v[0] + hull);
471 mima->maxy = max_ff(mima->maxy, v[1] + hull);
472 mima->maxz = max_ff(mima->maxz, v[2] + hull);
518 for (
int i = 0;
i < numobjects;
i++) {
547 if ((!
hash) || (!vertexowner)) {
555 for (
int i = 0;
i < numobjects;
i++) {
572 for (
const int i :
faces.index_range()) {
601 for (
int a = 0; a < mesh->
faces_num; a++) {
602 const int poly_size =
faces[a].size();
603 if (poly_size == 4) {
604 bs->
v1 = corner_verts[
faces[a].start() + 0];
605 bs->
v2 = corner_verts[
faces[a].start() + 2];
608 bs->
v1 = corner_verts[
faces[a].start() + 1];
609 bs->
v2 = corner_verts[
faces[a].start() + 3];
627 int a,
b, c, notthis = 0, v0;
660 if ((bs2->
v1 != notthis) && (bs2->
v1 > v0)) {
669 if ((bs2->
v2 != notthis) && (bs2->
v2 > v0)) {
689 stiffness *= stiffness;
765 int a,
b, akku_count;
789 if (akku_count > 0) {
818 if (ob->
soft ==
nullptr) {
837 for (
i = 0;
i < totpoint;
i++) {
869 for (k = 0; k < sb->
totkey; k++) {
870 key = *(sb->
keys + k);
968 return (numobjects != 0);
979 float aabbmin[3], aabbmax[3];
985 if ((sb ==
nullptr) || (sb->
scratch ==
nullptr)) {
1001 if ((aabbmax[0] < ccdm->
bbmin[0]) || (aabbmax[1] < ccdm->
bbmin[1]) ||
1002 (aabbmax[2] < ccdm->
bbmin[2]) || (aabbmin[0] > ccdm->
bbmax[0]) ||
1003 (aabbmin[1] > ccdm->
bbmax[1]) || (aabbmin[2] > ccdm->
bbmax[2]))
1031 const float face_v2[3],
1032 const float face_v3[3],
1041 float nv1[3], edge1[3], edge2[3], d_nvect[3], aabbmin[3], aabbmax[3];
1042 float facedist, outerfacethickness, tune = 10.0f;
1043 int a, deflected = 0;
1045 aabbmin[0] =
min_fff(face_v1[0], face_v2[0], face_v3[0]);
1046 aabbmin[1] =
min_fff(face_v1[1], face_v2[1], face_v3[1]);
1047 aabbmin[2] =
min_fff(face_v1[2], face_v2[2], face_v3[2]);
1048 aabbmax[0] =
max_fff(face_v1[0], face_v2[0], face_v3[0]);
1049 aabbmax[1] =
max_fff(face_v1[1], face_v2[1], face_v3[1]);
1050 aabbmax[2] =
max_fff(face_v1[2], face_v2[2], face_v3[2]);
1067 const float (*vert_positions)[3] =
nullptr;
1068 const float (*vert_positions_prev)[3] =
nullptr;
1074 if ((aabbmax[0] < ccdm->
bbmin[0]) || (aabbmax[1] < ccdm->
bbmin[1]) ||
1075 (aabbmax[2] < ccdm->
bbmin[2]) || (aabbmin[0] > ccdm->
bbmax[0]) ||
1076 (aabbmin[1] > ccdm->
bbmax[1]) || (aabbmin[2] > ccdm->
bbmax[2]))
1091 if (vert_positions) {
1094 if (vert_positions_prev) {
1096 madd_v3_v3fl(nv1, vert_positions_prev[a - 1], 1.0f - time);
1101 if (
fabsf(facedist) < outerfacethickness) {
1105 df = (outerfacethickness - facedist) / outerfacethickness;
1108 df = (outerfacethickness + facedist) / outerfacethickness;
1113 df = 0.01f *
expf(-100.0f * df);
1130 const float face_v2[3],
1131 const float face_v3[3],
1140 float nv1[3], nv2[3], nv3[3], edge1[3], edge2[3], d_nvect[3], aabbmin[3], aabbmax[3];
1141 float t, tune = 10.0f;
1142 int a, deflected = 0;
1144 aabbmin[0] =
min_fff(face_v1[0], face_v2[0], face_v3[0]);
1145 aabbmin[1] =
min_fff(face_v1[1], face_v2[1], face_v3[1]);
1146 aabbmin[2] =
min_fff(face_v1[2], face_v2[2], face_v3[2]);
1147 aabbmax[0] =
max_fff(face_v1[0], face_v2[0], face_v3[0]);
1148 aabbmax[1] =
max_fff(face_v1[1], face_v2[1], face_v3[1]);
1149 aabbmax[2] =
max_fff(face_v1[2], face_v2[2], face_v3[2]);
1160 const float (*vert_positions)[3] =
nullptr;
1161 const float (*vert_positions_prev)[3] =
nullptr;
1172 if ((aabbmax[0] < ccdm->
bbmin[0]) || (aabbmax[1] < ccdm->
bbmin[1]) ||
1173 (aabbmax[2] < ccdm->
bbmin[2]) || (aabbmin[0] > ccdm->
bbmax[0]) ||
1174 (aabbmin[1] > ccdm->
bbmax[1]) || (aabbmin[2] > ccdm->
bbmax[2]))
1190 if ((aabbmax[0] < mima->
minx) || (aabbmin[0] > mima->
maxx) ||
1191 (aabbmax[1] < mima->
miny) || (aabbmin[1] > mima->
maxy) ||
1192 (aabbmax[2] < mima->
minz) || (aabbmin[2] > mima->
maxz))
1199 if (vert_positions) {
1205 if (vert_positions_prev) {
1207 madd_v3_v3fl(nv1, vert_positions_prev[(*vt)[0]], 1.0f - time);
1210 madd_v3_v3fl(nv2, vert_positions_prev[(*vt)[1]], 1.0f - time);
1213 madd_v3_v3fl(nv3, vert_positions_prev[(*vt)[2]], 1.0f - time);
1246 float damp = 0.0f, choke = 1.0f;
1247 float tune = -10.0f;
1314 const float edge_v2[3],
1323 float nv1[3], nv2[3], nv3[3], edge1[3], edge2[3], d_nvect[3], aabbmin[3], aabbmax[3];
1325 int a, deflected = 0;
1341 const float (*vert_positions)[3] =
nullptr;
1342 const float (*vert_positions_prev)[3] =
nullptr;
1353 if ((aabbmax[0] < ccdm->
bbmin[0]) || (aabbmax[1] < ccdm->
bbmin[1]) ||
1354 (aabbmax[2] < ccdm->
bbmin[2]) || (aabbmin[0] > ccdm->
bbmax[0]) ||
1355 (aabbmin[1] > ccdm->
bbmax[1]) || (aabbmin[2] > ccdm->
bbmax[2]))
1371 if ((aabbmax[0] < mima->
minx) || (aabbmin[0] > mima->
maxx) ||
1372 (aabbmax[1] < mima->
miny) || (aabbmin[1] > mima->
maxy) ||
1373 (aabbmax[2] < mima->
minz) || (aabbmin[2] > mima->
maxz))
1380 if (vert_positions) {
1386 if (vert_positions_prev) {
1388 madd_v3_v3fl(nv1, vert_positions_prev[(*vt)[0]], 1.0f - time);
1391 madd_v3_v3fl(nv2, vert_positions_prev[(*vt)[1]], 1.0f - time);
1394 madd_v3_v3fl(nv3, vert_positions_prev[(*vt)[2]], 1.0f - time);
1406 float intrusiondepth, i1, i2;
1411 intrusiondepth = -
min_ff(i1, i2) / el;
1437 for (a = ifirst; a < ilast; a++) {
1440 feedback[0] = feedback[1] = feedback[2] = 0.0f;
1460 float vel[3], sp[3], pr[3], force[3];
1461 float f, windfactor = 0.25f;
1465 float speed[3] = {0.0f, 0.0f, 0.0f};
1481 f = -0.0001f * f * f * sb->
aeroedge;
1516 int *ptr_to_break_func(
void))
1521 int i, totthread,
left, dec;
1525 int lowsprings = 100;
1533 while ((totsprings / totthread < lowsprings) && (totthread > 1)) {
1539 dec = totsprings / totthread + 1;
1540 for (
i = 0;
i < totthread;
i++) {
1541 sb_threads[
i].
scene = scene;
1542 sb_threads[
i].
ob = ob;
1557 sb_threads[
i].
nr =
i;
1558 sb_threads[
i].
tot = totthread;
1560 if (totthread > 1) {
1563 for (
i = 0;
i < totthread;
i++) {
1581 float *
w,
float *
pos,
float *a,
float *
b,
float *c,
float *ca,
float *cb,
float *cc)
1612 float facenormal[3],
1623 float nv1[3], nv2[3], nv3[3], edge1[3], edge2[3], d_nvect[3], dv1[3], ve[3],
1624 avel[3] = {0.0, 0.0, 0.0}, vv1[3], vv2[3], vv3[3], coledge[3] = {0.0f, 0.0f, 0.0f},
1625 mindistedge = 1000.0f, outerforceaccu[3], innerforceaccu[3], facedist,
1626 force_mag_norm, minx, miny, minz, maxx, maxy, maxz,
1627 innerfacethickness = -0.5f, outerfacethickness = 0.2f, ee = 5.0f, ff = 0.1f, fa = 1;
1628 int a, deflected = 0, cavel = 0, ci = 0;
1633 outerforceaccu[0] = outerforceaccu[1] = outerforceaccu[2] = 0.0f;
1634 innerforceaccu[0] = innerforceaccu[1] = innerforceaccu[2] = 0.0f;
1643 const float (*vert_positions)[3] =
nullptr;
1644 const float (*vert_positions_prev)[3] =
nullptr;
1655 minx = ccdm->
bbmin[0];
1656 miny = ccdm->
bbmin[1];
1657 minz = ccdm->
bbmin[2];
1659 maxx = ccdm->
bbmax[0];
1660 maxy = ccdm->
bbmax[1];
1661 maxz = ccdm->
bbmax[2];
1663 if ((opco[0] < minx) || (opco[1] < miny) || (opco[2] < minz) || (opco[0] > maxx) ||
1664 (opco[1] > maxy) || (opco[2] > maxz))
1682 fa = (ff * outerfacethickness - outerfacethickness);
1685 avel[0] = avel[1] = avel[2] = 0.0f;
1688 if ((opco[0] < mima->
minx) || (opco[0] > mima->
maxx) || (opco[1] < mima->
miny) ||
1689 (opco[1] > mima->
maxy) || (opco[2] < mima->
minz) || (opco[2] > mima->
maxz))
1696 if (vert_positions) {
1702 if (vert_positions_prev) {
1708 sub_v3_v3v3(vv1, nv1, vert_positions_prev[(*vt)[0]]);
1709 sub_v3_v3v3(vv2, nv2, vert_positions_prev[(*vt)[1]]);
1710 sub_v3_v3v3(vv3, nv3, vert_positions_prev[(*vt)[2]]);
1713 madd_v3_v3fl(nv1, vert_positions_prev[(*vt)[0]], 1.0f - time);
1716 madd_v3_v3fl(nv2, vert_positions_prev[(*vt)[1]], 1.0f - time);
1719 madd_v3_v3fl(nv3, vert_positions_prev[(*vt)[2]], 1.0f - time);
1734 if ((facedist > innerfacethickness) && (facedist < outerfacethickness)) {
1736 force_mag_norm =
float(
exp(
double(-ee * facedist)));
1737 if (facedist > outerfacethickness * ff) {
1738 force_mag_norm = force_mag_norm * fa * (facedist - outerfacethickness) *
1739 (facedist - outerfacethickness);
1742 if (facedist > 0.0f) {
1743 *damp *= (1.0f - facedist / outerfacethickness);
1749 deflected = std::max(deflected, 2);
1751 if ((vert_positions_prev) && (*damp > 0.0f)) {
1756 *intrusion += facedist;
1769 if (deflected == 1) {
1770 force_mag_norm =
float(
exp(
double() - ee * mindistedge));
1771 if (mindistedge > outerfacethickness * ff) {
1772 force_mag_norm = force_mag_norm * fa * (mindistedge - outerfacethickness) *
1773 (mindistedge - outerfacethickness);
1777 if (mindistedge > 0.0f) {
1778 *damp *= (1.0f - mindistedge / outerfacethickness);
1781 if (deflected == 2) {
1784 if (deflected == 3) {
1816 s_actpos, facenormal, cf, force, ob, time, vel, intrusion);
1818 deflected = sb_detect_vertex_collisionCachedEx(
1819 s_actpos, facenormal, cf, force, ob, time, vel, intrusion);
1826static void dfdx_spring(
int ia,
int ic,
int op,
float dir[3],
float L,
float len,
float factor)
1831 for (
i = 0;
i < 3;
i++) {
1832 for (j = 0; j < 3; j++) {
1833 delta_ij = (
i == j ? (1.0f) : (0.0f));
1834 m = factor * (dir[
i] * dir[j] + (1 -
L /
len) * (delta_ij - dir[
i] * dir[j]));
1840 for (
i = 0;
i < 3;
i++) {
1841 for (j = 0; j < 3; j++) {
1842 m = factor * dir[
i] * dir[j];
1849static void dfdx_goal(
int ia,
int ic,
int op,
float factor)
1852 for (
i = 0;
i < 3;
i++) {
1857static void dfdv_goal(
int ia,
int ic,
float factor)
1860 for (
i = 0;
i < 3;
i++) {
1871 float dir[3], dvel[3];
1872 float distance, forcefactor, kd, absvel, projvel, kw;
1877 if (bpi == bs->
v1) {
1885 else if (bpi == bs->
v2) {
1895 CLOG_WARN(&
LOG,
"bodypoint <bpi> is not attached to spring <*bs>");
1903 iks = 1.0f / (1.0f - sb->
inspring) - 1.0f;
1906 iks = 1.0f / (1.0f - sb->
inpush) - 1.0f;
1909 if (bs->
len > 0.0f) {
1910 forcefactor = iks / bs->
len;
1940 kd *= absvel * projvel;
1953 int *ptr_to_break_func(
void),
1961 int bb, do_selfcollision, do_springcollision, do_aero;
1962 int number_of_points_here = ilast - ifirst;
1989 bp = &sb->
bpoint[ifirst];
1990 for (bb = number_of_points_here; bb > 0; bb--, bp++) {
1995 if (do_selfcollision) {
2000 float velcenter[3], dvel[3], def[3];
2012 if ((
fabsf(def[0]) > compare) || (
fabsf(def[1]) > compare) || (
fabsf(def[2]) > compare)) {
2021 if (
ELEM(ilast - bb, bs->
v2, bs->
v1)) {
2028 2.0f * bstune / compare;
2052 bp->
force[0] += -ks * (auxvect[0]);
2053 bp->
force[1] += -ks * (auxvect[1]);
2054 bp->
force[2] += -ks * (auxvect[2]);
2062 if (forcetime > 0.0f) {
2063 bp->
force[0] -= kd * (auxvect[0]);
2064 bp->
force[1] -= kd * (auxvect[1]);
2065 bp->
force[2] -= kd * (auxvect[2]);
2068 bp->
force[0] -= kd * (velgoal[0] - bp->
vec[0]);
2069 bp->
force[1] -= kd * (velgoal[1] - bp->
vec[1]);
2070 bp->
force[2] -= kd * (velgoal[2] - bp->
vec[2]);
2092 float force[3] = {0.0f, 0.0f, 0.0f};
2093 float speed[3] = {0.0f, 0.0f, 0.0f};
2103 mul_v3_fl(force, fieldfactor * eval_sb_fric_force_scale);
2107 kd = sb->
mediafrict * eval_sb_fric_force_scale;
2108 bp->
force[0] -= kd * (bp->
vec[0] + windfactor * speed[0] / eval_sb_fric_force_scale);
2109 bp->
force[1] -= kd * (bp->
vec[1] + windfactor * speed[1] / eval_sb_fric_force_scale);
2110 bp->
force[2] -= kd * (bp->
vec[2] + windfactor * speed[2] / eval_sb_fric_force_scale);
2127 float cfforce[3], defforce[3] = {0.0f, 0.0f, 0.0f}, vel[3] = {0.0f, 0.0f, 0.0f},
2128 facenormal[3], cf = 1.0f, intrusion;
2131 if (
sb_deflect_face(ob, bp->
pos, facenormal, defforce, &cf, timenow, vel, &intrusion)) {
2132 if (intrusion < 0.0f) {
2147 iks = 1.0f / (1.0f - sb->
inspring) - 1.0f;
2154 if (do_springcollision || do_aero) {
2193 int *ptr_to_break_func(
void),
2202 int i, totthread,
left, dec;
2206 int lowpoints = 100;
2211 while ((totpoint / totthread < lowpoints) && (totthread > 1)) {
2219 dec = totpoint / totthread + 1;
2220 for (
i = 0;
i < totthread;
i++) {
2221 sb_threads[
i].
scene = scene;
2222 sb_threads[
i].
ob = ob;
2237 sb_threads[
i].
nr =
i;
2238 sb_threads[
i].
tot = totthread;
2241 if (totthread > 1) {
2244 for (
i = 0;
i < totthread;
i++) {
2267 float fieldfactor = -1.0f, windfactor = 0.25;
2268 int do_deflector , do_springcollision, do_aero;
2285 if (do_springcollision || do_aero) {
2324 float dx[3] = {0}, dv[3], aabbmin[3], aabbmax[3], cm[3] = {0.0f, 0.0f, 0.0f};
2325 float timeovermass ;
2326 float maxerrpos = 0.0f, maxerrvel = 0.0f;
2331 aabbmin[0] = aabbmin[1] = aabbmin[2] = 1e20f;
2332 aabbmax[0] = aabbmax[1] = aabbmax[2] = -1e20f;
2338 timeovermass = forcetime / sb->
nodemass;
2341 timeovermass = forcetime / 0.009999f;
2352 timeovermass = forcetime / 0.009999f;
2439 if (bp->
choke > 0.0f) {
2464 *err =
max_ff(maxerrpos, maxerrvel);
2490static void softbody_store_step(
Object *ob)
2503static void softbody_store_state(
Object *ob,
float *ppos,
float *pvel)
2508 float *pp = ppos, *pv = pvel;
2521static void softbody_retrieve_state(
Object *ob,
float *ppos,
float *pvel)
2526 float *pp = ppos, *pv = pvel;
2539static void softbody_swap_state(
Object *ob,
float *ppos,
float *pvel)
2544 float *pp = ppos, *pv = pvel;
2599 if ((r > 1.05f) || (r < 0.95f)) {
2600 bs->
len = ((100.0f -
b) * bs->
len +
b *
l) / 100.0f;
2653 for (a = 0; a < mesh->
verts_num; a++, bp++) {
2678 int defgroup_index, defgroup_index_mass, defgroup_index_spring;
2694 const MDeformVert *dvert = mesh->deform_verts().data();
2696 defgroup_index = dvert ? (sb->
vertgroup - 1) : -1;
2700 for (a = 0; a < mesh->
verts_num; a++, bp++) {
2718 if (defgroup_index_mass != -1) {
2722 if (defgroup_index_spring != -1) {
2760 const Mesh *mesh =
static_cast<const Mesh *
>(ob->
data);
2770 mesh->vert_positions(), mesh->faces(), mesh->corner_verts(), corner_tris);
2776 bodyface->
v1 = corner_verts[corner_tris[a][0]];
2777 bodyface->
v2 = corner_verts[corner_tris[a][1]];
2778 bodyface->
v3 = corner_verts[corner_tris[a][2]];
2789 float accu_pos[3] = {0.0f, 0.0f, 0.0f};
2790 float accu_mass = 0.0f;
2796 for (a = 0; a < sb->
totpoint; a++, rp++, bp++) {
2814 mul_m4_v3(ob->object_to_world().ptr(), p1);
2816 mul_m4_v3(ob->object_to_world().ptr(), p2);
2823 int u,
v,
w, dv, dw, bpc = 0, bpuc;
2826 dw = dv * lt->
pntsv;
2832 for (u = 0, bpuc = 0, bpu =
nullptr; u < lt->
pntsu; u++, bp++, bpc++) {
2861 bs->
v2 = bpc - dw - dv - 1;
2863 bs->
len =
globallen((bp - dw - dv - 1)->vec, bp->vec, ob);
2866 if ((
v < lt->pntsv - 1) && (u != 0)) {
2868 bs->
v2 = bpc - dw + dv - 1;
2870 bs->
len =
globallen((bp - dw + dv - 1)->vec, bp->vec, ob);
2878 bs->
v2 = bpc + dw - dv - 1;
2880 bs->
len =
globallen((bp + dw - dv - 1)->vec, bp->vec, ob);
2883 if ((
v < lt->pntsv - 1) && (u != 0)) {
2885 bs->
v2 = bpc + dw + dv - 1;
2887 bs->
len =
globallen((bp + dw + dv - 1)->vec, bp->vec, ob);
2904 int totvert, totspring = 0, a;
2907 int defgroup_index, defgroup_index_mass, defgroup_index_spring;
2930 for (a = 0; a < totvert; a++, bp++, bpnt++) {
2943 if (defgroup_index_mass != -1) {
2947 if (defgroup_index_spring != -1) {
2971 int a, curindex = 0;
2972 int totvert, totspring = 0, setgoal = 0;
3008 for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++, bp += 3, curindex += 3) {
3013 (bp + 1)->goal = bp->
goal;
3014 (bp + 2)->goal = bp->
goal;
3022 bs->
v1 = curindex - 3;
3029 bs->
v2 = curindex + 1;
3034 bs->
v1 = curindex + 1;
3035 bs->
v2 = curindex + 2;
3043 for (bpnt = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bpnt++, bp++, curindex++) {
3047 if (totspring && a > 0) {
3048 bs->
v1 = curindex - 1;
3079 for (a = 0; a < numVerts; a++, bp++) {
3083 mul_m4_v3(ob->world_to_object().ptr(), vertexCos[a]);
3162 if (sb ==
nullptr) {
3199 return ((
Mesh *)ob->
data)->edges_num;
3215 float (*vertexCos)[3],
3221 if (!sb || !sb->
bpoint) {
3225 for (a = 0, bp = sb->
bpoint; a < numVerts; a++, bp++) {
3245 float com[3], rcom[3];
3248 if (!ob || !ob->
soft) {
3252 if (!sb || !sb->
bpoint) {
3264 sb->
totpoint, opos,
nullptr, rpos,
nullptr, com, rcom, lrot, lscale);
3286 for (a = 0, bp = sb->
bpoint; a < numVerts; a++, bp++) {
3292 bp->
vec[0] = bp->
vec[1] = bp->
vec[2] = 0.0f;
3355 if (dtime < 0 || dtime > 10.5f) {
3371 float forcetimemax = 1.0f;
3373 float forcetimemin = 0.01f;
3375 float timedone = 0.0;
3382 forcetimemax = dtime / sb->
minloops;
3385 forcetimemin = dtime / sb->
maxloops;
3392 forcetime = forcetimemax;
3393 while ((
fabsf(timedone) <
fabsf(dtime)) && (loops < 2000)) {
3411 if (forcetime > forcetimemin) {
3412 forcetime =
max_ff(forcetime / 2.0f, forcetimemin);
3417 timedone += forcetime;
3421 float newtime = forcetime * 1.1f;
3426 newtime = forcetime;
3431 newtime = forcetime;
3434 timedone += forcetime;
3435 newtime =
min_ff(forcetimemax,
max_ff(newtime, forcetimemin));
3437 if (forcetime > 0.0f) {
3438 forcetime =
min_ff(dtime - timedone, newtime);
3441 forcetime =
max_ff(dtime - timedone, newtime);
3447 if (sct - sst > 0.5) {
3448 printf(
"%3.0f%% \r", 100.0f * timedone / dtime);
3463 printf(
"\r needed %d steps/frame", loops);
3488 if ((sct - sst > 0.5) || (
G.debug &
G_DEBUG)) {
3489 printf(
" solver time %f sec %s\n", sct - sst, ob->
id.
name);
3500 object->soft->last_frame = framenr;
3508 float (*vertexCos)[3],
3514 float dtime, timescale;
3515 int framedelta, framenr, startframe, endframe;
3519 framenr = int(cfra);
3520 framedelta = framenr - cache->
simframe;
3533 if (framenr < startframe) {
3537 framenr = std::min(framenr, endframe);
3540 if (sb->
bpoint ==
nullptr ||
3568 if (framenr == startframe) {
3616 if (can_write_cache) {
3622 if (!can_simulate) {
3635 dtime = framedelta * timescale;
void BKE_collision_objects_free(struct Object **objects)
struct Object ** BKE_collision_objects_create(struct Depsgraph *depsgraph, struct Object *self, struct Collection *collection, unsigned int *numcollobj, unsigned int modifier_type)
int BKE_nurbList_verts_count(const ListBase *nurb)
CustomData interface, see also DNA_customdata_types.h.
struct EffectorWeights * BKE_effector_add_weights(struct Collection *collection)
void BKE_effectors_free(struct ListBase *lb)
void BKE_effectors_apply(struct ListBase *effectors, struct ListBase *colliders, struct EffectorWeights *weights, struct EffectedPoint *point, float *force, float *wind_force, float *impulse)
void pd_point_from_soft(struct Scene *scene, float *loc, float *vel, int index, struct EffectedPoint *point)
struct ListBase * BKE_effectors_create(struct Depsgraph *depsgraph, struct Object *ob_src, struct ParticleSystem *psys_src, struct EffectorWeights *weights, bool use_rotation)
ModifierData * BKE_modifiers_findby_type(const Object *ob, ModifierType type)
void BKE_ptcache_id_time(PTCacheID *pid, struct Scene *scene, float cfra, int *startframe, int *endframe, float *timescale)
void BKE_ptcache_validate(struct PointCache *cache, int framenr)
void BKE_ptcache_id_from_softbody(PTCacheID *pid, struct Object *ob, struct SoftBody *sb)
struct PointCache * BKE_ptcache_add(struct ListBase *ptcaches)
#define PTCACHE_READ_INTERPOLATED
int BKE_ptcache_read(PTCacheID *pid, float cfra, bool no_extrapolate_old)
int BKE_ptcache_write(PTCacheID *pid, unsigned int cfra)
void BKE_ptcache_free_list(struct ListBase *ptcaches)
#define PTCACHE_RESET_OUTDATED
int BKE_ptcache_id_reset(struct Scene *scene, PTCacheID *pid, int mode)
void BKE_ptcache_invalidate(struct PointCache *cache)
#define PTCACHE_READ_EXACT
int BKE_scene_num_threads(const Scene *scene)
BLI_INLINE void * BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
void BLI_ghashIterator_step(GHashIterator *ghi)
void BLI_ghashIterator_free(GHashIterator *ghi)
BLI_INLINE void * BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
GHashIterator * BLI_ghashIterator_new(GHash *gh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void(* GHashValFreeFP)(void *val)
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val) ATTR_WARN_UNUSED_RESULT
BLI_INLINE bool BLI_ghashIterator_done(const GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
#define LISTBASE_FOREACH(type, var, list)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float max_fff(float a, float b, float c)
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
MINLINE float min_fff(float a, float b, float c)
MINLINE int poly_to_tri_count(int poly_count, int corner_count)
void vcloud_estimate_transform_v3(int list_size, const float(*pos)[3], const float *weight, const float(*rpos)[3], const float *rweight, float lloc[3], float rloc[3], float lrot[3][3], float lscale[3][3])
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])
bool isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3])
void copy_m3_m3(float m1[3][3], const float m2[3][3])
void unit_m3(float m[3][3])
void mul_m4_v3(const float M[4][4], float r[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
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])
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
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])
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])
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
void BLI_threadpool_init(struct ListBase *threadbase, void *(*do_thread)(void *), int tot)
void BLI_threadpool_end(struct ListBase *threadbase)
void BLI_threadpool_insert(struct ListBase *threadbase, void *callerdata)
Platform independent time functions.
double BLI_time_now_seconds(void)
#define CLOG_ERROR(clg_ref,...)
#define CLOG_WARN(clg_ref,...)
bool DEG_is_active(const Depsgraph *depsgraph)
T * DEG_get_original(T *id)
Object groups, one object can be in many groups at once.
@ eModifierType_Collision
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
#define MEM_recallocN(vmemh, len)
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
BPy_StructRNA * depsgraph
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
constexpr IndexRange index_range() const
constexpr bool is_empty() const
float distance(VecOp< float, D >, VecOp< float, D >) RET
BLI_INLINE void dfdx_spring(float to[3][3], const float dir[3], float length, float L, float k)
void EIG_linear_solver_matrix_add(LinearSolver *solver, int row, int col, double value)
void * MEM_mallocN(size_t len, const char *str)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_callocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
void corner_tris_calc(Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, MutableSpan< int3 > corner_tris)
VecBase< int32_t, 3 > int3
static void add_mesh_quad_diag_springs(Object *ob)
static int query_external_colliders(Depsgraph *depsgraph, Collection *collection)
static ccd_Mesh * ccd_mesh_make(Object *ob)
#define SBF_OUTOFCOLLISION
static int sb_deflect_face(Object *ob, float *actpos, float *facenormal, float *force, float *cf, float time, float *vel, float *intrusion)
static void sbStoreLastFrame(Depsgraph *depsgraph, Object *object, float framenr)
static void ccd_mesh_free(ccd_Mesh *ccdm)
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], Object *vertexowner, float time)
static void * exec_softbody_calc_forces(void *data)
static float _final_mass(Object *ob, BodyPoint *bp)
static void mesh_faces_to_scratch(Object *ob)
static void springs_from_mesh(Object *ob)
static float _final_goal(Object *ob, BodyPoint *bp)
void sbObjectToSoftbody(Object *ob)
static void ccd_build_deflector_hash_single(GHash *hash, Object *ob)
static void softbody_restore_prev_step(Object *ob)
static void sb_sfesf_threads_run(Depsgraph *depsgraph, Scene *scene, Object *ob, float timenow, int totsprings, int *ptr_to_break_func(void))
static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float timenow, int totpoint, int *ptr_to_break_func(void), ListBase *effectors, int do_deflector, float fieldfactor, float windfactor)
void sbSetInterruptCallBack(int(*f)())
static int sb_detect_edge_collisionCached(const float edge_v1[3], const float edge_v2[3], float *damp, float force[3], Object *vertexowner, float time)
static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow, int ifirst, int ilast, ListBase *effectors)
static int(* SB_localInterruptCallBack)()
static void mesh_to_softbody(Object *ob)
static void sb_spring_force(Object *ob, int bpi, BodySpring *bs, float iks, float)
static void curve_surf_to_softbody(Object *ob)
static void softbody_apply_goalsnap(Object *ob)
static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *damp, float force[3], Object *vertexowner, float time, float vel[3], float *intrusion)
static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *err, int mid_flags)
static void ccd_build_deflector_hash(Depsgraph *depsgraph, Collection *collection, Object *vertexowner, GHash *hash)
static void calculate_collision_balls(Object *ob)
static void build_bps_springlist(Object *ob)
static void add_bp_springlist(BodyPoint *bp, int springID)
static const int CCD_SAFETY
static void softbody_reset(Object *ob, SoftBody *sb, float(*vertexCos)[3], int numVerts)
static void renew_softbody(Object *ob, int totpoint, int totspring)
static void softbody_step(Depsgraph *depsgraph, Scene *scene, Object *ob, SoftBody *sb, float dtime)
static float globallen(float *v1, float *v2, Object *ob)
static void softbody_to_object(Object *ob, float(*vertexCos)[3], int numVerts, int local)
static void add_2nd_order_springs(Object *ob, float stiffness)
static void ccd_update_deflector_hash_single(GHash *hash, Object *ob)
static void free_softbody_intern(SoftBody *sb)
static void softbody_calc_forces(Depsgraph *depsgraph, Scene *scene, Object *ob, float forcetime, float timenow)
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], Object *vertexowner, float time)
static void add_2nd_order_roller(Object *ob, float, int *counter, int addsprings)
void sbFreeSimulation(SoftBody *sb)
static int sb_detect_aabb_collisionCached(float[3], Object *vertexowner, float)
static void sb_new_scratch(SoftBody *sb)
static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, float forcetime, float timenow, int ifirst, int ilast, int *ptr_to_break_func(void), ListBase *effectors, int do_deflector, float fieldfactor, float windfactor)
static float sb_time_scale(Object *ob)
static void free_scratch(SoftBody *sb)
static void interpolate_exciter(Object *ob, int timescale, int time)
void SB_estimate_transform(Object *ob, float lloc[3], float lrot[3][3], float lscale[3][3])
void sbObjectStep(Depsgraph *depsgraph, Scene *scene, Object *ob, float cfra, float(*vertexCos)[3], int numVerts)
static int choose_winner(float *w, float *pos, float *a, float *b, float *c, float *ca, float *cb, float *cc)
static float sb_fric_force_scale(Object *)
static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff, Object *ob)
static void reference_to_scratch(Object *ob)
static bool object_has_edges(const Object *ob)
static void free_softbody_baked(SoftBody *sb)
static void lattice_to_softbody(Object *ob)
static void * exec_scan_for_ext_spring_forces(void *data)
static void ccd_update_deflector_hash(Depsgraph *depsgraph, Collection *collection, Object *vertexowner, GHash *hash)
static void scan_for_ext_face_forces(Object *ob, float timenow)
static float sb_grav_force_scale(Object *)
static void apply_spring_memory(Object *ob)
static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
static void softbody_update_positions(Object *ob, SoftBody *sb, float(*vertexCos)[3], int numVerts)
static int count_mesh_quads(Mesh *mesh)
struct MDeformVert * dvert
ObjectRuntimeHandle * runtime
short needstobuildcollider
struct PhysicsSettings physics_settings
struct PointCache * pointcache
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 float(* vert_positions_prev)[3]
const blender::int3 * vert_tris
const float(* vert_positions)[3]