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