27:m_softBodySolver(0),m_worldInfo(
worldInfo)
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);
357 t.m_rv =
VolumeOf(
t.m_n[0]->m_x,
t.m_n[1]->m_x,
t.m_n[2]->m_x,
t.m_n[3]->m_x);
426 pj->m_icontrol =
specs.icontrol;
1049 unsigned*
adj=
new unsigned[n*n];
1052#define IDX(_x_,_y_) ((_y_)*n+(_x_))
1122 for(
int k=0;
k<n;++
k)
1145 if(
adj[
IDX(i,
j)]==(
unsigned)distance)
1162 unsigned long seed=243703;
1163#define NEXTRAND (seed=(1664525L*seed+1013904223L)&0xffffffff)
1249 for(
int j=1;
j<
k;++
j)
1276 for(
int j=0;
j<3;++
j)
1279 for(
int q=1;
q<3;++
q)
1323 for (
int j=0;
j<4;
j++)
1340 for(
int j=0;
j<3;++
j)
1368 for (
int j=0;
j<
clb->m_nodes.size();
j++)
1370 if (
cla->m_nodes[i] ==
clb->m_nodes[
j])
1495 for(
j=2,
k=0;
k<3;
j=
k++)
1503 const int l=(
k+1)%3;
1534 if(
m>0) {
m*=0.5f;
m_nodes[i].m_im/=0.5f; }
1561 for(
int j=0;
j<2;++
j)
1576 for(
int j=0;
j<3;++
j)
1600 const bool sg[]={
ranks[
id[0]]==1,
1674 for(
int k=2,l=0;l<3;
k=l++)
1776 for (
int c=0;c<3;c++)
1963 const int nb=bodies.
size();
1978 for(
int j=0;
j<
nb;++
j)
1980 bodies[
j]->solveClusters(
sor);
1985 bodies[i]->cleanupClusters();
2011 const btScalar t=rayFromToTriangle( m_rayFrom,m_rayTo,m_rayNormalizedDirection,
2016 if((
t>0)&&(
t<m_mint))
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;
2102#define IDX2PTR(_p_,_b_) map?(&(_b_)[map[(((char*)_p_)-(char*)0)]]): \
2103 (&(_b_)[(((char*)_p_)-(char*)0)])
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++)
2408 for(
int j=0;
j<3;++
j)
2435 for(
int j=0;
j<3;++
j)
2443 m_nodes[i].m_area *= 0.3333333f;
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)
2635 for(
int j=1;
j<n;++
j)
2730 for(i=0;i<
deltas.size();++i)
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];
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];
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;
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]);
3036 if (
cti.m_colObj->hasContactResponse())
3063 for (
int j = 0;
j <
ndof ; ++
j) {
3222 pcoWrap->getCollisionShape()->getAabb(
pcoWrap->getWorldTransform(),
3327 if (
sbd->m_materials)
3344 memPtr->m_angularStiffness =
mat->m_kAST;
3345 memPtr->m_linearStiffness =
mat->m_kLST;
3346 memPtr->m_volumeStiffness =
mat->m_kVST;
3415 for (
int j=0;
j<3;
j++)
3427 if (
sbd->m_tetrahedra)
3435 for (
int j=0;
j<4;
j++)
3514 if (
memPtr->m_numPositions)
3553 if (
sbd->m_numClusters)
3577 memPtr->m_maxSelfCollisionImpulse =
m_clusters[i]->m_maxSelfCollisionImpulse;
3581 memPtr->m_selfCollisionImpulseFactor =
m_clusters[i]->m_selfCollisionImpulseFactor;
3623 if (
memPtr->m_nodeIndices )
3626 int sz =
sizeof(
int);
3664 for (
int j=0;
j<4;
j++)
3666 memPtr->m_relPosition[0].m_floats[
j] = 0.f;
3667 memPtr->m_relPosition[1].m_floats[
j] = 0.f;
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)
#define btAlignedFree(ptr)
#define btAlignedAlloc(size, alignment)
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
const T & btMax(const T &a, const T &b)
const T & btMin(const T &a, const T &b)
btScalar dot(const btQuaternion &q1, const btQuaternion &q2)
Calculate the dot product between two quaternions.
btScalar length(const btQuaternion &q)
Return the length of a quaternion.
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
#define ATTRIBUTE_ALIGNED16(a)
btScalar btSqrt(btScalar y)
btScalar btFabs(btScalar x)
btScalar btAcos(btScalar x)
bool btFuzzyZero(btScalar x)
#define BT_SBMATERIAL_CODE
@ BT_JOINT_SOFT_BODY_CLUSTER
@ BT_JOINT_COLLISION_OBJECT
static T sum(const btAlignedObjectArray< T > &items)
static btMatrix3x3 Mul(const btMatrix3x3 &a, btScalar b)
static btScalar ImplicitSolve(btSoftBody::ImplicitFn *fn, const btVector3 &a, const btVector3 &b, const btScalar accuracy, const int maxiterations=256)
static btDbvtVolume VolumeOf(const btSoftBody::Face &f, btScalar margin)
static T Lerp(const T &a, const T &b, btScalar t)
static btMatrix3x3 AngularImpulseMatrix(const btMatrix3x3 &iia, const btMatrix3x3 &iib)
static btScalar AreaOf(const btVector3 &x0, const btVector3 &x1, const btVector3 &x2)
static btVector3 NormalizeAny(const btVector3 &v)
static int PolarDecompose(const btMatrix3x3 &m, btMatrix3x3 &q, btMatrix3x3 &s)
static int MatchEdge(const btSoftBody::Node *a, const btSoftBody::Node *b, const btSoftBody::Node *ma, const btSoftBody::Node *mb)
static T BaryEval(const T &a, const T &b, const T &c, const btVector3 &coord)
static bool SameSign(const T &x, const T &y)
static void EvaluateMedium(const btSoftBodyWorldInfo *wfi, const btVector3 &x, btSoftBody::sMedium &medium)
static void ZeroInitialize(T &value)
static btVector3 ProjectOnPlane(const btVector3 &v, const btVector3 &a)
static btScalar ClusterMetric(const btVector3 &x, const btVector3 &y)
static btMatrix3x3 ImpulseMatrix(btScalar dt, btScalar ima, btScalar imb, const btMatrix3x3 &iwi, const btVector3 &r)
static void ApplyClampedForce(btSoftBody::Node &n, const btVector3 &f, btScalar dt)
static btVector3 Clamp(const btVector3 &v, btScalar maxlength)
#define IDX2PTR(_p_, _b_)
#define PTR2IDX(_p_, _b_)
#define btSoftBodyDataName
#define btSoftBodyData
btSoftBody implementation by Nathanael Presson
btScalar btDot(const btVector3 &v1, const btVector3 &v2)
Return the dot product between two vectors.
btVector3 btCross(const btVector3 &v1, const btVector3 &v2)
Return the cross product of two vectors.
The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods It...
int size() const
return the number of elements in the array
int findLinearSearch(const T &key) const
void resize(int newsize, const T &fillData=T())
void clear()
clear the array, deallocated memory. Generally it is better to use array.resize(0),...
void remove(const T &key)
void push_back(const T &_Val)
int capacity() const
return the pre-allocated (reserved) elements, this is at least as large as the total number of elemen...
virtual void setAabb(btBroadphaseProxy *proxy, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)=0
virtual const char * serialize(void *dataBuffer, class btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
btTransform & getWorldTransform()
btBroadphaseProxy * getBroadphaseHandle()
btTransform m_worldTransform
btCollisionShape * m_collisionShape
void activate(bool forceActivation=false) const
int m_internalType
m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody,...
const btCollisionShape * getCollisionShape() const
int getActivationState() const
The btCollisionShape class provides an interface for collision shapes that can be shared among btColl...
virtual void setMargin(btScalar margin)=0
virtual btScalar getMargin() const =0
The btHashMap template class implements a generic and lightweight hashmap.
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
btMatrix3x3 inverse() const
Return the inverse of the matrix.
btMatrix3x3 transpose() const
Return the transpose of the matrix.
void setIdentity()
Set the matrix to the identity.
void serializeFloat(struct btMatrix3x3FloatData &dataOut) const
static btMultiBodyLinkCollider * upcast(btCollisionObject *colObj)
btMultiBody * m_multiBody
The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatr...
The btRigidBody is the main class for rigid body objects.
btVector3 getVelocityInLocalPoint(const btVector3 &rel_pos) const
btScalar getInvMass() const
void applyImpulse(const btVector3 &impulse, const btVector3 &rel_pos)
static const btRigidBody * upcast(const btCollisionObject *colObj)
to keep collision detection and dynamics separate we don't store a rigidbody pointer but a rigidbody ...
const btMatrix3x3 & getInvInertiaTensorWorld() const
The btSoftBody is an class to simulate cloth and volumetric soft bodies.
static void PSolve_Links(btSoftBody *psb, btScalar kst, btScalar ti)
static void PSolve_SContacts(btSoftBody *psb, btScalar, btScalar ti)
bool checkLink(int node0, int node1) const
bool checkFace(int node0, int node1, int node2) const
void setPose(bool bvolume, bool bframe)
bool cutLink(int node0, int node1, btScalar position)
void appendFace(int model=-1, Material *mat=0)
void setMass(int node, btScalar mass)
void appendLinearJoint(const LJoint::Specs &specs, Cluster *body0, Body body1)
void scale(const btVector3 &scl)
btAlignedObjectArray< bool > m_clusterConnectivity
void defaultCollisionHandler(const btCollisionObjectWrapper *pcoWrap)
btScalar getVolume() const
bool rayTest(const btVector3 &rayFrom, const btVector3 &rayTo, sRayCast &results)
Ray casting using rayFrom and rayTo in worldspace, (not direction!)
void addVelocity(const btVector3 &velocity)
void predictMotion(btScalar dt)
void appendTetra(int model, Material *mat)
void setRestLengthScale(btScalar restLength)
void rotate(const btQuaternion &rot)
void applyClusters(bool drift)
static void PSolve_Anchors(btSoftBody *psb, btScalar kst, btScalar ti)
btSoftBodyWorldInfo * m_worldInfo
void updateArea(bool averageArea=true)
void addForce(const btVector3 &force)
void prepareClusters(int iterations)
static void clusterVImpulse(Cluster *cluster, const btVector3 &rpos, const btVector3 &impulse)
virtual const char * serialize(void *dataBuffer, class btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
static void VSolve_Links(btSoftBody *psb, btScalar kst)
btVector3 evaluateCom() const
void setTotalDensity(btScalar density)
btAlignedObjectArray< const class btCollisionObject * > m_collisionDisabledObjects
static void clusterDAImpulse(Cluster *cluster, const btVector3 &impulse)
void appendNode(const btVector3 &x, btScalar m)
btTransform m_initialWorldTransform
void staticSolve(int iterations)
void setVolumeMass(btScalar mass)
btScalar m_restLengthScale
const btVector3 & getWindVelocity()
Return the wind velocity for interaction with the air.
void addAeroForceToFace(const btVector3 &windVelocity, int faceIndex)
void appendAngularJoint(const AJoint::Specs &specs, Cluster *body0, Body body1)
void setVolumeDensity(btScalar density)
static void clusterDCImpulse(Cluster *cluster, const btVector3 &impulse)
void transform(const btTransform &trs)
static void clusterVAImpulse(Cluster *cluster, const btVector3 &impulse)
btScalar getMass(int node) const
tMaterialArray m_materials
btSoftBody(btSoftBodyWorldInfo *worldInfo, int node_count, const btVector3 *x, const btScalar *m)
btSoftBody implementation by Nathanael Presson
void addAeroForceToNode(const btVector3 &windVelocity, int nodeIndex)
static btVector3 clusterCom(const Cluster *cluster)
tRContactArray m_rcontacts
void appendAnchor(int node, btRigidBody *body, bool disableCollisionBetweenLinkedBodies=false, btScalar influence=1)
void releaseCluster(int index)
void setVelocity(const btVector3 &velocity)
int generateClusters(int k, int maxiterations=8192)
generateClusters with k=0 will create a convex cluster for each tetrahedron or triangle otherwise an ...
void refine(ImplicitFn *ifn, btScalar accurary, bool cut)
void setSolver(eSolverPresets::_ preset)
Material * appendMaterial()
static void solveClusters(const btAlignedObjectArray< btSoftBody * > &bodies)
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)
virtual int calculateSerializeBufferSize() const
static void PSolve_RContacts(btSoftBody *psb, btScalar kst, btScalar ti)
static void clusterImpulse(Cluster *cluster, const btVector3 &rpos, const Impulse &impulse)
static void clusterDImpulse(Cluster *cluster, const btVector3 &rpos, const btVector3 &impulse)
static btVector3 clusterVelocity(const Cluster *cluster, const btVector3 &rpos)
tSContactArray m_scontacts
void(* psolver_t)(btSoftBody *, btScalar, btScalar)
void initializeClusters()
btScalar getRestLengthScale()
void randomizeConstraints()
btScalar getTotalMass() const
void appendLink(int model=-1, Material *mat=0)
void setTotalMass(btScalar mass, bool fromfaces=false)
void updateLinkConstants()
void(* vsolver_t)(btSoftBody *, btScalar)
static psolver_t getSolver(ePSolver::_ solver)
bool checkContact(const btCollisionObjectWrapper *colObjWrap, const btVector3 &x, btScalar margin, btSoftBody::sCti &cti) const
void indicesToPointers(const int *map=0)
static void solveCommonConstraints(btSoftBody **bodies, int count, int iterations)
void setWindVelocity(const btVector3 &velocity)
Set a wind velocity for interaction with the air.
int generateBendingConstraints(int distance, Material *mat=0)
void translate(const btVector3 &trs)
void initializeFaceTree()
void resetLinkRestLengths()
static void clusterAImpulse(Cluster *cluster, const Impulse &impulse)
btVector3 can be used to represent 3D points and vectors.
void setMax(const btVector3 &other)
Set each element to the max of the current values and the values of another btVector3.
const btScalar & w() const
Return the w value.
const btScalar & z() const
Return the z value.
btScalar length() const
Return the length of the vector.
void serializeFloat(struct btVector3FloatData &dataOut) const
btVector3 normalized() const
Return a normalized version of this vector.
btScalar length2() const
Return the length of the vector squared.
const btScalar & x() const
Return the x value.
void setMin(const btVector3 &other)
Set each element to the min of the current values and the values of another btVector3.
const btScalar & y() const
Return the y value.
btAlignedObjectArray< int > m_links
static btDbvtAabbMm FromMM(const btVector3 &mi, const btVector3 &mx)
DBVT_INLINE const btVector3 & Mins() const
static btDbvtAabbMm FromCR(const btVector3 &c, btScalar r)
DBVT_INLINE const btVector3 & Maxs() const
btDbvtNode * insert(const btDbvtVolume &box, void *data)
void optimizeIncremental(int passes)
void update(btDbvtNode *leaf, int lookahead=-1)
DBVT_PREFIX void collideTV(const btDbvtNode *root, const btDbvtVolume &volume, DBVT_IPOLICY) const
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...
void remove(btDbvtNode *leaf)
DBVT_PREFIX void collideTT(const btDbvtNode *root0, const btDbvtNode *root1, DBVT_IPOLICY)
btDispatcher * m_dispatcher
btSparseSdf< 3 > m_sparsesdf
btScalar m_maxDisplacement
btBroadphaseInterface * m_broadphase
void Prepare(btScalar dt, int iterations)
void Solve(btScalar dt, btScalar sor)
void Terminate(btScalar dt)
const btTransform & xform() const
void Terminate(btScalar dt)
void Prepare(btScalar dt, int iterations)
void Solve(btScalar dt, btScalar sor)
tVector3Array m_framerefs
btAlignedObjectArray< Node * > m_nodes
tPSolverArray m_psequence
tPSolverArray m_dsequence
tVSolverArray m_vsequence
virtual void Prepare(btScalar dt, int iterations)
void Solve(btScalar dt, btScalar sor)
void Prepare(btScalar dt, int iterations)
void Terminate(btScalar dt)
RayFromToCaster takes a ray from, ray to (instead of direction!)
RayFromToCaster(const btVector3 &rayFrom, const btVector3 &rayTo, btScalar mxt)
void Process(const btDbvtNode *leaf)
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)
btVector3 m_rayNormalizedDirection
@ V_TwoSided
Vertex normals are oriented toward velocity.
@ V_OneSided
Vertex normals are flipped to match velocity and lift and drag forces are applied.
@ V_TwoSidedLiftDrag
Vertex normals are flipped to match velocity
@ F_OneSided
Face normals are flipped to match velocity and lift and drag forces are applied.
@ F_TwoSided
Vertex normals are taken as it is
@ F_TwoSidedLiftDrag
Face normals are flipped to match velocity.
@ RContacts
Anchor solver.
@ SContacts
Rigid contacts solver.
@ VF_SS
Rigid versus soft mask
@ Default
Cluster soft body self collision.
@ CL_SS
Vertex vs face soft vs soft handling.
@ CL_SELF
Cluster vs cluster soft vs soft handling.
@ SVSmask
Cluster vs convex rigid vs soft.
@ SDF_RS
Rigid versus soft mask.
@ CL_RS
SDF based rigid vs soft.
@ Default
Enable debug draw.
void ProcessColObj(btSoftBody *ps, const btCollisionObjectWrapper *colObWrap)
void ProcessSoftSoft(btSoftBody *psa, btSoftBody *psb)
btScalar Evaluate(const btVector3 &x, const btCollisionShape *shape, btVector3 &normal, btScalar margin)
btSoftBody implementation by Nathanael Presson