bullet: Update to current svn, r2636
[blender.git] / extern / bullet2 / src / BulletSoftBody / btSoftBody.h
index a62c21883c8932769116b1db96b106ec58950268..2116c34f06d22130a70b946593f1b855fedd6777 100644 (file)
@@ -27,8 +27,17 @@ subject to the following restrictions:
 #include "btSparseSDF.h"
 #include "BulletCollision/BroadphaseCollision/btDbvt.h"
 
+//#ifdef BT_USE_DOUBLE_PRECISION
+//#define btRigidBodyData      btRigidBodyDoubleData
+//#define btRigidBodyDataName  "btRigidBodyDoubleData"
+//#else
+#define btSoftBodyData btSoftBodyFloatData
+#define btSoftBodyDataName     "btSoftBodyFloatData"
+//#endif //BT_USE_DOUBLE_PRECISION
+
 class btBroadphaseInterface;
 class btDispatcher;
+class btSoftBodySolver;
 
 /* btSoftBodyWorldInfo */ 
 struct btSoftBodyWorldInfo
@@ -41,6 +50,17 @@ struct       btSoftBodyWorldInfo
        btDispatcher*   m_dispatcher;
        btVector3                               m_gravity;
        btSparseSdf<3>                  m_sparsesdf;
+
+       btSoftBodyWorldInfo()
+               :air_density((btScalar)1.2),
+               water_density(0),
+               water_offset(0),
+               water_normal(0,0,0),
+               m_broadphase(0),
+               m_dispatcher(0),
+               m_gravity(0,-10,0)
+       {
+       }
 };     
 
 
@@ -49,7 +69,10 @@ struct       btSoftBodyWorldInfo
 class  btSoftBody : public btCollisionObject
 {
 public:
-       btAlignedObjectArray<class btCollisionObject*> m_collisionDisabledObjects;
+       btAlignedObjectArray<const class btCollisionObject*> m_collisionDisabledObjects;
+
+       // The solver object that handles this soft body
+       btSoftBodySolver *m_softBodySolver;
 
        //
        // Enumerations
@@ -57,11 +80,13 @@ public:
 
        ///eAeroModel 
        struct eAeroModel { enum _ {
-               V_Point,        ///Vertex normals are oriented toward velocity
-               V_TwoSided,     ///Vertex normals are fliped to match velocity  
-               V_OneSided,     ///Vertex normals are taken as it is    
-               F_TwoSided,     ///Face normals are fliped to match velocity
-               F_OneSided,     ///Face normals are taken as it is
+               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
        };};
 
@@ -94,6 +119,7 @@ public:
                Node,
                Link,
                Face,
+               Tetra,
                END
        };};
 
@@ -110,9 +136,10 @@ public:
                SDF_RS  =       0x0001, ///SDF based rigid vs soft
                CL_RS   =       0x0002, ///Cluster vs convex rigid vs soft
 
-               SVSmask =       0x00f0, ///Rigid versus soft mask               
+               SVSmask =       0x0030, ///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
                /* presets      */ 
                Default =       SDF_RS,
                END
@@ -155,7 +182,7 @@ public:
        /* sCti is Softbody contact info        */ 
        struct  sCti
        {
-               btCollisionObject*      m_colObj;               /* Rigid body                   */ 
+               const btCollisionObject*        m_colObj;               /* Rigid body                   */ 
                btVector3               m_normal;       /* Outward normal               */ 
                btScalar                m_offset;       /* Offset from origin   */ 
        };      
@@ -220,6 +247,16 @@ public:
                btScalar                                m_ra;                   // Rest area
                btDbvtNode*                             m_leaf;                 // Leaf data
        };
+       /* 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)
+       };
        /* RContact             */ 
        struct  RContact
        {
@@ -248,6 +285,7 @@ public:
                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
@@ -276,9 +314,9 @@ public:
        };
        /* Cluster              */ 
        struct  Cluster
