27 :m_softBodySolver(0),m_worldInfo(worldInfo)
42 for(
int i=0,ni=node_count;i<ni;++i)
141 const Node* n[]={node0,node1};
145 if( (l.
m_n[0]==n[0]&&l.
m_n[1]==n[1])||
146 (l.
m_n[0]==n[1]&&l.
m_n[1]==n[0]))
166 if( (f.
m_n[j]==n[0])||
168 (f.
m_n[j]==n[2])) c|=1<<j;
else break;
170 if(c==7)
return(
true);
287 if((!bcheckexist)||(!
checkLink(node0,node1)))
366 appendAnchor(node,body,local,disableCollisionBetweenLinkedBodies,influence);
372 if (disableCollisionBetweenLinkedBodies)
467 const bool as_lift = kLF>0;
468 const bool as_drag = kDG>0;
469 const bool as_aero = as_lift || as_drag;
501 btScalar tri_area = 0.5f * n.m_area;
503 fDrag = 0.5f * kDG * medium.
m_density * rel_v2 * tri_area * n_dot_v * (-rel_v_nrm);
507 if ( 0 < n_dot_v && n_dot_v < 0.98480f)
508 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));
512 btScalar del_v_by_fDrag_len2 = del_v_by_fDrag.length2();
515 if (del_v_by_fDrag_len2 >= v_len2 && del_v_by_fDrag_len2 > 0)
517 btScalar del_v_by_fDrag_len = del_v_by_fDrag.length();
519 fDrag *=
btScalar(0.8)*(v_len / del_v_by_fDrag_len);
535 const btScalar c0 = n.m_area * dvn * rel_v2/2;
537 force += nrm*(-c1*kLF);
554 const bool as_lift = kLF>0;
555 const bool as_drag = kDG>0;
556 const bool as_aero = as_lift || as_drag;
589 fDrag = 0.5f * kDG * medium.
m_density * rel_v2 * tri_area * n_dot_v * (-rel_v_nrm);
593 if ( 0 < n_dot_v && n_dot_v < 0.98480f)
594 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));
608 if (del_v_by_fDrag_len2 >= v_len2 && del_v_by_fDrag_len2 > 0)
612 fDrag *=
btScalar(0.8)*(v_len / del_v_by_fDrag_len);
632 force += nrm*(-c1*kLF);
676 m_nodes[node].m_im=mass>0?1/mass:0;
880 if(
m_nodes[i].m_im<=0) tmass+=kmass;
956 for(
int i=0,ni=cluster->
m_nodes.size();i<ni;++i)
1048 const unsigned inf=(~(unsigned)0)>>1;
1049 unsigned* adj=
new unsigned[n*n];
1052 #define IDX(_x_,_y_) ((_y_)*n+(_x_)) 1059 adj[
IDX(i,j)]=adj[
IDX(j,i)]=inf;
1063 adj[
IDX(i,j)]=adj[
IDX(j,i)]=0;
1096 for (
int ii=0;ii<nodeLinks.
size();ii++)
1100 for (
int jj=0;jj<nodeLinks[ii].m_links.
size();jj++)
1102 int k = nodeLinks[ii].m_links[jj];
1103 for (
int kk=0;kk<nodeLinks[k].m_links.
size();kk++)
1105 int j = nodeLinks[k].m_links[kk];
1108 const unsigned sum=adj[
IDX(i,k)]+adj[
IDX(k,j)];
1110 if(adj[
IDX(i,j)]>sum)
1122 for(
int k=0;k<n;++k)
1128 const unsigned sum=adj[
IDX(i,k)]+adj[
IDX(k,j)];
1129 if(adj[
IDX(i,j)]>sum)
1145 if(adj[
IDX(i,j)]==(
unsigned)distance)
1162 unsigned long seed=243703;
1163 #define NEXTRAND (seed=(1664525L*seed+1013904223L)&0xffffffff) 1223 const btScalar w=2-btMin<btScalar>(1,iterations/slope);
1238 c = centers[i]+(c-centers[i])*w;
1249 for(
int j=1;j<k;++j)
1260 }
while(changed&&(iterations<maxiterations));
1276 for(
int j=0;j<3;++j)
1278 const int cid=cids[idx[j]];
1279 for(
int q=1;q<3;++q)
1281 const int kid=idx[(j+q)%3];
1323 for (
int j=0;j<4;j++)
1340 for(
int j=0;j<3;++j)
1363 bool connected=
false;
1366 for (
int i=0;!connected&&i<cla->
m_nodes.size();i++)
1368 for (
int j=0;j<clb->
m_nodes.size();j++)
1412 edges(
int(l.
m_n[0]-nbase),
int(l.
m_n[1]-nbase))=-1;
1417 edges(
int(f.
m_n[0]-nbase),
int(f.
m_n[1]-nbase))=-1;
1418 edges(
int(f.
m_n[1]-nbase),
int(f.
m_n[2]-nbase))=-1;
1419 edges(
int(f.
m_n[2]-nbase),
int(f.
m_n[0]-nbase))=-1;
1422 for(i=0;i<ncount;++i)
1424 for(j=i+1;j<ncount;++j)
1443 const btScalar f=(ma+mb)/(ma+mb+mc);
1471 const int idx[]={ int(feat.
m_n[0]-nbase),
1472 int(feat.
m_n[1]-nbase)};
1473 if((idx[0]<ncount)&&(idx[1]<ncount))
1475 const int ni=edges(idx[0],idx[1]);
1492 const int idx[]={ int(feat.
m_n[0]-nbase),
1493 int(feat.
m_n[1]-nbase),
1494 int(feat.
m_n[2]-nbase)};
1495 for(j=2,k=0;k<3;j=k++)
1497 if((idx[j]<ncount)&&(idx[k]<ncount))
1499 const int ni=edges(idx[j],idx[k]);
1503 const int l=(k+1)%3;
1522 const int pcount=ncount;
1527 for(i=0;i<ncount;++i)
1530 if((i>=pcount)||(
btFabs(ifn->
Eval(x))<accurary))
1534 if(m>0) { m*=0.5f;
m_nodes[i].m_im/=0.5f; }
1544 const int id[]={ int(
m_links[i].m_n[0]-nbase),
1545 int(
m_links[i].m_n[1]-nbase)};
1547 if(cnodes[
id[0]]&&cnodes[
id[1]])
1561 for(
int j=0;j<2;++j)
1563 int cn=cnodes[int(l.
m_n[j]-nbase)];
1572 if( (ifn->
Eval(n[0]->
m_x)<accurary)&&
1573 (ifn->
Eval(n[1]->
m_x)<accurary)&&
1574 (ifn->
Eval(n[2]->
m_x)<accurary))
1576 for(
int j=0;j<3;++j)
1578 int cn=cnodes[int(n[j]-nbase)];
1590 for(
int j=0;j<2;++j) ranks[
int(
m_links[i].m_n[j]-nbase)]++;
1594 for(
int j=0;j<3;++j) ranks[
int(
m_faces[i].m_n[j]-nbase)]++;
1598 const int id[]={ int(
m_links[i].m_n[0]-nbase),
1599 int(
m_links[i].m_n[1]-nbase)};
1600 const bool sg[]={ ranks[
id[0]]==1,
1611 for(i=nnodes-1;i>=0;--i)
1618 for(
int i=0;i<nnodes;++i) map[i]=i;
1619 PointersToIndices(
this);
1620 for(
int i=0,ni=todelete.
size();i<ni;++i)
1624 int& b=map[--nnodes];
1629 IndicesToPointers(
this,&map[0]);
1667 pft[0]->
m_n[1]=pn[mtch];
1668 pft[1]->
m_n[0]=pn[1-mtch];
1674 for(
int k=2,l=0;l<3;k=l++)
1681 pft[0]->
m_n[l]=pn[mtch];
1682 pft[1]->
m_n[k]=pn[1-mtch];
1683 appendLink(pn[0],pft[0]->m_n[(l+1)%3],pft[0]->m_material,
true);
1684 appendLink(pn[1],pft[0]->m_n[(l+1)%3],pft[0]->m_material,
true);
1706 results.
body =
this;
1776 for (
int c=0;c<3;c++)
1778 if (deltaV[c]>clampDeltaV)
1780 deltaV[c] = clampDeltaV;
1782 if (deltaV[c]<-clampDeltaV)
1784 deltaV[c]=-clampDeltaV;
1945 for(
int isolve=0;isolve<iterations;++isolve)
1963 const int nb=bodies.
size();
1973 bodies[i]->prepareClusters(iterations);
1975 for(i=0;i<iterations;++i)
1978 for(
int j=0;j<nb;++j)
1980 bodies[j]->solveClusters(sor);
1985 bodies[i]->cleanupClusters();
1999 m_rayFrom = rayFrom;
2000 m_rayNormalizedDirection = (rayTo-rayFrom);
2011 const btScalar t=rayFromToTriangle( m_rayFrom,m_rayTo,m_rayNormalizedDirection,
2016 if((t>0)&&(t<m_mint))
2026 const btVector3& rayNormalizedDirection,
2042 if((t>teps)&&(t<maxt))
2044 const btVector3 hit=rayFrom+rayNormalizedDirection*t;
2059 #define PTR2IDX(_p_,_b_) reinterpret_cast<btSoftBody::Node*>((_p_)-(_b_)) 2067 m_nodes[i].m_leaf->data=*(
void**)&i;
2082 m_faces[i].m_leaf->data=*(
void**)&i;
2091 for(
int j=0;j<
m_notes[i].m_rank;++j)
2102 #define IDX2PTR(_p_,_b_) map?(&(_b_)[map[(((char*)_p_)-(char*)0)]]): \ 2103 (&(_b_)[(((char*)_p_)-(char*)0)]) 2135 for(
int j=0;j<
m_notes[i].m_rank;++j)
2192 int tetfaces[4][3] = {{0,1,2},{0,1,3},{1,2,3},{0,2,3}};
2193 for (
int f=0;f<4;f++)
2196 int index0=tetfaces[f][0];
2197 int index1=tetfaces[f][1];
2198 int index2=tetfaces[f][2];
2360 Apq[0].setX(eps);Apq[1].setY(eps*2);Apq[2].setZ(eps*3);
2408 for(
int j=0;j<3;++j)
2435 for(
int j=0;j<3;++j)
2443 m_nodes[i].m_area *= 0.3333333f;
2481 for(
int j=0;j<c.
m_nodes.size();++j)
2504 for(i=0,ni=c.
m_nodes.size();i<ni;++i)
2509 ii[0][0] += m*(q[1]+q[2]);
2510 ii[1][1] += m*(q[0]+q[2]);
2511 ii[2][2] += m*(q[0]+q[1]);
2512 ii[0][1] -= m*k[0]*k[1];
2513 ii[0][2] -= m*k[0]*k[2];
2514 ii[1][2] -= m*k[1]*k[2];
2558 for(
int i=0;i<c.
m_nodes.size();++i)
2562 m[0]+=a[0]*b;m[1]+=a[1]*b;m[2]+=a[2]*b;
2578 c.
m_invwi=c.m_xform.getBasis().scaled(iin)*c.m_xform.getBasis().transpose();
2581 for(
int i=0;i<n;++i)
2586 c.
m_invwi[0][0] += m*(q[1]+q[2]);
2587 c.
m_invwi[1][1] += m*(q[0]+q[2]);
2588 c.
m_invwi[2][2] += m*(q[0]+q[1]);
2589 c.
m_invwi[0][1] -= m*k[0]*k[1];
2590 c.
m_invwi[0][2] -= m*k[0]*k[2];
2591 c.
m_invwi[1][2] -= m*k[1]*k[2];
2623 for(
int j=0;j<c.
m_nodes.size();++j)
2635 for(
int j=1;j<n;++j)
2720 for(
int j=0;j<c.
m_nodes.size();++j)
2730 for(i=0;i<deltas.
size();++i)
2734 m_nodes[i].m_x+=deltas[i]/weights[i];
2749 for(
int j=0;j<c.
m_nodes.size();++j)
2768 m_bodies[0].activate();
2769 m_bodies[1].activate();
2777 m_rpos[0] = m_bodies[0].xform()*m_refs[0];
2778 m_rpos[1] = m_bodies[1].xform()*m_refs[1];
2779 m_drift =
Clamp(m_rpos[0]-m_rpos[1],maxdrift)*m_erp/dt;
2780 m_rpos[0] -= m_bodies[0].xform().getOrigin();
2781 m_rpos[1] -= m_bodies[1].xform().getOrigin();
2782 m_massmatrix =
ImpulseMatrix( m_bodies[0].invMass(),m_bodies[0].invWorldInertia(),m_rpos[0],
2783 m_bodies[1].invMass(),m_bodies[1].invWorldInertia(),m_rpos[1]);
2786 m_sdrift = m_massmatrix*(m_drift*m_split);
2787 m_drift *= 1-m_split;
2795 const btVector3 va=m_bodies[0].velocity(m_rpos[0]);
2796 const btVector3 vb=m_bodies[1].velocity(m_rpos[1]);
2800 impulse.
m_velocity = m_massmatrix*(m_drift+vr*m_cfm)*sor;
2801 m_bodies[0].applyImpulse(-impulse,m_rpos[0]);
2802 m_bodies[1].applyImpulse( impulse,m_rpos[1]);
2810 m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]);
2811 m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]);
2819 m_icontrol->Prepare(
this);
2821 m_axis[0] = m_bodies[0].xform().getBasis()*m_refs[0];
2822 m_axis[1] = m_bodies[1].xform().getBasis()*m_refs[1];
2824 m_drift *=
btMin(maxdrift,
btAcos(Clamp<btScalar>(
btDot(m_axis[0],m_axis[1]),-1,+1)));
2825 m_drift *= m_erp/dt;
2826 m_massmatrix=
AngularImpulseMatrix(m_bodies[0].invWorldInertia(),m_bodies[1].invWorldInertia());
2829 m_sdrift = m_massmatrix*(m_drift*m_split);
2830 m_drift *= 1-m_split;
2838 const btVector3 va=m_bodies[0].angularVelocity();
2839 const btVector3 vb=m_bodies[1].angularVelocity();
2842 const btVector3 vc=vr-m_axis[0]*m_icontrol->Speed(
this,sp);
2845 impulse.
m_velocity = m_massmatrix*(m_drift+vc*m_cfm)*sor;
2846 m_bodies[0].applyAImpulse(-impulse);
2847 m_bodies[1].applyAImpulse( impulse);
2855 m_bodies[0].applyDAImpulse(-m_sdrift);
2856 m_bodies[1].applyDAImpulse( m_sdrift);
2864 const bool dodrift=(m_life==0);
2865 m_delete=(++m_life)>m_maxlife;
2868 m_drift=m_drift*m_erp/dt;
2871 m_sdrift = m_massmatrix*(m_drift*m_split);
2872 m_drift *= 1-m_split;
2885 const btVector3 va=m_bodies[0].velocity(m_rpos[0]);
2886 const btVector3 vb=m_bodies[1].velocity(m_rpos[1]);
2900 if (m_bodies[0].m_soft==m_bodies[1].m_soft)
2907 if (impulse.
m_velocity.
length() <m_bodies[0].m_soft->m_maxSelfCollisionImpulse)
2912 m_bodies[0].applyImpulse(-impulse*m_bodies[0].m_soft->m_selfCollisionImpulseFactor,m_rpos[0]);
2913 m_bodies[1].applyImpulse( impulse*m_bodies[0].m_soft->m_selfCollisionImpulseFactor,m_rpos[1]);
2919 m_bodies[0].applyImpulse(-impulse,m_rpos[0]);
2920 m_bodies[1].applyImpulse( impulse,m_rpos[1]);
2929 m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]);
2930 m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]);
2944 const bool as_lift = kLF>0;
2945 const bool as_drag = kDG>0;
2946 const bool as_pressure = kPR!=0;
2947 const bool as_volume = kVC>0;
2948 const bool as_aero = as_lift ||
2954 const bool use_medium = as_aero;
2955 const bool use_volume = as_pressure ||
2964 ivolumetp = 1/
btFabs(volume)*kPR;
3051 if (multibodyLinkCol)
3063 for (
int j = 0; j < ndof ; ++j) {
3088 if (multibodyLinkCol)
3090 double multiplier = 0.5;
3226 volume.Expand(
btVector3(basemargin,basemargin,basemargin));
3227 docollide.
psb =
this;
3231 docollide.
dynmargin = basemargin+timemargin;
3273 docollide.
psb[0]=
this;
3274 docollide.
psb[1]=psb;
3279 docollide.
psb[0]=psb;
3280 docollide.
psb[1]=
this;
3327 if (sbd->m_materials)
3330 int numElem = sbd->m_numMaterials;
3334 for (
int i=0;i<numElem;i++,memPtr++)
3361 int numElem = sbd->m_numNodes;
3364 for (
int i=0;i<numElem;i++,memPtr++)
3385 int numElem = sbd->m_numLinks;
3388 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++)
3427 if (sbd->m_tetrahedra)
3430 int numElem = sbd->m_numTetrahedra;
3433 for (
int i=0;i<numElem;i++,memPtr++)
3435 for (
int j=0;j<4;j++)
3453 int numElem = sbd->m_numAnchors;
3456 for (
int i=0;i<numElem;i++,memPtr++)
3471 sbd->m_config.m_dynamicFriction =
m_cfg.
kDF;
3473 sbd->m_config.m_pressure =
m_cfg.
kPR;
3482 sbd->m_config.m_damping =
m_cfg.
kDP;
3483 sbd->m_config.m_poseMatch =
m_cfg.
kMT;
3485 sbd->m_config.m_volume =
m_cfg.
kVC;
3486 sbd->m_config.m_rigidContactHardness =
m_cfg.
kCHR;
3487 sbd->m_config.m_kineticContactHardness =
m_cfg.
kKHR;
3488 sbd->m_config.m_softContactHardness =
m_cfg.
kSHR;
3489 sbd->m_config.m_anchorHardness =
m_cfg.
kAHR;
3493 sbd->m_config.m_softKineticClusterHardness =
m_cfg.
kSKHR_CL;
3520 for (
int i=0;i<numElem;i++,memPtr++)
3536 int sz =
sizeof(float);
3538 float* memPtr = (
float*) chunk->
m_oldPtr;
3539 for (
int i=0;i<numElem;i++,memPtr++)
3553 if (sbd->m_numClusters)
3555 int numElem = sbd->m_numClusters;
3559 for (
int i=0;i<numElem;i++,memPtr++)
3601 for (
int j=0;j<numElem;j++,memPtr++)
3603 m_clusters[i]->m_framerefs[j].serializeFloat(*memPtr);
3612 int sz =
sizeof(float);
3614 float* memPtr = (
float*) chunk->
m_oldPtr;
3615 for (
int j=0;j<numElem;j++,memPtr++)
3626 int sz =
sizeof(int);
3628 int* memPtr = (
int*) chunk->
m_oldPtr;
3629 for (
int j=0;j<numElem;j++,memPtr++)
3633 *memPtr = *indexPtr;
3654 for (
int i=0;i<numElem;i++,memPtr++)
3664 for (
int j=0;j<4;j++)
3671 if (
m_joints[i]->m_bodies[0].m_soft)
3676 if (
m_joints[i]->m_bodies[0].m_collisionObject)
3681 if (
m_joints[i]->m_bodies[0].m_rigid)
3687 if (
m_joints[i]->m_bodies[1].m_soft)
3692 if (
m_joints[i]->m_bodies[1].m_collisionObject)
3697 if (
m_joints[i]->m_bodies[1].m_rigid)
btMatrix3x3 inverse() const
Return the inverse of the matrix.
static void PSolve_RContacts(btSoftBody *psb, btScalar kst, btScalar ti)
btScalar getInvMass() const
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)
static void solveClusters(const btAlignedObjectArray< btSoftBody * > &bodies)
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.
SoftBodyMaterialData * m_material
btScalar m_maxDisplacement
void Prepare(btScalar dt, int iterations)
static void ZeroInitialize(T &value)
btAlignedObjectArray< btScalar > scratch_r
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)
btVector3FloatData m_relPosition[2]
Vertex normals are flipped to match velocity.
btScalar m_restLengthScale
tVector3Array m_framerefs
void setSolver(eSolverPresets::_ preset)
static btVector3 clusterVelocity(const Cluster *cluster, const btVector3 &rpos)
int getInternalType() const
reserved for Bullet internal usage
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)
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
void appendAnchor(int node, btRigidBody *body, bool disableCollisionBetweenLinkedBodies=false, btScalar influence=1)
static void clusterImpulse(Cluster *cluster, const btVector3 &rpos, const Impulse &impulse)
static bool SameSign(const T &x, const T &y)
const btTransform & xform() const
static btVector3 clusterCom(const Cluster *cluster)
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.
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...
btScalar dot(const btVector3 &v) const
Return the dot product.
bool hasContactResponse() const
void appendAngularJoint(const AJoint::Specs &specs, Cluster *body0, Body body1)
The btHashMap template class implements a generic and lightweight hashmap.
btVector3FloatData m_normal
const btScalar & x() const
Return the x value.
void appendFace(int model=-1, Material *mat=0)
btSoftBodyWorldInfo * m_worldInfo
btVector3 getVelocityInLocalPoint(const btVector3 &rel_pos) const
const btScalar & getZ() const
Return the z value.
btVector3FloatData m_normal
Cluster soft body self collision.
btScalar getTotalMass() const
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
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 ...
#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.
void appendLinearJoint(const LJoint::Specs &specs, Cluster *body0, Body body1)
btAlignedObjectArray< btScalar > m_deltaVelocitiesUnitImpulse
virtual const char * serialize(void *dataBuffer, class btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
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)
int size() const
return the number of elements in the array
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.
void Prepare(btScalar dt, int iterations)
void updateLinkConstants()
const btVector3 & getWindVelocity()
Return the wind velocity for interaction with the air.
const btScalar & w() const
Return the w value.
tMaterialArray m_materials
static void clusterDImpulse(Cluster *cluster, const btVector3 &rpos, const btVector3 &impulse)
SoftBodyMaterialData * m_material
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)
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)
btVector3 cross(const btVector3 &v) const
Return the cross product between this and another vector.
const btScalar & getY() const
Return the y value.
const btTransform & getWorldTransform() const
btScalar getMass(int node) const
void appendTetra(int model, Material *mat)
#define btAlignedFree(ptr)
void predictMotion(btScalar dt)
const btScalar & getX() const
Return the x value.
void insert(const Key &key, const Value &value)
static btVector3 Clamp(const btVector3 &v, btScalar maxlength)
btMatrix3x3FloatData m_invwi
static void clusterVAImpulse(Cluster *cluster, const btVector3 &impulse)
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.
btScalar length() const
Return the length of the vector.
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
static T BaryEval(const T &a, const T &b, const T &c, const btVector3 &coord)
btRigidBodyData * m_rigidBody
void serializeFloat(struct btVector3FloatData &dataOut) const
void setTotalDensity(btScalar density)
const btScalar & y() const
Return the y value.
btAlignedObjectArray< btScalar > m_jacobians
btAlignedObjectArray< int > m_links
const btCollisionShape * getCollisionShape() const
int capacity() const
return the pre-allocated (reserved) elements, this is at least as large as the total number of elemen...
static btMatrix3x3 AngularImpulseMatrix(const btMatrix3x3 &iia, const btMatrix3x3 &iib)
virtual int calculateSerializeBufferSize() const
void activate(bool forceActivation=false) const
btVector3 can be used to represent 3D points and vectors.
#define ATTRIBUTE_ALIGNED16(a)
const Value * find(const Key &key) const
btScalar length2() const
Return the length of the vector squared.
btScalar btAcos(btScalar x)
virtual btScalar Eval(const btVector3 &x)=0
DBVT_INLINE const btVector3 & Maxs() const
void serializeFloat(struct btMatrix3x3FloatData &dataOut) 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
void calcAccelerationDeltasMultiDof(const btScalar *force, btScalar *output, btAlignedObjectArray< btScalar > &scratch_r, btAlignedObjectArray< btVector3 > &scratch_v) const
void Solve(btScalar dt, btScalar sor)
float m_maxSelfCollisionImpulse
btVector3 normalized() const
Return a normalized version of this vector.
void Solve(btScalar dt, btScalar sor)
#define btSoftBodyData
btSoftBody implementation by Nathanael Presson
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 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)
int findLinearSearch(const T &key) const
btScalar Evaluate(const btVector3 &x, const btCollisionShape *shape, btVector3 &normal, btScalar margin)
void Terminate(btScalar dt)
btMatrix3x3 transpose() const
Return the transpose of the matrix.
Face normals are flipped to match velocity and lift and drag forces are applied.
SoftBodyMaterialData * m_material
btRigidBody * m_rigidBody
#define PTR2IDX(_p_, _b_)
bool checkContact(const btCollisionObjectWrapper *colObjWrap, const btVector3 &x, btScalar margin, btSoftBody::sCti &cti) const
virtual btScalar getMargin() const =0
void(* psolver_t)(btSoftBody *, btScalar, btScalar)
static void clusterAImpulse(Cluster *cluster, const Impulse &impulse)
void scale(const btVector3 &scl)
const T & btMax(const T &a, const T &b)
const btMatrix3x3 & getInvInertiaTensorWorld() 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)
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
virtual const char * serialize(void *dataBuffer, class btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
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 prepareClusters(int iterations)
btMultiBody * m_multiBody
static void solveCommonConstraints(btSoftBody **bodies, int count, int iterations)
DBVT_INLINE const btVector3 & Mins() const
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
const btCollisionShape * getCollisionShape() const
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)
bool checkFace(int node0, int node1, int node2) const
DBVT_PREFIX void collideTV(const btDbvtNode *root, const btDbvtVolume &volume, DBVT_IPOLICY) const
int getActivationState() const
tRContactArray m_rcontacts
btScalar determinant() const
Return the determinant of the matrix.
btVector3 evaluateCom() const
float m_selfCollisionImpulseFactor
static void PSolve_Links(btSoftBody *psb, btScalar kst, btScalar ti)
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.
btScalar getVolume() const
const btScalar * getVelocityVector() const
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...
bool checkLink(int node0, int node1) const
void Terminate(btScalar dt)
btMatrix3x3FloatData m_locii
const btCollisionObject * getCollisionObject() const
btScalar btFabs(btScalar x)
void resetLinkRestLengths()
const btScalar & z() const
Return the z value.