2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
15 ///btSoftBody implementation by Nathanael Presson
17 #ifndef _BT_SOFT_BODY_H
18 #define _BT_SOFT_BODY_H
20 #include "LinearMath/btAlignedObjectArray.h"
21 #include "LinearMath/btPoint3.h"
22 #include "LinearMath/btTransform.h"
23 #include "LinearMath/btIDebugDraw.h"
24 #include "BulletDynamics/Dynamics/btRigidBody.h"
26 #include "BulletCollision/CollisionShapes/btConcaveShape.h"
27 #include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
28 #include "btSparseSDF.h"
29 #include "BulletCollision/BroadphaseCollision/btDbvt.h"
31 class btBroadphaseInterface;
32 class btCollisionDispatcher;
34 /* btSoftBodyWorldInfo */
35 struct btSoftBodyWorldInfo
38 btScalar water_density;
39 btScalar water_offset;
40 btVector3 water_normal;
41 btBroadphaseInterface* m_broadphase;
42 btCollisionDispatcher* m_dispatcher;
44 btSparseSdf<3> m_sparsesdf;
48 /// btSoftBody is work-in-progress
49 class btSoftBody : public btCollisionObject
57 struct eAeroModel { enum _ {
58 V_Point, ///Vertex normals are oriented toward velocity
59 V_TwoSided, ///Vertex normals are fliped to match velocity
60 V_OneSided, ///Vertex normals are taken as it is
61 F_TwoSided, ///Face normals are fliped to match velocity
62 F_OneSided, ///Face normals are taken as it is
66 ///eVSolver : velocities solvers
67 struct eVSolver { enum _ {
68 Linear, ///Linear solver
72 ///ePSolver : positions solvers
73 struct ePSolver { enum _ {
74 Linear, ///Linear solver
75 Anchors, ///Anchor solver
76 RContacts, ///Rigid contacts solver
77 SContacts, ///Soft contacts solver
82 struct eSolverPresets { enum _ {
90 struct eFeature { enum _ {
98 typedef btAlignedObjectArray<eVSolver::_> tVSolverArray;
99 typedef btAlignedObjectArray<ePSolver::_> tPSolverArray;
106 struct fCollision { enum _ {
107 RVSmask = 0x000f, ///Rigid versus soft mask
108 SDF_RS = 0x0001, ///SDF based rigid vs soft
109 CL_RS = 0x0002, ///Cluster vs convex rigid vs soft
111 SVSmask = 0x00f0, ///Rigid versus soft mask
112 VF_SS = 0x0010, ///Vertex vs face soft vs soft handling
113 CL_SS = 0x0020, ///Cluster vs cluster soft vs soft handling
120 struct fMaterial { enum _ {
121 DebugDraw = 0x0001, /// Enable debug draw
134 btSoftBody* body; /// soft body
135 eFeature::_ feature; /// feature type
136 int index; /// feature index
137 btScalar time; /// time of impact (rayorg+raydir*time)
143 virtual btScalar Eval(const btVector3& x)=0;
150 typedef btAlignedObjectArray<btScalar> tScalarArray;
151 typedef btAlignedObjectArray<btVector3> tVector3Array;
153 /* sCti is Softbody contact info */
156 btRigidBody* m_body; /* Rigid body */
157 btVector3 m_normal; /* Outward normal */
158 btScalar m_offset; /* Offset from origin */
164 btVector3 m_velocity; /* Velocity */
165 btScalar m_pressure; /* Pressure */
166 btScalar m_density; /* Density */
172 void* m_tag; // User data
173 Element() : m_tag(0) {}
176 struct Material : Element
178 btScalar m_kLST; // Linear stiffness coefficient [0,1]
179 btScalar m_kAST; // Area/Angular stiffness coefficient [0,1]
180 btScalar m_kVST; // Volume stiffness coefficient [0,1]
181 int m_flags; // Flags
185 struct Feature : Element
187 Material* m_material; // Material
190 struct Node : Feature
192 btVector3 m_x; // Position
193 btVector3 m_q; // Previous step position
194 btVector3 m_v; // Velocity
195 btVector3 m_f; // Force accumulator
196 btVector3 m_n; // Normal
197 btScalar m_im; // 1/mass
198 btScalar m_area; // Area
199 btDbvtNode* m_leaf; // Leaf data
200 int m_battach:1; // Attached
203 struct Link : Feature
205 Node* m_n[2]; // Node pointers
206 btScalar m_rl; // Rest length
207 int m_bbending:1; // Bending link
208 btScalar m_c0; // (ima+imb)*kLST
209 btScalar m_c1; // rl^2
210 btScalar m_c2; // |gradient|^2/c0
211 btVector3 m_c3; // gradient
214 struct Face : Feature
216 Node* m_n[3]; // Node pointers
217 btVector3 m_normal; // Normal
218 btScalar m_ra; // Rest area
219 btDbvtNode* m_leaf; // Leaf data
224 sCti m_cti; // Contact infos
225 Node* m_node; // Owner node
226 btMatrix3x3 m_c0; // Impulse matrix
227 btVector3 m_c1; // Relative anchor
228 btScalar m_c2; // ima*dt
229 btScalar m_c3; // Friction
230 btScalar m_c4; // Hardness
235 Node* m_node; // Node
236 Face* m_face; // Face
237 btVector3 m_weights; // Weigths
238 btVector3 m_normal; // Normal
239 btScalar m_margin; // Margin
240 btScalar m_friction; // Friction
241 btScalar m_cfm[2]; // Constraint force mixing
246 Node* m_node; // Node pointer
247 btVector3 m_local; // Anchor position in body space
248 btRigidBody* m_body; // Body
249 btMatrix3x3 m_c0; // Impulse matrix
250 btVector3 m_c1; // Relative anchor
251 btScalar m_c2; // ima*dt
254 struct Note : Element
256 const char* m_text; // Text
257 btVector3 m_offset; // Offset
259 Node* m_nodes[4]; // Nodes
260 btScalar m_coords[4]; // Coordinates
265 bool m_bvolume; // Is valid
266 bool m_bframe; // Is frame
267 btScalar m_volume; // Rest volume
268 tVector3Array m_pos; // Reference positions
269 tScalarArray m_wgh; // Weights
270 btVector3 m_com; // COM
271 btMatrix3x3 m_rot; // Rotation
272 btMatrix3x3 m_scl; // Scale
273 btMatrix3x3 m_aqq; // Base scaling
278 btAlignedObjectArray<Node*> m_nodes;
279 tScalarArray m_masses;
280 tVector3Array m_framerefs;
281 btTransform m_framexform;
287 btVector3 m_vimpulses[2];
288 btVector3 m_dimpulses[2];
299 Cluster() : m_leaf(0),m_ndamping(0),m_ldamping(0),m_adamping(0),m_matching(0) {}
304 btVector3 m_velocity;
308 Impulse() : m_velocity(0,0,0),m_drift(0,0,0),m_asVelocity(0),m_asDrift(0) {}
309 Impulse operator -() const
312 i.m_velocity=-i.m_velocity;
313 i.m_drift=-i.m_drift;
316 Impulse operator*(btScalar x) const
328 btRigidBody* m_rigid;
329 Body() : m_soft(0),m_rigid(0) {}
330 Body(Cluster* p) : m_soft(p),m_rigid(0) {}
331 Body(btRigidBody* p) : m_soft(0),m_rigid(p) {}
332 void activate() const
334 if(m_rigid) m_rigid->activate();
336 const btMatrix3x3& invWorldInertia() const
338 static const btMatrix3x3 iwi(0,0,0,0,0,0,0,0,0);
339 if(m_rigid) return(m_rigid->getInvInertiaTensorWorld());
340 if(m_soft) return(m_soft->m_invwi);
343 btScalar invMass() const
345 if(m_rigid) return(m_rigid->getInvMass());
346 if(m_soft) return(m_soft->m_imass);
349 const btTransform& xform() const
351 static const btTransform identity=btTransform::getIdentity();
352 if(m_rigid) return(m_rigid->getInterpolationWorldTransform());
353 if(m_soft) return(m_soft->m_framexform);
356 btVector3 linearVelocity() const
358 if(m_rigid) return(m_rigid->getLinearVelocity());
359 if(m_soft) return(m_soft->m_lv);
360 return(btVector3(0,0,0));
362 btVector3 angularVelocity(const btVector3& rpos) const
364 if(m_rigid) return(cross(m_rigid->getAngularVelocity(),rpos));
365 if(m_soft) return(cross(m_soft->m_av,rpos));
366 return(btVector3(0,0,0));
368 btVector3 angularVelocity() const
370 if(m_rigid) return(m_rigid->getAngularVelocity());
371 if(m_soft) return(m_soft->m_av);
372 return(btVector3(0,0,0));
374 btVector3 velocity(const btVector3& rpos) const
376 return(linearVelocity()+angularVelocity(rpos));
378 void applyVImpulse(const btVector3& impulse,const btVector3& rpos) const
380 if(m_rigid) m_rigid->applyImpulse(impulse,rpos);
381 if(m_soft) btSoftBody::clusterVImpulse(m_soft,rpos,impulse);
383 void applyDImpulse(const btVector3& impulse,const btVector3& rpos) const
385 if(m_rigid) m_rigid->applyImpulse(impulse,rpos);
386 if(m_soft) btSoftBody::clusterDImpulse(m_soft,rpos,impulse);
388 void applyImpulse(const Impulse& impulse,const btVector3& rpos) const
390 if(impulse.m_asVelocity) applyVImpulse(impulse.m_velocity,rpos);
391 if(impulse.m_asDrift) applyDImpulse(impulse.m_drift,rpos);
393 void applyVAImpulse(const btVector3& impulse) const
395 if(m_rigid) m_rigid->applyTorqueImpulse(impulse);
396 if(m_soft) btSoftBody::clusterVAImpulse(m_soft,impulse);
398 void applyDAImpulse(const btVector3& impulse) const
400 if(m_rigid) m_rigid->applyTorqueImpulse(impulse);
401 if(m_soft) btSoftBody::clusterDAImpulse(m_soft,impulse);
403 void applyAImpulse(const Impulse& impulse) const
405 if(impulse.m_asVelocity) applyVAImpulse(impulse.m_velocity);
406 if(impulse.m_asDrift) applyDAImpulse(impulse.m_drift);
408 void applyDCImpulse(const btVector3& impulse) const
410 if(m_rigid) m_rigid->applyCentralImpulse(impulse);
411 if(m_soft) btSoftBody::clusterDCImpulse(m_soft,impulse);
417 struct eType { enum _ {
424 Specs() : erp(1),cfm(1),split(1) {}
436 btMatrix3x3 m_massmatrix;
439 Joint() : m_delete(false) {}
440 virtual void Prepare(btScalar dt,int iterations);
441 virtual void Solve(btScalar dt,btScalar sor)=0;
442 virtual void Terminate(btScalar dt)=0;
443 virtual eType::_ Type() const=0;
446 struct LJoint : Joint
448 struct Specs : Joint::Specs
453 void Prepare(btScalar dt,int iterations);
454 void Solve(btScalar dt,btScalar sor);
455 void Terminate(btScalar dt);
456 eType::_ Type() const { return(eType::Linear); }
459 struct AJoint : Joint
463 virtual void Prepare(AJoint*) {}
464 virtual btScalar Speed(AJoint*,btScalar current) { return(current); }
465 static IControl* Default() { static IControl def;return(&def); }
467 struct Specs : Joint::Specs
469 Specs() : icontrol(IControl::Default()) {}
474 IControl* m_icontrol;
475 void Prepare(btScalar dt,int iterations);
476 void Solve(btScalar dt,btScalar sor);
477 void Terminate(btScalar dt);
478 eType::_ Type() const { return(eType::Angular); }
481 struct CJoint : Joint
488 void Prepare(btScalar dt,int iterations);
489 void Solve(btScalar dt,btScalar sor);
490 void Terminate(btScalar dt);
491 eType::_ Type() const { return(eType::Contact); }
496 eAeroModel::_ aeromodel; // Aerodynamic model (default: V_Point)
497 btScalar kVCF; // Velocities correction factor (Baumgarte)
498 btScalar kDP; // Damping coefficient [0,1]
499 btScalar kDG; // Drag coefficient [0,+inf]
500 btScalar kLF; // Lift coefficient [0,+inf]
501 btScalar kPR; // Pressure coefficient [-inf,+inf]
502 btScalar kVC; // Volume conversation coefficient [0,+inf]
503 btScalar kDF; // Dynamic friction coefficient [0,1]
504 btScalar kMT; // Pose matching coefficient [0,1]
505 btScalar kCHR; // Rigid contacts hardness [0,1]
506 btScalar kKHR; // Kinetic contacts hardness [0,1]
507 btScalar kSHR; // Soft contacts hardness [0,1]
508 btScalar kAHR; // Anchors hardness [0,1]
509 btScalar kSRHR_CL; // Soft vs rigid hardness [0,1] (cluster only)
510 btScalar kSKHR_CL; // Soft vs kinetic hardness [0,1] (cluster only)
511 btScalar kSSHR_CL; // Soft vs soft hardness [0,1] (cluster only)
512 btScalar kSR_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only)
513 btScalar kSK_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only)
514 btScalar kSS_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only)
515 btScalar maxvolume; // Maximum volume ratio for pose
516 btScalar timescale; // Time scale
517 int viterations; // Velocities solver iterations
518 int piterations; // Positions solver iterations
519 int diterations; // Drift solver iterations
520 int citerations; // Cluster solver iterations
521 int collisions; // Collisions flags
522 tVSolverArray m_vsequence; // Velocity solvers sequence
523 tPSolverArray m_psequence; // Position solvers sequence
524 tPSolverArray m_dsequence; // Drift solvers sequence
529 btScalar sdt; // dt*timescale
530 btScalar isdt; // 1/sdt
531 btScalar velmrg; // velocity margin
532 btScalar radmrg; // radial margin
533 btScalar updmrg; // Update margin
536 struct RayCaster : btDbvt::ICollide
543 RayCaster(const btVector3& org,const btVector3& dir,btScalar mxt);
544 void Process(const btDbvtNode* leaf);
545 static inline btScalar rayTriangle(const btVector3& org,
546 const btVector3& dir,
550 btScalar maxt=SIMD_INFINITY);
557 typedef void (*psolver_t)(btSoftBody*,btScalar,btScalar);
558 typedef void (*vsolver_t)(btSoftBody*,btScalar);
559 typedef btAlignedObjectArray<Cluster*> tClusterArray;
560 typedef btAlignedObjectArray<Note> tNoteArray;
561 typedef btAlignedObjectArray<Node> tNodeArray;
562 typedef btAlignedObjectArray<btDbvtNode*> tLeafArray;
563 typedef btAlignedObjectArray<Link> tLinkArray;
564 typedef btAlignedObjectArray<Face> tFaceArray;
565 typedef btAlignedObjectArray<Anchor> tAnchorArray;
566 typedef btAlignedObjectArray<RContact> tRContactArray;
567 typedef btAlignedObjectArray<SContact> tSContactArray;
568 typedef btAlignedObjectArray<Material*> tMaterialArray;
569 typedef btAlignedObjectArray<Joint*> tJointArray;
570 typedef btAlignedObjectArray<btSoftBody*> tSoftBodyArray;
576 Config m_cfg; // Configuration
577 SolverState m_sst; // Solver state
579 void* m_tag; // User data
580 btSoftBodyWorldInfo* m_worldInfo; // World info
581 tNoteArray m_notes; // Notes
582 tNodeArray m_nodes; // Nodes
583 tLinkArray m_links; // Links
584 tFaceArray m_faces; // Faces
585 tAnchorArray m_anchors; // Anchors
586 tRContactArray m_rcontacts; // Rigid contacts
587 tSContactArray m_scontacts; // Soft contacts
588 tJointArray m_joints; // Joints
589 tMaterialArray m_materials; // Materials
590 btScalar m_timeacc; // Time accumulator
591 btVector3 m_bounds[2]; // Spatial bounds
592 bool m_bUpdateRtCst; // Update runtime constants
593 btDbvt m_ndbvt; // Nodes tree
594 btDbvt m_fdbvt; // Faces tree
595 btDbvt m_cdbvt; // Clusters tree
596 tClusterArray m_clusters; // Clusters
603 btSoftBody( btSoftBodyWorldInfo* worldInfo,int node_count,
607 virtual ~btSoftBody();
608 /* Check for existing link */
609 bool checkLink( int node0,
611 bool checkLink( const Node* node0,
612 const Node* node1) const;
613 /* Check for existring face */
614 bool checkFace( int node0,
617 /* Append material */
618 Material* appendMaterial();
620 void appendNote( const char* text,
622 const btVector4& c=btVector4(1,0,0,0),
627 void appendNote( const char* text,
630 void appendNote( const char* text,
633 void appendNote( const char* text,
637 void appendNode( const btVector3& x,btScalar m);
639 void appendLink(int model=-1,Material* mat=0);
640 void appendLink( int node0,
643 bool bcheckexist=false);
644 void appendLink( Node* node0,
647 bool bcheckexist=false);
649 void appendFace(int model=-1,Material* mat=0);
650 void appendFace( int node0,
655 void appendAnchor( int node,
657 /* Append linear joint */
658 void appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1);
659 void appendLinearJoint(const LJoint::Specs& specs,Body body=Body());
660 void appendLinearJoint(const LJoint::Specs& specs,btSoftBody* body);
661 /* Append linear joint */
662 void appendAngularJoint(const AJoint::Specs& specs,Cluster* body0,Body body1);
663 void appendAngularJoint(const AJoint::Specs& specs,Body body=Body());
664 void appendAngularJoint(const AJoint::Specs& specs,btSoftBody* body);
665 /* Add force (or gravity) to the entire body */
666 void addForce( const btVector3& force);
667 /* Add force (or gravity) to a node of the body */
668 void addForce( const btVector3& force,
670 /* Add velocity to the entire body */
671 void addVelocity( const btVector3& velocity);
672 /* Add velocity to a node of the body */
673 void addVelocity( const btVector3& velocity,
676 void setMass( int node,
679 btScalar getMass( int node) const;
681 btScalar getTotalMass() const;
682 /* Set total mass (weighted by previous masses) */
683 void setTotalMass( btScalar mass,
684 bool fromfaces=false);
685 /* Set total density */
686 void setTotalDensity(btScalar density);
688 void transform( const btTransform& trs);
690 void translate( const btVector3& trs);
692 void rotate( const btQuaternion& rot);
694 void scale( const btVector3& scl);
695 /* Set current state as pose */
696 void setPose( bool bvolume,
698 /* Return the volume */
699 btScalar getVolume() const;
701 int clusterCount() const;
702 /* Cluster center of mass */
703 static btVector3 clusterCom(const Cluster* cluster);
704 btVector3 clusterCom(int cluster) const;
705 /* Cluster velocity at rpos */
706 static btVector3 clusterVelocity(const Cluster* cluster,const btVector3& rpos);
707 /* Cluster impulse */
708 static void clusterVImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse);
709 static void clusterDImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse);
710 static void clusterImpulse(Cluster* cluster,const btVector3& rpos,const Impulse& impulse);
711 static void clusterVAImpulse(Cluster* cluster,const btVector3& impulse);
712 static void clusterDAImpulse(Cluster* cluster,const btVector3& impulse);
713 static void clusterAImpulse(Cluster* cluster,const Impulse& impulse);
714 static void clusterDCImpulse(Cluster* cluster,const btVector3& impulse);
715 /* Generate bending constraints based on distance in the adjency graph */
716 int generateBendingConstraints( int distance,
718 /* Randomize constraints to reduce solver bias */
719 void randomizeConstraints();
720 /* Generate clusters (K-mean) */
721 int generateClusters(int k,int maxiterations=8192);
723 void refine(ImplicitFn* ifn,btScalar accurary,bool cut);
725 bool cutLink(int node0,int node1,btScalar position);
726 bool cutLink(const Node* node0,const Node* node1,btScalar position);
728 bool rayCast(const btVector3& org,
729 const btVector3& dir,
731 btScalar maxtime=SIMD_INFINITY);
733 void setSolver(eSolverPresets::_ preset);
735 void predictMotion(btScalar dt);
736 /* solveConstraints */
737 void solveConstraints();
739 void staticSolve(int iterations);
740 /* solveCommonConstraints */
741 static void solveCommonConstraints(btSoftBody** bodies,int count,int iterations);
743 static void solveClusters(const btAlignedObjectArray<btSoftBody*>& bodies);
744 /* integrateMotion */
745 void integrateMotion();
746 /* defaultCollisionHandlers */
747 void defaultCollisionHandler(btCollisionObject* pco);
748 void defaultCollisionHandler(btSoftBody* psb);
754 static const btSoftBody* upcast(const btCollisionObject* colObj)
756 if (colObj->getInternalType()==CO_SOFT_BODY)
757 return (const btSoftBody*)colObj;
760 static btSoftBody* upcast(btCollisionObject* colObj)
762 if (colObj->getInternalType()==CO_SOFT_BODY)
763 return (btSoftBody*)colObj;
768 // ::btCollisionObject
771 virtual void getAabb(btVector3& aabbMin,btVector3& aabbMax) const
773 aabbMin = m_bounds[0];
774 aabbMax = m_bounds[1];
779 void pointersToIndices();
780 void indicesToPointers(const int* map=0);
781 int rayCast(const btVector3& org,const btVector3& dir,
782 btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const;
783 void initializeFaceTree();
784 btVector3 evaluateCom() const;
785 bool checkContact(btRigidBody* prb,const btVector3& x,btScalar margin,btSoftBody::sCti& cti) const;
786 void updateNormals();
789 void updateConstants();
790 void initializeClusters();
791 void updateClusters();
792 void cleanupClusters();
793 void prepareClusters(int iterations);
794 void solveClusters(btScalar sor);
795 void applyClusters(bool drift);
798 static void PSolve_Anchors(btSoftBody* psb,btScalar kst,btScalar ti);
799 static void PSolve_RContacts(btSoftBody* psb,btScalar kst,btScalar ti);
800 static void PSolve_SContacts(btSoftBody* psb,btScalar,btScalar ti);
801 static void PSolve_Links(btSoftBody* psb,btScalar kst,btScalar ti);
802 static void VSolve_Links(btSoftBody* psb,btScalar kst);
803 static psolver_t getSolver(ePSolver::_ solver);
804 static vsolver_t getSolver(eVSolver::_ solver);
810 #endif //_BT_SOFT_BODY_H