-       {               
-               btAlignedObjectArray<Node*>     m_nodes;                
+       {
                tScalarArray                            m_masses;
+               btAlignedObjectArray<Node*>     m_nodes;                
                tVector3Array                           m_framerefs;
                btTransform                                     m_framexform;
                btScalar                                        m_idmass;
@@ -297,9 +335,16 @@ public:
                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) {}
+               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
@@ -329,18 +374,22 @@ public:
        {
                Cluster*                        m_soft;
                btRigidBody*            m_rigid;
-               btCollisionObject*      m_collisionObject;
+               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(btCollisionObject* colObj) : m_soft(0),m_collisionObject(colObj)
+               Body(const btCollisionObject* colObj) : m_soft(0),m_collisionObject(colObj)
                {
-                       m_rigid = btRigidBody::upcast(m_collisionObject);
+                       m_rigid = (btRigidBody*)btRigidBody::upcast(m_collisionObject);
                }
 
                void                                            activate() const
                {
-                       if(m_rigid) m_rigid->activate();
+                       if(m_rigid) 
+                               m_rigid->activate();
+                       if (m_collisionObject)
+                               m_collisionObject->activate();
+
                }
                const btMatrix3x3&                      invWorldInertia() const
                {
@@ -358,7 +407,7 @@ public:
                const btTransform&                      xform() const
                {
                        static const btTransform        identity=btTransform::getIdentity();            
-                       if(m_collisionObject) return(m_collisionObject->getInterpolationWorldTransform());
+                       if(m_collisionObject) return(m_collisionObject->getWorldTransform());
                        if(m_soft)      return(m_soft->m_framexform);
                        return(identity);
                }
@@ -370,8 +419,8 @@ public:
                }
                btVector3                                       angularVelocity(const btVector3& rpos) const
                {                       
-                       if(m_rigid) return(cross(m_rigid->getAngularVelocity(),rpos));
-                       if(m_soft)      return(cross(m_soft->m_av,rpos));
+                       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
@@ -396,8 +445,16 @@ public:
                }               
                void                                            applyImpulse(const Impulse& impulse,const btVector3& rpos) const
                {
-                       if(impulse.m_asVelocity)        applyVImpulse(impulse.m_velocity,rpos);
-                       if(impulse.m_asDrift)           applyDImpulse(impulse.m_drift,rpos);
+                       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
                {
@@ -424,7 +481,7 @@ public:
        struct  Joint
        {
                struct eType { enum _ {
-                       Linear,
+                       Linear=0,
                        Angular,
                        Contact
                };};
@@ -563,7 +620,7 @@ public:
        };
 
        //
-       // Typedef's
+       // Typedefs
        //
 
        typedef void                                                            (*psolver_t)(btSoftBody*,btScalar,btScalar);
@@ -574,6 +631,7 @@ public:
        typedef btAlignedObjectArray<btDbvtNode*>       tLeafArray;
        typedef btAlignedObjectArray<Link>                      tLinkArray;
        typedef btAlignedObjectArray<Face>                      tFaceArray;
+       typedef btAlignedObjectArray<Tetra>                     tTetraArray;
        typedef btAlignedObjectArray<Anchor>            tAnchorArray;
        typedef btAlignedObjectArray<RContact>          tRContactArray;
        typedef btAlignedObjectArray<SContact>          tSContactArray;
@@ -594,6 +652,7 @@ public:
        tNodeArray                              m_nodes;                // Nodes
        tLinkArray                              m_links;                // Links
        tFaceArray                              m_faces;                // Faces
+       tTetraArray                             m_tetras;               // Tetras
        tAnchorArray                    m_anchors;              // Anchors
        tRContactArray                  m_rcontacts;    // Rigid contacts
        tSContactArray                  m_scontacts;    // Soft contacts
@@ -611,14 +670,22 @@ public:
 
        btTransform                     m_initialWorldTransform;
 
+       btVector3                       m_windVelocity;
+       
+       btScalar        m_restLengthScale;
+       
        //
        // Api
        //
 
        /* ctor                                                                                                                                 */ 
-       btSoftBody(     btSoftBodyWorldInfo* worldInfo,int node_count,
-               const btVector3* x,
-               const btScalar* m);
+       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                                                                                              */ 
@@ -681,9 +748,19 @@ public:
                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                            appendAnchor(   int node,
-               btRigidBody* body, bool disableCollisionBetweenLinkedBodies=false);
+               btRigidBody* body, bool disableCollisionBetweenLinkedBodies=false,btScalar influence = 1);
+       void                    appendAnchor(int node,btRigidBody* body, const btVector3& localPivot,bool disableCollisionBetweenLinkedBodies=false,btScalar influence = 1);
        /* Append linear joint                                                                                                  */ 
        void                            appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1);
        void                            appendLinearJoint(const LJoint::Specs& specs,Body body=Body());
@@ -697,6 +774,12 @@ public:
        /* 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);
 
@@ -718,6 +801,10 @@ public:
                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);
        /* Transform                                                                                                                    */ 
        void                            transform(              const btTransform& trs);
        /* Translate                                                                                                                    */ 
@@ -726,9 +813,15 @@ public:
        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                                                                                                                */ 
@@ -755,6 +848,8 @@ public:
        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);
@@ -781,9 +876,52 @@ public:
        /* integrateMotion                                                                                                              */ 
        void                            integrateMotion();
        /* defaultCollisionHandlers                                                                                             */ 
-       void                            defaultCollisionHandler(btCollisionObject* pco);
+       void                            defaultCollisionHandler(const btCollisionObjectWrapper* pcoWrap);
        void                            defaultCollisionHandler(btSoftBody* psb);
 
+
+
+       //
+       // 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
        //
@@ -820,11 +958,13 @@ public:
                btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const;
        void                            initializeFaceTree();
        btVector3                       evaluateCom() const;
-       bool                            checkContact(btCollisionObject* colObj,const btVector3& x,btScalar margin,btSoftBody::sCti& cti) 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();
@@ -841,8 +981,18 @@ public:
        static psolver_t        getSolver(ePSolver::_ solver);
        static vsolver_t        getSolver(eVSolver::_ solver);
 
+
+       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;
+
+       //virtual void serializeSingleObject(class btSerializer* serializer) const;
+
+
 };
 
 
 
+
 #endif //_BT_SOFT_BODY_H