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 */
611 virtual void setCollisionShape(btCollisionShape* collisionShape)
613 //don't do anything, due to the internal shape hack: todo: fix this
616 bool checkLink( int node0,
618 bool checkLink( const Node* node0,
619 const Node* node1) const;
620 /* Check for existring face */
621 bool checkFace( int node0,
624 /* Append material */
625 Material* appendMaterial();
627 void appendNote( const char* text,
629 const btVector4& c=btVector4(1,0,0,0),
634 void appendNote( const char* text,
637 void appendNote( const char* text,
640 void appendNote( const char* text,
644 void appendNode( const btVector3& x,btScalar m);
646 void appendLink(int model=-1,Material* mat=0);
647 void appendLink( int node0,
650 bool bcheckexist=false);
651 void appendLink( Node* node0,
654 bool bcheckexist=false);
656 void appendFace(int model=-1,Material* mat=0);
657 void appendFace( int node0,
662 void appendAnchor( int node,
664 /* Append linear joint */
665 void appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1);
666 void appendLinearJoint(const LJoint::Specs& specs,Body body=Body());
667 void appendLinearJoint(const LJoint::Specs& specs,btSoftBody* body);
668 /* Append linear joint */
669 void appendAngularJoint(const AJoint::Specs& specs,Cluster* body0,Body body1);
670 void appendAngularJoint(const AJoint::Specs& specs,Body body=Body());
671 void appendAngularJoint(const AJoint::Specs& specs,btSoftBody* body);
672 /* Add force (or gravity) to the entire body */
673 void addForce( const btVector3& force);
674 /* Add force (or gravity) to a node of the body */
675 void addForce( const btVector3& force,
677 /* Add velocity to the entire body */
678 void addVelocity( const btVector3& velocity);
679 /* Add velocity to a node of the body */
680 void addVelocity( const btVector3& velocity,
683 void setMass( int node,
686 btScalar getMass( int node) const;
688 btScalar getTotalMass() const;
689 /* Set total mass (weighted by previous masses) */
690 void setTotalMass( btScalar mass,
691 bool fromfaces=false);
692 /* Set total density */
693 void setTotalDensity(btScalar density);
695 void transform( const btTransform& trs);
697 void translate( const btVector3& trs);
699 void rotate( const btQuaternion& rot);
701 void scale( const btVector3& scl);
702 /* Set current state as pose */
703 void setPose( bool bvolume,
705 /* Return the volume */
706 btScalar getVolume() const;
708 int clusterCount() const;
709 /* Cluster center of mass */
710 static btVector3 clusterCom(const Cluster* cluster);
711 btVector3 clusterCom(int cluster) const;
712 /* Cluster velocity at rpos */
713 static btVector3 clusterVelocity(const Cluster* cluster,const btVector3& rpos);
714 /* Cluster impulse */
715 static void clusterVImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse);
716 static void clusterDImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse);
717 static void clusterImpulse(Cluster* cluster,const btVector3& rpos,const Impulse& impulse);
718 static void clusterVAImpulse(Cluster* cluster,const btVector3& impulse);
719 static void clusterDAImpulse(Cluster* cluster,const btVector3& impulse);
720 static void clusterAImpulse(Cluster* cluster,const Impulse& impulse);
721 static void clusterDCImpulse(Cluster* cluster,const btVector3& impulse);
722 /* Generate bending constraints based on distance in the adjency graph */
723 int generateBendingConstraints( int distance,
725 /* Randomize constraints to reduce solver bias */
726 void randomizeConstraints();
727 /* Release clusters */
728 void releaseCluster(int index);
729 void releaseClusters();
730 /* Generate clusters (K-mean) */
731 int generateClusters(int k,int maxiterations=8192);
733 void refine(ImplicitFn* ifn,btScalar accurary,bool cut);
735 bool cutLink(int node0,int node1,btScalar position);
736 bool cutLink(const Node* node0,const Node* node1,btScalar position);
738 bool rayCast(const btVector3& org,
739 const btVector3& dir,
741 btScalar maxtime=SIMD_INFINITY);
743 void setSolver(eSolverPresets::_ preset);
745 void predictMotion(btScalar dt);
746 /* solveConstraints */
747 void solveConstraints();
749 void staticSolve(int iterations);
750 /* solveCommonConstraints */
751 static void solveCommonConstraints(btSoftBody** bodies,int count,int iterations);
753 static void solveClusters(const btAlignedObjectArray<btSoftBody*>& bodies);
754 /* integrateMotion */
755 void integrateMotion();
756 /* defaultCollisionHandlers */
757 void defaultCollisionHandler(btCollisionObject* pco);
758 void defaultCollisionHandler(btSoftBody* psb);
764 static const btSoftBody* upcast(const btCollisionObject* colObj)
766 if (colObj->getInternalType()==CO_SOFT_BODY)
767 return (const btSoftBody*)colObj;
770 static btSoftBody* upcast(btCollisionObject* colObj)
772 if (colObj->getInternalType()==CO_SOFT_BODY)
773 return (btSoftBody*)colObj;
778 // ::btCollisionObject
781 virtual void getAabb(btVector3& aabbMin,btVector3& aabbMax) const
783 aabbMin = m_bounds[0];
784 aabbMax = m_bounds[1];
789 void pointersToIndices();
790 void indicesToPointers(const int* map=0);
791 int rayCast(const btVector3& org,const btVector3& dir,
792 btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const;
793 void initializeFaceTree();
794 btVector3 evaluateCom() const;
795 bool checkContact(btRigidBody* prb,const btVector3& x,btScalar margin,btSoftBody::sCti& cti) const;
796 void updateNormals();
799 void updateConstants();
800 void initializeClusters();
801 void updateClusters();
802 void cleanupClusters();
803 void prepareClusters(int iterations);
804 void solveClusters(btScalar sor);
805 void applyClusters(bool drift);
808 static void PSolve_Anchors(btSoftBody* psb,btScalar kst,btScalar ti);
809 static void PSolve_RContacts(btSoftBody* psb,btScalar kst,btScalar ti);
810 static void PSolve_SContacts(btSoftBody* psb,btScalar,btScalar ti);
811 static void PSolve_Links(btSoftBody* psb,btScalar kst,btScalar ti);
812 static void VSolve_Links(btSoftBody* psb,btScalar kst);
813 static psolver_t getSolver(ePSolver::_ solver);
814 static vsolver_t getSolver(eVSolver::_ solver);
820 #endif //_BT_SOFT_BODY_H