26 : m_softBodySolver(0), m_worldInfo(worldInfo)
41 for (
int i = 0, ni = node_count; i < ni; ++i)
47 n.
m_im = m ? *m++ : 1;
56 : m_worldInfo(worldInfo)
138 const Node* n[] = {node0, node1};
142 if ((l.
m_n[0] == n[0] && l.
m_n[1] == n[1]) ||
143 (l.
m_n[0] == n[1] && l.
m_n[1] == n[0]))
161 for (
int j = 0; j < 3; ++j)
163 if ((f.
m_n[j] == n[0]) ||
164 (f.
m_n[j] == n[1]) ||
170 if (c == 7)
return (
true);
260 n.
m_im = m > 0 ? 1 / m : 0;
294 if ((!bcheckexist) || (!
checkLink(node0, node1)))
381 appendAnchor(node, body, local, disableCollisionBetweenLinkedBodies, influence);
387 if (disableCollisionBetweenLinkedBodies)
482 const bool as_lift = kLF > 0;
483 const bool as_drag = kDG > 0;
484 const bool as_aero = as_lift || as_drag;
516 btScalar tri_area = 0.5f * n.m_area;
518 fDrag = 0.5f * kDG * medium.
m_density * rel_v2 * tri_area * n_dot_v * (-rel_v_nrm);
522 if (0 < n_dot_v && n_dot_v < 0.98480f)
523 fLift = 0.5f * kLF * medium.
m_density * rel_v_len * tri_area *
btSqrt(1.0f - n_dot_v * n_dot_v) * (nrm.
cross(rel_v_nrm).
cross(rel_v_nrm));
527 btScalar del_v_by_fDrag_len2 = del_v_by_fDrag.length2();
530 if (del_v_by_fDrag_len2 >= v_len2 && del_v_by_fDrag_len2 > 0)
532 btScalar del_v_by_fDrag_len = del_v_by_fDrag.length();
534 fDrag *=
btScalar(0.8) * (v_len / del_v_by_fDrag_len);
550 const btScalar c0 = n.m_area * dvn * rel_v2 / 2;
552 force += nrm * (-c1 * kLF);
569 const bool as_lift = kLF > 0;
570 const bool as_drag = kDG > 0;
571 const bool as_aero = as_lift || as_drag;
604 fDrag = 0.5f * kDG * medium.
m_density * rel_v2 * tri_area * n_dot_v * (-rel_v_nrm);
608 if (0 < n_dot_v && n_dot_v < 0.98480f)
609 fLift = 0.5f * kLF * medium.
m_density * rel_v_len * tri_area *
btSqrt(1.0f - n_dot_v * n_dot_v) * (nrm.
cross(rel_v_nrm).
cross(rel_v_nrm));
614 for (
int j = 0; j < 3; ++j)
623 if (del_v_by_fDrag_len2 >= v_len2 && del_v_by_fDrag_len2 > 0)
627 fDrag *=
btScalar(0.8) * (v_len / del_v_by_fDrag_len);
647 force += nrm * (-c1 * kLF);
689 m_nodes[node].m_im = mass > 0 ? 1 / mass : 0;
727 for (
int j = 0; j < 3; ++j)
766 for (
int j = 0; j < 4; ++j)
789 for (
int j = 0; j < 4; ++j)
893 if (
m_nodes[i].m_im <= 0) tmass += kmass;
967 for (
int i = 0, ni = cluster->
m_nodes.size(); i < ni; ++i)
971 return (com * cluster->
m_imass);
1020 cluster->
m_av += ai;
1060 const unsigned inf = (~(unsigned)0) >> 1;
1061 unsigned* adj =
new unsigned[n * n];
1063 #define IDX(_x_, _y_) ((_y_)*n + (_x_)) 1064 for (j = 0; j < n; ++j)
1066 for (i = 0; i < n; ++i)
1070 adj[
IDX(i, j)] = adj[
IDX(j, i)] = inf;
1074 adj[
IDX(i, j)] = adj[
IDX(j, i)] = 0;
1082 adj[
IDX(ia, ib)] = 1;
1083 adj[
IDX(ib, ia)] = 1;
1104 for (
int ii = 0; ii < nodeLinks.
size(); ii++)
1108 for (
int jj = 0; jj < nodeLinks[ii].m_links.
size(); jj++)
1110 int k = nodeLinks[ii].m_links[jj];
1111 for (
int kk = 0; kk < nodeLinks[k].m_links.
size(); kk++)
1113 int j = nodeLinks[k].m_links[kk];
1116 const unsigned sum = adj[
IDX(i, k)] + adj[
IDX(k, j)];
1118 if (adj[
IDX(i, j)] >
sum)
1130 for (
int k = 0; k < n; ++k)
1132 for (j = 0; j < n; ++j)
1134 for (i = j + 1; i < n; ++i)
1136 const unsigned sum = adj[
IDX(i, k)] + adj[
IDX(k, j)];
1137 if (adj[
IDX(i, j)] >
sum)
1148 for (j = 0; j < n; ++j)
1150 for (i = j + 1; i < n; ++i)
1152 if (adj[
IDX(i, j)] == (
unsigned)distance)
1169 unsigned long seed = 243703;
1170 #define NEXTRAND (seed = (1664525L * seed + 1013904223L) & 0xffffffff) 1231 const btScalar w = 2 - btMin<btScalar>(1, iterations / slope);
1236 for (i = 0; i < k; ++i)
1246 c = centers[i] + (c - centers[i]) * w;
1247 changed |= ((c - centers[i]).length2() >
SIMD_EPSILON);
1257 for (
int j = 1; j < k; ++j)
1268 }
while (changed && (iterations < maxiterations));
1284 for (
int j = 0; j < 3; ++j)
1286 const int cid = cids[idx[j]];
1287 for (
int q = 1; q < 3; ++q)
1289 const int kid = idx[(j + q) % 3];
1290 if (cids[kid] != cid)
1332 for (
int j = 0; j < 4; j++)
1349 for (
int j = 0; j < 3; ++j)
1370 bool connected =
false;
1373 for (
int i = 0; !connected && i < cla->
m_nodes.size(); i++)
1375 for (
int j = 0; j < clb->
m_nodes.size(); j++)
1420 edges(
int(l.
m_n[0] - nbase),
int(l.
m_n[1] - nbase)) = -1;
1425 edges(
int(f.
m_n[0] - nbase),
int(f.
m_n[1] - nbase)) = -1;
1426 edges(
int(f.
m_n[1] - nbase),
int(f.
m_n[2] - nbase)) = -1;
1427 edges(
int(f.
m_n[2] - nbase),
int(f.
m_n[0] - nbase)) = -1;
1430 for (i = 0; i < ncount; ++i)
1432 for (j = i + 1; j < ncount; ++j)
1434 if (edges(i, j) == -1)
1451 const btScalar f = (ma + mb) / (ma + mb + mc);
1452 a.
m_im = 1 / (ma * f);
1453 b.
m_im = 1 / (mb * f);
1485 const int idx[] = {int(feat.
m_n[0] - nbase),
1486 int(feat.
m_n[1] - nbase)};
1487 if ((idx[0] < ncount) && (idx[1] < ncount))
1489 const int ni = edges(idx[0], idx[1]);
1506 const int idx[] = {int(feat.
m_n[0] - nbase),
1507 int(feat.
m_n[1] - nbase),
1508 int(feat.
m_n[2] - nbase)};
1509 for (j = 2, k = 0; k < 3; j = k++)
1511 if ((idx[j] < ncount) && (idx[k] < ncount))
1513 const int ni = edges(idx[j], idx[k]);
1517 const int l = (k + 1) % 3;
1537 const int pcount = ncount;
1540 cnodes.
resize(ncount, 0);
1542 for (i = 0; i < ncount; ++i)
1545 if ((i >= pcount) || (
btFabs(ifn->
Eval(x)) < accurary))
1563 const int id[] = {int(
m_links[i].m_n[0] - nbase),
1564 int(
m_links[i].m_n[1] - nbase)};
1566 if (cnodes[
id[0]] && cnodes[
id[1]])
1573 if (((ifn->
Eval(
m_nodes[
id[0]].m_x) < accurary) &&
1580 for (
int j = 0; j < 2; ++j)
1582 int cn = cnodes[int(l.
m_n[j] - nbase)];
1591 if ((ifn->
Eval(n[0]->
m_x) < accurary) &&
1592 (ifn->
Eval(n[1]->
m_x) < accurary) &&
1593 (ifn->
Eval(n[2]->
m_x) < accurary))
1595 for (
int j = 0; j < 3; ++j)
1597 int cn = cnodes[int(n[j] - nbase)];
1609 for (
int j = 0; j < 2; ++j) ranks[
int(
m_links[i].m_n[j] - nbase)]++;
1613 for (
int j = 0; j < 3; ++j) ranks[
int(
m_faces[i].m_n[j] - nbase)]++;
1617 const int id[] = {int(
m_links[i].m_n[0] - nbase),
1618 int(
m_links[i].m_n[1] - nbase)};
1619 const bool sg[] = {ranks[
id[0]] == 1,
1631 for(i=nnodes-1;i>=0;--i)
1638 for(
int i=0;i<nnodes;++i) map[i]=i;
1639 PointersToIndices(
this);
1640 for(
int i=0,ni=todelete.
size();i<ni;++i)
1644 int& b=map[--nnodes];
1649 IndicesToPointers(
this,&map[0]);
1687 pft[0]->
m_n[1] = pn[mtch];
1688 pft[1]->
m_n[0] = pn[1 - mtch];
1694 for (
int k = 2, l = 0; l < 3; k = l++)
1701 pft[0]->
m_n[l] = pn[mtch];
1702 pft[1]->
m_n[k] = pn[1 - mtch];
1703 appendLink(pn[0], pft[0]->m_n[(l + 1) % 3], pft[0]->m_material,
true);
1704 appendLink(pn[1], pft[0]->m_n[(l + 1) % 3], pft[0]->m_material,
true);
1726 results.
body =
this;
1795 for (
int c = 0; c < 3; c++)
1797 if (deltaV[c] > clampDeltaV)
1799 deltaV[c] = clampDeltaV;
1801 if (deltaV[c] < -clampDeltaV)
1803 deltaV[c] = -clampDeltaV;
1965 for (
int isolve = 0; isolve < iterations; ++isolve)
1983 const int nb = bodies.
size();
1987 for (i = 0; i < nb; ++i)
1991 for (i = 0; i < nb; ++i)
1993 bodies[i]->prepareClusters(iterations);
1995 for (i = 0; i < iterations; ++i)
1998 for (
int j = 0; j < nb; ++j)
2000 bodies[j]->solveClusters(sor);
2003 for (i = 0; i < nb; ++i)
2005 bodies[i]->cleanupClusters();
2031 const btScalar t = rayFromToTriangle(m_rayFrom, m_rayTo, m_rayNormalizedDirection,
2036 if ((t > 0) && (t < m_mint))
2047 const btVector3& rayNormalizedDirection,
2063 if ((t > teps) && (t < maxt))
2065 const btVector3 hit = rayFrom + rayNormalizedDirection * t;
2080 #define PTR2IDX(_p_, _b_) reinterpret_cast<btSoftBody::Node*>((_p_) - (_b_)) 2088 m_nodes[i].m_leaf->data = *(
void**)&i;
2103 m_faces[i].m_leaf->data = *(
void**)&i;
2112 for (
int j = 0; j <
m_notes[i].m_rank; ++j)
2123 #define IDX2PTR(_p_, _b_) map ? (&(_b_)[map[(((char*)_p_) - (char*)0)]]) : (&(_b_)[(((char*)_p_) - (char*)0)]) 2155 for (
int j = 0; j <
m_notes[i].m_rank; ++j)
2211 int tetfaces[4][3] = {{0, 1, 2}, {0, 1, 3}, {1, 2, 3}, {0, 2, 3}};
2212 for (
int f = 0; f < 4; f++)
2214 int index0 = tetfaces[f][0];
2215 int index1 = tetfaces[f][1];
2216 int index2 = tetfaces[f][2];
2375 Apq[0] = Apq[1] = Apq[2] =
btVector3(0, 0, 0);
2377 Apq[1].setY(eps * 2);
2378 Apq[2].setZ(eps * 3);
2383 Apq[0] += a.
x() * b;
2384 Apq[1] += a.
y() * b;
2385 Apq[2] += a.
z() * b;
2425 for (
int j = 0; j < 3; ++j)
2427 const int index = (int)(f.
m_n[j] - &
m_nodes[0]);
2452 for (
int j = 0; j < 3; ++j)
2460 m_nodes[i].m_area *= 0.3333333f;
2495 for (
int j = 0; j < c.
m_nodes.size(); ++j)
2515 ii[0] = ii[1] = ii[2] =
btVector3(0, 0, 0);
2519 for (i = 0, ni = c.
m_nodes.size(); i < ni; ++i)
2524 ii[0][0] += m * (q[1] + q[2]);
2525 ii[1][1] += m * (q[0] + q[2]);
2526 ii[2][2] += m * (q[0] + q[1]);
2527 ii[0][1] -= m * k[0] * k[1];
2528 ii[0][2] -= m * k[0] * k[2];
2529 ii[1][2] -= m * k[1] * k[2];
2532 ii[1][0] = ii[0][1];
2533 ii[2][0] = ii[0][2];
2534 ii[2][1] = ii[1][2];
2561 const int n = c.
m_nodes.size();
2568 m[0] = m[1] = m[2] =
btVector3(0, 0, 0);
2573 for (
int i = 0; i < c.
m_nodes.size(); ++i)
2595 c.
m_invwi=c.m_xform.getBasis().scaled(iin)*c.m_xform.getBasis().transpose();
2598 for (
int i = 0; i < n; ++i)
2603 c.
m_invwi[0][0] += m * (q[1] + q[2]);
2604 c.
m_invwi[1][1] += m * (q[0] + q[2]);
2605 c.
m_invwi[2][2] += m * (q[0] + q[1]);
2606 c.
m_invwi[0][1] -= m * k[0] * k[1];
2607 c.
m_invwi[0][2] -= m * k[0] * k[2];
2608 c.
m_invwi[1][2] -= m * k[1] * k[2];
2622 for (i = 0; i < n; ++i)
2640 for (
int j = 0; j < c.
m_nodes.size(); ++j)
2652 for (
int j = 1; j < n; ++j)
2732 for (
int j = 0; j < c.
m_nodes.size(); ++j)
2742 for (i = 0; i < deltas.
size(); ++i)
2746 m_nodes[i].m_x += deltas[i] / weights[i];
2761 for (
int j = 0; j < c.
m_nodes.size(); ++j)
2780 m_bodies[0].activate();
2781 m_bodies[1].activate();
2787 static const btScalar maxdrift = 4;
2789 m_rpos[0] = m_bodies[0].xform() * m_refs[0];
2790 m_rpos[1] = m_bodies[1].xform() * m_refs[1];
2791 m_drift =
Clamp(m_rpos[0] - m_rpos[1], maxdrift) * m_erp / dt;
2792 m_rpos[0] -= m_bodies[0].xform().getOrigin();
2793 m_rpos[1] -= m_bodies[1].xform().getOrigin();
2794 m_massmatrix =
ImpulseMatrix(m_bodies[0].invMass(), m_bodies[0].invWorldInertia(), m_rpos[0],
2795 m_bodies[1].invMass(), m_bodies[1].invWorldInertia(), m_rpos[1]);
2798 m_sdrift = m_massmatrix * (m_drift * m_split);
2799 m_drift *= 1 - m_split;
2807 const btVector3 va = m_bodies[0].velocity(m_rpos[0]);
2808 const btVector3 vb = m_bodies[1].velocity(m_rpos[1]);
2812 impulse.
m_velocity = m_massmatrix * (m_drift + vr * m_cfm) * sor;
2813 m_bodies[0].applyImpulse(-impulse, m_rpos[0]);
2814 m_bodies[1].applyImpulse(impulse, m_rpos[1]);
2822 m_bodies[0].applyDImpulse(-m_sdrift, m_rpos[0]);
2823 m_bodies[1].applyDImpulse(m_sdrift, m_rpos[1]);
2831 m_icontrol->Prepare(
this);
2833 m_axis[0] = m_bodies[0].xform().getBasis() * m_refs[0];
2834 m_axis[1] = m_bodies[1].xform().getBasis() * m_refs[1];
2836 m_drift *=
btMin(maxdrift,
btAcos(Clamp<btScalar>(
btDot(m_axis[0], m_axis[1]), -1, +1)));
2837 m_drift *= m_erp / dt;
2838 m_massmatrix =
AngularImpulseMatrix(m_bodies[0].invWorldInertia(), m_bodies[1].invWorldInertia());
2841 m_sdrift = m_massmatrix * (m_drift * m_split);
2842 m_drift *= 1 - m_split;
2850 const btVector3 va = m_bodies[0].angularVelocity();
2851 const btVector3 vb = m_bodies[1].angularVelocity();
2854 const btVector3 vc = vr - m_axis[0] * m_icontrol->Speed(
this, sp);
2857 impulse.
m_velocity = m_massmatrix * (m_drift + vc * m_cfm) * sor;
2858 m_bodies[0].applyAImpulse(-impulse);
2859 m_bodies[1].applyAImpulse(impulse);
2867 m_bodies[0].applyDAImpulse(-m_sdrift);
2868 m_bodies[1].applyDAImpulse(m_sdrift);
2876 const bool dodrift = (m_life == 0);
2877 m_delete = (++m_life) > m_maxlife;
2880 m_drift = m_drift * m_erp / dt;
2883 m_sdrift = m_massmatrix * (m_drift * m_split);
2884 m_drift *= 1 - m_split;
2890 m_drift = m_sdrift =
btVector3(0, 0, 0);
2897 const btVector3 va = m_bodies[0].velocity(m_rpos[0]);
2898 const btVector3 vb = m_bodies[1].velocity(m_rpos[1]);
2912 if (m_bodies[0].m_soft == m_bodies[1].m_soft)
2919 if (impulse.
m_velocity.
length() < m_bodies[0].m_soft->m_maxSelfCollisionImpulse)
2924 m_bodies[0].applyImpulse(-impulse * m_bodies[0].m_soft->m_selfCollisionImpulseFactor, m_rpos[0]);
2925 m_bodies[1].applyImpulse(impulse * m_bodies[0].m_soft->m_selfCollisionImpulseFactor, m_rpos[1]);
2932 m_bodies[0].applyImpulse(-impulse, m_rpos[0]);
2933 m_bodies[1].applyImpulse(impulse, m_rpos[1]);
2942 m_bodies[0].applyDImpulse(-m_sdrift, m_rpos[0]);
2943 m_bodies[1].applyDImpulse(m_sdrift, m_rpos[1]);
2956 const bool as_lift = kLF > 0;
2957 const bool as_drag = kDG > 0;
2958 const bool as_pressure = kPR != 0;
2959 const bool as_volume = kVC > 0;
2960 const bool as_aero = as_lift ||
2966 const bool use_medium = as_aero;
2967 const bool use_volume = as_pressure ||
2976 ivolumetp = 1 /
btFabs(volume) * kPR;
3062 if (multibodyLinkCol)
3074 for (
int j = 0; j < ndof; ++j)
3100 if (multibodyLinkCol)
3102 double multiplier = 0.5;
3150 for (
int i = 0, ni = psb->
m_links.
size(); i < ni; ++i)
3173 for (
int i = 0, ni = psb->
m_links.
size(); i < ni; ++i)
3239 volume.Expand(
btVector3(basemargin, basemargin, basemargin));
3240 docollide.
psb =
this;
3244 docollide.
dynmargin = basemargin + timemargin;
3284 docollide.
psb[0] =
this;
3285 docollide.
psb[1] = psb;
3290 docollide.
psb[0] = psb;
3291 docollide.
psb[1] =
this;
3332 if (sbd->m_materials)
3335 int numElem = sbd->m_numMaterials;
3339 for (
int i = 0; i < numElem; i++, memPtr++)
3348 memPtr->
m_flags = mat->m_flags;
3363 int numElem = sbd->m_numNodes;
3366 for (
int i = 0; i < numElem; i++, memPtr++)
3387 int numElem = sbd->m_numLinks;
3390 for (
int i = 0; i < numElem; i++, memPtr++)
3408 int numElem = sbd->m_numFaces;
3411 for (
int i = 0; i < numElem; i++, memPtr++)
3415 for (
int j = 0; j < 3; j++)
3426 if (sbd->m_tetrahedra)
3429 int numElem = sbd->m_numTetrahedra;
3432 for (
int i = 0; i < numElem; i++, memPtr++)
3434 for (
int j = 0; j < 4; j++)
3452 int numElem = sbd->m_numAnchors;
3455 for (
int i = 0; i < numElem; i++, memPtr++)
3469 sbd->m_config.m_dynamicFriction =
m_cfg.
kDF;
3471 sbd->m_config.m_pressure =
m_cfg.
kPR;
3480 sbd->m_config.m_damping =
m_cfg.
kDP;
3481 sbd->m_config.m_poseMatch =
m_cfg.
kMT;
3483 sbd->m_config.m_volume =
m_cfg.
kVC;
3484 sbd->m_config.m_rigidContactHardness =
m_cfg.
kCHR;
3485 sbd->m_config.m_kineticContactHardness =
m_cfg.
kKHR;
3486 sbd->m_config.m_softContactHardness =
m_cfg.
kSHR;
3487 sbd->m_config.m_anchorHardness =
m_cfg.
kAHR;
3491 sbd->m_config.m_softKineticClusterHardness =
m_cfg.
kSKHR_CL;
3518 for (
int i = 0; i < numElem; i++, memPtr++)
3533 int sz =
sizeof(float);
3535 float* memPtr = (
float*)chunk->
m_oldPtr;
3536 for (
int i = 0; i < numElem; i++, memPtr++)
3550 if (sbd->m_numClusters)
3552 int numElem = sbd->m_numClusters;
3556 for (
int i = 0; i < numElem; i++, memPtr++)
3596 for (
int j = 0; j < numElem; j++, memPtr++)
3598 m_clusters[i]->m_framerefs[j].serializeFloat(*memPtr);
3607 int sz =
sizeof(float);
3609 float* memPtr = (
float*)chunk->
m_oldPtr;
3610 for (
int j = 0; j < numElem; j++, memPtr++)
3621 int sz =
sizeof(int);
3623 int* memPtr = (
int*)chunk->
m_oldPtr;
3624 for (
int j = 0; j < numElem; j++, memPtr++)
3628 *memPtr = *indexPtr;
3646 for (
int i = 0; i < numElem; i++, memPtr++)
3656 for (
int j = 0; j < 4; j++)
3663 if (
m_joints[i]->m_bodies[0].m_soft)
3668 if (
m_joints[i]->m_bodies[0].m_collisionObject)
3673 if (
m_joints[i]->m_bodies[0].m_rigid)
3679 if (
m_joints[i]->m_bodies[1].m_soft)
3684 if (
m_joints[i]->m_bodies[1].m_collisionObject)
3689 if (
m_joints[i]->m_bodies[1].m_rigid)
static void PSolve_RContacts(btSoftBody *psb, btScalar kst, btScalar ti)
RayFromToCaster(const btVector3 &rayFrom, const btVector3 &rayTo, btScalar mxt)
static T sum(const btAlignedObjectArray< T > &items)
const btCollisionObject * m_colObj
static const btRigidBody * upcast(const btCollisionObject *colObj)
to keep collision detection and dynamics separate we don't store a rigidbody pointer but a rigidbody ...
int generateBendingConstraints(int distance, Material *mat=0)
void(* vsolver_t)(btSoftBody *, btScalar)
btScalar length(const btQuaternion &q)
Return the length of a quaternion.
eFeature::_ feature
soft body
static btMultiBodyLinkCollider * upcast(btCollisionObject *colObj)
void push_back(const T &_Val)
void Process(const btDbvtNode *leaf)
Vertex normals are oriented toward velocity.
bool checkFace(int node0, int node1, int node2) const
SoftBodyMaterialData * m_material
btScalar m_maxDisplacement
void Prepare(btScalar dt, int iterations)
DBVT_INLINE const btVector3 & Mins() const
virtual const char * serialize(void *dataBuffer, class btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
btScalar getTotalMass() const
static void ZeroInitialize(T &value)
btAlignedObjectArray< btScalar > scratch_r
void serializeFloat(struct btMatrix3x3FloatData &dataOut) const
void defaultCollisionHandler(const btCollisionObjectWrapper *pcoWrap)
btSoftBody implementation by Nathanael Presson
static btMatrix3x3 ImpulseMatrix(btScalar dt, btScalar ima, btScalar imb, const btMatrix3x3 &iwi, const btVector3 &r)
bool cutLink(int node0, int node1, btScalar position)
virtual int calculateSerializeBufferSize() const
btVector3FloatData m_relPosition[2]
int findLinearSearch(const T &key) const
Vertex normals are flipped to match velocity.
btScalar m_restLengthScale
const Value * find(const Key &key) const
tVector3Array m_framerefs
void setSolver(eSolverPresets::_ preset)
static btVector3 clusterVelocity(const Cluster *cluster, const btVector3 &rpos)
btScalar length2() const
Return the length of the vector squared.
const btCollisionObjectWrapper * m_colObj1Wrap
btVector3FloatData m_previousPosition
btVector3FloatData m_localFrame
btAlignedObjectArray< bool > m_clusterConnectivity
virtual void * getUniquePointer(void *oldPtr)=0
Material * appendMaterial()
virtual void Prepare(btScalar dt, int iterations)
btScalar btSqrt(btScalar y)
static btScalar rayFromToTriangle(const btVector3 &rayFrom, const btVector3 &rayTo, const btVector3 &rayNormalizedDirection, const btVector3 &a, const btVector3 &b, const btVector3 &c, btScalar maxt=SIMD_INFINITY)
void Prepare(btScalar dt, int iterations)
Cluster vs convex rigid vs soft.
btAlignedObjectArray< Node * > m_nodes
static void clusterVImpulse(Cluster *cluster, const btVector3 &rpos, const btVector3 &impulse)
void serializeFloat(struct btVector3FloatData &dataOut) const
btDispatcher * m_dispatcher
The btCollisionShape class provides an interface for collision shapes that can be shared among btColl...
btScalar fraction
feature index
void setVelocity(const btVector3 &velocity)
static btMatrix3x3 Mul(const btMatrix3x3 &a, btScalar b)
btDbvtNode * insert(const btDbvtVolume &box, void *data)
btVector3FloatData m_vimpulses[2]
void Solve(btScalar dt, btScalar sor)
static btScalar AreaOf(const btVector3 &x0, const btVector3 &x1, const btVector3 &x2)
tSContactArray m_scontacts
const btScalar & getY() const
Return the y value.
void appendAnchor(int node, btRigidBody *body, bool disableCollisionBetweenLinkedBodies=false, btScalar influence=1)
static void clusterImpulse(Cluster *cluster, const btVector3 &rpos, const Impulse &impulse)
int getActivationState() const
static bool SameSign(const T &x, const T &y)
btScalar getMass(int node) const
static btVector3 clusterCom(const Cluster *cluster)
void calcAccelerationDeltasMultiDof(const btScalar *force, btScalar *output, btAlignedObjectArray< btScalar > &scratch_r, btAlignedObjectArray< btVector3 > &scratch_v) const
stepVelocitiesMultiDof is deprecated, use computeAccelerationsArticulatedBodyAlgorithmMultiDof instea...
static int PolarDecompose(const btMatrix3x3 &m, btMatrix3x3 &q, btMatrix3x3 &s)
btVector3FloatData m_dimpulses[2]
static DBVT_PREFIX void rayTest(const btDbvtNode *root, const btVector3 &rayFrom, const btVector3 &rayTo, DBVT_IPOLICY)
rayTest is a re-entrant ray test, and can be called in parallel as long as the btAlignedAlloc is thre...
Vertex normals are taken as it is.
void addForce(const btVector3 &force)
static void EvaluateMedium(const btSoftBodyWorldInfo *wfi, const btVector3 &x, btSoftBody::sMedium &medium)
btVector3FloatData m_accumulatedForce
void setWindVelocity(const btVector3 &velocity)
Set a wind velocity for interaction with the air.
const btCollisionShape * getCollisionShape() const
void ProcessColObj(btSoftBody *ps, const btCollisionObjectWrapper *colObWrap)
void applyDeltaVeeMultiDof(const btScalar *delta_vee, btScalar multiplier)
Cluster vs cluster soft vs soft handling.
btTransform m_initialWorldTransform
btTransform m_worldTransform
btSoftBody(btSoftBodyWorldInfo *worldInfo, int node_count, const btVector3 *x, const btScalar *m)
btSoftBody implementation by Nathanael Presson
void appendLink(int model=-1, Material *mat=0)
void Terminate(btScalar dt)
bool rayTest(const btVector3 &rayFrom, const btVector3 &rayTo, sRayCast &results)
Ray casting using rayFrom and rayTo in worldspace, (not direction!)
btCollisionShape * m_collisionShape
btAlignedObjectArray< btMatrix3x3 > scratch_m
virtual void getAabb(const btTransform &t, btVector3 &aabbMin, btVector3 &aabbMax) const =0
getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t...
void appendAngularJoint(const AJoint::Specs &specs, Cluster *body0, Body body1)
The btHashMap template class implements a generic and lightweight hashmap.
btVector3FloatData m_normal
btVector3 normalized() const
Return a normalized version of this vector.
void appendFace(int model=-1, Material *mat=0)
btSoftBodyWorldInfo * m_worldInfo
btVector3FloatData m_normal
Cluster soft body self collision.
static btDbvtVolume VolumeOf(const btSoftBody::Face &f, btScalar margin)
void clear()
clear the array, deallocated memory. Generally it is better to use array.resize(0), to reduce performance overhead of run-time memory (de)allocations.
btSparseSdf< 3 > m_sparsesdf
btMatrix3x3 transpose() const
Return the transpose of the matrix.
static btVector3 ProjectOnPlane(const btVector3 &v, const btVector3 &a)
int generateClusters(int k, int maxiterations=8192)
generateClusters with k=0 will create a convex cluster for each tetrahedron or triangle otherwise an ...
DBVT_INLINE const btVector3 & Maxs() const
#define IDX2PTR(_p_, _b_)
void addVelocity(const btVector3 &velocity)
void addAeroForceToNode(const btVector3 &windVelocity, int nodeIndex)
btVector3 btCross(const btVector3 &v1, const btVector3 &v2)
Return the cross product of two vectors.
static void solveClusters(const btAlignedObjectArray< btSoftBody *> &bodies)
void appendLinearJoint(const LJoint::Specs &specs, Cluster *body0, Body body1)
btAlignedObjectArray< btScalar > m_deltaVelocitiesUnitImpulse
const btScalar & getZ() const
Return the z value.
void activate(bool forceActivation=false) const
void update(btDbvtNode *leaf, int lookahead=-1)
btScalar getRestLengthScale()
btTransform & getWorldTransform()
btVector3FloatData m_refs[2]
btMatrix3x3FloatData m_c0
int m_internalType
m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody, btGhostObject etc.
btMatrix3x3FloatData m_rot
void indicesToPointers(const int *map=0)
void optimizeIncremental(int passes)
btBroadphaseProxy * getBroadphaseHandle()
void setVolumeMass(btScalar mass)
static void ApplyClampedForce(btSoftBody::Node &n, const btVector3 &f, btScalar dt)
void randomizeConstraints()
Vertex normals are flipped to match velocity and lift and drag forces are applied.
const btScalar & x() const
Return the x value.
void Prepare(btScalar dt, int iterations)
void updateLinkConstants()
const btVector3 & getWindVelocity()
Return the wind velocity for interaction with the air.
tMaterialArray m_materials
static void clusterDImpulse(Cluster *cluster, const btVector3 &rpos, const btVector3 &impulse)
SoftBodyMaterialData * m_material
btScalar getInvMass() const
void refine(ImplicitFn *ifn, btScalar accurary, bool cut)
static void PSolve_SContacts(btSoftBody *psb, btScalar, btScalar ti)
static btDbvtAabbMm FromMM(const btVector3 &mi, const btVector3 &mx)
btVector3 cross(const btVector3 &v) const
Return the cross product between this and another vector.
btScalar dot(const btVector3 &v) const
Return the dot product.
const btCollisionObject * getCollisionObject() const
static btScalar ClusterMetric(const btVector3 &x, const btVector3 &y)
void staticSolve(int iterations)
RayFromToCaster takes a ray from, ray to (instead of direction!)
static psolver_t getSolver(ePSolver::_ solver)
#define btSoftBodyDataName
void releaseCluster(int index)
void appendTetra(int model, Material *mat)
#define btAlignedFree(ptr)
const btScalar & y() const
Return the y value.
const btScalar & z() const
Return the z value.
int capacity() const
return the pre-allocated (reserved) elements, this is at least as large as the total number of elemen...
virtual const char * serialize(void *dataBuffer, class btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
void predictMotion(btScalar dt)
void insert(const Key &key, const Value &value)
DBVT_PREFIX void collideTV(const btDbvtNode *root, const btDbvtVolume &volume, DBVT_IPOLICY) const
static btVector3 Clamp(const btVector3 &v, btScalar maxlength)
btMatrix3x3FloatData m_invwi
static void clusterVAImpulse(Cluster *cluster, const btVector3 &impulse)
bool hasContactResponse() const
void appendNode(const btVector3 &x, btScalar m)
void appendNote(const char *text, const btVector3 &o, const btVector4 &c=btVector4(1, 0, 0, 0), Node *n0=0, Node *n1=0, Node *n2=0, Node *n3=0)
btVector3FloatData m_velocity
The btRigidBody is the main class for rigid body objects.
static void VSolve_Links(btSoftBody *psb, btScalar kst)
virtual void setMargin(btScalar margin)=0
void setTotalMass(btScalar mass, bool fromfaces=false)
void initializeClusters()
static int MatchEdge(const btSoftBody::Node *a, const btSoftBody::Node *b, const btSoftBody::Node *ma, const btSoftBody::Node *mb)
tPSolverArray m_dsequence
static btDbvtAabbMm FromCR(const btVector3 &c, btScalar r)
void initializeFaceTree()
void rotate(const btQuaternion &rot)
btMatrix3x3FloatData m_scale
const btScalar & w() const
Return the w value.
static T BaryEval(const T &a, const T &b, const T &c, const btVector3 &coord)
btRigidBodyData * m_rigidBody
void setTotalDensity(btScalar density)
btAlignedObjectArray< btScalar > m_jacobians
btAlignedObjectArray< int > m_links
static btMatrix3x3 AngularImpulseMatrix(const btMatrix3x3 &iia, const btMatrix3x3 &iib)
btVector3 can be used to represent 3D points and vectors.
#define ATTRIBUTE_ALIGNED16(a)
btScalar btAcos(btScalar x)
virtual btScalar Eval(const btVector3 &x)=0
int size() const
return the number of elements in the array
btScalar getVolume() const
btVector3 getVelocityInLocalPoint(const btVector3 &rel_pos) const
btAlignedObjectArray< btVector3 > scratch_v
virtual void finalizeChunk(btChunk *chunk, const char *structType, int chunkCode, void *oldPtr)=0
btMatrix3x3FloatData m_aqq
static btScalar ImplicitSolve(btSoftBody::ImplicitFn *fn, const btVector3 &a, const btVector3 &b, const btScalar accuracy, const int maxiterations=256)
btVector3FloatData m_position
btScalar determinant() const
Return the determinant of the matrix.
void Solve(btScalar dt, btScalar sor)
float m_maxSelfCollisionImpulse
void Solve(btScalar dt, btScalar sor)
#define btSoftBodyData
btSoftBody implementation by Nathanael Presson
void remove(const T &key)
void applyClusters(bool drift)
static T Lerp(const T &a, const T &b, btScalar t)
Face normals are flipped to match velocity.
void transform(const btTransform &trs)
void resize(int newsize, const T &fillData=T())
#define BT_SBMATERIAL_CODE
bool btFuzzyZero(btScalar x)
void ProcessSoftSoft(btSoftBody *psa, btSoftBody *psb)
btScalar Evaluate(const btVector3 &x, const btCollisionShape *shape, btVector3 &normal, btScalar margin)
int getInternalType() const
reserved for Bullet internal usage
void Terminate(btScalar dt)
Face normals are flipped to match velocity and lift and drag forces are applied.
SoftBodyMaterialData * m_material
btRigidBody * m_rigidBody
#define PTR2IDX(_p_, _b_)
virtual btScalar getMargin() const =0
const btTransform & getWorldTransform() const
void(* psolver_t)(btSoftBody *, btScalar, btScalar)
bool checkContact(const btCollisionObjectWrapper *colObjWrap, const btVector3 &x, btScalar margin, btSoftBody::sCti &cti) const
const btTransform & xform() const
static void clusterAImpulse(Cluster *cluster, const Impulse &impulse)
void scale(const btVector3 &scl)
const T & btMax(const T &a, const T &b)
bool checkLink(int node0, int node1) const
tVSolverArray m_vsequence
btVector3FloatData * m_framerefs
virtual void setAabb(btBroadphaseProxy *proxy, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)=0
#define btAlignedAlloc(size, alignment)
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
tPSolverArray m_psequence
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
static btVector3 NormalizeAny(const btVector3 &v)
btScalar dot(const btQuaternion &q1, const btQuaternion &q2)
Calculate the dot product between two quaternions.
btVector3FloatData m_c0[4]
SoftBodyMaterialData * m_material
btBroadphaseInterface * m_broadphase
void translate(const btVector3 &trs)
DBVT_PREFIX void collideTT(const btDbvtNode *root0, const btDbvtNode *root1, DBVT_IPOLICY)
void applyImpulse(const btVector3 &impulse, const btVector3 &rel_pos)
const btMatrix3x3 & getInvInertiaTensorWorld() const
The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatr...
void setRestLengthScale(btScalar restLength)
btScalar btDot(const btVector3 &v1, const btVector3 &v2)
Return the dot product between two vectors.
btAlignedObjectArray< const class btCollisionObject * > m_collisionDisabledObjects
void setMax(const btVector3 &other)
Set each element to the max of the current values and the values of another btVector3.
virtual void * findPointer(void *oldPtr)=0
void fillContactJacobianMultiDof(int link, const btVector3 &contact_point, const btVector3 &normal, btScalar *jac, btAlignedObjectArray< btScalar > &scratch_r, btAlignedObjectArray< btVector3 > &scratch_v, btAlignedObjectArray< btMatrix3x3 > &scratch_m) const
void prepareClusters(int iterations)
btMultiBody * m_multiBody
static void solveCommonConstraints(btSoftBody **bodies, int count, int iterations)
btMatrix3x3 inverse() const
Return the inverse of the matrix.
The btSoftBody is an class to simulate cloth and volumetric soft bodies.
static void clusterDCImpulse(Cluster *cluster, const btVector3 &impulse)
const T & btMin(const T &a, const T &b)
btTransformFloatData m_framexform
void setPose(bool bvolume, bool bframe)
static void PSolve_Anchors(btSoftBody *psb, btScalar kst, btScalar ti)
void setMass(int node, btScalar mass)
void setVolumeDensity(btScalar density)
tRContactArray m_rcontacts
const btScalar * getVelocityVector() const
float m_selfCollisionImpulseFactor
static void PSolve_Links(btSoftBody *psb, btScalar kst, btScalar ti)
btVector3 evaluateCom() const
btVector3 m_rayNormalizedDirection
void remove(btDbvtNode *leaf)
void addAeroForceToFace(const btVector3 &windVelocity, int faceIndex)
void setIdentity()
Set the matrix to the identity.
static void clusterDAImpulse(Cluster *cluster, const btVector3 &impulse)
virtual btChunk * allocate(size_t size, int numElements)=0
btVector3FloatData * m_positions
Vertex vs face soft vs soft handling.
const btScalar & getX() const
Return the x value.
void updateArea(bool averageArea=true)
void setMin(const btVector3 &other)
Set each element to the min of the current values and the values of another btVector3.
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
const btCollisionShape * getCollisionShape() const
void Terminate(btScalar dt)
btMatrix3x3FloatData m_locii
btScalar length() const
Return the length of the vector.
btScalar btFabs(btScalar x)
void resetLinkRestLengths()