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"
23 #include "LinearMath/btVector3.h"
25 
28 #include "btSparseSDF.h"
32 //#ifdef BT_USE_DOUBLE_PRECISION
33 //#define btRigidBodyData btRigidBodyDoubleData
34 //#define btRigidBodyDataName "btRigidBodyDoubleData"
35 //#else
36 #define btSoftBodyData btSoftBodyFloatData
37 #define btSoftBodyDataName "btSoftBodyFloatData"
39 static unsigned long seed = 243703;
40 //#endif //BT_USE_DOUBLE_PRECISION
41 
43 class btDispatcher;
44 class btSoftBodySolver;
45 
46 /* btSoftBodyWorldInfo */
48 {
58 
60  : air_density((btScalar)1.2),
61  water_density(0),
62  water_offset(0),
63  m_maxDisplacement(1000.f), //avoid soft body from 'exploding' so use some upper threshold of maximum motion that a node can travel per frame
64  water_normal(0, 0, 0),
65  m_broadphase(0),
66  m_dispatcher(0),
67  m_gravity(0, -10, 0)
68  {
69  }
70 };
71 
75 {
76 public:
78 
79  // The solver object that handles this soft body
81 
82  //
83  // Enumerations
84  //
85 
87  struct eAeroModel
88  {
89  enum _
90  {
98  END
99  };
100  };
101 
103  struct eVSolver
104  {
105  enum _
106  {
108  END
109  };
110  };
111 
113  struct ePSolver
114  {
115  enum _
116  {
121  END
122  };
123  };
124 
127  {
128  enum _
129  {
133  END
134  };
135  };
136 
138  struct eFeature
139  {
140  enum _
141  {
147  END
148  };
149  };
150 
153 
154  //
155  // Flags
156  //
157 
159  struct fCollision
160  {
161  enum _
162  {
163  RVSmask = 0x000f,
164  SDF_RS = 0x0001,
165  CL_RS = 0x0002,
166  SDF_RD = 0x0004,
167 
168  SVSmask = 0x00f0,
169  VF_SS = 0x0010,
170  CL_SS = 0x0020,
171  CL_SELF = 0x0040,
172  VF_DD = 0x0080,
173 
174  RVDFmask = 0x0f00,
175  SDF_RDF = 0x0100,
176  SDF_MDF = 0x0200,
177  SDF_RDN = 0x0400,
178  /* presets */
180  END
181  };
182  };
183 
185  struct fMaterial
186  {
187  enum _
188  {
189  DebugDraw = 0x0001,
190  /* presets */
192  END
193  };
194  };
195 
196  //
197  // API Types
198  //
199 
200  /* sRayCast */
201  struct sRayCast
202  {
205  int index;
207  };
208 
209  /* ImplicitFn */
210  struct ImplicitFn
211  {
212  virtual ~ImplicitFn() {}
213  virtual btScalar Eval(const btVector3& x) = 0;
214  };
215 
216  //
217  // Internal types
218  //
219 
222 
223  /* sCti is Softbody contact info */
224  struct sCti
225  {
226  const btCollisionObject* m_colObj; /* Rigid body */
227  btVector3 m_normal; /* Outward normal */
228  btScalar m_offset; /* Offset from origin */
229  btVector3 m_bary; /* Barycentric weights for faces */
230  };
231 
232  /* sMedium */
233  struct sMedium
234  {
235  btVector3 m_velocity; /* Velocity */
236  btScalar m_pressure; /* Pressure */
237  btScalar m_density; /* Density */
238  };
239 
240  /* Base type */
241  struct Element
242  {
243  void* m_tag; // User data
244  Element() : m_tag(0) {}
245  };
246  /* Material */
247  struct Material : Element
248  {
249  btScalar m_kLST; // Linear stiffness coefficient [0,1]
250  btScalar m_kAST; // Area/Angular stiffness coefficient [0,1]
251  btScalar m_kVST; // Volume stiffness coefficient [0,1]
252  int m_flags; // Flags
253  };
254 
255  /* Feature */
256  struct Feature : Element
257  {
258  Material* m_material; // Material
259  };
260  /* Node */
261  struct RenderNode
262  {
266  };
267  struct Node : Feature
268  {
269  btVector3 m_x; // Position
270  btVector3 m_q; // Previous step position/Test position
271  btVector3 m_v; // Velocity
272  btVector3 m_vn; // Previous step velocity
273  btVector3 m_f; // Force accumulator
274  btVector3 m_n; // Normal
275  btScalar m_im; // 1/mass
276  btScalar m_area; // Area
277  btDbvtNode* m_leaf; // Leaf data
278  int m_constrained; // depth of penetration
279  int m_battach : 1; // Attached
280  int index;
281  btVector3 m_splitv; // velocity associated with split impulse
282  btMatrix3x3 m_effectiveMass; // effective mass in contact
283  btMatrix3x3 m_effectiveMass_inv; // inverse of effective mass
284  };
285  /* Link */
287  Link : Feature
288  {
289  btVector3 m_c3; // gradient
290  Node* m_n[2]; // Node pointers
291  btScalar m_rl; // Rest length
292  int m_bbending : 1; // Bending link
293  btScalar m_c0; // (ima+imb)*kLST
294  btScalar m_c1; // rl^2
295  btScalar m_c2; // |gradient|^2/c0
296 
298  };
299  struct RenderFace
300  {
301  RenderNode* m_n[3]; // Node pointers
302  };
303 
304  /* Face */
305  struct Face : Feature
306  {
307  Node* m_n[3]; // Node pointers
308  btVector3 m_normal; // Normal
309  btScalar m_ra; // Rest area
310  btDbvtNode* m_leaf; // Leaf data
311  btVector4 m_pcontact; // barycentric weights of the persistent contact
313  int m_index;
314  };
315  /* Tetra */
316  struct Tetra : Feature
317  {
318  Node* m_n[4]; // Node pointers
319  btScalar m_rv; // Rest volume
320  btDbvtNode* m_leaf; // Leaf data
321  btVector3 m_c0[4]; // gradients
322  btScalar m_c1; // (4*kVST)/(im0+im1+im2+im3)
323  btScalar m_c2; // m_c1/sum(|g0..3|^2)
324  btMatrix3x3 m_Dm_inverse; // rest Dm^-1
327  btVector4 m_P_inv[3]; // first three columns of P_inv matrix
328  };
329 
330  /* TetraScratch */
332  {
333  btMatrix3x3 m_F; // deformation gradient F
334  btScalar m_trace; // trace of F^T * F
335  btScalar m_J; // det(F)
336  btMatrix3x3 m_cofF; // cofactor of F
337  btMatrix3x3 m_corotation; // corotatio of the tetra
338  };
339 
340  /* RContact */
341  struct RContact
342  {
343  sCti m_cti; // Contact infos
344  Node* m_node; // Owner node
345  btMatrix3x3 m_c0; // Impulse matrix
346  btVector3 m_c1; // Relative anchor
347  btScalar m_c2; // ima*dt
348  btScalar m_c3; // Friction
349  btScalar m_c4; // Hardness
350 
351  // jacobians and unit impulse responses for multibody
357  };
358 
360  {
361  public:
362  sCti m_cti; // Contact infos
363  btMatrix3x3 m_c0; // Impulse matrix
364  btVector3 m_c1; // Relative anchor
365  btScalar m_c2; // inverse mass of node/face
366  btScalar m_c3; // Friction
367  btScalar m_c4; // Hardness
368  btMatrix3x3 m_c5; // inverse effective mass
369 
370  // jacobians and unit impulse responses for multibody
376  };
377 
379  {
380  public:
381  Node* m_node; // Owner node
382  };
383 
385  {
386  public:
387  btVector3 m_local; // Anchor position in body space
388  };
389 
391  {
392  public:
393  Face* m_face; // Owner face
394  btVector3 m_contactPoint; // Contact point
395  btVector3 m_bary; // Barycentric weights
396  btVector3 m_weights; // v_contactPoint * m_weights[i] = m_face->m_node[i]->m_v;
397  };
398 
400  {
401  Node* m_node; // Node
402  Face* m_face; // Face
403  btVector3 m_bary; // Barycentric weights
404  btVector3 m_weights; // v_contactPoint * m_weights[i] = m_face->m_node[i]->m_v;
405  btVector3 m_normal; // Normal
406  btScalar m_margin; // Margin
407  btScalar m_friction; // Friction
408  btScalar m_imf; // inverse mass of the face at contact point
409  btScalar m_c0; // scale of the impulse matrix;
410  };
411 
412  /* SContact */
413  struct SContact
414  {
415  Node* m_node; // Node
416  Face* m_face; // Face
417  btVector3 m_weights; // Weigths
418  btVector3 m_normal; // Normal
419  btScalar m_margin; // Margin
420  btScalar m_friction; // Friction
421  btScalar m_cfm[2]; // Constraint force mixing
422  };
423  /* Anchor */
424  struct Anchor
425  {
426  Node* m_node; // Node pointer
427  btVector3 m_local; // Anchor position in body space
428  btRigidBody* m_body; // Body
430  btMatrix3x3 m_c0; // Impulse matrix
431  btVector3 m_c1; // Relative anchor
432  btScalar m_c2; // ima*dt
433  };
434  /* Note */
435  struct Note : Element
436  {
437  const char* m_text; // Text
438  btVector3 m_offset; // Offset
439  int m_rank; // Rank
440  Node* m_nodes[4]; // Nodes
441  btScalar m_coords[4]; // Coordinates
442  };
443  /* Pose */
444  struct Pose
445  {
446  bool m_bvolume; // Is valid
447  bool m_bframe; // Is frame
448  btScalar m_volume; // Rest volume
449  tVector3Array m_pos; // Reference positions
450  tScalarArray m_wgh; // Weights
451  btVector3 m_com; // COM
452  btMatrix3x3 m_rot; // Rotation
453  btMatrix3x3 m_scl; // Scale
454  btMatrix3x3 m_aqq; // Base scaling
455  };
456  /* Cluster */
457  struct Cluster
458  {
475  btScalar m_ndamping; /* Node damping */
476  btScalar m_ldamping; /* Linear damping */
477  btScalar m_adamping; /* Angular damping */
482  bool m_collide;
485  {
486  }
487  };
488  /* Impulse */
489  struct Impulse
490  {
493  int m_asVelocity : 1;
494  int m_asDrift : 1;
495  Impulse() : m_velocity(0, 0, 0), m_drift(0, 0, 0), m_asVelocity(0), m_asDrift(0) {}
497  {
498  Impulse i = *this;
499  i.m_velocity = -i.m_velocity;
500  i.m_drift = -i.m_drift;
501  return (i);
502  }
504  {
505  Impulse i = *this;
506  i.m_velocity *= x;
507  i.m_drift *= x;
508  return (i);
509  }
510  };
511  /* Body */
512  struct Body
513  {
517 
520  Body(const btCollisionObject* colObj) : m_soft(0), m_collisionObject(colObj)
521  {
523  }
524 
525  void activate() const
526  {
527  if (m_rigid)
528  m_rigid->activate();
529  if (m_collisionObject)
531  }
533  {
534  static const btMatrix3x3 iwi(0, 0, 0, 0, 0, 0, 0, 0, 0);
535  if (m_rigid) return (m_rigid->getInvInertiaTensorWorld());
536  if (m_soft) return (m_soft->m_invwi);
537  return (iwi);
538  }
540  {
541  if (m_rigid) return (m_rigid->getInvMass());
542  if (m_soft) return (m_soft->m_imass);
543  return (0);
544  }
545  const btTransform& xform() const
546  {
547  static const btTransform identity = btTransform::getIdentity();
549  if (m_soft) return (m_soft->m_framexform);
550  return (identity);
551  }
553  {
554  if (m_rigid) return (m_rigid->getLinearVelocity());
555  if (m_soft) return (m_soft->m_lv);
556  return (btVector3(0, 0, 0));
557  }
559  {
560  if (m_rigid) return (btCross(m_rigid->getAngularVelocity(), rpos));
561  if (m_soft) return (btCross(m_soft->m_av, rpos));
562  return (btVector3(0, 0, 0));
563  }
565  {
566  if (m_rigid) return (m_rigid->getAngularVelocity());
567  if (m_soft) return (m_soft->m_av);
568  return (btVector3(0, 0, 0));
569  }
570  btVector3 velocity(const btVector3& rpos) const
571  {
572  return (linearVelocity() + angularVelocity(rpos));
573  }
574  void applyVImpulse(const btVector3& impulse, const btVector3& rpos) const
575  {
576  if (m_rigid) m_rigid->applyImpulse(impulse, rpos);
577  if (m_soft) btSoftBody::clusterVImpulse(m_soft, rpos, impulse);
578  }
579  void applyDImpulse(const btVector3& impulse, const btVector3& rpos) const
580  {
581  if (m_rigid) m_rigid->applyImpulse(impulse, rpos);
582  if (m_soft) btSoftBody::clusterDImpulse(m_soft, rpos, impulse);
583  }
584  void applyImpulse(const Impulse& impulse, const btVector3& rpos) const
585  {
586  if (impulse.m_asVelocity)
587  {
588  // printf("impulse.m_velocity = %f,%f,%f\n",impulse.m_velocity.getX(),impulse.m_velocity.getY(),impulse.m_velocity.getZ());
589  applyVImpulse(impulse.m_velocity, rpos);
590  }
591  if (impulse.m_asDrift)
592  {
593  // printf("impulse.m_drift = %f,%f,%f\n",impulse.m_drift.getX(),impulse.m_drift.getY(),impulse.m_drift.getZ());
594  applyDImpulse(impulse.m_drift, rpos);
595  }
596  }
597  void applyVAImpulse(const btVector3& impulse) const
598  {
599  if (m_rigid) m_rigid->applyTorqueImpulse(impulse);
601  }
602  void applyDAImpulse(const btVector3& impulse) const
603  {
604  if (m_rigid) m_rigid->applyTorqueImpulse(impulse);
606  }
607  void applyAImpulse(const Impulse& impulse) const
608  {
609  if (impulse.m_asVelocity) applyVAImpulse(impulse.m_velocity);
610  if (impulse.m_asDrift) applyDAImpulse(impulse.m_drift);
611  }
612  void applyDCImpulse(const btVector3& impulse) const
613  {
614  if (m_rigid) m_rigid->applyCentralImpulse(impulse);
616  }
617  };
618  /* Joint */
619  struct Joint
620  {
621  struct eType
622  {
623  enum _
624  {
625  Linear = 0,
627  Contact
628  };
629  };
630  struct Specs
631  {
632  Specs() : erp(1), cfm(1), split(1) {}
636  };
645  bool m_delete;
646  virtual ~Joint() {}
647  Joint() : m_delete(false) {}
648  virtual void Prepare(btScalar dt, int iterations);
649  virtual void Solve(btScalar dt, btScalar sor) = 0;
650  virtual void Terminate(btScalar dt) = 0;
651  virtual eType::_ Type() const = 0;
652  };
653  /* LJoint */
654  struct LJoint : Joint
655  {
657  {
659  };
661  void Prepare(btScalar dt, int iterations);
662  void Solve(btScalar dt, btScalar sor);
663  void Terminate(btScalar dt);
664  eType::_ Type() const { return (eType::Linear); }
665  };
666  /* AJoint */
667  struct AJoint : Joint
668  {
669  struct IControl
670  {
671  virtual ~IControl() {}
672  virtual void Prepare(AJoint*) {}
673  virtual btScalar Speed(AJoint*, btScalar current) { return (current); }
674  static IControl* Default()
675  {
676  static IControl def;
677  return (&def);
678  }
679  };
681  {
682  Specs() : icontrol(IControl::Default()) {}
685  };
688  void Prepare(btScalar dt, int iterations);
689  void Solve(btScalar dt, btScalar sor);
690  void Terminate(btScalar dt);
691  eType::_ Type() const { return (eType::Angular); }
692  };
693  /* CJoint */
694  struct CJoint : Joint
695  {
696  int m_life;
701  void Prepare(btScalar dt, int iterations);
702  void Solve(btScalar dt, btScalar sor);
703  void Terminate(btScalar dt);
704  eType::_ Type() const { return (eType::Contact); }
705  };
706  /* Config */
707  struct Config
708  {
709  eAeroModel::_ aeromodel; // Aerodynamic model (default: V_Point)
710  btScalar kVCF; // Velocities correction factor (Baumgarte)
711  btScalar kDP; // Damping coefficient [0,1]
712  btScalar kDG; // Drag coefficient [0,+inf]
713  btScalar kLF; // Lift coefficient [0,+inf]
714  btScalar kPR; // Pressure coefficient [-inf,+inf]
715  btScalar kVC; // Volume conversation coefficient [0,+inf]
716  btScalar kDF; // Dynamic friction coefficient [0,1]
717  btScalar kMT; // Pose matching coefficient [0,1]
718  btScalar kCHR; // Rigid contacts hardness [0,1]
719  btScalar kKHR; // Kinetic contacts hardness [0,1]
720  btScalar kSHR; // Soft contacts hardness [0,1]
721  btScalar kAHR; // Anchors hardness [0,1]
722  btScalar kSRHR_CL; // Soft vs rigid hardness [0,1] (cluster only)
723  btScalar kSKHR_CL; // Soft vs kinetic hardness [0,1] (cluster only)
724  btScalar kSSHR_CL; // Soft vs soft hardness [0,1] (cluster only)
725  btScalar kSR_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only)
726  btScalar kSK_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only)
727  btScalar kSS_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only)
728  btScalar maxvolume; // Maximum volume ratio for pose
729  btScalar timescale; // Time scale
730  int viterations; // Velocities solver iterations
731  int piterations; // Positions solver iterations
732  int diterations; // Drift solver iterations
733  int citerations; // Cluster solver iterations
734  int collisions; // Collisions flags
735  tVSolverArray m_vsequence; // Velocity solvers sequence
736  tPSolverArray m_psequence; // Position solvers sequence
737  tPSolverArray m_dsequence; // Drift solvers sequence
738  btScalar drag; // deformable air drag
739  btScalar m_maxStress; // Maximum principle first Piola stress
740  };
741  /* SolverState */
742  struct SolverState
743  {
744  //if you add new variables, always initialize them!
746  : sdt(0),
747  isdt(0),
748  velmrg(0),
749  radmrg(0),
750  updmrg(0)
751  {
752  }
753  btScalar sdt; // dt*timescale
754  btScalar isdt; // 1/sdt
755  btScalar velmrg; // velocity margin
756  btScalar radmrg; // radial margin
757  btScalar updmrg; // Update margin
758  };
761  {
767  int m_tests;
768  RayFromToCaster(const btVector3& rayFrom, const btVector3& rayTo, btScalar mxt);
769  void Process(const btDbvtNode* leaf);
770 
771  static /*inline*/ btScalar rayFromToTriangle(const btVector3& rayFrom,
772  const btVector3& rayTo,
773  const btVector3& rayNormalizedDirection,
774  const btVector3& a,
775  const btVector3& b,
776  const btVector3& c,
777  btScalar maxt = SIMD_INFINITY);
778  };
779 
780  //
781  // Typedefs
782  //
783 
784  typedef void (*psolver_t)(btSoftBody*, btScalar, btScalar);
785  typedef void (*vsolver_t)(btSoftBody*, btScalar);
801 
802  //
803  // Fields
804  //
805 
806  Config m_cfg; // Configuration
807  SolverState m_sst; // Solver state
808  Pose m_pose; // Pose
809  void* m_tag; // User data
811  tNoteArray m_notes; // Notes
812  tNodeArray m_nodes; // Nodes
814  tLinkArray m_links; // Links
815  tFaceArray m_faces; // Faces
822  tRContactArray m_rcontacts; // Rigid contacts
826  tSContactArray m_scontacts; // Soft contacts
829  btScalar m_timeacc; // Time accumulator
830  btVector3 m_bounds[2]; // Spatial bounds
831  bool m_bUpdateRtCst; // Update runtime constants
832  btDbvt m_ndbvt; // Nodes tree
833  btDbvt m_fdbvt; // Faces tree
834  btDbvntNode* m_fdbvnt; // Faces tree with normals
835  btDbvt m_cdbvt; // Clusters tree
837  btScalar m_dampingCoefficient; // Damping Coefficient
840  btAlignedObjectArray<btVector3> m_quads; // quadrature points for collision detection
844  btAlignedObjectArray<btVector3> m_X; // initial positions
845 
848  btAlignedObjectArray<btScalar> m_z; // vertical distance used in extrapolation
851 
852  btAlignedObjectArray<bool> m_clusterConnectivity; //cluster connectivity, for self-collision
853 
855 
857 
858  //
859  // Api
860  //
861 
862  /* ctor */
863  btSoftBody(btSoftBodyWorldInfo* worldInfo, int node_count, const btVector3* x, const btScalar* m);
864 
865  /* ctor */
866  btSoftBody(btSoftBodyWorldInfo* worldInfo);
867 
868  void initDefaults();
869 
870  /* dtor */
871  virtual ~btSoftBody();
872  /* Check for existing link */
873 
875 
877  {
878  return m_worldInfo;
879  }
880 
881  void setDampingCoefficient(btScalar damping_coeff)
882  {
883  m_dampingCoefficient = damping_coeff;
884  }
885 
887  virtual void setCollisionShape(btCollisionShape* collisionShape)
888  {
889  }
890 
891  bool checkLink(int node0,
892  int node1) const;
893  bool checkLink(const Node* node0,
894  const Node* node1) const;
895  /* Check for existring face */
896  bool checkFace(int node0,
897  int node1,
898  int node2) const;
899  /* Append material */
900  Material* appendMaterial();
901  /* Append note */
902  void appendNote(const char* text,
903  const btVector3& o,
904  const btVector4& c = btVector4(1, 0, 0, 0),
905  Node* n0 = 0,
906  Node* n1 = 0,
907  Node* n2 = 0,
908  Node* n3 = 0);
909  void appendNote(const char* text,
910  const btVector3& o,
911  Node* feature);
912  void appendNote(const char* text,
913  const btVector3& o,
914  Link* feature);
915  void appendNote(const char* text,
916  const btVector3& o,
917  Face* feature);
918  /* Append node */
919  void appendNode(const btVector3& x, btScalar m);
920  /* Append link */
921  void appendLink(int model = -1, Material* mat = 0);
922  void appendLink(int node0,
923  int node1,
924  Material* mat = 0,
925  bool bcheckexist = false);
926  void appendLink(Node* node0,
927  Node* node1,
928  Material* mat = 0,
929  bool bcheckexist = false);
930  /* Append face */
931  void appendFace(int model = -1, Material* mat = 0);
932  void appendFace(int node0,
933  int node1,
934  int node2,
935  Material* mat = 0);
936  void appendTetra(int model, Material* mat);
937  //
938  void appendTetra(int node0,
939  int node1,
940  int node2,
941  int node3,
942  Material* mat = 0);
943 
944  /* Append anchor */
945  void appendDeformableAnchor(int node, btRigidBody* body);
946  void appendDeformableAnchor(int node, btMultiBodyLinkCollider* link);
947  void appendAnchor(int node,
948  btRigidBody* body, bool disableCollisionBetweenLinkedBodies = false, btScalar influence = 1);
949  void appendAnchor(int node, btRigidBody* body, const btVector3& localPivot, bool disableCollisionBetweenLinkedBodies = false, btScalar influence = 1);
950  void removeAnchor(int node);
951  /* Append linear joint */
952  void appendLinearJoint(const LJoint::Specs& specs, Cluster* body0, Body body1);
953  void appendLinearJoint(const LJoint::Specs& specs, Body body = Body());
954  void appendLinearJoint(const LJoint::Specs& specs, btSoftBody* body);
955  /* Append linear joint */
956  void appendAngularJoint(const AJoint::Specs& specs, Cluster* body0, Body body1);
957  void appendAngularJoint(const AJoint::Specs& specs, Body body = Body());
958  void appendAngularJoint(const AJoint::Specs& specs, btSoftBody* body);
959  /* Add force (or gravity) to the entire body */
960  void addForce(const btVector3& force);
961  /* Add force (or gravity) to a node of the body */
962  void addForce(const btVector3& force,
963  int node);
964  /* Add aero force to a node of the body */
965  void addAeroForceToNode(const btVector3& windVelocity, int nodeIndex);
966 
967  /* Add aero force to a face of the body */
968  void addAeroForceToFace(const btVector3& windVelocity, int faceIndex);
969 
970  /* Add velocity to the entire body */
971  void addVelocity(const btVector3& velocity);
972 
973  /* Set velocity for the entire body */
974  void setVelocity(const btVector3& velocity);
975 
976  /* Add velocity to a node of the body */
977  void addVelocity(const btVector3& velocity,
978  int node);
979  /* Set mass */
980  void setMass(int node,
981  btScalar mass);
982  /* Get mass */
983  btScalar getMass(int node) const;
984  /* Get total mass */
985  btScalar getTotalMass() const;
986  /* Set total mass (weighted by previous masses) */
987  void setTotalMass(btScalar mass,
988  bool fromfaces = false);
989  /* Set total density */
990  void setTotalDensity(btScalar density);
991  /* Set volume mass (using tetrahedrons) */
992  void setVolumeMass(btScalar mass);
993  /* Set volume density (using tetrahedrons) */
994  void setVolumeDensity(btScalar density);
995  /* Get the linear velocity of the center of mass */
997  /* Set the linear velocity of the center of mass */
998  void setLinearVelocity(const btVector3& linVel);
999  /* Set the angular velocity of the center of mass */
1000  void setAngularVelocity(const btVector3& angVel);
1001  /* Get best fit rigid transform */
1003  /* Transform to given pose */
1004  void transformTo(const btTransform& trs);
1005  /* Transform */
1006  void transform(const btTransform& trs);
1007  /* Translate */
1008  void translate(const btVector3& trs);
1009  /* Rotate */
1010  void rotate(const btQuaternion& rot);
1011  /* Scale */
1012  void scale(const btVector3& scl);
1013  /* Get link resting lengths scale */
1015  /* Scale resting length of all springs */
1016  void setRestLengthScale(btScalar restLength);
1017  /* Set current state as pose */
1018  void setPose(bool bvolume,
1019  bool bframe);
1020  /* Set current link lengths as resting lengths */
1021  void resetLinkRestLengths();
1022  /* Return the volume */
1023  btScalar getVolume() const;
1024  /* Cluster count */
1026  {
1027  btVector3 com(0, 0, 0);
1028  for (int i = 0; i < m_nodes.size(); i++)
1029  {
1030  com += (m_nodes[i].m_x * this->getMass(i));
1031  }
1032  com /= this->getTotalMass();
1033  return com;
1034  }
1035  int clusterCount() const;
1036  /* Cluster center of mass */
1037  static btVector3 clusterCom(const Cluster* cluster);
1038  btVector3 clusterCom(int cluster) const;
1039  /* Cluster velocity at rpos */
1040  static btVector3 clusterVelocity(const Cluster* cluster, const btVector3& rpos);
1041  /* Cluster impulse */
1042  static void clusterVImpulse(Cluster* cluster, const btVector3& rpos, const btVector3& impulse);
1043  static void clusterDImpulse(Cluster* cluster, const btVector3& rpos, const btVector3& impulse);
1044  static void clusterImpulse(Cluster* cluster, const btVector3& rpos, const Impulse& impulse);
1045  static void clusterVAImpulse(Cluster* cluster, const btVector3& impulse);
1046  static void clusterDAImpulse(Cluster* cluster, const btVector3& impulse);
1047  static void clusterAImpulse(Cluster* cluster, const Impulse& impulse);
1048  static void clusterDCImpulse(Cluster* cluster, const btVector3& impulse);
1049  /* Generate bending constraints based on distance in the adjency graph */
1050  int generateBendingConstraints(int distance,
1051  Material* mat = 0);
1052  /* Randomize constraints to reduce solver bias */
1053  void randomizeConstraints();
1054  /* Release clusters */
1055  void releaseCluster(int index);
1056  void releaseClusters();
1057  /* Generate clusters (K-mean) */
1060  int generateClusters(int k, int maxiterations = 8192);
1061  /* Refine */
1062  void refine(ImplicitFn* ifn, btScalar accurary, bool cut);
1063  /* CutLink */
1064  bool cutLink(int node0, int node1, btScalar position);
1065  bool cutLink(const Node* node0, const Node* node1, btScalar position);
1066 
1068  bool rayTest(const btVector3& rayFrom,
1069  const btVector3& rayTo,
1070  sRayCast& results);
1071  bool rayFaceTest(const btVector3& rayFrom,
1072  const btVector3& rayTo,
1073  sRayCast& results);
1074  int rayFaceTest(const btVector3& rayFrom, const btVector3& rayTo,
1075  btScalar& mint, int& index) const;
1076  /* Solver presets */
1077  void setSolver(eSolverPresets::_ preset);
1078  /* predictMotion */
1079  void predictMotion(btScalar dt);
1080  /* solveConstraints */
1081  void solveConstraints();
1082  /* staticSolve */
1083  void staticSolve(int iterations);
1084  /* solveCommonConstraints */
1085  static void solveCommonConstraints(btSoftBody** bodies, int count, int iterations);
1086  /* solveClusters */
1087  static void solveClusters(const btAlignedObjectArray<btSoftBody*>& bodies);
1088  /* integrateMotion */
1089  void integrateMotion();
1090  /* defaultCollisionHandlers */
1094  bool useSelfCollision();
1095  void updateDeactivation(btScalar timeStep);
1096  void setZeroVelocity();
1097  bool wantsSleeping();
1098 
1099  //
1100  // Functionality to deal with new accelerated solvers.
1101  //
1102 
1106  void setWindVelocity(const btVector3& velocity);
1107 
1111  const btVector3& getWindVelocity();
1112 
1113  //
1114  // Set the solver that handles this soft body
1115  // Should not be allowed to get out of sync with reality
1116  // Currently called internally on addition to the world
1117  void setSoftBodySolver(btSoftBodySolver* softBodySolver)
1118  {
1119  m_softBodySolver = softBodySolver;
1120  }
1121 
1122  //
1123  // Return the solver that handles this soft body
1124  //
1126  {
1127  return m_softBodySolver;
1128  }
1129 
1130  //
1131  // Return the solver that handles this soft body
1132  //
1134  {
1135  return m_softBodySolver;
1136  }
1137 
1138  //
1139  // Cast
1140  //
1141 
1142  static const btSoftBody* upcast(const btCollisionObject* colObj)
1143  {
1144  if (colObj->getInternalType() == CO_SOFT_BODY)
1145  return (const btSoftBody*)colObj;
1146  return 0;
1147  }
1149  {
1150  if (colObj->getInternalType() == CO_SOFT_BODY)
1151  return (btSoftBody*)colObj;
1152  return 0;
1153  }
1154 
1155  //
1156  // ::btCollisionObject
1157  //
1158 
1159  virtual void getAabb(btVector3& aabbMin, btVector3& aabbMax) const
1160  {
1161  aabbMin = m_bounds[0];
1162  aabbMax = m_bounds[1];
1163  }
1164  //
1165  // Private
1166  //
1167  void pointersToIndices();
1168  void indicesToPointers(const int* map = 0);
1169 
1170  int rayTest(const btVector3& rayFrom, const btVector3& rayTo,
1171  btScalar& mint, eFeature::_& feature, int& index, bool bcountonly) const;
1172  void initializeFaceTree();
1173  void rebuildNodeTree();
1174  btVector3 evaluateCom() const;
1175  bool checkDeformableContact(const btCollisionObjectWrapper* colObjWrap, const btVector3& x, btScalar margin, btSoftBody::sCti& cti, bool predict = false) const;
1176  bool checkDeformableFaceContact(const btCollisionObjectWrapper* colObjWrap, Face& f, btVector3& contact_point, btVector3& bary, btScalar margin, btSoftBody::sCti& cti, bool predict = false) const;
1177  bool checkContact(const btCollisionObjectWrapper* colObjWrap, const btVector3& x, btScalar margin, btSoftBody::sCti& cti) const;
1178  void updateNormals();
1179  void updateBounds();
1180  void updatePose();
1181  void updateConstants();
1182  void updateLinkConstants();
1183  void updateArea(bool averageArea = true);
1184  void initializeClusters();
1185  void updateClusters();
1186  void cleanupClusters();
1187  void prepareClusters(int iterations);
1188  void solveClusters(btScalar sor);
1189  void applyClusters(bool drift);
1190  void dampClusters();
1191  void setSpringStiffness(btScalar k);
1192  void setGravityFactor(btScalar gravFactor);
1193  void setCacheBarycenter(bool cacheBarycenter);
1194  void initializeDmInverse();
1195  void updateDeformation();
1196  void advanceDeformation();
1197  void applyForces();
1198  void setMaxStress(btScalar maxStress);
1199  void interpolateRenderMesh();
1200  void setCollisionQuadrature(int N);
1201  static void PSolve_Anchors(btSoftBody* psb, btScalar kst, btScalar ti);
1202  static void PSolve_RContacts(btSoftBody* psb, btScalar kst, btScalar ti);
1203  static void PSolve_SContacts(btSoftBody* psb, btScalar, btScalar ti);
1204  static void PSolve_Links(btSoftBody* psb, btScalar kst, btScalar ti);
1205  static void VSolve_Links(btSoftBody* psb, btScalar kst);
1206  static psolver_t getSolver(ePSolver::_ solver);
1207  static vsolver_t getSolver(eVSolver::_ solver);
1209 #define SAFE_EPSILON SIMD_EPSILON * 100.0
1210  void updateNode(btDbvtNode* node, bool use_velocity, bool margin)
1211  {
1212  if (node->isleaf())
1213  {
1214  btSoftBody::Node* n = (btSoftBody::Node*)(node->data);
1216  vol;
1217  btScalar pad = margin ? m_sst.radmrg : SAFE_EPSILON; // use user defined margin or margin for floating point precision
1218  if (use_velocity)
1219  {
1220  btVector3 points[2] = {n->m_x, n->m_x + m_sst.sdt * n->m_v};
1221  vol = btDbvtVolume::FromPoints(points, 2);
1222  vol.Expand(btVector3(pad, pad, pad));
1223  }
1224  else
1225  {
1226  vol = btDbvtVolume::FromCR(n->m_x, pad);
1227  }
1228  node->volume = vol;
1229  return;
1230  }
1231  else
1232  {
1233  updateNode(node->childs[0], use_velocity, margin);
1234  updateNode(node->childs[1], use_velocity, margin);
1236  vol;
1237  Merge(node->childs[0]->volume, node->childs[1]->volume, vol);
1238  node->volume = vol;
1239  }
1240  }
1241 
1242  void updateNodeTree(bool use_velocity, bool margin)
1243  {
1244  if (m_ndbvt.m_root)
1245  updateNode(m_ndbvt.m_root, use_velocity, margin);
1246  }
1247 
1248  template <class DBVTNODE> // btDbvtNode or btDbvntNode
1249  void updateFace(DBVTNODE* node, bool use_velocity, bool margin)
1250  {
1251  if (node->isleaf())
1252  {
1253  btSoftBody::Face* f = (btSoftBody::Face*)(node->data);
1254  btScalar pad = margin ? m_sst.radmrg : SAFE_EPSILON; // use user defined margin or margin for floating point precision
1256  vol;
1257  if (use_velocity)
1258  {
1259  btVector3 points[6] = {f->m_n[0]->m_x, f->m_n[0]->m_x + m_sst.sdt * f->m_n[0]->m_v,
1260  f->m_n[1]->m_x, f->m_n[1]->m_x + m_sst.sdt * f->m_n[1]->m_v,
1261  f->m_n[2]->m_x, f->m_n[2]->m_x + m_sst.sdt * f->m_n[2]->m_v};
1262  vol = btDbvtVolume::FromPoints(points, 6);
1263  }
1264  else
1265  {
1266  btVector3 points[3] = {f->m_n[0]->m_x,
1267  f->m_n[1]->m_x,
1268  f->m_n[2]->m_x};
1269  vol = btDbvtVolume::FromPoints(points, 3);
1270  }
1271  vol.Expand(btVector3(pad, pad, pad));
1272  node->volume = vol;
1273  return;
1274  }
1275  else
1276  {
1277  updateFace(node->childs[0], use_velocity, margin);
1278  updateFace(node->childs[1], use_velocity, margin);
1280  vol;
1281  Merge(node->childs[0]->volume, node->childs[1]->volume, vol);
1282  node->volume = vol;
1283  }
1284  }
1285  void updateFaceTree(bool use_velocity, bool margin)
1286  {
1287  if (m_fdbvt.m_root)
1288  updateFace(m_fdbvt.m_root, use_velocity, margin);
1289  if (m_fdbvnt)
1290  updateFace(m_fdbvnt, use_velocity, margin);
1291  }
1292 
1293  template <typename T>
1294  static inline T BaryEval(const T& a,
1295  const T& b,
1296  const T& c,
1297  const btVector3& coord)
1298  {
1299  return (a * coord.x() + b * coord.y() + c * coord.z());
1300  }
1301 
1302  void applyRepulsionForce(btScalar timeStep, bool applySpringForce)
1303  {
1304  btAlignedObjectArray<int> indices;
1305  {
1306  // randomize the order of repulsive force
1307  indices.resize(m_faceNodeContacts.size());
1308  for (int i = 0; i < m_faceNodeContacts.size(); ++i)
1309  indices[i] = i;
1310 #define NEXTRAND (seed = (1664525L * seed + 1013904223L) & 0xffffffff)
1311  int i, ni;
1312 
1313  for (i = 0, ni = indices.size(); i < ni; ++i)
1314  {
1315  btSwap(indices[i], indices[NEXTRAND % ni]);
1316  }
1317  }
1318  for (int k = 0; k < m_faceNodeContacts.size(); ++k)
1319  {
1320  int i = indices[k];
1322  btSoftBody::Node* node = c.m_node;
1323  btSoftBody::Face* face = c.m_face;
1324  const btVector3& w = c.m_bary;
1325  const btVector3& n = c.m_normal;
1326  btVector3 l = node->m_x - BaryEval(face->m_n[0]->m_x, face->m_n[1]->m_x, face->m_n[2]->m_x, w);
1327  btScalar d = c.m_margin - n.dot(l);
1328  d = btMax(btScalar(0), d);
1329 
1330  const btVector3& va = node->m_v;
1331  btVector3 vb = BaryEval(face->m_n[0]->m_v, face->m_n[1]->m_v, face->m_n[2]->m_v, w);
1332  btVector3 vr = va - vb;
1333  const btScalar vn = btDot(vr, n); // dn < 0 <==> opposing
1334  if (vn > OVERLAP_REDUCTION_FACTOR * d / timeStep)
1335  continue;
1336  btVector3 vt = vr - vn * n;
1337  btScalar I = 0;
1338  btScalar mass = node->m_im == 0 ? 0 : btScalar(1) / node->m_im;
1339  if (applySpringForce)
1340  I = -btMin(m_repulsionStiffness * timeStep * d, mass * (OVERLAP_REDUCTION_FACTOR * d / timeStep - vn));
1341  if (vn < 0)
1342  I += 0.5 * mass * vn;
1343  int face_penetration = 0, node_penetration = node->m_constrained;
1344  for (int i = 0; i < 3; ++i)
1345  face_penetration |= face->m_n[i]->m_constrained;
1346  btScalar I_tilde = 2.0 * I / (1.0 + w.length2());
1347 
1348  // double the impulse if node or face is constrained.
1349  if (face_penetration > 0 || node_penetration > 0)
1350  {
1351  I_tilde *= 2.0;
1352  }
1353  if (face_penetration <= 0)
1354  {
1355  for (int j = 0; j < 3; ++j)
1356  face->m_n[j]->m_v += w[j] * n * I_tilde * node->m_im;
1357  }
1358  if (node_penetration <= 0)
1359  {
1360  node->m_v -= I_tilde * node->m_im * n;
1361  }
1362 
1363  // apply frictional impulse
1364  btScalar vt_norm = vt.safeNorm();
1365  if (vt_norm > SIMD_EPSILON)
1366  {
1367  btScalar delta_vn = -2 * I * node->m_im;
1368  btScalar mu = c.m_friction;
1369  btScalar vt_new = btMax(btScalar(1) - mu * delta_vn / (vt_norm + SIMD_EPSILON), btScalar(0)) * vt_norm;
1370  I = 0.5 * mass * (vt_norm - vt_new);
1371  vt.safeNormalize();
1372  I_tilde = 2.0 * I / (1.0 + w.length2());
1373  // double the impulse if node or face is constrained.
1374  if (face_penetration > 0 || node_penetration > 0)
1375  I_tilde *= 2.0;
1376  if (face_penetration <= 0)
1377  {
1378  for (int j = 0; j < 3; ++j)
1379  face->m_n[j]->m_v += w[j] * vt * I_tilde * (face->m_n[j])->m_im;
1380  }
1381  if (node_penetration <= 0)
1382  {
1383  node->m_v -= I_tilde * node->m_im * vt;
1384  }
1385  }
1386  }
1387  }
1388  virtual int calculateSerializeBufferSize() const;
1389 
1391  virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const;
1392 };
1393 
1394 #endif //_BT_SOFT_BODY_H
DBVT_INLINE void Merge(const btDbvtAabbMm &a, const btDbvtAabbMm &b, btDbvtAabbMm &r)
Definition: btDbvt.h:745
const T & btMax(const T &a, const T &b)
Definition: btMinMax.h:27
const T & btMin(const T &a, const T &b)
Definition: btMinMax.h:21
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:314
#define ATTRIBUTE_ALIGNED16(a)
Definition: btScalar.h:99
#define SIMD_INFINITY
Definition: btScalar.h:544
#define SIMD_EPSILON
Definition: btScalar.h:543
void btSwap(T &a, T &b)
Definition: btScalar.h:643
static unsigned long seed
Definition: btSoftBody.h:39
static const btScalar OVERLAP_REDUCTION_FACTOR
Definition: btSoftBody.h:38
#define NEXTRAND
#define SAFE_EPSILON
Definition: btSoftBody.h:1209
btScalar btDot(const btVector3 &v1, const btVector3 &v2)
Return the dot product between two vectors.
Definition: btVector3.h:890
btVector3 btCross(const btVector3 &v1, const btVector3 &v2)
Return the cross product of two vectors.
Definition: btVector3.h:918
int size() const
return the number of elements in the array
void resize(int newsize, const T &fillData=T())
The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs.
btCollisionObject can be used to manage collision detection objects.
btTransform & getWorldTransform()
int getInternalType() const
reserved for Bullet internal usage
void activate(bool forceActivation=false) const
The btCollisionShape class provides an interface for collision shapes that can be shared among btColl...
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Definition: btDispatcher.h:77
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
Definition: btMatrix3x3.h:50
The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatr...
Definition: btQuaternion.h:50
The btRigidBody is the main class for rigid body objects.
Definition: btRigidBody.h:60
void applyTorqueImpulse(const btVector3 &torque)
Definition: btRigidBody.h:327
const btVector3 & getAngularVelocity() const
Definition: btRigidBody.h:437
btScalar getInvMass() const
Definition: btRigidBody.h:263
static const btRigidBody * upcast(const btCollisionObject *colObj)
to keep collision detection and dynamics separate we don't store a rigidbody pointer but a rigidbody ...
Definition: btRigidBody.h:189
void applyImpulse(const btVector3 &impulse, const btVector3 &rel_pos)
Definition: btRigidBody.h:335
void applyCentralImpulse(const btVector3 &impulse)
Definition: btRigidBody.h:319
const btVector3 & getLinearVelocity() const
Definition: btRigidBody.h:433
const btMatrix3x3 & getInvInertiaTensorWorld() const
Definition: btRigidBody.h:265
btMultiBodyJacobianData jacobianData_t1
Definition: btSoftBody.h:372
btMultiBodyJacobianData jacobianData_normal
Definition: btSoftBody.h:371
btMultiBodyJacobianData jacobianData_t2
Definition: btSoftBody.h:373
The btSoftBody is an class to simulate cloth and volumetric soft bodies.
Definition: btSoftBody.h:75
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
Definition: btSoftBody.cpp:253
bool m_bUpdateRtCst
Definition: btSoftBody.h:831
btScalar m_sleepingThreshold
Definition: btSoftBody.h:838
void transformTo(const btTransform &trs)
btVector3 getLinearVelocity()
bool checkFace(int node0, int node1, int node2) const
Definition: btSoftBody.cpp:275
void advanceDeformation()
btAlignedObjectArray< eVSolver::_ > tVSolverArray
Definition: btSoftBody.h:151
void setGravityFactor(btScalar gravFactor)
void updateClusters()
btDbvt m_cdbvt
Definition: btSoftBody.h:835
void setPose(bool bvolume, bool bframe)
btAlignedObjectArray< RenderNode > tRenderNodeArray
Definition: btSoftBody.h:789
bool cutLink(int node0, int node1, btScalar position)
btSoftBodySolver * getSoftBodySolver()
Definition: btSoftBody.h:1125
void appendFace(int model=-1, Material *mat=0)
Definition: btSoftBody.cpp:429
void setMass(int node, btScalar mass)
Definition: btSoftBody.cpp:920
void interpolateRenderMesh()
tJointArray m_joints
Definition: btSoftBody.h:827
btScalar m_dampingCoefficient
Definition: btSoftBody.h:837
void updateNode(btDbvtNode *node, bool use_velocity, bool margin)
Definition: btSoftBody.h:1210
btAlignedObjectArray< TetraScratch > m_tetraScratchesTn
Definition: btSoftBody.h:819
void integrateMotion()
btAlignedObjectArray< Tetra > tTetraArray
Definition: btSoftBody.h:794
void rebuildNodeTree()
bool rayFaceTest(const btVector3 &rayFrom, const btVector3 &rayTo, sRayCast &results)
void appendLinearJoint(const LJoint::Specs &specs, Cluster *body0, Body body1)
Definition: btSoftBody.cpp:637
tRenderFaceArray m_renderFaces
Definition: btSoftBody.h:816
btAlignedObjectArray< SContact > tSContactArray
Definition: btSoftBody.h:797
void scale(const btVector3 &scl)
btAlignedObjectArray< bool > m_clusterConnectivity
Definition: btSoftBody.h:852
void updateFaceTree(bool use_velocity, bool margin)
Definition: btSoftBody.h:1285
void defaultCollisionHandler(const btCollisionObjectWrapper *pcoWrap)
btSoftBodyWorldInfo * getWorldInfo()
Definition: btSoftBody.h:876
btScalar getVolume() const
bool rayTest(const btVector3 &rayFrom, const btVector3 &rayTo, sRayCast &results)
Ray casting using rayFrom and rayTo in worldspace, (not direction!)
SolverState m_sst
Definition: btSoftBody.h:807
void addVelocity(const btVector3 &velocity)
Definition: btSoftBody.cpp:890
btAlignedObjectArray< RContact > tRContactArray
Definition: btSoftBody.h:796
void setDampingCoefficient(btScalar damping_coeff)
Definition: btSoftBody.h:881
void predictMotion(btScalar dt)
void setSelfCollision(bool useSelfCollision)
void setLinearVelocity(const btVector3 &linVel)
btScalar m_timeacc
Definition: btSoftBody.h:829
Pose m_pose
Definition: btSoftBody.h:808
btAlignedObjectArray< int > m_userIndexMapping
Definition: btSoftBody.h:874
btAlignedObjectArray< Face > tFaceArray
Definition: btSoftBody.h:792
void appendTetra(int model, Material *mat)
Definition: btSoftBody.cpp:469
void setRestLengthScale(btScalar restLength)
btDbvntNode * m_fdbvnt
Definition: btSoftBody.h:834
void updateNodeTree(bool use_velocity, bool margin)
Definition: btSoftBody.h:1242
void rotate(const btQuaternion &rot)
void updateFace(DBVTNODE *node, bool use_velocity, bool margin)
Definition: btSoftBody.h:1249
void applyClusters(bool drift)
void setZeroVelocity()
static void PSolve_Anchors(btSoftBody *psb, btScalar kst, btScalar ti)
btSoftBodyWorldInfo * m_worldInfo
Definition: btSoftBody.h:810
void setSoftBodySolver(btSoftBodySolver *softBodySolver)
Definition: btSoftBody.h:1117
void updateArea(bool averageArea=true)
void addForce(const btVector3 &force)
Definition: btSoftBody.cpp:690
bool wantsSleeping()
void prepareClusters(int iterations)
void setCollisionQuadrature(int N)
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)
btAlignedObjectArray< DeformableFaceNodeContact > m_faceNodeContacts
Definition: btSoftBody.h:824
static void VSolve_Links(btSoftBody *psb, btScalar kst)
tTetraArray m_tetras
Definition: btSoftBody.h:817
bool useSelfCollision()
btVector3 evaluateCom() const
void setTotalDensity(btScalar density)
Definition: btSoftBody.cpp:980
btAlignedObjectArray< const class btCollisionObject * > m_collisionDisabledObjects
Definition: btSoftBody.h:77
btAlignedObjectArray< Link > tLinkArray
Definition: btSoftBody.h:791
static void clusterDAImpulse(Cluster *cluster, const btVector3 &impulse)
void appendNode(const btVector3 &x, btScalar m)
Definition: btSoftBody.cpp:369
void staticSolve(int iterations)
void setVolumeMass(btScalar mass)
Definition: btSoftBody.cpp:986
btScalar m_restLengthScale
Definition: btSoftBody.h:856
bool checkDeformableContact(const btCollisionObjectWrapper *colObjWrap, const btVector3 &x, btScalar margin, btSoftBody::sCti &cti, bool predict=false) const
void cleanupClusters()
Config m_cfg
Definition: btSoftBody.h:806
void updateDeactivation(btScalar timeStep)
btAlignedObjectArray< TetraScratch > m_tetraScratches
Definition: btSoftBody.h:818
const btVector3 & getWindVelocity()
Return the wind velocity for interaction with the air.
void addAeroForceToFace(const btVector3 &windVelocity, int faceIndex)
Definition: btSoftBody.cpp:794
btAlignedObjectArray< btVector4 > m_renderNodesInterpolationWeights
Definition: btSoftBody.h:846
void appendAngularJoint(const AJoint::Specs &specs, Cluster *body0, Body body1)
Definition: btSoftBody.cpp:663
tFaceArray m_faces
Definition: btSoftBody.h:815
void setAngularVelocity(const btVector3 &angVel)
void setVolumeDensity(btScalar density)
static void clusterDCImpulse(Cluster *cluster, const btVector3 &impulse)
void transform(const btTransform &trs)
bool m_softSoftCollision
Definition: btSoftBody.h:850
static void clusterVAImpulse(Cluster *cluster, const btVector3 &impulse)
btScalar getMass(int node) const
Definition: btSoftBody.cpp:927
tMaterialArray m_materials
Definition: btSoftBody.h:828
void setMaxStress(btScalar maxStress)
void dampClusters()
btSoftBody(btSoftBodyWorldInfo *worldInfo, int node_count, const btVector3 *x, const btScalar *m)
Definition: btSoftBody.cpp:130
void updateDeformation()
btAlignedObjectArray< btScalar > m_z
Definition: btSoftBody.h:848
void addAeroForceToNode(const btVector3 &windVelocity, int nodeIndex)
Definition: btSoftBody.cpp:705
void applyRepulsionForce(btScalar timeStep, bool applySpringForce)
Definition: btSoftBody.h:1302
btAlignedObjectArray< btVector3 > tVector3Array
Definition: btSoftBody.h:221
static btVector3 clusterCom(const Cluster *cluster)
tRContactArray m_rcontacts
Definition: btSoftBody.h:822
void appendAnchor(int node, btRigidBody *body, bool disableCollisionBetweenLinkedBodies=false, btScalar influence=1)
Definition: btSoftBody.cpp:501
btAlignedObjectArray< Node > tNodeArray
Definition: btSoftBody.h:788
btVector3 m_bounds[2]
Definition: btSoftBody.h:830
btScalar m_maxSpeedSquared
Definition: btSoftBody.h:839
void releaseCluster(int index)
btScalar m_repulsionStiffness
Definition: btSoftBody.h:841
void setVelocity(const btVector3 &velocity)
Definition: btSoftBody.cpp:896
tClusterArray m_clusters
Definition: btSoftBody.h:836
btAlignedObjectArray< Joint * > tJointArray
Definition: btSoftBody.h:799
void solveConstraints()
btAlignedObjectArray< DeformableFaceRigidContact > m_faceRigidContacts
Definition: btSoftBody.h:825
int generateClusters(int k, int maxiterations=8192)
generateClusters with k=0 will create a convex cluster for each tetrahedron or triangle otherwise an ...
void geometricCollisionHandler(btSoftBody *psb)
void releaseClusters()
void refine(ImplicitFn *ifn, btScalar accurary, bool cut)
void setSolver(eSolverPresets::_ preset)
btSoftBodySolver * getSoftBodySolver() const
Definition: btSoftBody.h:1133
static T BaryEval(const T &a, const T &b, const T &c, const btVector3 &coord)
Definition: btSoftBody.h:1294
Material * appendMaterial()
Definition: btSoftBody.cpp:299
void removeAnchor(int node)
Definition: btSoftBody.cpp:563
btAlignedObjectArray< DeformableNodeRigidAnchor > m_deformableAnchors
Definition: btSoftBody.h:821
void setCacheBarycenter(bool cacheBarycenter)
btAlignedObjectArray< Material * > tMaterialArray
Definition: btSoftBody.h:798
btAlignedObjectArray< Anchor > tAnchorArray
Definition: btSoftBody.h:795
btScalar m_gravityFactor
Definition: btSoftBody.h:842
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)
Definition: btSoftBody.cpp:311
bool checkDeformableFaceContact(const btCollisionObjectWrapper *colObjWrap, Face &f, btVector3 &contact_point, btVector3 &bary, btScalar margin, btSoftBody::sCti &cti, bool predict=false) const
virtual int calculateSerializeBufferSize() const
btAlignedObjectArray< DeformableNodeRigidContact > m_nodeRigidContacts
Definition: btSoftBody.h:823
btAlignedObjectArray< btSoftBody * > tSoftBodyArray
Definition: btSoftBody.h:800
static void PSolve_RContacts(btSoftBody *psb, btScalar kst, btScalar ti)
static void clusterImpulse(Cluster *cluster, const btVector3 &rpos, const Impulse &impulse)
btAlignedObjectArray< btAlignedObjectArray< const btSoftBody::Node * > > m_renderNodesParents
Definition: btSoftBody.h:847
tRenderNodeArray m_renderNodes
Definition: btSoftBody.h:813
void pointersToIndices()
tNoteArray m_notes
Definition: btSoftBody.h:811
void updateNormals()
static void clusterDImpulse(Cluster *cluster, const btVector3 &rpos, const btVector3 &impulse)
static btSoftBody * upcast(btCollisionObject *colObj)
Definition: btSoftBody.h:1148
btDbvt m_fdbvt
Definition: btSoftBody.h:833
tLinkArray m_links
Definition: btSoftBody.h:814
void applyForces()
static btVector3 clusterVelocity(const Cluster *cluster, const btVector3 &rpos)
btTransform getRigidTransform()
tSContactArray m_scontacts
Definition: btSoftBody.h:826
bool m_cacheBarycenter
Definition: btSoftBody.h:843
bool m_useSelfCollision
Definition: btSoftBody.h:849
void * m_tag
Definition: btSoftBody.h:809
void updatePose()
btAlignedObjectArray< btDbvtNode * > tLeafArray
Definition: btSoftBody.h:790
void(* psolver_t)(btSoftBody *, btScalar, btScalar)
Definition: btSoftBody.h:784
static const btSoftBody * upcast(const btCollisionObject *colObj)
Definition: btSoftBody.h:1142
void initializeClusters()
tAnchorArray m_anchors
Definition: btSoftBody.h:820
btScalar getRestLengthScale()
btAlignedObjectArray< Note > tNoteArray
Definition: btSoftBody.h:787
void randomizeConstraints()
virtual void setCollisionShape(btCollisionShape *collisionShape)
Definition: btSoftBody.h:887
btVector3 m_windVelocity
Definition: btSoftBody.h:854
btScalar getTotalMass() const
Definition: btSoftBody.cpp:933
tNodeArray m_nodes
Definition: btSoftBody.h:812
btAlignedObjectArray< ePSolver::_ > tPSolverArray
Definition: btSoftBody.h:152
void appendLink(int model=-1, Material *mat=0)
Definition: btSoftBody.cpp:389
void setSpringStiffness(btScalar k)
void initializeDmInverse()
void updateConstants()
void setTotalMass(btScalar mass, bool fromfaces=false)
Definition: btSoftBody.cpp:944
virtual ~btSoftBody()
Definition: btSoftBody.cpp:237
void appendDeformableAnchor(int node, btRigidBody *body)
Definition: btSoftBody.cpp:528
btAlignedObjectArray< RenderFace > tRenderFaceArray
Definition: btSoftBody.h:793
void updateLinkConstants()
virtual void getAabb(btVector3 &aabbMin, btVector3 &aabbMax) const
Definition: btSoftBody.h:1159
void(* vsolver_t)(btSoftBody *, btScalar)
Definition: btSoftBody.h:785
void initDefaults()
Definition: btSoftBody.cpp:170
btAlignedObjectArray< btVector3 > m_quads
Definition: btSoftBody.h:840
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)
btAlignedObjectArray< Cluster * > tClusterArray
Definition: btSoftBody.h:786
void updateBounds()
void setWindVelocity(const btVector3 &velocity)
Set a wind velocity for interaction with the air.
int generateBendingConstraints(int distance, Material *mat=0)
btAlignedObjectArray< btVector3 > m_X
Definition: btSoftBody.h:844
void translate(const btVector3 &trs)
btVector3 getCenterOfMass() const
Definition: btSoftBody.h:1025
void initializeFaceTree()
btSoftBodySolver * m_softBodySolver
Definition: btSoftBody.h:80
void resetLinkRestLengths()
int clusterCount() const
btAlignedObjectArray< btScalar > tScalarArray
Definition: btSoftBody.h:220
btDbvt m_ndbvt
Definition: btSoftBody.h:832
static void clusterAImpulse(Cluster *cluster, const Impulse &impulse)
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:30
static const btTransform & getIdentity()
Return an identity transform.
Definition: btTransform.h:197
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:82
btVector3 & safeNormalize()
Definition: btVector3.h:286
btScalar safeNorm() const
Return the norm (length) of the vector.
Definition: btVector3.h:269
const btScalar & y() const
Return the y value.
Definition: btVector3.h:577
const btScalar & z() const
Return the z value.
Definition: btVector3.h:579
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition: btVector3.h:229
const btScalar & x() const
Return the x value.
Definition: btVector3.h:575
btScalar length2() const
Return the length of the vector squared.
Definition: btVector3.h:251
static btDbvtAabbMm FromCR(const btVector3 &c, btScalar r)
Definition: btDbvt.h:473
static btDbvtAabbMm FromPoints(const btVector3 *pts, int n)
Definition: btDbvt.h:488
btDbvtNode * childs[2]
Definition: btDbvt.h:187
void * data
Definition: btDbvt.h:188
btDbvtVolume volume
Definition: btDbvt.h:182
DBVT_INLINE bool isleaf() const
Definition: btDbvt.h:184
The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes ...
Definition: btDbvt.h:229
btDbvtNode * m_root
Definition: btDbvt.h:302
btScalar air_density
Definition: btSoftBody.h:49
btDispatcher * m_dispatcher
Definition: btSoftBody.h:55
btScalar water_density
Definition: btSoftBody.h:50
btSparseSdf< 3 > m_sparsesdf
Definition: btSoftBody.h:57
btVector3 m_gravity
Definition: btSoftBody.h:56
btVector3 water_normal
Definition: btSoftBody.h:53
btScalar m_maxDisplacement
Definition: btSoftBody.h:52
btScalar water_offset
Definition: btSoftBody.h:51
btBroadphaseInterface * m_broadphase
Definition: btSoftBody.h:54
virtual btScalar Speed(AJoint *, btScalar current)
Definition: btSoftBody.h:673
virtual void Prepare(AJoint *)
Definition: btSoftBody.h:672
static IControl * Default()
Definition: btSoftBody.h:674
btVector3 m_axis[2]
Definition: btSoftBody.h:686
void Prepare(btScalar dt, int iterations)
void Solve(btScalar dt, btScalar sor)
IControl * m_icontrol
Definition: btSoftBody.h:687
void Terminate(btScalar dt)
eType::_ Type() const
Definition: btSoftBody.h:691
btScalar m_influence
Definition: btSoftBody.h:429
btVector3 m_local
Definition: btSoftBody.h:427
btRigidBody * m_body
Definition: btSoftBody.h:428
btMatrix3x3 m_c0
Definition: btSoftBody.h:430
btScalar invMass() const
Definition: btSoftBody.h:539
Body(Cluster *p)
Definition: btSoftBody.h:519
void applyVImpulse(const btVector3 &impulse, const btVector3 &rpos) const
Definition: btSoftBody.h:574
btVector3 angularVelocity() const
Definition: btSoftBody.h:564
const btTransform & xform() const
Definition: btSoftBody.h:545
btRigidBody * m_rigid
Definition: btSoftBody.h:515
btVector3 linearVelocity() const
Definition: btSoftBody.h:552
btVector3 angularVelocity(const btVector3 &rpos) const
Definition: btSoftBody.h:558
void applyDImpulse(const btVector3 &impulse, const btVector3 &rpos) const
Definition: btSoftBody.h:579
Body(const btCollisionObject *colObj)
Definition: btSoftBody.h:520
btVector3 velocity(const btVector3 &rpos) const
Definition: btSoftBody.h:570
void applyDCImpulse(const btVector3 &impulse) const
Definition: btSoftBody.h:612
void applyDAImpulse(const btVector3 &impulse) const
Definition: btSoftBody.h:602
const btMatrix3x3 & invWorldInertia() const
Definition: btSoftBody.h:532
void activate() const
Definition: btSoftBody.h:525
void applyVAImpulse(const btVector3 &impulse) const
Definition: btSoftBody.h:597
Cluster * m_soft
Definition: btSoftBody.h:514
void applyAImpulse(const Impulse &impulse) const
Definition: btSoftBody.h:607
void applyImpulse(const Impulse &impulse, const btVector3 &rpos) const
Definition: btSoftBody.h:584
const btCollisionObject * m_collisionObject
Definition: btSoftBody.h:516
void Terminate(btScalar dt)
eType::_ Type() const
Definition: btSoftBody.h:704
btVector3 m_rpos[2]
Definition: btSoftBody.h:698
void Prepare(btScalar dt, int iterations)
btVector3 m_normal
Definition: btSoftBody.h:699
btScalar m_friction
Definition: btSoftBody.h:700
void Solve(btScalar dt, btScalar sor)
btVector3 m_dimpulses[2]
Definition: btSoftBody.h:469
tVector3Array m_framerefs
Definition: btSoftBody.h:461
btMatrix3x3 m_invwi
Definition: btSoftBody.h:466
btScalar m_maxSelfCollisionImpulse
Definition: btSoftBody.h:479
btMatrix3x3 m_locii
Definition: btSoftBody.h:465
btAlignedObjectArray< Node * > m_nodes
Definition: btSoftBody.h:460
btDbvtNode * m_leaf
Definition: btSoftBody.h:474
btVector3 m_vimpulses[2]
Definition: btSoftBody.h:468
tScalarArray m_masses
Definition: btSoftBody.h:459
btScalar m_selfCollisionImpulseFactor
Definition: btSoftBody.h:480
btTransform m_framexform
Definition: btSoftBody.h:462
btScalar maxvolume
Definition: btSoftBody.h:728
tPSolverArray m_psequence
Definition: btSoftBody.h:736
tPSolverArray m_dsequence
Definition: btSoftBody.h:737
btScalar kSK_SPLT_CL
Definition: btSoftBody.h:726
btScalar kSS_SPLT_CL
Definition: btSoftBody.h:727
btScalar m_maxStress
Definition: btSoftBody.h:739
eAeroModel::_ aeromodel
Definition: btSoftBody.h:709
btScalar kSR_SPLT_CL
Definition: btSoftBody.h:725
tVSolverArray m_vsequence
Definition: btSoftBody.h:735
btScalar timescale
Definition: btSoftBody.h:729
btVector4 m_pcontact
Definition: btSoftBody.h:311
btVector3 m_normal
Definition: btSoftBody.h:308
btVector3 m_n0
Definition: btSoftBody.h:312
btVector3 m_n1
Definition: btSoftBody.h:312
btVector3 m_vn
Definition: btSoftBody.h:312
Node * m_n[3]
Definition: btSoftBody.h:307
btDbvtNode * m_leaf
Definition: btSoftBody.h:310
Material * m_material
Definition: btSoftBody.h:258
virtual btScalar Eval(const btVector3 &x)=0
Impulse operator*(btScalar x) const
Definition: btSoftBody.h:503
Impulse operator-() const
Definition: btSoftBody.h:496
btVector3 m_velocity
Definition: btSoftBody.h:491
btVector3 m_drift
Definition: btSoftBody.h:642
btVector3 m_sdrift
Definition: btSoftBody.h:643
btScalar m_split
Definition: btSoftBody.h:641
virtual void Solve(btScalar dt, btScalar sor)=0
virtual void Terminate(btScalar dt)=0
btMatrix3x3 m_massmatrix
Definition: btSoftBody.h:644
virtual ~Joint()
Definition: btSoftBody.h:646
btVector3 m_refs[2]
Definition: btSoftBody.h:638
virtual void Prepare(btScalar dt, int iterations)
virtual eType::_ Type() const =0
void Solve(btScalar dt, btScalar sor)
btVector3 m_rpos[2]
Definition: btSoftBody.h:660
eType::_ Type() const
Definition: btSoftBody.h:664
void Prepare(btScalar dt, int iterations)
void Terminate(btScalar dt)
btScalar m_area
Definition: btSoftBody.h:276
btVector3 m_x
Definition: btSoftBody.h:269
btVector3 m_splitv
Definition: btSoftBody.h:281
btVector3 m_vn
Definition: btSoftBody.h:272
btVector3 m_v
Definition: btSoftBody.h:271
btVector3 m_q
Definition: btSoftBody.h:270
btDbvtNode * m_leaf
Definition: btSoftBody.h:277
btVector3 m_n
Definition: btSoftBody.h:274
btVector3 m_f
Definition: btSoftBody.h:273
btMatrix3x3 m_effectiveMass_inv
Definition: btSoftBody.h:283
btMatrix3x3 m_effectiveMass
Definition: btSoftBody.h:282
btScalar m_coords[4]
Definition: btSoftBody.h:441
btVector3 m_offset
Definition: btSoftBody.h:438
Node * m_nodes[4]
Definition: btSoftBody.h:440
const char * m_text
Definition: btSoftBody.h:437
btMatrix3x3 m_scl
Definition: btSoftBody.h:453
btScalar m_volume
Definition: btSoftBody.h:448
btVector3 m_com
Definition: btSoftBody.h:451
tVector3Array m_pos
Definition: btSoftBody.h:449
btMatrix3x3 m_aqq
Definition: btSoftBody.h:454
btMatrix3x3 m_rot
Definition: btSoftBody.h:452
tScalarArray m_wgh
Definition: btSoftBody.h:450
btMultiBodyJacobianData jacobianData_t2
Definition: btSoftBody.h:354
btMultiBodyJacobianData jacobianData_t1
Definition: btSoftBody.h:353
btMatrix3x3 m_c0
Definition: btSoftBody.h:345
btMultiBodyJacobianData jacobianData_normal
Definition: btSoftBody.h:352
RayFromToCaster takes a ray from, ray to (instead of direction!)
Definition: btSoftBody.h:761
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
Definition: btSoftBody.h:764
RenderNode * m_n[3]
Definition: btSoftBody.h:301
btScalar m_cfm[2]
Definition: btSoftBody.h:421
btMatrix3x3 m_corotation
Definition: btSoftBody.h:337
btScalar m_element_measure
Definition: btSoftBody.h:326
btMatrix3x3 m_Dm_inverse
Definition: btSoftBody.h:324
btMatrix3x3 m_F
Definition: btSoftBody.h:325
btVector4 m_P_inv[3]
Definition: btSoftBody.h:327
btVector3 m_c0[4]
Definition: btSoftBody.h:321
btDbvtNode * m_leaf
Definition: btSoftBody.h:320
@ V_TwoSided
Vertex normals are oriented toward velocity.
Definition: btSoftBody.h:92
@ V_OneSided
Vertex normals are flipped to match velocity and lift and drag forces are applied.
Definition: btSoftBody.h:94
@ END
Face normals are taken as it is.
Definition: btSoftBody.h:98
@ V_TwoSidedLiftDrag
Vertex normals are flipped to match velocity.
Definition: btSoftBody.h:93
@ F_OneSided
Face normals are flipped to match velocity and lift and drag forces are applied.
Definition: btSoftBody.h:97
@ F_TwoSided
Vertex normals are taken as it is.
Definition: btSoftBody.h:95
@ F_TwoSidedLiftDrag
Face normals are flipped to match velocity.
Definition: btSoftBody.h:96
ePSolver : positions solvers
Definition: btSoftBody.h:114
@ RContacts
Anchor solver.
Definition: btSoftBody.h:119
@ SContacts
Rigid contacts solver.
Definition: btSoftBody.h:120
@ Anchors
Linear solver.
Definition: btSoftBody.h:118
@ END
Soft contacts solver.
Definition: btSoftBody.h:121
eVSolver : velocities solvers
Definition: btSoftBody.h:104
@ END
Linear solver.
Definition: btSoftBody.h:108
@ SDF_RDN
GJK based Multibody vs. deformable face.
Definition: btSoftBody.h:177
@ VF_SS
Rigid versus soft mask.
Definition: btSoftBody.h:169
@ Default
SDF based Rigid vs. deformable node.
Definition: btSoftBody.h:179
@ RVDFmask
Vertex vs face soft vs soft handling.
Definition: btSoftBody.h:174
@ VF_DD
Cluster soft body self collision.
Definition: btSoftBody.h:172
@ CL_SS
Vertex vs face soft vs soft handling.
Definition: btSoftBody.h:170
@ CL_SELF
Cluster vs cluster soft vs soft handling.
Definition: btSoftBody.h:171
@ SVSmask
rigid vs deformable
Definition: btSoftBody.h:168
@ SDF_RS
Rigid versus soft mask.
Definition: btSoftBody.h:164
@ SDF_RD
Cluster vs convex rigid vs soft.
Definition: btSoftBody.h:166
@ SDF_RDF
Rigid versus deformable face mask.
Definition: btSoftBody.h:175
@ SDF_MDF
GJK based Rigid vs. deformable face.
Definition: btSoftBody.h:176
@ CL_RS
SDF based rigid vs soft.
Definition: btSoftBody.h:165
@ Default
Enable debug draw.
Definition: btSoftBody.h:191
const btCollisionObject * m_colObj
Definition: btSoftBody.h:226
btVector3 m_bary
Definition: btSoftBody.h:229
btScalar m_offset
Definition: btSoftBody.h:228
btVector3 m_normal
Definition: btSoftBody.h:227
btVector3 m_velocity
Definition: btSoftBody.h:235
eFeature::_ feature
soft body
Definition: btSoftBody.h:204
btScalar fraction
feature index
Definition: btSoftBody.h:206
int index
feature type
Definition: btSoftBody.h:205
btSoftBody * body
Definition: btSoftBody.h:203