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 */ 15 ///btSoftBody implementation by Nathanael Presson 16 17 #ifndef _BT_SOFT_BODY_H 18 #define _BT_SOFT_BODY_H 19 20 #include "LinearMath/btAlignedObjectArray.h" 21 #include "LinearMath/btTransform.h" 22 #include "LinearMath/btIDebugDraw.h" 23 #include "BulletDynamics/Dynamics/btRigidBody.h" 24 25 #include "BulletCollision/CollisionShapes/btConcaveShape.h" 26 #include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" 27 #include "btSparseSDF.h" 28 #include "BulletCollision/BroadphaseCollision/btDbvt.h" 29 30 class btBroadphaseInterface; 31 class btDispatcher; 32 33 /* btSoftBodyWorldInfo */ 34 struct btSoftBodyWorldInfo 35 { 36 btScalar air_density; 37 btScalar water_density; 38 btScalar water_offset; 39 btVector3 water_normal; 40 btBroadphaseInterface* m_broadphase; 41 btDispatcher* m_dispatcher; 42 btVector3 m_gravity; 43 btSparseSdf<3> m_sparsesdf; 44 }; 45 46 47 ///The btSoftBody is an class to simulate cloth and volumetric soft bodies. 48 ///There is two-way interaction between btSoftBody and btRigidBody/btCollisionObject. 49 class btSoftBody : public btCollisionObject 50 { 51 public: 52 btAlignedObjectArray<class btCollisionObject*> m_collisionDisabledObjects; 53 54 // 55 // Enumerations 56 // 57 58 ///eAeroModel 59 struct eAeroModel { enum _ { 60 V_Point, ///Vertex normals are oriented toward velocity 61 V_TwoSided, ///Vertex normals are fliped to match velocity 62 V_OneSided, ///Vertex normals are taken as it is 63 F_TwoSided, ///Face normals are fliped to match velocity 64 F_OneSided, ///Face normals are taken as it is 65 END 66 };}; 67 68 ///eVSolver : velocities solvers 69 struct eVSolver { enum _ { 70 Linear, ///Linear solver 71 END 72 };}; 73 74 ///ePSolver : positions solvers 75 struct ePSolver { enum _ { 76 Linear, ///Linear solver 77 Anchors, ///Anchor solver 78 RContacts, ///Rigid contacts solver 79 SContacts, ///Soft contacts solver 80 END 81 };}; 82 83 ///eSolverPresets 84 struct eSolverPresets { enum _ { 85 Positions, 86 Velocities, 87 Default = Positions, 88 END 89 };}; 90 91 ///eFeature 92 struct eFeature { enum _ { 93 None, 94 Node, 95 Link, 96 Face, 97 END 98 };}; 99 100 typedef btAlignedObjectArray<eVSolver::_> tVSolverArray; 101 typedef btAlignedObjectArray<ePSolver::_> tPSolverArray; 102 103 // 104 // Flags 105 // 106 107 ///fCollision 108 struct fCollision { enum _ { 109 RVSmask = 0x000f, ///Rigid versus soft mask 110 SDF_RS = 0x0001, ///SDF based rigid vs soft 111 CL_RS = 0x0002, ///Cluster vs convex rigid vs soft 112 113 SVSmask = 0x0030, ///Rigid versus soft mask 114 VF_SS = 0x0010, ///Vertex vs face soft vs soft handling 115 CL_SS = 0x0020, ///Cluster vs cluster soft vs soft handling 116 CL_SELF = 0x0040, ///Cluster soft body self collision 117 /* presets */ 118 Default = SDF_RS, 119 END 120 };}; 121 122 ///fMaterial 123 struct fMaterial { enum _ { 124 DebugDraw = 0x0001, /// Enable debug draw 125 /* presets */ 126 Default = DebugDraw, 127 END 128 };}; 129 130 // 131 // API Types 132 // 133 134 /* sRayCast */ 135 struct sRayCast 136 { 137 btSoftBody* body; /// soft body 138 eFeature::_ feature; /// feature type 139 int index; /// feature index 140 btScalar fraction; /// time of impact fraction (rayorg+(rayto-rayfrom)*fraction) 141 }; 142 143 /* ImplicitFn */ 144 struct ImplicitFn 145 { 146 virtual btScalar Eval(const btVector3& x)=0; 147 }; 148 149 // 150 // Internal types 151 // 152 153 typedef btAlignedObjectArray<btScalar> tScalarArray; 154 typedef btAlignedObjectArray<btVector3> tVector3Array; 155 156 /* sCti is Softbody contact info */ 157 struct sCti 158 { 159 btCollisionObject* m_colObj; /* Rigid body */ 160 btVector3 m_normal; /* Outward normal */ 161 btScalar m_offset; /* Offset from origin */ 162 }; 163 164 /* sMedium */ 165 struct sMedium 166 { 167 btVector3 m_velocity; /* Velocity */ 168 btScalar m_pressure; /* Pressure */ 169 btScalar m_density; /* Density */ 170 }; 171 172 /* Base type */ 173 struct Element 174 { 175 void* m_tag; // User data ElementElement176 Element() : m_tag(0) {} 177 }; 178 /* Material */ 179 struct Material : Element 180 { 181 btScalar m_kLST; // Linear stiffness coefficient [0,1] 182 btScalar m_kAST; // Area/Angular stiffness coefficient [0,1] 183 btScalar m_kVST; // Volume stiffness coefficient [0,1] 184 int m_flags; // Flags MaterialMaterial185 Material() {} 186 }; 187 188 /* Feature */ 189 struct Feature : Element 190 { 191 Material* m_material; // Material 192 }; 193 /* Node */ 194 struct Node : Feature 195 { 196 btVector3 m_x; // Position 197 btVector3 m_q; // Previous step position 198 btVector3 m_v; // Velocity 199 btVector3 m_f; // Force accumulator 200 btVector3 m_n; // Normal 201 btScalar m_im; // 1/mass 202 btScalar m_area; // Area 203 btDbvtNode* m_leaf; // Leaf data 204 int m_battach:1; // Attached NodeNode205 Node() {} 206 }; 207 /* Link */ 208 struct Link : Feature 209 { 210 Node* m_n[2]; // Node pointers 211 btScalar m_rl; // Rest length 212 int m_bbending:1; // Bending link 213 btScalar m_c0; // (ima+imb)*kLST 214 btScalar m_c1; // rl^2 215 btScalar m_c2; // |gradient|^2/c0 216 btVector3 m_c3; // gradient LinkLink217 Link() {} 218 }; 219 /* Face */ 220 struct Face : Feature 221 { 222 Node* m_n[3]; // Node pointers 223 btVector3 m_normal; // Normal 224 btScalar m_ra; // Rest area 225 btDbvtNode* m_leaf; // Leaf data FaceFace226 Face() {} 227 }; 228 /* Tetra */ 229 struct Tetra : Feature 230 { 231 Node* m_n[4]; // Node pointers 232 btScalar m_rv; // Rest volume 233 btDbvtNode* m_leaf; // Leaf data 234 btVector3 m_c0[4]; // gradients 235 btScalar m_c1; // (4*kVST)/(im0+im1+im2+im3) 236 btScalar m_c2; // m_c1/sum(|g0..3|^2) TetraTetra237 Tetra() {} 238 }; 239 /* RContact */ 240 struct RContact 241 { 242 sCti m_cti; // Contact infos 243 Node* m_node; // Owner node 244 btMatrix3x3 m_c0; // Impulse matrix 245 btVector3 m_c1; // Relative anchor 246 btScalar m_c2; // ima*dt 247 btScalar m_c3; // Friction 248 btScalar m_c4; // Hardness 249 }; 250 /* SContact */ 251 struct SContact 252 { 253 Node* m_node; // Node 254 Face* m_face; // Face 255 btVector3 m_weights; // Weigths 256 btVector3 m_normal; // Normal 257 btScalar m_margin; // Margin 258 btScalar m_friction; // Friction 259 btScalar m_cfm[2]; // Constraint force mixing 260 }; 261 /* Anchor */ 262 struct Anchor 263 { 264 Node* m_node; // Node pointer 265 btVector3 m_local; // Anchor position in body space 266 btRigidBody* m_body; // Body 267 btMatrix3x3 m_c0; // Impulse matrix 268 btVector3 m_c1; // Relative anchor 269 btScalar m_c2; // ima*dt 270 }; 271 /* Note */ 272 struct Note : Element 273 { 274 const char* m_text; // Text 275 btVector3 m_offset; // Offset 276 int m_rank; // Rank 277 Node* m_nodes[4]; // Nodes 278 btScalar m_coords[4]; // Coordinates NoteNote279 Note() {} 280 }; 281 /* Pose */ 282 struct Pose 283 { 284 bool m_bvolume; // Is valid 285 bool m_bframe; // Is frame 286 btScalar m_volume; // Rest volume 287 tVector3Array m_pos; // Reference positions 288 tScalarArray m_wgh; // Weights 289 btVector3 m_com; // COM 290 btMatrix3x3 m_rot; // Rotation 291 btMatrix3x3 m_scl; // Scale 292 btMatrix3x3 m_aqq; // Base scaling 293 }; 294 /* Cluster */ 295 struct Cluster 296 { 297 btAlignedObjectArray<Node*> m_nodes; 298 tScalarArray m_masses; 299 tVector3Array m_framerefs; 300 btTransform m_framexform; 301 btScalar m_idmass; 302 btScalar m_imass; 303 btMatrix3x3 m_locii; 304 btMatrix3x3 m_invwi; 305 btVector3 m_com; 306 btVector3 m_vimpulses[2]; 307 btVector3 m_dimpulses[2]; 308 int m_nvimpulses; 309 int m_ndimpulses; 310 btVector3 m_lv; 311 btVector3 m_av; 312 btDbvtNode* m_leaf; 313 btScalar m_ndamping; /* Node damping */ 314 btScalar m_ldamping; /* Linear damping */ 315 btScalar m_adamping; /* Angular damping */ 316 btScalar m_matching; 317 btScalar m_maxSelfCollisionImpulse; 318 btScalar m_selfCollisionImpulseFactor; 319 bool m_containsAnchor; 320 bool m_collide; 321 int m_clusterIndex; ClusterCluster322 Cluster() : m_leaf(0),m_ndamping(0),m_ldamping(0),m_adamping(0),m_matching(0) 323 ,m_maxSelfCollisionImpulse(100.f), 324 m_selfCollisionImpulseFactor(0.01f), 325 m_containsAnchor(false) 326 {} 327 }; 328 /* Impulse */ 329 struct Impulse 330 { 331 btVector3 m_velocity; 332 btVector3 m_drift; 333 int m_asVelocity:1; 334 int m_asDrift:1; ImpulseImpulse335 Impulse() : m_velocity(0,0,0),m_drift(0,0,0),m_asVelocity(0),m_asDrift(0) {} 336 Impulse operator -() const 337 { 338 Impulse i=*this; 339 i.m_velocity=-i.m_velocity; 340 i.m_drift=-i.m_drift; 341 return(i); 342 } 343 Impulse operator*(btScalar x) const 344 { 345 Impulse i=*this; 346 i.m_velocity*=x; 347 i.m_drift*=x; 348 return(i); 349 } 350 }; 351 /* Body */ 352 struct Body 353 { 354 Cluster* m_soft; 355 btRigidBody* m_rigid; 356 btCollisionObject* m_collisionObject; 357 BodyBody358 Body() : m_soft(0),m_rigid(0),m_collisionObject(0) {} BodyBody359 Body(Cluster* p) : m_soft(p),m_rigid(0),m_collisionObject(0) {} BodyBody360 Body(btCollisionObject* colObj) : m_soft(0),m_collisionObject(colObj) 361 { 362 m_rigid = btRigidBody::upcast(m_collisionObject); 363 } 364 activateBody365 void activate() const 366 { 367 if(m_rigid) m_rigid->activate(); 368 } invWorldInertiaBody369 const btMatrix3x3& invWorldInertia() const 370 { 371 static const btMatrix3x3 iwi(0,0,0,0,0,0,0,0,0); 372 if(m_rigid) return(m_rigid->getInvInertiaTensorWorld()); 373 if(m_soft) return(m_soft->m_invwi); 374 return(iwi); 375 } invMassBody376 btScalar invMass() const 377 { 378 if(m_rigid) return(m_rigid->getInvMass()); 379 if(m_soft) return(m_soft->m_imass); 380 return(0); 381 } xformBody382 const btTransform& xform() const 383 { 384 static const btTransform identity=btTransform::getIdentity(); 385 if(m_collisionObject) return(m_collisionObject->getInterpolationWorldTransform()); 386 if(m_soft) return(m_soft->m_framexform); 387 return(identity); 388 } linearVelocityBody389 btVector3 linearVelocity() const 390 { 391 if(m_rigid) return(m_rigid->getLinearVelocity()); 392 if(m_soft) return(m_soft->m_lv); 393 return(btVector3(0,0,0)); 394 } angularVelocityBody395 btVector3 angularVelocity(const btVector3& rpos) const 396 { 397 if(m_rigid) return(btCross(m_rigid->getAngularVelocity(),rpos)); 398 if(m_soft) return(btCross(m_soft->m_av,rpos)); 399 return(btVector3(0,0,0)); 400 } angularVelocityBody401 btVector3 angularVelocity() const 402 { 403 if(m_rigid) return(m_rigid->getAngularVelocity()); 404 if(m_soft) return(m_soft->m_av); 405 return(btVector3(0,0,0)); 406 } velocityBody407 btVector3 velocity(const btVector3& rpos) const 408 { 409 return(linearVelocity()+angularVelocity(rpos)); 410 } applyVImpulseBody411 void applyVImpulse(const btVector3& impulse,const btVector3& rpos) const 412 { 413 if(m_rigid) m_rigid->applyImpulse(impulse,rpos); 414 if(m_soft) btSoftBody::clusterVImpulse(m_soft,rpos,impulse); 415 } applyDImpulseBody416 void applyDImpulse(const btVector3& impulse,const btVector3& rpos) const 417 { 418 if(m_rigid) m_rigid->applyImpulse(impulse,rpos); 419 if(m_soft) btSoftBody::clusterDImpulse(m_soft,rpos,impulse); 420 } applyImpulseBody421 void applyImpulse(const Impulse& impulse,const btVector3& rpos) const 422 { 423 if(impulse.m_asVelocity) 424 { 425 // printf("impulse.m_velocity = %f,%f,%f\n",impulse.m_velocity.getX(),impulse.m_velocity.getY(),impulse.m_velocity.getZ()); 426 applyVImpulse(impulse.m_velocity,rpos); 427 } 428 if(impulse.m_asDrift) 429 { 430 // printf("impulse.m_drift = %f,%f,%f\n",impulse.m_drift.getX(),impulse.m_drift.getY(),impulse.m_drift.getZ()); 431 applyDImpulse(impulse.m_drift,rpos); 432 } 433 } applyVAImpulseBody434 void applyVAImpulse(const btVector3& impulse) const 435 { 436 if(m_rigid) m_rigid->applyTorqueImpulse(impulse); 437 if(m_soft) btSoftBody::clusterVAImpulse(m_soft,impulse); 438 } applyDAImpulseBody439 void applyDAImpulse(const btVector3& impulse) const 440 { 441 if(m_rigid) m_rigid->applyTorqueImpulse(impulse); 442 if(m_soft) btSoftBody::clusterDAImpulse(m_soft,impulse); 443 } applyAImpulseBody444 void applyAImpulse(const Impulse& impulse) const 445 { 446 if(impulse.m_asVelocity) applyVAImpulse(impulse.m_velocity); 447 if(impulse.m_asDrift) applyDAImpulse(impulse.m_drift); 448 } applyDCImpulseBody449 void applyDCImpulse(const btVector3& impulse) const 450 { 451 if(m_rigid) m_rigid->applyCentralImpulse(impulse); 452 if(m_soft) btSoftBody::clusterDCImpulse(m_soft,impulse); 453 } 454 }; 455 /* Joint */ 456 struct Joint 457 { 458 struct eType { enum _ { 459 Linear, 460 Angular, 461 Contact 462 };}; 463 struct Specs 464 { SpecsJoint::Specs465 Specs() : erp(1),cfm(1),split(1) {} 466 btScalar erp; 467 btScalar cfm; 468 btScalar split; 469 }; 470 Body m_bodies[2]; 471 btVector3 m_refs[2]; 472 btScalar m_cfm; 473 btScalar m_erp; 474 btScalar m_split; 475 btVector3 m_drift; 476 btVector3 m_sdrift; 477 btMatrix3x3 m_massmatrix; 478 bool m_delete; ~JointJoint479 virtual ~Joint() {} JointJoint480 Joint() : m_delete(false) {} 481 virtual void Prepare(btScalar dt,int iterations); 482 virtual void Solve(btScalar dt,btScalar sor)=0; 483 virtual void Terminate(btScalar dt)=0; 484 virtual eType::_ Type() const=0; 485 }; 486 /* LJoint */ 487 struct LJoint : Joint 488 { 489 struct Specs : Joint::Specs 490 { 491 btVector3 position; 492 }; 493 btVector3 m_rpos[2]; 494 void Prepare(btScalar dt,int iterations); 495 void Solve(btScalar dt,btScalar sor); 496 void Terminate(btScalar dt); TypeLJoint497 eType::_ Type() const { return(eType::Linear); } 498 }; 499 /* AJoint */ 500 struct AJoint : Joint 501 { 502 struct IControl 503 { PrepareAJoint::IControl504 virtual void Prepare(AJoint*) {} SpeedAJoint::IControl505 virtual btScalar Speed(AJoint*,btScalar current) { return(current); } DefaultAJoint::IControl506 static IControl* Default() { static IControl def;return(&def); } 507 }; 508 struct Specs : Joint::Specs 509 { SpecsAJoint::Specs510 Specs() : icontrol(IControl::Default()) {} 511 btVector3 axis; 512 IControl* icontrol; 513 }; 514 btVector3 m_axis[2]; 515 IControl* m_icontrol; 516 void Prepare(btScalar dt,int iterations); 517 void Solve(btScalar dt,btScalar sor); 518 void Terminate(btScalar dt); TypeAJoint519 eType::_ Type() const { return(eType::Angular); } 520 }; 521 /* CJoint */ 522 struct CJoint : Joint 523 { 524 int m_life; 525 int m_maxlife; 526 btVector3 m_rpos[2]; 527 btVector3 m_normal; 528 btScalar m_friction; 529 void Prepare(btScalar dt,int iterations); 530 void Solve(btScalar dt,btScalar sor); 531 void Terminate(btScalar dt); TypeCJoint532 eType::_ Type() const { return(eType::Contact); } 533 }; 534 /* Config */ 535 struct Config 536 { 537 eAeroModel::_ aeromodel; // Aerodynamic model (default: V_Point) 538 btScalar kVCF; // Velocities correction factor (Baumgarte) 539 btScalar kDP; // Damping coefficient [0,1] 540 btScalar kDG; // Drag coefficient [0,+inf] 541 btScalar kLF; // Lift coefficient [0,+inf] 542 btScalar kPR; // Pressure coefficient [-inf,+inf] 543 btScalar kVC; // Volume conversation coefficient [0,+inf] 544 btScalar kDF; // Dynamic friction coefficient [0,1] 545 btScalar kMT; // Pose matching coefficient [0,1] 546 btScalar kCHR; // Rigid contacts hardness [0,1] 547 btScalar kKHR; // Kinetic contacts hardness [0,1] 548 btScalar kSHR; // Soft contacts hardness [0,1] 549 btScalar kAHR; // Anchors hardness [0,1] 550 btScalar kSRHR_CL; // Soft vs rigid hardness [0,1] (cluster only) 551 btScalar kSKHR_CL; // Soft vs kinetic hardness [0,1] (cluster only) 552 btScalar kSSHR_CL; // Soft vs soft hardness [0,1] (cluster only) 553 btScalar kSR_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only) 554 btScalar kSK_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only) 555 btScalar kSS_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only) 556 btScalar maxvolume; // Maximum volume ratio for pose 557 btScalar timescale; // Time scale 558 int viterations; // Velocities solver iterations 559 int piterations; // Positions solver iterations 560 int diterations; // Drift solver iterations 561 int citerations; // Cluster solver iterations 562 int collisions; // Collisions flags 563 tVSolverArray m_vsequence; // Velocity solvers sequence 564 tPSolverArray m_psequence; // Position solvers sequence 565 tPSolverArray m_dsequence; // Drift solvers sequence 566 }; 567 /* SolverState */ 568 struct SolverState 569 { 570 btScalar sdt; // dt*timescale 571 btScalar isdt; // 1/sdt 572 btScalar velmrg; // velocity margin 573 btScalar radmrg; // radial margin 574 btScalar updmrg; // Update margin 575 }; 576 /// RayFromToCaster takes a ray from, ray to (instead of direction!) 577 struct RayFromToCaster : btDbvt::ICollide 578 { 579 btVector3 m_rayFrom; 580 btVector3 m_rayTo; 581 btVector3 m_rayNormalizedDirection; 582 btScalar m_mint; 583 Face* m_face; 584 int m_tests; 585 RayFromToCaster(const btVector3& rayFrom,const btVector3& rayTo,btScalar mxt); 586 void Process(const btDbvtNode* leaf); 587 588 static inline btScalar rayFromToTriangle(const btVector3& rayFrom, 589 const btVector3& rayTo, 590 const btVector3& rayNormalizedDirection, 591 const btVector3& a, 592 const btVector3& b, 593 const btVector3& c, 594 btScalar maxt=SIMD_INFINITY); 595 }; 596 597 // 598 // Typedef's 599 // 600 601 typedef void (*psolver_t)(btSoftBody*,btScalar,btScalar); 602 typedef void (*vsolver_t)(btSoftBody*,btScalar); 603 typedef btAlignedObjectArray<Cluster*> tClusterArray; 604 typedef btAlignedObjectArray<Note> tNoteArray; 605 typedef btAlignedObjectArray<Node> tNodeArray; 606 typedef btAlignedObjectArray<btDbvtNode*> tLeafArray; 607 typedef btAlignedObjectArray<Link> tLinkArray; 608 typedef btAlignedObjectArray<Face> tFaceArray; 609 typedef btAlignedObjectArray<Tetra> tTetraArray; 610 typedef btAlignedObjectArray<Anchor> tAnchorArray; 611 typedef btAlignedObjectArray<RContact> tRContactArray; 612 typedef btAlignedObjectArray<SContact> tSContactArray; 613 typedef btAlignedObjectArray<Material*> tMaterialArray; 614 typedef btAlignedObjectArray<Joint*> tJointArray; 615 typedef btAlignedObjectArray<btSoftBody*> tSoftBodyArray; 616 617 // 618 // Fields 619 // 620 621 Config m_cfg; // Configuration 622 SolverState m_sst; // Solver state 623 Pose m_pose; // Pose 624 void* m_tag; // User data 625 btSoftBodyWorldInfo* m_worldInfo; // World info 626 tNoteArray m_notes; // Notes 627 tNodeArray m_nodes; // Nodes 628 tLinkArray m_links; // Links 629 tFaceArray m_faces; // Faces 630 tTetraArray m_tetras; // Tetras 631 tAnchorArray m_anchors; // Anchors 632 tRContactArray m_rcontacts; // Rigid contacts 633 tSContactArray m_scontacts; // Soft contacts 634 tJointArray m_joints; // Joints 635 tMaterialArray m_materials; // Materials 636 btScalar m_timeacc; // Time accumulator 637 btVector3 m_bounds[2]; // Spatial bounds 638 bool m_bUpdateRtCst; // Update runtime constants 639 btDbvt m_ndbvt; // Nodes tree 640 btDbvt m_fdbvt; // Faces tree 641 btDbvt m_cdbvt; // Clusters tree 642 tClusterArray m_clusters; // Clusters 643 644 btAlignedObjectArray<bool>m_clusterConnectivity;//cluster connectivity, for self-collision 645 646 btTransform m_initialWorldTransform; 647 648 // 649 // Api 650 // 651 652 /* ctor */ 653 btSoftBody( btSoftBodyWorldInfo* worldInfo,int node_count, 654 const btVector3* x, 655 const btScalar* m); 656 /* dtor */ 657 virtual ~btSoftBody(); 658 /* Check for existing link */ 659 660 btAlignedObjectArray<int> m_userIndexMapping; 661 getWorldInfo()662 btSoftBodyWorldInfo* getWorldInfo() 663 { 664 return m_worldInfo; 665 } 666 667 ///@todo: avoid internal softbody shape hack and move collision code to collision library setCollisionShape(btCollisionShape * collisionShape)668 virtual void setCollisionShape(btCollisionShape* collisionShape) 669 { 670 671 } 672 673 bool checkLink( int node0, 674 int node1) const; 675 bool checkLink( const Node* node0, 676 const Node* node1) const; 677 /* Check for existring face */ 678 bool checkFace( int node0, 679 int node1, 680 int node2) const; 681 /* Append material */ 682 Material* appendMaterial(); 683 /* Append note */ 684 void appendNote( const char* text, 685 const btVector3& o, 686 const btVector4& c=btVector4(1,0,0,0), 687 Node* n0=0, 688 Node* n1=0, 689 Node* n2=0, 690 Node* n3=0); 691 void appendNote( const char* text, 692 const btVector3& o, 693 Node* feature); 694 void appendNote( const char* text, 695 const btVector3& o, 696 Link* feature); 697 void appendNote( const char* text, 698 const btVector3& o, 699 Face* feature); 700 /* Append node */ 701 void appendNode( const btVector3& x,btScalar m); 702 /* Append link */ 703 void appendLink(int model=-1,Material* mat=0); 704 void appendLink( int node0, 705 int node1, 706 Material* mat=0, 707 bool bcheckexist=false); 708 void appendLink( Node* node0, 709 Node* node1, 710 Material* mat=0, 711 bool bcheckexist=false); 712 /* Append face */ 713 void appendFace(int model=-1,Material* mat=0); 714 void appendFace( int node0, 715 int node1, 716 int node2, 717 Material* mat=0); 718 void appendTetra(int model,Material* mat); 719 // 720 void appendTetra(int node0, 721 int node1, 722 int node2, 723 int node3, 724 Material* mat=0); 725 726 727 /* Append anchor */ 728 void appendAnchor( int node, 729 btRigidBody* body, bool disableCollisionBetweenLinkedBodies=false); 730 /* Append linear joint */ 731 void appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1); 732 void appendLinearJoint(const LJoint::Specs& specs,Body body=Body()); 733 void appendLinearJoint(const LJoint::Specs& specs,btSoftBody* body); 734 /* Append linear joint */ 735 void appendAngularJoint(const AJoint::Specs& specs,Cluster* body0,Body body1); 736 void appendAngularJoint(const AJoint::Specs& specs,Body body=Body()); 737 void appendAngularJoint(const AJoint::Specs& specs,btSoftBody* body); 738 /* Add force (or gravity) to the entire body */ 739 void addForce( const btVector3& force); 740 /* Add force (or gravity) to a node of the body */ 741 void addForce( const btVector3& force, 742 int node); 743 /* Add velocity to the entire body */ 744 void addVelocity( const btVector3& velocity); 745 746 /* Set velocity for the entire body */ 747 void setVelocity( const btVector3& velocity); 748 749 /* Add velocity to a node of the body */ 750 void addVelocity( const btVector3& velocity, 751 int node); 752 /* Set mass */ 753 void setMass( int node, 754 btScalar mass); 755 /* Get mass */ 756 btScalar getMass( int node) const; 757 /* Get total mass */ 758 btScalar getTotalMass() const; 759 /* Set total mass (weighted by previous masses) */ 760 void setTotalMass( btScalar mass, 761 bool fromfaces=false); 762 /* Set total density */ 763 void setTotalDensity(btScalar density); 764 /* Set volume mass (using tetrahedrons) */ 765 void setVolumeMass( btScalar mass); 766 /* Set volume density (using tetrahedrons) */ 767 void setVolumeDensity( btScalar density); 768 /* Transform */ 769 void transform( const btTransform& trs); 770 /* Translate */ 771 void translate( const btVector3& trs); 772 /* Rotate */ 773 void rotate( const btQuaternion& rot); 774 /* Scale */ 775 void scale( const btVector3& scl); 776 /* Set current state as pose */ 777 void setPose( bool bvolume, 778 bool bframe); 779 /* Return the volume */ 780 btScalar getVolume() const; 781 /* Cluster count */ 782 int clusterCount() const; 783 /* Cluster center of mass */ 784 static btVector3 clusterCom(const Cluster* cluster); 785 btVector3 clusterCom(int cluster) const; 786 /* Cluster velocity at rpos */ 787 static btVector3 clusterVelocity(const Cluster* cluster,const btVector3& rpos); 788 /* Cluster impulse */ 789 static void clusterVImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse); 790 static void clusterDImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse); 791 static void clusterImpulse(Cluster* cluster,const btVector3& rpos,const Impulse& impulse); 792 static void clusterVAImpulse(Cluster* cluster,const btVector3& impulse); 793 static void clusterDAImpulse(Cluster* cluster,const btVector3& impulse); 794 static void clusterAImpulse(Cluster* cluster,const Impulse& impulse); 795 static void clusterDCImpulse(Cluster* cluster,const btVector3& impulse); 796 /* Generate bending constraints based on distance in the adjency graph */ 797 int generateBendingConstraints( int distance, 798 Material* mat=0); 799 /* Randomize constraints to reduce solver bias */ 800 void randomizeConstraints(); 801 /* Release clusters */ 802 void releaseCluster(int index); 803 void releaseClusters(); 804 /* Generate clusters (K-mean) */ 805 ///generateClusters with k=0 will create a convex cluster for each tetrahedron or triangle 806 ///otherwise an approximation will be used (better performance) 807 int generateClusters(int k,int maxiterations=8192); 808 /* Refine */ 809 void refine(ImplicitFn* ifn,btScalar accurary,bool cut); 810 /* CutLink */ 811 bool cutLink(int node0,int node1,btScalar position); 812 bool cutLink(const Node* node0,const Node* node1,btScalar position); 813 814 ///Ray casting using rayFrom and rayTo in worldspace, (not direction!) 815 bool rayTest(const btVector3& rayFrom, 816 const btVector3& rayTo, 817 sRayCast& results); 818 /* Solver presets */ 819 void setSolver(eSolverPresets::_ preset); 820 /* predictMotion */ 821 void predictMotion(btScalar dt); 822 /* solveConstraints */ 823 void solveConstraints(); 824 /* staticSolve */ 825 void staticSolve(int iterations); 826 /* solveCommonConstraints */ 827 static void solveCommonConstraints(btSoftBody** bodies,int count,int iterations); 828 /* solveClusters */ 829 static void solveClusters(const btAlignedObjectArray<btSoftBody*>& bodies); 830 /* integrateMotion */ 831 void integrateMotion(); 832 /* defaultCollisionHandlers */ 833 void defaultCollisionHandler(btCollisionObject* pco); 834 void defaultCollisionHandler(btSoftBody* psb); 835 836 // 837 // Cast 838 // 839 upcast(const btCollisionObject * colObj)840 static const btSoftBody* upcast(const btCollisionObject* colObj) 841 { 842 if (colObj->getInternalType()==CO_SOFT_BODY) 843 return (const btSoftBody*)colObj; 844 return 0; 845 } upcast(btCollisionObject * colObj)846 static btSoftBody* upcast(btCollisionObject* colObj) 847 { 848 if (colObj->getInternalType()==CO_SOFT_BODY) 849 return (btSoftBody*)colObj; 850 return 0; 851 } 852 853 // 854 // ::btCollisionObject 855 // 856 getAabb(btVector3 & aabbMin,btVector3 & aabbMax)857 virtual void getAabb(btVector3& aabbMin,btVector3& aabbMax) const 858 { 859 aabbMin = m_bounds[0]; 860 aabbMax = m_bounds[1]; 861 } 862 // 863 // Private 864 // 865 void pointersToIndices(); 866 void indicesToPointers(const int* map=0); 867 868 int rayTest(const btVector3& rayFrom,const btVector3& rayTo, 869 btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const; 870 void initializeFaceTree(); 871 btVector3 evaluateCom() const; 872 bool checkContact(btCollisionObject* colObj,const btVector3& x,btScalar margin,btSoftBody::sCti& cti) const; 873 void updateNormals(); 874 void updateBounds(); 875 void updatePose(); 876 void updateConstants(); 877 void initializeClusters(); 878 void updateClusters(); 879 void cleanupClusters(); 880 void prepareClusters(int iterations); 881 void solveClusters(btScalar sor); 882 void applyClusters(bool drift); 883 void dampClusters(); 884 void applyForces(); 885 static void PSolve_Anchors(btSoftBody* psb,btScalar kst,btScalar ti); 886 static void PSolve_RContacts(btSoftBody* psb,btScalar kst,btScalar ti); 887 static void PSolve_SContacts(btSoftBody* psb,btScalar,btScalar ti); 888 static void PSolve_Links(btSoftBody* psb,btScalar kst,btScalar ti); 889 static void VSolve_Links(btSoftBody* psb,btScalar kst); 890 static psolver_t getSolver(ePSolver::_ solver); 891 static vsolver_t getSolver(eVSolver::_ solver); 892 893 }; 894 895 896 897 #endif //_BT_SOFT_BODY_H 898