123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395 |
- /*
- Bullet Continuous Collision Detection and Physics Library
- Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
- This software is provided 'as-is', without any express or implied warranty.
- In no event will the authors be held liable for any damages arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it freely,
- subject to the following restrictions:
- 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.
- 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
- */
- ///btSoftBody implementation by Nathanael Presson
- #ifndef _BT_SOFT_BODY_H
- #define _BT_SOFT_BODY_H
- #include "LinearMath/btAlignedObjectArray.h"
- #include "LinearMath/btTransform.h"
- #include "LinearMath/btIDebugDraw.h"
- #include "LinearMath/btVector3.h"
- #include "BulletDynamics/Dynamics/btRigidBody.h"
- #include "BulletCollision/CollisionShapes/btConcaveShape.h"
- #include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
- #include "btSparseSDF.h"
- #include "BulletCollision/BroadphaseCollision/btDbvt.h"
- #include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h"
- #include "BulletDynamics/Featherstone/btMultiBodyConstraint.h"
- //#ifdef BT_USE_DOUBLE_PRECISION
- //#define btRigidBodyData btRigidBodyDoubleData
- //#define btRigidBodyDataName "btRigidBodyDoubleData"
- //#else
- #define btSoftBodyData btSoftBodyFloatData
- #define btSoftBodyDataName "btSoftBodyFloatData"
- static const btScalar OVERLAP_REDUCTION_FACTOR = 0.1;
- static unsigned long seed = 243703;
- //#endif //BT_USE_DOUBLE_PRECISION
- class btBroadphaseInterface;
- class btDispatcher;
- class btSoftBodySolver;
- /* btSoftBodyWorldInfo */
- struct btSoftBodyWorldInfo
- {
- btScalar air_density;
- btScalar water_density;
- btScalar water_offset;
- btScalar m_maxDisplacement;
- btVector3 water_normal;
- btBroadphaseInterface* m_broadphase;
- btDispatcher* m_dispatcher;
- btVector3 m_gravity;
- btSparseSdf<3> m_sparsesdf;
- btSoftBodyWorldInfo()
- : air_density((btScalar)1.2),
- water_density(0),
- water_offset(0),
- m_maxDisplacement(1000.f), //avoid soft body from 'exploding' so use some upper threshold of maximum motion that a node can travel per frame
- water_normal(0, 0, 0),
- m_broadphase(0),
- m_dispatcher(0),
- m_gravity(0, -10, 0)
- {
- }
- };
- ///The btSoftBody is an class to simulate cloth and volumetric soft bodies.
- ///There is two-way interaction between btSoftBody and btRigidBody/btCollisionObject.
- class btSoftBody : public btCollisionObject
- {
- public:
- btAlignedObjectArray<const class btCollisionObject*> m_collisionDisabledObjects;
- // The solver object that handles this soft body
- btSoftBodySolver* m_softBodySolver;
- //
- // Enumerations
- //
- ///eAeroModel
- struct eAeroModel
- {
- enum _
- {
- V_Point, ///Vertex normals are oriented toward velocity
- V_TwoSided, ///Vertex normals are flipped to match velocity
- V_TwoSidedLiftDrag, ///Vertex normals are flipped to match velocity and lift and drag forces are applied
- V_OneSided, ///Vertex normals are taken as it is
- F_TwoSided, ///Face normals are flipped to match velocity
- F_TwoSidedLiftDrag, ///Face normals are flipped to match velocity and lift and drag forces are applied
- F_OneSided, ///Face normals are taken as it is
- END
- };
- };
- ///eVSolver : velocities solvers
- struct eVSolver
- {
- enum _
- {
- Linear, ///Linear solver
- END
- };
- };
- ///ePSolver : positions solvers
- struct ePSolver
- {
- enum _
- {
- Linear, ///Linear solver
- Anchors, ///Anchor solver
- RContacts, ///Rigid contacts solver
- SContacts, ///Soft contacts solver
- END
- };
- };
- ///eSolverPresets
- struct eSolverPresets
- {
- enum _
- {
- Positions,
- Velocities,
- Default = Positions,
- END
- };
- };
- ///eFeature
- struct eFeature
- {
- enum _
- {
- None,
- Node,
- Link,
- Face,
- Tetra,
- END
- };
- };
- typedef btAlignedObjectArray<eVSolver::_> tVSolverArray;
- typedef btAlignedObjectArray<ePSolver::_> tPSolverArray;
- //
- // Flags
- //
- ///fCollision
- struct fCollision
- {
- enum _
- {
- RVSmask = 0x000f, ///Rigid versus soft mask
- SDF_RS = 0x0001, ///SDF based rigid vs soft
- CL_RS = 0x0002, ///Cluster vs convex rigid vs soft
- SDF_RD = 0x0004, ///rigid vs deformable
- SVSmask = 0x00f0, ///Rigid versus soft mask
- VF_SS = 0x0010, ///Vertex vs face soft vs soft handling
- CL_SS = 0x0020, ///Cluster vs cluster soft vs soft handling
- CL_SELF = 0x0040, ///Cluster soft body self collision
- VF_DD = 0x0080, ///Vertex vs face soft vs soft handling
- RVDFmask = 0x0f00, /// Rigid versus deformable face mask
- SDF_RDF = 0x0100, /// GJK based Rigid vs. deformable face
- SDF_MDF = 0x0200, /// GJK based Multibody vs. deformable face
- SDF_RDN = 0x0400, /// SDF based Rigid vs. deformable node
- /* presets */
- Default = SDF_RS,
- END
- };
- };
- ///fMaterial
- struct fMaterial
- {
- enum _
- {
- DebugDraw = 0x0001, /// Enable debug draw
- /* presets */
- Default = DebugDraw,
- END
- };
- };
- //
- // API Types
- //
- /* sRayCast */
- struct sRayCast
- {
- btSoftBody* body; /// soft body
- eFeature::_ feature; /// feature type
- int index; /// feature index
- btScalar fraction; /// time of impact fraction (rayorg+(rayto-rayfrom)*fraction)
- };
- /* ImplicitFn */
- struct ImplicitFn
- {
- virtual ~ImplicitFn() {}
- virtual btScalar Eval(const btVector3& x) = 0;
- };
- //
- // Internal types
- //
- typedef btAlignedObjectArray<btScalar> tScalarArray;
- typedef btAlignedObjectArray<btVector3> tVector3Array;
- /* sCti is Softbody contact info */
- struct sCti
- {
- const btCollisionObject* m_colObj; /* Rigid body */
- btVector3 m_normal; /* Outward normal */
- btScalar m_offset; /* Offset from origin */
- btVector3 m_bary; /* Barycentric weights for faces */
- };
- /* sMedium */
- struct sMedium
- {
- btVector3 m_velocity; /* Velocity */
- btScalar m_pressure; /* Pressure */
- btScalar m_density; /* Density */
- };
- /* Base type */
- struct Element
- {
- void* m_tag; // User data
- Element() : m_tag(0) {}
- };
- /* Material */
- struct Material : Element
- {
- btScalar m_kLST; // Linear stiffness coefficient [0,1]
- btScalar m_kAST; // Area/Angular stiffness coefficient [0,1]
- btScalar m_kVST; // Volume stiffness coefficient [0,1]
- int m_flags; // Flags
- };
- /* Feature */
- struct Feature : Element
- {
- Material* m_material; // Material
- };
- /* Node */
- struct RenderNode
- {
- btVector3 m_x;
- btVector3 m_uv1;
- btVector3 m_normal;
- };
- struct Node : Feature
- {
- btVector3 m_x; // Position
- btVector3 m_q; // Previous step position/Test position
- btVector3 m_v; // Velocity
- btVector3 m_vn; // Previous step velocity
- btVector3 m_f; // Force accumulator
- btVector3 m_n; // Normal
- btScalar m_im; // 1/mass
- btScalar m_area; // Area
- btDbvtNode* m_leaf; // Leaf data
- int m_constrained; // depth of penetration
- int m_battach : 1; // Attached
- int index;
- btVector3 m_splitv; // velocity associated with split impulse
- btMatrix3x3 m_effectiveMass; // effective mass in contact
- btMatrix3x3 m_effectiveMass_inv; // inverse of effective mass
- };
- /* Link */
- ATTRIBUTE_ALIGNED16(struct)
- Link : Feature
- {
- btVector3 m_c3; // gradient
- Node* m_n[2]; // Node pointers
- btScalar m_rl; // Rest length
- int m_bbending : 1; // Bending link
- btScalar m_c0; // (ima+imb)*kLST
- btScalar m_c1; // rl^2
- btScalar m_c2; // |gradient|^2/c0
- BT_DECLARE_ALIGNED_ALLOCATOR();
- };
- struct RenderFace
- {
- RenderNode* m_n[3]; // Node pointers
- };
- /* Face */
- struct Face : Feature
- {
- Node* m_n[3]; // Node pointers
- btVector3 m_normal; // Normal
- btScalar m_ra; // Rest area
- btDbvtNode* m_leaf; // Leaf data
- btVector4 m_pcontact; // barycentric weights of the persistent contact
- btVector3 m_n0, m_n1, m_vn;
- int m_index;
- };
- /* Tetra */
- struct Tetra : Feature
- {
- Node* m_n[4]; // Node pointers
- btScalar m_rv; // Rest volume
- btDbvtNode* m_leaf; // Leaf data
- btVector3 m_c0[4]; // gradients
- btScalar m_c1; // (4*kVST)/(im0+im1+im2+im3)
- btScalar m_c2; // m_c1/sum(|g0..3|^2)
- btMatrix3x3 m_Dm_inverse; // rest Dm^-1
- btMatrix3x3 m_F;
- btScalar m_element_measure;
- btVector4 m_P_inv[3]; // first three columns of P_inv matrix
- };
- /* TetraScratch */
- struct TetraScratch
- {
- btMatrix3x3 m_F; // deformation gradient F
- btScalar m_trace; // trace of F^T * F
- btScalar m_J; // det(F)
- btMatrix3x3 m_cofF; // cofactor of F
- btMatrix3x3 m_corotation; // corotatio of the tetra
- };
- /* RContact */
- struct RContact
- {
- sCti m_cti; // Contact infos
- Node* m_node; // Owner node
- btMatrix3x3 m_c0; // Impulse matrix
- btVector3 m_c1; // Relative anchor
- btScalar m_c2; // ima*dt
- btScalar m_c3; // Friction
- btScalar m_c4; // Hardness
- // jacobians and unit impulse responses for multibody
- btMultiBodyJacobianData jacobianData_normal;
- btMultiBodyJacobianData jacobianData_t1;
- btMultiBodyJacobianData jacobianData_t2;
- btVector3 t1;
- btVector3 t2;
- };
- class DeformableRigidContact
- {
- public:
- sCti m_cti; // Contact infos
- btMatrix3x3 m_c0; // Impulse matrix
- btVector3 m_c1; // Relative anchor
- btScalar m_c2; // inverse mass of node/face
- btScalar m_c3; // Friction
- btScalar m_c4; // Hardness
- btMatrix3x3 m_c5; // inverse effective mass
- // jacobians and unit impulse responses for multibody
- btMultiBodyJacobianData jacobianData_normal;
- btMultiBodyJacobianData jacobianData_t1;
- btMultiBodyJacobianData jacobianData_t2;
- btVector3 t1;
- btVector3 t2;
- };
- class DeformableNodeRigidContact : public DeformableRigidContact
- {
- public:
- Node* m_node; // Owner node
- };
- class DeformableNodeRigidAnchor : public DeformableNodeRigidContact
- {
- public:
- btVector3 m_local; // Anchor position in body space
- };
- class DeformableFaceRigidContact : public DeformableRigidContact
- {
- public:
- Face* m_face; // Owner face
- btVector3 m_contactPoint; // Contact point
- btVector3 m_bary; // Barycentric weights
- btVector3 m_weights; // v_contactPoint * m_weights[i] = m_face->m_node[i]->m_v;
- };
- struct DeformableFaceNodeContact
- {
- Node* m_node; // Node
- Face* m_face; // Face
- btVector3 m_bary; // Barycentric weights
- btVector3 m_weights; // v_contactPoint * m_weights[i] = m_face->m_node[i]->m_v;
- btVector3 m_normal; // Normal
- btScalar m_margin; // Margin
- btScalar m_friction; // Friction
- btScalar m_imf; // inverse mass of the face at contact point
- btScalar m_c0; // scale of the impulse matrix;
- };
- /* SContact */
- struct SContact
- {
- Node* m_node; // Node
- Face* m_face; // Face
- btVector3 m_weights; // Weigths
- btVector3 m_normal; // Normal
- btScalar m_margin; // Margin
- btScalar m_friction; // Friction
- btScalar m_cfm[2]; // Constraint force mixing
- };
- /* Anchor */
- struct Anchor
- {
- Node* m_node; // Node pointer
- btVector3 m_local; // Anchor position in body space
- btRigidBody* m_body; // Body
- btScalar m_influence;
- btMatrix3x3 m_c0; // Impulse matrix
- btVector3 m_c1; // Relative anchor
- btScalar m_c2; // ima*dt
- };
- /* Note */
- struct Note : Element
- {
- const char* m_text; // Text
- btVector3 m_offset; // Offset
- int m_rank; // Rank
- Node* m_nodes[4]; // Nodes
- btScalar m_coords[4]; // Coordinates
- };
- /* Pose */
- struct Pose
- {
- bool m_bvolume; // Is valid
- bool m_bframe; // Is frame
- btScalar m_volume; // Rest volume
- tVector3Array m_pos; // Reference positions
- tScalarArray m_wgh; // Weights
- btVector3 m_com; // COM
- btMatrix3x3 m_rot; // Rotation
- btMatrix3x3 m_scl; // Scale
- btMatrix3x3 m_aqq; // Base scaling
- };
- /* Cluster */
- struct Cluster
- {
- tScalarArray m_masses;
- btAlignedObjectArray<Node*> m_nodes;
- tVector3Array m_framerefs;
- btTransform m_framexform;
- btScalar m_idmass;
- btScalar m_imass;
- btMatrix3x3 m_locii;
- btMatrix3x3 m_invwi;
- btVector3 m_com;
- btVector3 m_vimpulses[2];
- btVector3 m_dimpulses[2];
- int m_nvimpulses;
- int m_ndimpulses;
- btVector3 m_lv;
- btVector3 m_av;
- btDbvtNode* m_leaf;
- btScalar m_ndamping; /* Node damping */
- btScalar m_ldamping; /* Linear damping */
- btScalar m_adamping; /* Angular damping */
- btScalar m_matching;
- btScalar m_maxSelfCollisionImpulse;
- btScalar m_selfCollisionImpulseFactor;
- bool m_containsAnchor;
- bool m_collide;
- int m_clusterIndex;
- Cluster() : m_leaf(0), m_ndamping(0), m_ldamping(0), m_adamping(0), m_matching(0), m_maxSelfCollisionImpulse(100.f), m_selfCollisionImpulseFactor(0.01f), m_containsAnchor(false)
- {
- }
- };
- /* Impulse */
- struct Impulse
- {
- btVector3 m_velocity;
- btVector3 m_drift;
- int m_asVelocity : 1;
- int m_asDrift : 1;
- Impulse() : m_velocity(0, 0, 0), m_drift(0, 0, 0), m_asVelocity(0), m_asDrift(0) {}
- Impulse operator-() const
- {
- Impulse i = *this;
- i.m_velocity = -i.m_velocity;
- i.m_drift = -i.m_drift;
- return (i);
- }
- Impulse operator*(btScalar x) const
- {
- Impulse i = *this;
- i.m_velocity *= x;
- i.m_drift *= x;
- return (i);
- }
- };
- /* Body */
- struct Body
- {
- Cluster* m_soft;
- btRigidBody* m_rigid;
- const btCollisionObject* m_collisionObject;
- Body() : m_soft(0), m_rigid(0), m_collisionObject(0) {}
- Body(Cluster* p) : m_soft(p), m_rigid(0), m_collisionObject(0) {}
- Body(const btCollisionObject* colObj) : m_soft(0), m_collisionObject(colObj)
- {
- m_rigid = (btRigidBody*)btRigidBody::upcast(m_collisionObject);
- }
- void activate() const
- {
- if (m_rigid)
- m_rigid->activate();
- if (m_collisionObject)
- m_collisionObject->activate();
- }
- const btMatrix3x3& invWorldInertia() const
- {
- static const btMatrix3x3 iwi(0, 0, 0, 0, 0, 0, 0, 0, 0);
- if (m_rigid) return (m_rigid->getInvInertiaTensorWorld());
- if (m_soft) return (m_soft->m_invwi);
- return (iwi);
- }
- btScalar invMass() const
- {
- if (m_rigid) return (m_rigid->getInvMass());
- if (m_soft) return (m_soft->m_imass);
- return (0);
- }
- const btTransform& xform() const
- {
- static const btTransform identity = btTransform::getIdentity();
- if (m_collisionObject) return (m_collisionObject->getWorldTransform());
- if (m_soft) return (m_soft->m_framexform);
- return (identity);
- }
- btVector3 linearVelocity() const
- {
- if (m_rigid) return (m_rigid->getLinearVelocity());
- if (m_soft) return (m_soft->m_lv);
- return (btVector3(0, 0, 0));
- }
- btVector3 angularVelocity(const btVector3& rpos) const
- {
- if (m_rigid) return (btCross(m_rigid->getAngularVelocity(), rpos));
- if (m_soft) return (btCross(m_soft->m_av, rpos));
- return (btVector3(0, 0, 0));
- }
- btVector3 angularVelocity() const
- {
- if (m_rigid) return (m_rigid->getAngularVelocity());
- if (m_soft) return (m_soft->m_av);
- return (btVector3(0, 0, 0));
- }
- btVector3 velocity(const btVector3& rpos) const
- {
- return (linearVelocity() + angularVelocity(rpos));
- }
- void applyVImpulse(const btVector3& impulse, const btVector3& rpos) const
- {
- if (m_rigid) m_rigid->applyImpulse(impulse, rpos);
- if (m_soft) btSoftBody::clusterVImpulse(m_soft, rpos, impulse);
- }
- void applyDImpulse(const btVector3& impulse, const btVector3& rpos) const
- {
- if (m_rigid) m_rigid->applyImpulse(impulse, rpos);
- if (m_soft) btSoftBody::clusterDImpulse(m_soft, rpos, impulse);
- }
- void applyImpulse(const Impulse& impulse, const btVector3& rpos) const
- {
- if (impulse.m_asVelocity)
- {
- // printf("impulse.m_velocity = %f,%f,%f\n",impulse.m_velocity.getX(),impulse.m_velocity.getY(),impulse.m_velocity.getZ());
- applyVImpulse(impulse.m_velocity, rpos);
- }
- if (impulse.m_asDrift)
- {
- // printf("impulse.m_drift = %f,%f,%f\n",impulse.m_drift.getX(),impulse.m_drift.getY(),impulse.m_drift.getZ());
- applyDImpulse(impulse.m_drift, rpos);
- }
- }
- void applyVAImpulse(const btVector3& impulse) const
- {
- if (m_rigid) m_rigid->applyTorqueImpulse(impulse);
- if (m_soft) btSoftBody::clusterVAImpulse(m_soft, impulse);
- }
- void applyDAImpulse(const btVector3& impulse) const
- {
- if (m_rigid) m_rigid->applyTorqueImpulse(impulse);
- if (m_soft) btSoftBody::clusterDAImpulse(m_soft, impulse);
- }
- void applyAImpulse(const Impulse& impulse) const
- {
- if (impulse.m_asVelocity) applyVAImpulse(impulse.m_velocity);
- if (impulse.m_asDrift) applyDAImpulse(impulse.m_drift);
- }
- void applyDCImpulse(const btVector3& impulse) const
- {
- if (m_rigid) m_rigid->applyCentralImpulse(impulse);
- if (m_soft) btSoftBody::clusterDCImpulse(m_soft, impulse);
- }
- };
- /* Joint */
- struct Joint
- {
- struct eType
- {
- enum _
- {
- Linear = 0,
- Angular,
- Contact
- };
- };
- struct Specs
- {
- Specs() : erp(1), cfm(1), split(1) {}
- btScalar erp;
- btScalar cfm;
- btScalar split;
- };
- Body m_bodies[2];
- btVector3 m_refs[2];
- btScalar m_cfm;
- btScalar m_erp;
- btScalar m_split;
- btVector3 m_drift;
- btVector3 m_sdrift;
- btMatrix3x3 m_massmatrix;
- bool m_delete;
- virtual ~Joint() {}
- Joint() : m_delete(false) {}
- virtual void Prepare(btScalar dt, int iterations);
- virtual void Solve(btScalar dt, btScalar sor) = 0;
- virtual void Terminate(btScalar dt) = 0;
- virtual eType::_ Type() const = 0;
- };
- /* LJoint */
- struct LJoint : Joint
- {
- struct Specs : Joint::Specs
- {
- btVector3 position;
- };
- btVector3 m_rpos[2];
- void Prepare(btScalar dt, int iterations);
- void Solve(btScalar dt, btScalar sor);
- void Terminate(btScalar dt);
- eType::_ Type() const { return (eType::Linear); }
- };
- /* AJoint */
- struct AJoint : Joint
- {
- struct IControl
- {
- virtual ~IControl() {}
- virtual void Prepare(AJoint*) {}
- virtual btScalar Speed(AJoint*, btScalar current) { return (current); }
- static IControl* Default()
- {
- static IControl def;
- return (&def);
- }
- };
- struct Specs : Joint::Specs
- {
- Specs() : icontrol(IControl::Default()) {}
- btVector3 axis;
- IControl* icontrol;
- };
- btVector3 m_axis[2];
- IControl* m_icontrol;
- void Prepare(btScalar dt, int iterations);
- void Solve(btScalar dt, btScalar sor);
- void Terminate(btScalar dt);
- eType::_ Type() const { return (eType::Angular); }
- };
- /* CJoint */
- struct CJoint : Joint
- {
- int m_life;
- int m_maxlife;
- btVector3 m_rpos[2];
- btVector3 m_normal;
- btScalar m_friction;
- void Prepare(btScalar dt, int iterations);
- void Solve(btScalar dt, btScalar sor);
- void Terminate(btScalar dt);
- eType::_ Type() const { return (eType::Contact); }
- };
- /* Config */
- struct Config
- {
- eAeroModel::_ aeromodel; // Aerodynamic model (default: V_Point)
- btScalar kVCF; // Velocities correction factor (Baumgarte)
- btScalar kDP; // Damping coefficient [0,1]
- btScalar kDG; // Drag coefficient [0,+inf]
- btScalar kLF; // Lift coefficient [0,+inf]
- btScalar kPR; // Pressure coefficient [-inf,+inf]
- btScalar kVC; // Volume conversation coefficient [0,+inf]
- btScalar kDF; // Dynamic friction coefficient [0,1]
- btScalar kMT; // Pose matching coefficient [0,1]
- btScalar kCHR; // Rigid contacts hardness [0,1]
- btScalar kKHR; // Kinetic contacts hardness [0,1]
- btScalar kSHR; // Soft contacts hardness [0,1]
- btScalar kAHR; // Anchors hardness [0,1]
- btScalar kSRHR_CL; // Soft vs rigid hardness [0,1] (cluster only)
- btScalar kSKHR_CL; // Soft vs kinetic hardness [0,1] (cluster only)
- btScalar kSSHR_CL; // Soft vs soft hardness [0,1] (cluster only)
- btScalar kSR_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only)
- btScalar kSK_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only)
- btScalar kSS_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only)
- btScalar maxvolume; // Maximum volume ratio for pose
- btScalar timescale; // Time scale
- int viterations; // Velocities solver iterations
- int piterations; // Positions solver iterations
- int diterations; // Drift solver iterations
- int citerations; // Cluster solver iterations
- int collisions; // Collisions flags
- tVSolverArray m_vsequence; // Velocity solvers sequence
- tPSolverArray m_psequence; // Position solvers sequence
- tPSolverArray m_dsequence; // Drift solvers sequence
- btScalar drag; // deformable air drag
- btScalar m_maxStress; // Maximum principle first Piola stress
- };
- /* SolverState */
- struct SolverState
- {
- //if you add new variables, always initialize them!
- SolverState()
- : sdt(0),
- isdt(0),
- velmrg(0),
- radmrg(0),
- updmrg(0)
- {
- }
- btScalar sdt; // dt*timescale
- btScalar isdt; // 1/sdt
- btScalar velmrg; // velocity margin
- btScalar radmrg; // radial margin
- btScalar updmrg; // Update margin
- };
- /// RayFromToCaster takes a ray from, ray to (instead of direction!)
- struct RayFromToCaster : btDbvt::ICollide
- {
- btVector3 m_rayFrom;
- btVector3 m_rayTo;
- btVector3 m_rayNormalizedDirection;
- btScalar m_mint;
- Face* m_face;
- int m_tests;
- RayFromToCaster(const btVector3& rayFrom, const btVector3& rayTo, btScalar mxt);
- void Process(const btDbvtNode* leaf);
- static /*inline*/ btScalar rayFromToTriangle(const btVector3& rayFrom,
- const btVector3& rayTo,
- const btVector3& rayNormalizedDirection,
- const btVector3& a,
- const btVector3& b,
- const btVector3& c,
- btScalar maxt = SIMD_INFINITY);
- };
- //
- // Typedefs
- //
- typedef void (*psolver_t)(btSoftBody*, btScalar, btScalar);
- typedef void (*vsolver_t)(btSoftBody*, btScalar);
- typedef btAlignedObjectArray<Cluster*> tClusterArray;
- typedef btAlignedObjectArray<Note> tNoteArray;
- typedef btAlignedObjectArray<Node> tNodeArray;
- typedef btAlignedObjectArray< RenderNode> tRenderNodeArray;
- typedef btAlignedObjectArray<btDbvtNode*> tLeafArray;
- typedef btAlignedObjectArray<Link> tLinkArray;
- typedef btAlignedObjectArray<Face> tFaceArray;
- typedef btAlignedObjectArray<RenderFace> tRenderFaceArray;
- typedef btAlignedObjectArray<Tetra> tTetraArray;
- typedef btAlignedObjectArray<Anchor> tAnchorArray;
- typedef btAlignedObjectArray<RContact> tRContactArray;
- typedef btAlignedObjectArray<SContact> tSContactArray;
- typedef btAlignedObjectArray<Material*> tMaterialArray;
- typedef btAlignedObjectArray<Joint*> tJointArray;
- typedef btAlignedObjectArray<btSoftBody*> tSoftBodyArray;
- //
- // Fields
- //
- Config m_cfg; // Configuration
- SolverState m_sst; // Solver state
- Pose m_pose; // Pose
- void* m_tag; // User data
- btSoftBodyWorldInfo* m_worldInfo; // World info
- tNoteArray m_notes; // Notes
- tNodeArray m_nodes; // Nodes
- tRenderNodeArray m_renderNodes; // Render Nodes
- tLinkArray m_links; // Links
- tFaceArray m_faces; // Faces
- tRenderFaceArray m_renderFaces; // Faces
- tTetraArray m_tetras; // Tetras
- btAlignedObjectArray<TetraScratch> m_tetraScratches;
- btAlignedObjectArray<TetraScratch> m_tetraScratchesTn;
- tAnchorArray m_anchors; // Anchors
- btAlignedObjectArray<DeformableNodeRigidAnchor> m_deformableAnchors;
- tRContactArray m_rcontacts; // Rigid contacts
- btAlignedObjectArray<DeformableNodeRigidContact> m_nodeRigidContacts;
- btAlignedObjectArray<DeformableFaceNodeContact> m_faceNodeContacts;
- btAlignedObjectArray<DeformableFaceRigidContact> m_faceRigidContacts;
- tSContactArray m_scontacts; // Soft contacts
- tJointArray m_joints; // Joints
- tMaterialArray m_materials; // Materials
- btScalar m_timeacc; // Time accumulator
- btVector3 m_bounds[2]; // Spatial bounds
- bool m_bUpdateRtCst; // Update runtime constants
- btDbvt m_ndbvt; // Nodes tree
- btDbvt m_fdbvt; // Faces tree
- btDbvntNode* m_fdbvnt; // Faces tree with normals
- btDbvt m_cdbvt; // Clusters tree
- tClusterArray m_clusters; // Clusters
- btScalar m_dampingCoefficient; // Damping Coefficient
- btScalar m_sleepingThreshold;
- btScalar m_maxSpeedSquared;
- btAlignedObjectArray<btVector3> m_quads; // quadrature points for collision detection
- btScalar m_repulsionStiffness;
- btScalar m_gravityFactor;
- bool m_cacheBarycenter;
- btAlignedObjectArray<btVector3> m_X; // initial positions
- btAlignedObjectArray<btVector4> m_renderNodesInterpolationWeights;
- btAlignedObjectArray<btAlignedObjectArray<const btSoftBody::Node*> > m_renderNodesParents;
- btAlignedObjectArray<btScalar> m_z; // vertical distance used in extrapolation
- bool m_useSelfCollision;
- bool m_softSoftCollision;
- btAlignedObjectArray<bool> m_clusterConnectivity; //cluster connectivity, for self-collision
- btVector3 m_windVelocity;
- btScalar m_restLengthScale;
- //
- // Api
- //
- /* ctor */
- btSoftBody(btSoftBodyWorldInfo* worldInfo, int node_count, const btVector3* x, const btScalar* m);
- /* ctor */
- btSoftBody(btSoftBodyWorldInfo* worldInfo);
- void initDefaults();
- /* dtor */
- virtual ~btSoftBody();
- /* Check for existing link */
- btAlignedObjectArray<int> m_userIndexMapping;
- btSoftBodyWorldInfo* getWorldInfo()
- {
- return m_worldInfo;
- }
- void setDampingCoefficient(btScalar damping_coeff)
- {
- m_dampingCoefficient = damping_coeff;
- }
- ///@todo: avoid internal softbody shape hack and move collision code to collision library
- virtual void setCollisionShape(btCollisionShape* collisionShape)
- {
- }
- bool checkLink(int node0,
- int node1) const;
- bool checkLink(const Node* node0,
- const Node* node1) const;
- /* Check for existring face */
- bool checkFace(int node0,
- int node1,
- int node2) const;
- /* Append material */
- Material* appendMaterial();
- /* Append note */
- 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);
- void appendNote(const char* text,
- const btVector3& o,
- Node* feature);
- void appendNote(const char* text,
- const btVector3& o,
- Link* feature);
- void appendNote(const char* text,
- const btVector3& o,
- Face* feature);
- /* Append node */
- void appendNode(const btVector3& x, btScalar m);
- /* Append link */
- void appendLink(int model = -1, Material* mat = 0);
- void appendLink(int node0,
- int node1,
- Material* mat = 0,
- bool bcheckexist = false);
- void appendLink(Node* node0,
- Node* node1,
- Material* mat = 0,
- bool bcheckexist = false);
- /* Append face */
- void appendFace(int model = -1, Material* mat = 0);
- void appendFace(int node0,
- int node1,
- int node2,
- Material* mat = 0);
- void appendTetra(int model, Material* mat);
- //
- void appendTetra(int node0,
- int node1,
- int node2,
- int node3,
- Material* mat = 0);
- /* Append anchor */
- void appendDeformableAnchor(int node, btRigidBody* body);
- void appendDeformableAnchor(int node, btMultiBodyLinkCollider* link);
- void appendAnchor(int node,
- btRigidBody* body, bool disableCollisionBetweenLinkedBodies = false, btScalar influence = 1);
- void appendAnchor(int node, btRigidBody* body, const btVector3& localPivot, bool disableCollisionBetweenLinkedBodies = false, btScalar influence = 1);
- void removeAnchor(int node);
- /* Append linear joint */
- void appendLinearJoint(const LJoint::Specs& specs, Cluster* body0, Body body1);
- void appendLinearJoint(const LJoint::Specs& specs, Body body = Body());
- void appendLinearJoint(const LJoint::Specs& specs, btSoftBody* body);
- /* Append linear joint */
- void appendAngularJoint(const AJoint::Specs& specs, Cluster* body0, Body body1);
- void appendAngularJoint(const AJoint::Specs& specs, Body body = Body());
- void appendAngularJoint(const AJoint::Specs& specs, btSoftBody* body);
- /* Add force (or gravity) to the entire body */
- void addForce(const btVector3& force);
- /* Add force (or gravity) to a node of the body */
- void addForce(const btVector3& force,
- int node);
- /* Add aero force to a node of the body */
- void addAeroForceToNode(const btVector3& windVelocity, int nodeIndex);
- /* Add aero force to a face of the body */
- void addAeroForceToFace(const btVector3& windVelocity, int faceIndex);
- /* Add velocity to the entire body */
- void addVelocity(const btVector3& velocity);
- /* Set velocity for the entire body */
- void setVelocity(const btVector3& velocity);
- /* Add velocity to a node of the body */
- void addVelocity(const btVector3& velocity,
- int node);
- /* Set mass */
- void setMass(int node,
- btScalar mass);
- /* Get mass */
- btScalar getMass(int node) const;
- /* Get total mass */
- btScalar getTotalMass() const;
- /* Set total mass (weighted by previous masses) */
- void setTotalMass(btScalar mass,
- bool fromfaces = false);
- /* Set total density */
- void setTotalDensity(btScalar density);
- /* Set volume mass (using tetrahedrons) */
- void setVolumeMass(btScalar mass);
- /* Set volume density (using tetrahedrons) */
- void setVolumeDensity(btScalar density);
- /* Get the linear velocity of the center of mass */
- btVector3 getLinearVelocity();
- /* Set the linear velocity of the center of mass */
- void setLinearVelocity(const btVector3& linVel);
- /* Set the angular velocity of the center of mass */
- void setAngularVelocity(const btVector3& angVel);
- /* Get best fit rigid transform */
- btTransform getRigidTransform();
- /* Transform to given pose */
- void transformTo(const btTransform& trs);
- /* Transform */
- void transform(const btTransform& trs);
- /* Translate */
- void translate(const btVector3& trs);
- /* Rotate */
- void rotate(const btQuaternion& rot);
- /* Scale */
- void scale(const btVector3& scl);
- /* Get link resting lengths scale */
- btScalar getRestLengthScale();
- /* Scale resting length of all springs */
- void setRestLengthScale(btScalar restLength);
- /* Set current state as pose */
- void setPose(bool bvolume,
- bool bframe);
- /* Set current link lengths as resting lengths */
- void resetLinkRestLengths();
- /* Return the volume */
- btScalar getVolume() const;
- /* Cluster count */
- btVector3 getCenterOfMass() const
- {
- btVector3 com(0, 0, 0);
- for (int i = 0; i < m_nodes.size(); i++)
- {
- com += (m_nodes[i].m_x * this->getMass(i));
- }
- com /= this->getTotalMass();
- return com;
- }
- int clusterCount() const;
- /* Cluster center of mass */
- static btVector3 clusterCom(const Cluster* cluster);
- btVector3 clusterCom(int cluster) const;
- /* Cluster velocity at rpos */
- static btVector3 clusterVelocity(const Cluster* cluster, const btVector3& rpos);
- /* Cluster impulse */
- static void clusterVImpulse(Cluster* cluster, const btVector3& rpos, const btVector3& impulse);
- static void clusterDImpulse(Cluster* cluster, const btVector3& rpos, const btVector3& impulse);
- static void clusterImpulse(Cluster* cluster, const btVector3& rpos, const Impulse& impulse);
- static void clusterVAImpulse(Cluster* cluster, const btVector3& impulse);
- static void clusterDAImpulse(Cluster* cluster, const btVector3& impulse);
- static void clusterAImpulse(Cluster* cluster, const Impulse& impulse);
- static void clusterDCImpulse(Cluster* cluster, const btVector3& impulse);
- /* Generate bending constraints based on distance in the adjency graph */
- int generateBendingConstraints(int distance,
- Material* mat = 0);
- /* Randomize constraints to reduce solver bias */
- void randomizeConstraints();
- /* Release clusters */
- void releaseCluster(int index);
- void releaseClusters();
- /* Generate clusters (K-mean) */
- ///generateClusters with k=0 will create a convex cluster for each tetrahedron or triangle
- ///otherwise an approximation will be used (better performance)
- int generateClusters(int k, int maxiterations = 8192);
- /* Refine */
- void refine(ImplicitFn* ifn, btScalar accurary, bool cut);
- /* CutLink */
- bool cutLink(int node0, int node1, btScalar position);
- bool cutLink(const Node* node0, const Node* node1, btScalar position);
- ///Ray casting using rayFrom and rayTo in worldspace, (not direction!)
- bool rayTest(const btVector3& rayFrom,
- const btVector3& rayTo,
- sRayCast& results);
- bool rayFaceTest(const btVector3& rayFrom,
- const btVector3& rayTo,
- sRayCast& results);
- int rayFaceTest(const btVector3& rayFrom, const btVector3& rayTo,
- btScalar& mint, int& index) const;
- /* Solver presets */
- void setSolver(eSolverPresets::_ preset);
- /* predictMotion */
- void predictMotion(btScalar dt);
- /* solveConstraints */
- void solveConstraints();
- /* staticSolve */
- void staticSolve(int iterations);
- /* solveCommonConstraints */
- static void solveCommonConstraints(btSoftBody** bodies, int count, int iterations);
- /* solveClusters */
- static void solveClusters(const btAlignedObjectArray<btSoftBody*>& bodies);
- /* integrateMotion */
- void integrateMotion();
- /* defaultCollisionHandlers */
- void defaultCollisionHandler(const btCollisionObjectWrapper* pcoWrap);
- void defaultCollisionHandler(btSoftBody* psb);
- void setSelfCollision(bool useSelfCollision);
- bool useSelfCollision();
- void updateDeactivation(btScalar timeStep);
- void setZeroVelocity();
- bool wantsSleeping();
- //
- // Functionality to deal with new accelerated solvers.
- //
- /**
- * Set a wind velocity for interaction with the air.
- */
- void setWindVelocity(const btVector3& velocity);
- /**
- * Return the wind velocity for interaction with the air.
- */
- const btVector3& getWindVelocity();
- //
- // Set the solver that handles this soft body
- // Should not be allowed to get out of sync with reality
- // Currently called internally on addition to the world
- void setSoftBodySolver(btSoftBodySolver* softBodySolver)
- {
- m_softBodySolver = softBodySolver;
- }
- //
- // Return the solver that handles this soft body
- //
- btSoftBodySolver* getSoftBodySolver()
- {
- return m_softBodySolver;
- }
- //
- // Return the solver that handles this soft body
- //
- btSoftBodySolver* getSoftBodySolver() const
- {
- return m_softBodySolver;
- }
- //
- // Cast
- //
- static const btSoftBody* upcast(const btCollisionObject* colObj)
- {
- if (colObj->getInternalType() == CO_SOFT_BODY)
- return (const btSoftBody*)colObj;
- return 0;
- }
- static btSoftBody* upcast(btCollisionObject* colObj)
- {
- if (colObj->getInternalType() == CO_SOFT_BODY)
- return (btSoftBody*)colObj;
- return 0;
- }
- //
- // ::btCollisionObject
- //
- virtual void getAabb(btVector3& aabbMin, btVector3& aabbMax) const
- {
- aabbMin = m_bounds[0];
- aabbMax = m_bounds[1];
- }
- //
- // Private
- //
- void pointersToIndices();
- void indicesToPointers(const int* map = 0);
- int rayTest(const btVector3& rayFrom, const btVector3& rayTo,
- btScalar& mint, eFeature::_& feature, int& index, bool bcountonly) const;
- void initializeFaceTree();
- void rebuildNodeTree();
- btVector3 evaluateCom() const;
- bool checkDeformableContact(const btCollisionObjectWrapper* colObjWrap, const btVector3& x, btScalar margin, btSoftBody::sCti& cti, bool predict = false) const;
- bool checkDeformableFaceContact(const btCollisionObjectWrapper* colObjWrap, Face& f, btVector3& contact_point, btVector3& bary, btScalar margin, btSoftBody::sCti& cti, bool predict = false) const;
- bool checkContact(const btCollisionObjectWrapper* colObjWrap, const btVector3& x, btScalar margin, btSoftBody::sCti& cti) const;
- void updateNormals();
- void updateBounds();
- void updatePose();
- void updateConstants();
- void updateLinkConstants();
- void updateArea(bool averageArea = true);
- void initializeClusters();
- void updateClusters();
- void cleanupClusters();
- void prepareClusters(int iterations);
- void solveClusters(btScalar sor);
- void applyClusters(bool drift);
- void dampClusters();
- void setSpringStiffness(btScalar k);
- void setGravityFactor(btScalar gravFactor);
- void setCacheBarycenter(bool cacheBarycenter);
- void initializeDmInverse();
- void updateDeformation();
- void advanceDeformation();
- void applyForces();
- void setMaxStress(btScalar maxStress);
- void interpolateRenderMesh();
- void setCollisionQuadrature(int N);
- static void PSolve_Anchors(btSoftBody* psb, btScalar kst, btScalar ti);
- static void PSolve_RContacts(btSoftBody* psb, btScalar kst, btScalar ti);
- static void PSolve_SContacts(btSoftBody* psb, btScalar, btScalar ti);
- static void PSolve_Links(btSoftBody* psb, btScalar kst, btScalar ti);
- static void VSolve_Links(btSoftBody* psb, btScalar kst);
- static psolver_t getSolver(ePSolver::_ solver);
- static vsolver_t getSolver(eVSolver::_ solver);
- void geometricCollisionHandler(btSoftBody* psb);
- #define SAFE_EPSILON SIMD_EPSILON * 100.0
- void updateNode(btDbvtNode* node, bool use_velocity, bool margin)
- {
- if (node->isleaf())
- {
- btSoftBody::Node* n = (btSoftBody::Node*)(node->data);
- ATTRIBUTE_ALIGNED16(btDbvtVolume)
- vol;
- btScalar pad = margin ? m_sst.radmrg : SAFE_EPSILON; // use user defined margin or margin for floating point precision
- if (use_velocity)
- {
- btVector3 points[2] = {n->m_x, n->m_x + m_sst.sdt * n->m_v};
- vol = btDbvtVolume::FromPoints(points, 2);
- vol.Expand(btVector3(pad, pad, pad));
- }
- else
- {
- vol = btDbvtVolume::FromCR(n->m_x, pad);
- }
- node->volume = vol;
- return;
- }
- else
- {
- updateNode(node->childs[0], use_velocity, margin);
- updateNode(node->childs[1], use_velocity, margin);
- ATTRIBUTE_ALIGNED16(btDbvtVolume)
- vol;
- Merge(node->childs[0]->volume, node->childs[1]->volume, vol);
- node->volume = vol;
- }
- }
- void updateNodeTree(bool use_velocity, bool margin)
- {
- if (m_ndbvt.m_root)
- updateNode(m_ndbvt.m_root, use_velocity, margin);
- }
- template <class DBVTNODE> // btDbvtNode or btDbvntNode
- void updateFace(DBVTNODE* node, bool use_velocity, bool margin)
- {
- if (node->isleaf())
- {
- btSoftBody::Face* f = (btSoftBody::Face*)(node->data);
- btScalar pad = margin ? m_sst.radmrg : SAFE_EPSILON; // use user defined margin or margin for floating point precision
- ATTRIBUTE_ALIGNED16(btDbvtVolume)
- vol;
- if (use_velocity)
- {
- btVector3 points[6] = {f->m_n[0]->m_x, f->m_n[0]->m_x + m_sst.sdt * f->m_n[0]->m_v,
- f->m_n[1]->m_x, f->m_n[1]->m_x + m_sst.sdt * f->m_n[1]->m_v,
- f->m_n[2]->m_x, f->m_n[2]->m_x + m_sst.sdt * f->m_n[2]->m_v};
- vol = btDbvtVolume::FromPoints(points, 6);
- }
- else
- {
- btVector3 points[3] = {f->m_n[0]->m_x,
- f->m_n[1]->m_x,
- f->m_n[2]->m_x};
- vol = btDbvtVolume::FromPoints(points, 3);
- }
- vol.Expand(btVector3(pad, pad, pad));
- node->volume = vol;
- return;
- }
- else
- {
- updateFace(node->childs[0], use_velocity, margin);
- updateFace(node->childs[1], use_velocity, margin);
- ATTRIBUTE_ALIGNED16(btDbvtVolume)
- vol;
- Merge(node->childs[0]->volume, node->childs[1]->volume, vol);
- node->volume = vol;
- }
- }
- void updateFaceTree(bool use_velocity, bool margin)
- {
- if (m_fdbvt.m_root)
- updateFace(m_fdbvt.m_root, use_velocity, margin);
- if (m_fdbvnt)
- updateFace(m_fdbvnt, use_velocity, margin);
- }
- template <typename T>
- static inline T BaryEval(const T& a,
- const T& b,
- const T& c,
- const btVector3& coord)
- {
- return (a * coord.x() + b * coord.y() + c * coord.z());
- }
- void applyRepulsionForce(btScalar timeStep, bool applySpringForce)
- {
- btAlignedObjectArray<int> indices;
- {
- // randomize the order of repulsive force
- indices.resize(m_faceNodeContacts.size());
- for (int i = 0; i < m_faceNodeContacts.size(); ++i)
- indices[i] = i;
- #define NEXTRAND (seed = (1664525L * seed + 1013904223L) & 0xffffffff)
- int i, ni;
- for (i = 0, ni = indices.size(); i < ni; ++i)
- {
- btSwap(indices[i], indices[NEXTRAND % ni]);
- }
- }
- for (int k = 0; k < m_faceNodeContacts.size(); ++k)
- {
- int idx = indices[k];
- btSoftBody::DeformableFaceNodeContact& c = m_faceNodeContacts[idx];
- btSoftBody::Node* node = c.m_node;
- btSoftBody::Face* face = c.m_face;
- const btVector3& w = c.m_bary;
- const btVector3& n = c.m_normal;
- 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);
- btScalar d = c.m_margin - n.dot(l);
- d = btMax(btScalar(0), d);
- const btVector3& va = node->m_v;
- btVector3 vb = BaryEval(face->m_n[0]->m_v, face->m_n[1]->m_v, face->m_n[2]->m_v, w);
- btVector3 vr = va - vb;
- const btScalar vn = btDot(vr, n); // dn < 0 <==> opposing
- if (vn > OVERLAP_REDUCTION_FACTOR * d / timeStep)
- continue;
- btVector3 vt = vr - vn * n;
- btScalar I = 0;
- btScalar mass = node->m_im == 0 ? 0 : btScalar(1) / node->m_im;
- if (applySpringForce)
- I = -btMin(m_repulsionStiffness * timeStep * d, mass * (OVERLAP_REDUCTION_FACTOR * d / timeStep - vn));
- if (vn < 0)
- I += 0.5 * mass * vn;
- int face_penetration = 0, node_penetration = node->m_constrained;
- for (int i = 0; i < 3; ++i)
- face_penetration |= face->m_n[i]->m_constrained;
- btScalar I_tilde = 2.0 * I / (1.0 + w.length2());
- // double the impulse if node or face is constrained.
- if (face_penetration > 0 || node_penetration > 0)
- {
- I_tilde *= 2.0;
- }
- if (face_penetration <= 0)
- {
- for (int j = 0; j < 3; ++j)
- face->m_n[j]->m_v += w[j] * n * I_tilde * node->m_im;
- }
- if (node_penetration <= 0)
- {
- node->m_v -= I_tilde * node->m_im * n;
- }
- // apply frictional impulse
- btScalar vt_norm = vt.safeNorm();
- if (vt_norm > SIMD_EPSILON)
- {
- btScalar delta_vn = -2 * I * node->m_im;
- btScalar mu = c.m_friction;
- btScalar vt_new = btMax(btScalar(1) - mu * delta_vn / (vt_norm + SIMD_EPSILON), btScalar(0)) * vt_norm;
- I = 0.5 * mass * (vt_norm - vt_new);
- vt.safeNormalize();
- I_tilde = 2.0 * I / (1.0 + w.length2());
- // double the impulse if node or face is constrained.
- if (face_penetration > 0 || node_penetration > 0)
- I_tilde *= 2.0;
- if (face_penetration <= 0)
- {
- for (int j = 0; j < 3; ++j)
- face->m_n[j]->m_v += w[j] * vt * I_tilde * (face->m_n[j])->m_im;
- }
- if (node_penetration <= 0)
- {
- node->m_v -= I_tilde * node->m_im * vt;
- }
- }
- }
- }
- virtual int calculateSerializeBufferSize() const;
- ///fills the dataBuffer and returns the struct name (and 0 on failure)
- virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const;
- };
- #endif //_BT_SOFT_BODY_H
|