Bullet Collision Detection & Physics Library
btSoftBody.h
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
4 
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:
10 
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.
14 */
16 
17 #ifndef _BT_SOFT_BODY_H
18 #define _BT_SOFT_BODY_H
19 
21 #include "LinearMath/btTransform.h"
24 
27 #include "btSparseSDF.h"
29 
30 //#ifdef BT_USE_DOUBLE_PRECISION
31 //#define btRigidBodyData btRigidBodyDoubleData
32 //#define btRigidBodyDataName "btRigidBodyDoubleData"
33 //#else
34 #define btSoftBodyData btSoftBodyFloatData
35 #define btSoftBodyDataName "btSoftBodyFloatData"
36 //#endif //BT_USE_DOUBLE_PRECISION
37 
39 class btDispatcher;
40 class btSoftBodySolver;
41 
42 /* btSoftBodyWorldInfo */
44 {
53 
55  :air_density((btScalar)1.2),
56  water_density(0),
57  water_offset(0),
58  water_normal(0,0,0),
59  m_broadphase(0),
60  m_dispatcher(0),
61  m_gravity(0,-10,0)
62  {
63  }
64 };
65 
66 
70 {
71 public:
73 
74  // The solver object that handles this soft body
76 
77  //
78  // Enumerations
79  //
80 
82  struct eAeroModel { enum _ {
91  };};
92 
94  struct eVSolver { enum _ {
97  };};
98 
100  struct ePSolver { enum _ {
106  };};
107 
109  struct eSolverPresets { enum _ {
114  };};
115 
117  struct eFeature { enum _ {
124  };};
125 
128 
129  //
130  // Flags
131  //
132 
134  struct fCollision { enum _ {
135  RVSmask = 0x000f,
136  SDF_RS = 0x0001,
137  CL_RS = 0x0002,
138 
139  SVSmask = 0x0030,
140  VF_SS = 0x0010,
141  CL_SS = 0x0020,
142  CL_SELF = 0x0040,
143  /* presets */
146  };};
147 
149  struct fMaterial { enum _ {
150  DebugDraw = 0x0001,
151  /* presets */
154  };};
155 
156  //
157  // API Types
158  //
159 
160  /* sRayCast */
161  struct sRayCast
162  {
165  int index;
167  };
168 
169  /* ImplicitFn */
170  struct ImplicitFn
171  {
172  virtual btScalar Eval(const btVector3& x)=0;
173  };
174 
175  //
176  // Internal types
177  //
178 
181 
182  /* sCti is Softbody contact info */
183  struct sCti
184  {
185  const btCollisionObject* m_colObj; /* Rigid body */
186  btVector3 m_normal; /* Outward normal */
187  btScalar m_offset; /* Offset from origin */
188  };
189 
190  /* sMedium */
191  struct sMedium
192  {
193  btVector3 m_velocity; /* Velocity */
194  btScalar m_pressure; /* Pressure */
195  btScalar m_density; /* Density */
196  };
197 
198  /* Base type */
199  struct Element
200  {
201  void* m_tag; // User data
202  Element() : m_tag(0) {}
203  };
204  /* Material */
205  struct Material : Element
206  {
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
211  };
212 
213  /* Feature */
214  struct Feature : Element
215  {
216  Material* m_material; // Material
217  };
218  /* Node */
219  struct Node : Feature
220  {
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
230  };
231  /* Link */
232  struct Link : Feature
233  {
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
241  };
242  /* Face */
243  struct Face : Feature
244  {
245  Node* m_n[3]; // Node pointers
246  btVector3 m_normal; // Normal
247  btScalar m_ra; // Rest area
248  btDbvtNode* m_leaf; // Leaf data
249  };
250  /* Tetra */
251  struct Tetra : Feature
252  {
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)
259  };
260  /* RContact */
261  struct RContact
262  {
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
270  };
271  /* SContact */
272  struct SContact
273  {
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
281  };
282  /* Anchor */
283  struct Anchor
284  {
285  Node* m_node; // Node pointer
286  btVector3 m_local; // Anchor position in body space
287  btRigidBody* m_body; // Body
289  btMatrix3x3 m_c0; // Impulse matrix
290  btVector3 m_c1; // Relative anchor
291  btScalar m_c2; // ima*dt
292  };
293  /* Note */
294  struct Note : Element
295  {
296  const char* m_text; // Text
297  btVector3 m_offset; // Offset
298  int m_rank; // Rank
299  Node* m_nodes[4]; // Nodes
300  btScalar m_coords[4]; // Coordinates
301  };
302  /* Pose */
303  struct Pose
304  {
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
314  };
315  /* Cluster */
316  struct Cluster
317  {
334  btScalar m_ndamping; /* Node damping */
335  btScalar m_ldamping; /* Linear damping */
336  btScalar m_adamping; /* Angular damping */
341  bool m_collide;
346  m_containsAnchor(false)
347  {}
348  };
349  /* Impulse */
350  struct Impulse
351  {
355  int m_asDrift:1;
356  Impulse() : m_velocity(0,0,0),m_drift(0,0,0),m_asVelocity(0),m_asDrift(0) {}
358  {
359  Impulse i=*this;
360  i.m_velocity=-i.m_velocity;
361  i.m_drift=-i.m_drift;
362  return(i);
363  }
365  {
366  Impulse i=*this;
367  i.m_velocity*=x;
368  i.m_drift*=x;
369  return(i);
370  }
371  };
372  /* Body */
373  struct Body
374  {
378 
381  Body(const btCollisionObject* colObj) : m_soft(0),m_collisionObject(colObj)
382  {
384  }
385 
386  void activate() const
387  {
388  if(m_rigid)
389  m_rigid->activate();
390  if (m_collisionObject)
392 
393  }
395  {
396  static const btMatrix3x3 iwi(0,0,0,0,0,0,0,0,0);
398  if(m_soft) return(m_soft->m_invwi);
399  return(iwi);
400  }
402  {
403  if(m_rigid) return(m_rigid->getInvMass());
404  if(m_soft) return(m_soft->m_imass);
405  return(0);
406  }
407  const btTransform& xform() const
408  {
409  static const btTransform identity=btTransform::getIdentity();
411  if(m_soft) return(m_soft->m_framexform);
412  return(identity);
413  }
415  {
416  if(m_rigid) return(m_rigid->getLinearVelocity());
417  if(m_soft) return(m_soft->m_lv);
418  return(btVector3(0,0,0));
419  }
421  {
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));
425  }
427  {
428  if(m_rigid) return(m_rigid->getAngularVelocity());
429  if(m_soft) return(m_soft->m_av);
430  return(btVector3(0,0,0));
431  }
432  btVector3 velocity(const btVector3& rpos) const
433  {
434  return(linearVelocity()+angularVelocity(rpos));
435  }
436  void applyVImpulse(const btVector3& impulse,const btVector3& rpos) const
437  {
438  if(m_rigid) m_rigid->applyImpulse(impulse,rpos);
439  if(m_soft) btSoftBody::clusterVImpulse(m_soft,rpos,impulse);
440  }
441  void applyDImpulse(const btVector3& impulse,const btVector3& rpos) const
442  {
443  if(m_rigid) m_rigid->applyImpulse(impulse,rpos);
444  if(m_soft) btSoftBody::clusterDImpulse(m_soft,rpos,impulse);
445  }
446  void applyImpulse(const Impulse& impulse,const btVector3& rpos) const
447  {
448  if(impulse.m_asVelocity)
449  {
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);
452  }
453  if(impulse.m_asDrift)
454  {
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);
457  }
458  }
459  void applyVAImpulse(const btVector3& impulse) const
460  {
461  if(m_rigid) m_rigid->applyTorqueImpulse(impulse);
463  }
464  void applyDAImpulse(const btVector3& impulse) const
465  {
466  if(m_rigid) m_rigid->applyTorqueImpulse(impulse);
468  }
469  void applyAImpulse(const Impulse& impulse) const
470  {
471  if(impulse.m_asVelocity) applyVAImpulse(impulse.m_velocity);
472  if(impulse.m_asDrift) applyDAImpulse(impulse.m_drift);
473  }
474  void applyDCImpulse(const btVector3& impulse) const
475  {
476  if(m_rigid) m_rigid->applyCentralImpulse(impulse);
478  }
479  };
480  /* Joint */
481  struct Joint
482  {
483  struct eType { enum _ {
487  };};
488  struct Specs
489  {
490  Specs() : erp(1),cfm(1),split(1) {}
494  };
503  bool m_delete;
504  virtual ~Joint() {}
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;
510  };
511  /* LJoint */
512  struct LJoint : Joint
513  {
515  {
517  };
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); }
523  };
524  /* AJoint */
525  struct AJoint : Joint
526  {
527  struct IControl
528  {
529  virtual void Prepare(AJoint*) {}
530  virtual btScalar Speed(AJoint*,btScalar current) { return(current); }
531  static IControl* Default() { static IControl def;return(&def); }
532  };
534  {
535  Specs() : icontrol(IControl::Default()) {}
538  };
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); }
545  };
546  /* CJoint */
547  struct CJoint : Joint
548  {
549  int m_life;
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); }
558  };
559  /* Config */
560  struct Config
561  {
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
591  };
592  /* SolverState */
593  struct SolverState
594  {
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
600  };
603  {
609  int m_tests;
610  RayFromToCaster(const btVector3& rayFrom,const btVector3& rayTo,btScalar mxt);
611  void Process(const btDbvtNode* leaf);
612 
613  static inline btScalar rayFromToTriangle(const btVector3& rayFrom,
614  const btVector3& rayTo,
615  const btVector3& rayNormalizedDirection,
616  const btVector3& a,
617  const btVector3& b,
618  const btVector3& c,
619  btScalar maxt=SIMD_INFINITY);
620  };
621 
622  //
623  // Typedefs
624  //
625 
627  typedef void (*vsolver_t)(btSoftBody*,btScalar);
641 
642  //
643  // Fields
644  //
645 
646  Config m_cfg; // Configuration
647  SolverState m_sst; // Solver state
648  Pose m_pose; // Pose
649  void* m_tag; // User data
651  tNoteArray m_notes; // Notes
652  tNodeArray m_nodes; // Nodes
653  tLinkArray m_links; // Links
654  tFaceArray m_faces; // Faces
657  tRContactArray m_rcontacts; // Rigid contacts
658  tSContactArray m_scontacts; // Soft contacts
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
668 
669  btAlignedObjectArray<bool>m_clusterConnectivity;//cluster connectivity, for self-collision
670 
672 
674 
676 
677  //
678  // Api
679  //
680 
681  /* ctor */
682  btSoftBody( btSoftBodyWorldInfo* worldInfo,int node_count, const btVector3* x, const btScalar* m);
683 
684  /* ctor */
685  btSoftBody( btSoftBodyWorldInfo* worldInfo);
686 
687  void initDefaults();
688 
689  /* dtor */
690  virtual ~btSoftBody();
691  /* Check for existing link */
692 
694 
696  {
697  return m_worldInfo;
698  }
699 
701  virtual void setCollisionShape(btCollisionShape* collisionShape)
702  {
703 
704  }
705 
706  bool checkLink( int node0,
707  int node1) const;
708  bool checkLink( const Node* node0,
709  const Node* node1) const;
710  /* Check for existring face */
711  bool checkFace( int node0,
712  int node1,
713  int node2) const;
714  /* Append material */
715  Material* appendMaterial();
716  /* Append note */
717  void appendNote( const char* text,
718  const btVector3& o,
719  const btVector4& c=btVector4(1,0,0,0),
720  Node* n0=0,
721  Node* n1=0,
722  Node* n2=0,
723  Node* n3=0);
724  void appendNote( const char* text,
725  const btVector3& o,
726  Node* feature);
727  void appendNote( const char* text,
728  const btVector3& o,
729  Link* feature);
730  void appendNote( const char* text,
731  const btVector3& o,
732  Face* feature);
733  /* Append node */
734  void appendNode( const btVector3& x,btScalar m);
735  /* Append link */
736  void appendLink(int model=-1,Material* mat=0);
737  void appendLink( int node0,
738  int node1,
739  Material* mat=0,
740  bool bcheckexist=false);
741  void appendLink( Node* node0,
742  Node* node1,
743  Material* mat=0,
744  bool bcheckexist=false);
745  /* Append face */
746  void appendFace(int model=-1,Material* mat=0);
747  void appendFace( int node0,
748  int node1,
749  int node2,
750  Material* mat=0);
751  void appendTetra(int model,Material* mat);
752  //
753  void appendTetra(int node0,
754  int node1,
755  int node2,
756  int node3,
757  Material* mat=0);
758 
759 
760  /* Append anchor */
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,
776  int node);
777  /* Add aero force to a node of the body */
778  void addAeroForceToNode(const btVector3& windVelocity,int nodeIndex);
779 
780  /* Add aero force to a face of the body */
781  void addAeroForceToFace(const btVector3& windVelocity,int faceIndex);
782 
783  /* Add velocity to the entire body */
784  void addVelocity( const btVector3& velocity);
785 
786  /* Set velocity for the entire body */
787  void setVelocity( const btVector3& velocity);
788 
789  /* Add velocity to a node of the body */
790  void addVelocity( const btVector3& velocity,
791  int node);
792  /* Set mass */
793  void setMass( int node,
794  btScalar mass);
795  /* Get mass */
796  btScalar getMass( int node) const;
797  /* Get total mass */
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);
808  /* Transform */
809  void transform( const btTransform& trs);
810  /* Translate */
811  void translate( const btVector3& trs);
812  /* Rotate */
813  void rotate( const btQuaternion& rot);
814  /* Scale */
815  void scale( const btVector3& scl);
816  /* Get link resting lengths scale */
818  /* Scale resting length of all springs */
819  void setRestLengthScale(btScalar restLength);
820  /* Set current state as pose */
821  void setPose( bool bvolume,
822  bool bframe);
823  /* Set current link lengths as resting lengths */
824  void resetLinkRestLengths();
825  /* Return the volume */
826  btScalar getVolume() const;
827  /* Cluster count */
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,
844  Material* mat=0);
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) */
853  int generateClusters(int k,int maxiterations=8192);
854  /* Refine */
855  void refine(ImplicitFn* ifn,btScalar accurary,bool cut);
856  /* CutLink */
857  bool cutLink(int node0,int node1,btScalar position);
858  bool cutLink(const Node* node0,const Node* node1,btScalar position);
859 
861  bool rayTest(const btVector3& rayFrom,
862  const btVector3& rayTo,
863  sRayCast& results);
864  /* Solver presets */
865  void setSolver(eSolverPresets::_ preset);
866  /* predictMotion */
867  void predictMotion(btScalar dt);
868  /* solveConstraints */
869  void solveConstraints();
870  /* staticSolve */
871  void staticSolve(int iterations);
872  /* solveCommonConstraints */
873  static void solveCommonConstraints(btSoftBody** bodies,int count,int iterations);
874  /* solveClusters */
875  static void solveClusters(const btAlignedObjectArray<btSoftBody*>& bodies);
876  /* integrateMotion */
877  void integrateMotion();
878  /* defaultCollisionHandlers */
881 
882 
883 
884  //
885  // Functionality to deal with new accelerated solvers.
886  //
887 
891  void setWindVelocity( const btVector3 &velocity );
892 
893 
897  const btVector3& getWindVelocity();
898 
899  //
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 )
904  {
905  m_softBodySolver = softBodySolver;
906  }
907 
908  //
909  // Return the solver that handles this soft body
910  //
912  {
913  return m_softBodySolver;
914  }
915 
916  //
917  // Return the solver that handles this soft body
918  //
920  {
921  return m_softBodySolver;
922  }
923 
924 
925  //
926  // Cast
927  //
928 
929  static const btSoftBody* upcast(const btCollisionObject* colObj)
930  {
931  if (colObj->getInternalType()==CO_SOFT_BODY)
932  return (const btSoftBody*)colObj;
933  return 0;
934  }
936  {
937  if (colObj->getInternalType()==CO_SOFT_BODY)
938  return (btSoftBody*)colObj;
939  return 0;
940  }
941 
942  //
943  // ::btCollisionObject
944  //
945 
946  virtual void getAabb(btVector3& aabbMin,btVector3& aabbMax) const
947  {
948  aabbMin = m_bounds[0];
949  aabbMax = m_bounds[1];
950  }
951  //
952  // Private
953  //
954  void pointersToIndices();
955  void indicesToPointers(const int* map=0);
956 
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();
963  void updateBounds();
964  void updatePose();
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);
974  void dampClusters();
975  void applyForces();
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);
983 
984 
985  virtual int calculateSerializeBufferSize() const;
986 
988  virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const;
989 
990  //virtual void serializeSingleObject(class btSerializer* serializer) const;
991 
992 
993 };
994 
995 
996 
997 
998 #endif //_BT_SOFT_BODY_H