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/btTransform.h"
22 #include "LinearMath/btIDebugDraw.h"
23 #include "BulletDynamics/Dynamics/btRigidBody.h"
25 #include "BulletCollision/CollisionShapes/btConcaveShape.h"
26 #include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
27 #include "btSparseSDF.h"
28 #include "BulletCollision/BroadphaseCollision/btDbvt.h"
30 //#ifdef BT_USE_DOUBLE_PRECISION
31 //#define btRigidBodyData btRigidBodyDoubleData
32 //#define btRigidBodyDataName "btRigidBodyDoubleData"
34 #define btSoftBodyData btSoftBodyFloatData
35 #define btSoftBodyDataName "btSoftBodyFloatData"
36 //#endif //BT_USE_DOUBLE_PRECISION
38 class btBroadphaseInterface;
40 class btSoftBodySolver;
42 /* btSoftBodyWorldInfo */
43 struct btSoftBodyWorldInfo
46 btScalar water_density;
47 btScalar water_offset;
48 btVector3 water_normal;
49 btBroadphaseInterface* m_broadphase;
50 btDispatcher* m_dispatcher;
52 btSparseSdf<3> m_sparsesdf;
55 :air_density((btScalar)1.2),
67 ///The btSoftBody is an class to simulate cloth and volumetric soft bodies.
68 ///There is two-way interaction between btSoftBody and btRigidBody/btCollisionObject.
69 class btSoftBody : public btCollisionObject
72 btAlignedObjectArray<const class btCollisionObject*> m_collisionDisabledObjects;
74 // The solver object that handles this soft body
75 btSoftBodySolver *m_softBodySolver;
82 struct eAeroModel { enum _ {
83 V_Point, ///Vertex normals are oriented toward velocity
84 V_TwoSided, ///Vertex normals are flipped to match velocity
85 V_TwoSidedLiftDrag, ///Vertex normals are flipped to match velocity and lift and drag forces are applied
86 V_OneSided, ///Vertex normals are taken as it is
87 F_TwoSided, ///Face normals are flipped to match velocity
88 F_TwoSidedLiftDrag, ///Face normals are flipped to match velocity and lift and drag forces are applied
89 F_OneSided, ///Face normals are taken as it is
93 ///eVSolver : velocities solvers
94 struct eVSolver { enum _ {
95 Linear, ///Linear solver
99 ///ePSolver : positions solvers
100 struct ePSolver { enum _ {
101 Linear, ///Linear solver
102 Anchors, ///Anchor solver
103 RContacts, ///Rigid contacts solver
104 SContacts, ///Soft contacts solver
109 struct eSolverPresets { enum _ {
117 struct eFeature { enum _ {
126 typedef btAlignedObjectArray<eVSolver::_> tVSolverArray;
127 typedef btAlignedObjectArray<ePSolver::_> tPSolverArray;
134 struct fCollision { enum _ {
135 RVSmask = 0x000f, ///Rigid versus soft mask
136 SDF_RS = 0x0001, ///SDF based rigid vs soft
137 CL_RS = 0x0002, ///Cluster vs convex rigid vs soft
139 SVSmask = 0x0030, ///Rigid versus soft mask
140 VF_SS = 0x0010, ///Vertex vs face soft vs soft handling
141 CL_SS = 0x0020, ///Cluster vs cluster soft vs soft handling
142 CL_SELF = 0x0040, ///Cluster soft body self collision
149 struct fMaterial { enum _ {
150 DebugDraw = 0x0001, /// Enable debug draw
163 btSoftBody* body; /// soft body
164 eFeature::_ feature; /// feature type
165 int index; /// feature index
166 btScalar fraction; /// time of impact fraction (rayorg+(rayto-rayfrom)*fraction)
172 virtual btScalar Eval(const btVector3& x)=0;
179 typedef btAlignedObjectArray<btScalar> tScalarArray;
180 typedef btAlignedObjectArray<btVector3> tVector3Array;
182 /* sCti is Softbody contact info */
185 const btCollisionObject* m_colObj; /* Rigid body */
186 btVector3 m_normal; /* Outward normal */
187 btScalar m_offset; /* Offset from origin */
193 btVector3 m_velocity; /* Velocity */
194 btScalar m_pressure; /* Pressure */
195 btScalar m_density; /* Density */
201 void* m_tag; // User data
202 Element() : m_tag(0) {}
205 struct Material : Element
207 btScalar m_kLST; // Linear stiffness coefficient [0,1]
208 btScalar m_kAST; // Area/Angular stiffness coefficient [0,1]
209 btScalar m_kVST; // Volume stiffness coefficient [0,1]
210 int m_flags; // Flags
214 struct Feature : Element
216 Material* m_material; // Material
219 struct Node : Feature
221 btVector3 m_x; // Position
222 btVector3 m_q; // Previous step position
223 btVector3 m_v; // Velocity
224 btVector3 m_f; // Force accumulator
225 btVector3 m_n; // Normal
226 btScalar m_im; // 1/mass
227 btScalar m_area; // Area
228 btDbvtNode* m_leaf; // Leaf data
229 int m_battach:1; // Attached
232 struct Link : Feature
234 Node* m_n[2]; // Node pointers
235 btScalar m_rl; // Rest length
236 int m_bbending:1; // Bending link
237 btScalar m_c0; // (ima+imb)*kLST
238 btScalar m_c1; // rl^2
239 btScalar m_c2; // |gradient|^2/c0
240 btVector3 m_c3; // gradient
243 struct Face : Feature
245 Node* m_n[3]; // Node pointers
246 btVector3 m_normal; // Normal
247 btScalar m_ra; // Rest area
248 btDbvtNode* m_leaf; // Leaf data
251 struct Tetra : Feature
253 Node* m_n[4]; // Node pointers
254 btScalar m_rv; // Rest volume
255 btDbvtNode* m_leaf; // Leaf data
256 btVector3 m_c0[4]; // gradients
257 btScalar m_c1; // (4*kVST)/(im0+im1+im2+im3)
258 btScalar m_c2; // m_c1/sum(|g0..3|^2)
263 sCti m_cti; // Contact infos
264 Node* m_node; // Owner node
265 btMatrix3x3 m_c0; // Impulse matrix
266 btVector3 m_c1; // Relative anchor
267 btScalar m_c2; // ima*dt
268 btScalar m_c3; // Friction
269 btScalar m_c4; // Hardness
274 Node* m_node; // Node
275 Face* m_face; // Face
276 btVector3 m_weights; // Weigths
277 btVector3 m_normal; // Normal
278 btScalar m_margin; // Margin
279 btScalar m_friction; // Friction
280 btScalar m_cfm[2]; // Constraint force mixing
285 Node* m_node; // Node pointer
286 btVector3 m_local; // Anchor position in body space
287 btRigidBody* m_body; // Body
288 btScalar m_influence;
289 btMatrix3x3 m_c0; // Impulse matrix
290 btVector3 m_c1; // Relative anchor
291 btScalar m_c2; // ima*dt
294 struct Note : Element
296 const char* m_text; // Text
297 btVector3 m_offset; // Offset
299 Node* m_nodes[4]; // Nodes
300 btScalar m_coords[4]; // Coordinates
305 bool m_bvolume; // Is valid
306 bool m_bframe; // Is frame
307 btScalar m_volume; // Rest volume
308 tVector3Array m_pos; // Reference positions
309 tScalarArray m_wgh; // Weights
310 btVector3 m_com; // COM
311 btMatrix3x3 m_rot; // Rotation
312 btMatrix3x3 m_scl; // Scale
313 btMatrix3x3 m_aqq; // Base scaling
318 tScalarArray m_masses;
319 btAlignedObjectArray<Node*> m_nodes;
320 tVector3Array m_framerefs;
321 btTransform m_framexform;
327 btVector3 m_vimpulses[2];
328 btVector3 m_dimpulses[2];
334 btScalar m_ndamping; /* Node damping */
335 btScalar m_ldamping; /* Linear damping */
336 btScalar m_adamping; /* Angular damping */
338 btScalar m_maxSelfCollisionImpulse;
339 btScalar m_selfCollisionImpulseFactor;
340 bool m_containsAnchor;
343 Cluster() : m_leaf(0),m_ndamping(0),m_ldamping(0),m_adamping(0),m_matching(0)
344 ,m_maxSelfCollisionImpulse(100.f),
345 m_selfCollisionImpulseFactor(0.01f),
346 m_containsAnchor(false)
352 btVector3 m_velocity;
356 Impulse() : m_velocity(0,0,0),m_drift(0,0,0),m_asVelocity(0),m_asDrift(0) {}
357 Impulse operator -() const
360 i.m_velocity=-i.m_velocity;
361 i.m_drift=-i.m_drift;
364 Impulse operator*(btScalar x) const
376 btRigidBody* m_rigid;
377 const btCollisionObject* m_collisionObject;
379 Body() : m_soft(0),m_rigid(0),m_collisionObject(0) {}
380 Body(Cluster* p) : m_soft(p),m_rigid(0),m_collisionObject(0) {}
381 Body(const btCollisionObject* colObj) : m_soft(0),m_collisionObject(colObj)
383 m_rigid = (btRigidBody*)btRigidBody::upcast(m_collisionObject);
386 void activate() const
390 if (m_collisionObject)
391 m_collisionObject->activate();
394 const btMatrix3x3& invWorldInertia() const
396 static const btMatrix3x3 iwi(0,0,0,0,0,0,0,0,0);
397 if(m_rigid) return(m_rigid->getInvInertiaTensorWorld());
398 if(m_soft) return(m_soft->m_invwi);
401 btScalar invMass() const
403 if(m_rigid) return(m_rigid->getInvMass());
404 if(m_soft) return(m_soft->m_imass);
407 const btTransform& xform() const
409 static const btTransform identity=btTransform::getIdentity();
410 if(m_collisionObject) return(m_collisionObject->getWorldTransform());
411 if(m_soft) return(m_soft->m_framexform);
414 btVector3 linearVelocity() const
416 if(m_rigid) return(m_rigid->getLinearVelocity());
417 if(m_soft) return(m_soft->m_lv);
418 return(btVector3(0,0,0));
420 btVector3 angularVelocity(const btVector3& rpos) const
422 if(m_rigid) return(btCross(m_rigid->getAngularVelocity(),rpos));
423 if(m_soft) return(btCross(m_soft->m_av,rpos));
424 return(btVector3(0,0,0));
426 btVector3 angularVelocity() const
428 if(m_rigid) return(m_rigid->getAngularVelocity());
429 if(m_soft) return(m_soft->m_av);
430 return(btVector3(0,0,0));
432 btVector3 velocity(const btVector3& rpos) const
434 return(linearVelocity()+angularVelocity(rpos));
436 void applyVImpulse(const btVector3& impulse,const btVector3& rpos) const
438 if(m_rigid) m_rigid->applyImpulse(impulse,rpos);
439 if(m_soft) btSoftBody::clusterVImpulse(m_soft,rpos,impulse);
441 void applyDImpulse(const btVector3& impulse,const btVector3& rpos) const
443 if(m_rigid) m_rigid->applyImpulse(impulse,rpos);
444 if(m_soft) btSoftBody::clusterDImpulse(m_soft,rpos,impulse);
446 void applyImpulse(const Impulse& impulse,const btVector3& rpos) const
448 if(impulse.m_asVelocity)
450 // printf("impulse.m_velocity = %f,%f,%f\n",impulse.m_velocity.getX(),impulse.m_velocity.getY(),impulse.m_velocity.getZ());
451 applyVImpulse(impulse.m_velocity,rpos);
453 if(impulse.m_asDrift)
455 // printf("impulse.m_drift = %f,%f,%f\n",impulse.m_drift.getX(),impulse.m_drift.getY(),impulse.m_drift.getZ());
456 applyDImpulse(impulse.m_drift,rpos);
459 void applyVAImpulse(const btVector3& impulse) const
461 if(m_rigid) m_rigid->applyTorqueImpulse(impulse);
462 if(m_soft) btSoftBody::clusterVAImpulse(m_soft,impulse);
464 void applyDAImpulse(const btVector3& impulse) const
466 if(m_rigid) m_rigid->applyTorqueImpulse(impulse);
467 if(m_soft) btSoftBody::clusterDAImpulse(m_soft,impulse);
469 void applyAImpulse(const Impulse& impulse) const
471 if(impulse.m_asVelocity) applyVAImpulse(impulse.m_velocity);
472 if(impulse.m_asDrift) applyDAImpulse(impulse.m_drift);
474 void applyDCImpulse(const btVector3& impulse) const
476 if(m_rigid) m_rigid->applyCentralImpulse(impulse);
477 if(m_soft) btSoftBody::clusterDCImpulse(m_soft,impulse);
483 struct eType { enum _ {
490 Specs() : erp(1),cfm(1),split(1) {}
502 btMatrix3x3 m_massmatrix;
505 Joint() : m_delete(false) {}
506 virtual void Prepare(btScalar dt,int iterations);
507 virtual void Solve(btScalar dt,btScalar sor)=0;
508 virtual void Terminate(btScalar dt)=0;
509 virtual eType::_ Type() const=0;
512 struct LJoint : Joint
514 struct Specs : Joint::Specs
519 void Prepare(btScalar dt,int iterations);
520 void Solve(btScalar dt,btScalar sor);
521 void Terminate(btScalar dt);
522 eType::_ Type() const { return(eType::Linear); }
525 struct AJoint : Joint
529 virtual void Prepare(AJoint*) {}
530 virtual btScalar Speed(AJoint*,btScalar current) { return(current); }
531 static IControl* Default() { static IControl def;return(&def); }
533 struct Specs : Joint::Specs
535 Specs() : icontrol(IControl::Default()) {}
540 IControl* m_icontrol;
541 void Prepare(btScalar dt,int iterations);
542 void Solve(btScalar dt,btScalar sor);
543 void Terminate(btScalar dt);
544 eType::_ Type() const { return(eType::Angular); }
547 struct CJoint : Joint
554 void Prepare(btScalar dt,int iterations);
555 void Solve(btScalar dt,btScalar sor);
556 void Terminate(btScalar dt);
557 eType::_ Type() const { return(eType::Contact); }
562 eAeroModel::_ aeromodel; // Aerodynamic model (default: V_Point)
563 btScalar kVCF; // Velocities correction factor (Baumgarte)
564 btScalar kDP; // Damping coefficient [0,1]
565 btScalar kDG; // Drag coefficient [0,+inf]
566 btScalar kLF; // Lift coefficient [0,+inf]
567 btScalar kPR; // Pressure coefficient [-inf,+inf]
568 btScalar kVC; // Volume conversation coefficient [0,+inf]
569 btScalar kDF; // Dynamic friction coefficient [0,1]
570 btScalar kMT; // Pose matching coefficient [0,1]
571 btScalar kCHR; // Rigid contacts hardness [0,1]
572 btScalar kKHR; // Kinetic contacts hardness [0,1]
573 btScalar kSHR; // Soft contacts hardness [0,1]
574 btScalar kAHR; // Anchors hardness [0,1]
575 btScalar kSRHR_CL; // Soft vs rigid hardness [0,1] (cluster only)
576 btScalar kSKHR_CL; // Soft vs kinetic hardness [0,1] (cluster only)
577 btScalar kSSHR_CL; // Soft vs soft hardness [0,1] (cluster only)
578 btScalar kSR_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only)
579 btScalar kSK_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only)
580 btScalar kSS_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only)
581 btScalar maxvolume; // Maximum volume ratio for pose
582 btScalar timescale; // Time scale
583 int viterations; // Velocities solver iterations
584 int piterations; // Positions solver iterations
585 int diterations; // Drift solver iterations
586 int citerations; // Cluster solver iterations
587 int collisions; // Collisions flags
588 tVSolverArray m_vsequence; // Velocity solvers sequence
589 tPSolverArray m_psequence; // Position solvers sequence
590 tPSolverArray m_dsequence; // Drift solvers sequence
595 btScalar sdt; // dt*timescale
596 btScalar isdt; // 1/sdt
597 btScalar velmrg; // velocity margin
598 btScalar radmrg; // radial margin
599 btScalar updmrg; // Update margin
601 /// RayFromToCaster takes a ray from, ray to (instead of direction!)
602 struct RayFromToCaster : btDbvt::ICollide
606 btVector3 m_rayNormalizedDirection;
610 RayFromToCaster(const btVector3& rayFrom,const btVector3& rayTo,btScalar mxt);
611 void Process(const btDbvtNode* leaf);
613 static inline btScalar rayFromToTriangle(const btVector3& rayFrom,
614 const btVector3& rayTo,
615 const btVector3& rayNormalizedDirection,
619 btScalar maxt=SIMD_INFINITY);
626 typedef void (*psolver_t)(btSoftBody*,btScalar,btScalar);
627 typedef void (*vsolver_t)(btSoftBody*,btScalar);
628 typedef btAlignedObjectArray<Cluster*> tClusterArray;
629 typedef btAlignedObjectArray<Note> tNoteArray;
630 typedef btAlignedObjectArray<Node> tNodeArray;
631 typedef btAlignedObjectArray<btDbvtNode*> tLeafArray;
632 typedef btAlignedObjectArray<Link> tLinkArray;
633 typedef btAlignedObjectArray<Face> tFaceArray;
634 typedef btAlignedObjectArray<Tetra> tTetraArray;
635 typedef btAlignedObjectArray<Anchor> tAnchorArray;
636 typedef btAlignedObjectArray<RContact> tRContactArray;
637 typedef btAlignedObjectArray<SContact> tSContactArray;
638 typedef btAlignedObjectArray<Material*> tMaterialArray;
639 typedef btAlignedObjectArray<Joint*> tJointArray;
640 typedef btAlignedObjectArray<btSoftBody*> tSoftBodyArray;
646 Config m_cfg; // Configuration
647 SolverState m_sst; // Solver state
649 void* m_tag; // User data
650 btSoftBodyWorldInfo* m_worldInfo; // World info
651 tNoteArray m_notes; // Notes
652 tNodeArray m_nodes; // Nodes
653 tLinkArray m_links; // Links
654 tFaceArray m_faces; // Faces
655 tTetraArray m_tetras; // Tetras
656 tAnchorArray m_anchors; // Anchors
657 tRContactArray m_rcontacts; // Rigid contacts
658 tSContactArray m_scontacts; // Soft contacts
659 tJointArray m_joints; // Joints
660 tMaterialArray m_materials; // Materials
661 btScalar m_timeacc; // Time accumulator
662 btVector3 m_bounds[2]; // Spatial bounds
663 bool m_bUpdateRtCst; // Update runtime constants
664 btDbvt m_ndbvt; // Nodes tree
665 btDbvt m_fdbvt; // Faces tree
666 btDbvt m_cdbvt; // Clusters tree
667 tClusterArray m_clusters; // Clusters
669 btAlignedObjectArray<bool>m_clusterConnectivity;//cluster connectivity, for self-collision
671 btTransform m_initialWorldTransform;
673 btVector3 m_windVelocity;
675 btScalar m_restLengthScale;
682 btSoftBody( btSoftBodyWorldInfo* worldInfo,int node_count, const btVector3* x, const btScalar* m);
685 btSoftBody( btSoftBodyWorldInfo* worldInfo);
690 virtual ~btSoftBody();
691 /* Check for existing link */
693 btAlignedObjectArray<int> m_userIndexMapping;
695 btSoftBodyWorldInfo* getWorldInfo()
700 ///@todo: avoid internal softbody shape hack and move collision code to collision library
701 virtual void setCollisionShape(btCollisionShape* collisionShape)
706 bool checkLink( int node0,
708 bool checkLink( const Node* node0,
709 const Node* node1) const;
710 /* Check for existring face */
711 bool checkFace( int node0,
714 /* Append material */
715 Material* appendMaterial();
717 void appendNote( const char* text,
719 const btVector4& c=btVector4(1,0,0,0),
724 void appendNote( const char* text,
727 void appendNote( const char* text,
730 void appendNote( const char* text,
734 void appendNode( const btVector3& x,btScalar m);
736 void appendLink(int model=-1,Material* mat=0);
737 void appendLink( int node0,
740 bool bcheckexist=false);
741 void appendLink( Node* node0,
744 bool bcheckexist=false);
746 void appendFace(int model=-1,Material* mat=0);
747 void appendFace( int node0,
751 void appendTetra(int model,Material* mat);
753 void appendTetra(int node0,
761 void appendAnchor( int node,
762 btRigidBody* body, bool disableCollisionBetweenLinkedBodies=false,btScalar influence = 1);
763 void appendAnchor(int node,btRigidBody* body, const btVector3& localPivot,bool disableCollisionBetweenLinkedBodies=false,btScalar influence = 1);
764 /* Append linear joint */
765 void appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1);
766 void appendLinearJoint(const LJoint::Specs& specs,Body body=Body());
767 void appendLinearJoint(const LJoint::Specs& specs,btSoftBody* body);
768 /* Append linear joint */
769 void appendAngularJoint(const AJoint::Specs& specs,Cluster* body0,Body body1);
770 void appendAngularJoint(const AJoint::Specs& specs,Body body=Body());
771 void appendAngularJoint(const AJoint::Specs& specs,btSoftBody* body);
772 /* Add force (or gravity) to the entire body */
773 void addForce( const btVector3& force);
774 /* Add force (or gravity) to a node of the body */
775 void addForce( const btVector3& force,
777 /* Add aero force to a node of the body */
778 void addAeroForceToNode(const btVector3& windVelocity,int nodeIndex);
780 /* Add aero force to a face of the body */
781 void addAeroForceToFace(const btVector3& windVelocity,int faceIndex);
783 /* Add velocity to the entire body */
784 void addVelocity( const btVector3& velocity);
786 /* Set velocity for the entire body */
787 void setVelocity( const btVector3& velocity);
789 /* Add velocity to a node of the body */
790 void addVelocity( const btVector3& velocity,
793 void setMass( int node,
796 btScalar getMass( int node) const;
798 btScalar getTotalMass() const;
799 /* Set total mass (weighted by previous masses) */
800 void setTotalMass( btScalar mass,
801 bool fromfaces=false);
802 /* Set total density */
803 void setTotalDensity(btScalar density);
804 /* Set volume mass (using tetrahedrons) */
805 void setVolumeMass( btScalar mass);
806 /* Set volume density (using tetrahedrons) */
807 void setVolumeDensity( btScalar density);
809 void transform( const btTransform& trs);
811 void translate( const btVector3& trs);
813 void rotate( const btQuaternion& rot);
815 void scale( const btVector3& scl);
816 /* Get link resting lengths scale */
817 btScalar getRestLengthScale();
818 /* Scale resting length of all springs */
819 void setRestLengthScale(btScalar restLength);
820 /* Set current state as pose */
821 void setPose( bool bvolume,
823 /* Set current link lengths as resting lengths */
824 void resetLinkRestLengths();
825 /* Return the volume */
826 btScalar getVolume() const;
828 int clusterCount() const;
829 /* Cluster center of mass */
830 static btVector3 clusterCom(const Cluster* cluster);
831 btVector3 clusterCom(int cluster) const;
832 /* Cluster velocity at rpos */
833 static btVector3 clusterVelocity(const Cluster* cluster,const btVector3& rpos);
834 /* Cluster impulse */
835 static void clusterVImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse);
836 static void clusterDImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse);
837 static void clusterImpulse(Cluster* cluster,const btVector3& rpos,const Impulse& impulse);
838 static void clusterVAImpulse(Cluster* cluster,const btVector3& impulse);
839 static void clusterDAImpulse(Cluster* cluster,const btVector3& impulse);
840 static void clusterAImpulse(Cluster* cluster,const Impulse& impulse);
841 static void clusterDCImpulse(Cluster* cluster,const btVector3& impulse);
842 /* Generate bending constraints based on distance in the adjency graph */
843 int generateBendingConstraints( int distance,
845 /* Randomize constraints to reduce solver bias */
846 void randomizeConstraints();
847 /* Release clusters */
848 void releaseCluster(int index);
849 void releaseClusters();
850 /* Generate clusters (K-mean) */
851 ///generateClusters with k=0 will create a convex cluster for each tetrahedron or triangle
852 ///otherwise an approximation will be used (better performance)
853 int generateClusters(int k,int maxiterations=8192);
855 void refine(ImplicitFn* ifn,btScalar accurary,bool cut);
857 bool cutLink(int node0,int node1,btScalar position);
858 bool cutLink(const Node* node0,const Node* node1,btScalar position);
860 ///Ray casting using rayFrom and rayTo in worldspace, (not direction!)
861 bool rayTest(const btVector3& rayFrom,
862 const btVector3& rayTo,
865 void setSolver(eSolverPresets::_ preset);
867 void predictMotion(btScalar dt);
868 /* solveConstraints */
869 void solveConstraints();
871 void staticSolve(int iterations);
872 /* solveCommonConstraints */
873 static void solveCommonConstraints(btSoftBody** bodies,int count,int iterations);
875 static void solveClusters(const btAlignedObjectArray<btSoftBody*>& bodies);
876 /* integrateMotion */
877 void integrateMotion();
878 /* defaultCollisionHandlers */
879 void defaultCollisionHandler(const btCollisionObjectWrapper* pcoWrap);
880 void defaultCollisionHandler(btSoftBody* psb);
885 // Functionality to deal with new accelerated solvers.
889 * Set a wind velocity for interaction with the air.
891 void setWindVelocity( const btVector3 &velocity );
895 * Return the wind velocity for interaction with the air.
897 const btVector3& getWindVelocity();
900 // Set the solver that handles this soft body
901 // Should not be allowed to get out of sync with reality
902 // Currently called internally on addition to the world
903 void setSoftBodySolver( btSoftBodySolver *softBodySolver )
905 m_softBodySolver = softBodySolver;
909 // Return the solver that handles this soft body
911 btSoftBodySolver *getSoftBodySolver()
913 return m_softBodySolver;
917 // Return the solver that handles this soft body
919 btSoftBodySolver *getSoftBodySolver() const
921 return m_softBodySolver;
929 static const btSoftBody* upcast(const btCollisionObject* colObj)
931 if (colObj->getInternalType()==CO_SOFT_BODY)
932 return (const btSoftBody*)colObj;
935 static btSoftBody* upcast(btCollisionObject* colObj)
937 if (colObj->getInternalType()==CO_SOFT_BODY)
938 return (btSoftBody*)colObj;
943 // ::btCollisionObject
946 virtual void getAabb(btVector3& aabbMin,btVector3& aabbMax) const
948 aabbMin = m_bounds[0];
949 aabbMax = m_bounds[1];
954 void pointersToIndices();
955 void indicesToPointers(const int* map=0);
957 int rayTest(const btVector3& rayFrom,const btVector3& rayTo,
958 btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const;
959 void initializeFaceTree();
960 btVector3 evaluateCom() const;
961 bool checkContact(const btCollisionObjectWrapper* colObjWrap,const btVector3& x,btScalar margin,btSoftBody::sCti& cti) const;
962 void updateNormals();
965 void updateConstants();
966 void updateLinkConstants();
967 void updateArea(bool averageArea = true);
968 void initializeClusters();
969 void updateClusters();
970 void cleanupClusters();
971 void prepareClusters(int iterations);
972 void solveClusters(btScalar sor);
973 void applyClusters(bool drift);
976 static void PSolve_Anchors(btSoftBody* psb,btScalar kst,btScalar ti);
977 static void PSolve_RContacts(btSoftBody* psb,btScalar kst,btScalar ti);
978 static void PSolve_SContacts(btSoftBody* psb,btScalar,btScalar ti);
979 static void PSolve_Links(btSoftBody* psb,btScalar kst,btScalar ti);
980 static void VSolve_Links(btSoftBody* psb,btScalar kst);
981 static psolver_t getSolver(ePSolver::_ solver);
982 static vsolver_t getSolver(eVSolver::_ solver);
985 virtual int calculateSerializeBufferSize() const;
987 ///fills the dataBuffer and returns the struct name (and 0 on failure)
988 virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const;
990 //virtual void serializeSingleObject(class btSerializer* serializer) const;
998 #endif //_BT_SOFT_BODY_H