Fix T47758: rigidbody bug with constraint breaking and disable collisions.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Sun, 27 Mar 2016 00:25:25 +0000 (01:25 +0100)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Sun, 27 Mar 2016 00:32:28 +0000 (01:32 +0100)
This is a regression in Bullet, reverted the problematic change for now with
a custom patch.

extern/bullet2/patches/blender.patch
extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp
extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h

index f67d69104223b9db3b9c4eb4db3485dc48288a4a..96357ddd31573cee049370b766df5783ee81210c 100644 (file)
@@ -233,3 +233,92 @@ index e05bdcc..dbcf2b6 100644
  
  
  #include "btVector3.h"
+diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp
+index e0e8bc7..a788268 100644
+--- a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp
++++ b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp
+@@ -425,50 +425,38 @@ void btRigidBody::setCenterOfMassTransform(const btTransform& xform)
+ }
++bool btRigidBody::checkCollideWithOverride(const  btCollisionObject* co) const
++{
++      const btRigidBody* otherRb = btRigidBody::upcast(co);
++      if (!otherRb)
++              return true;
++
++      for (int i = 0; i < m_constraintRefs.size(); ++i)
++      {
++              const btTypedConstraint* c = m_constraintRefs[i];
++              if (c->isEnabled())
++                      if (&c->getRigidBodyA() == otherRb || &c->getRigidBodyB() == otherRb)
++                              return false;
++      }
++
++      return true;
++}
+ void btRigidBody::addConstraintRef(btTypedConstraint* c)
+ {
+-      ///disable collision with the 'other' body
+-
+       int index = m_constraintRefs.findLinearSearch(c);
+-      //don't add constraints that are already referenced
+-      //btAssert(index == m_constraintRefs.size());
+       if (index == m_constraintRefs.size())
+-      {
+-              m_constraintRefs.push_back(c);
+-              btCollisionObject* colObjA = &c->getRigidBodyA();
+-              btCollisionObject* colObjB = &c->getRigidBodyB();
+-              if (colObjA == this)
+-              {
+-                      colObjA->setIgnoreCollisionCheck(colObjB, true);
+-              }
+-              else
+-              {
+-                      colObjB->setIgnoreCollisionCheck(colObjA, true);
+-              }
+-      } 
++              m_constraintRefs.push_back(c); 
++
++      m_checkCollideWith = true;
+ }
+ void btRigidBody::removeConstraintRef(btTypedConstraint* c)
+ {
+-      int index = m_constraintRefs.findLinearSearch(c);
+-      //don't remove constraints that are not referenced
+-      if(index < m_constraintRefs.size())
+-    {
+-        m_constraintRefs.remove(c);
+-        btCollisionObject* colObjA = &c->getRigidBodyA();
+-        btCollisionObject* colObjB = &c->getRigidBodyB();
+-        if (colObjA == this)
+-        {
+-            colObjA->setIgnoreCollisionCheck(colObjB, false);
+-        }
+-        else
+-        {
+-            colObjB->setIgnoreCollisionCheck(colObjA, false);
+-        }
+-    }
++      m_constraintRefs.remove(c);
++      m_checkCollideWith = m_constraintRefs.size() > 0;
+ }
+ int   btRigidBody::calculateSerializeBufferSize()     const
+diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h
+index 1d177db..c2f8c5d 100644
+--- a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h
++++ b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h
+@@ -509,6 +509,8 @@ public:
+               return (getBroadphaseProxy() != 0);
+       }
++      virtual bool checkCollideWithOverride(const  btCollisionObject* co) const;
++
+       void addConstraintRef(btTypedConstraint* c);
+       void removeConstraintRef(btTypedConstraint* c);
index e0e8bc70f5718835999d720b122de0286a4c152d..a7882684bf1af7b2f560daafddeb45be43db06bb 100644 (file)
@@ -425,50 +425,38 @@ void btRigidBody::setCenterOfMassTransform(const btTransform& xform)
 }
 
 
+bool btRigidBody::checkCollideWithOverride(const  btCollisionObject* co) const
+{
+       const btRigidBody* otherRb = btRigidBody::upcast(co);
+       if (!otherRb)
+               return true;
+
+       for (int i = 0; i < m_constraintRefs.size(); ++i)
+       {
+               const btTypedConstraint* c = m_constraintRefs[i];
+               if (c->isEnabled())
+                       if (&c->getRigidBodyA() == otherRb || &c->getRigidBodyB() == otherRb)
+                               return false;
+       }
+
+       return true;
+}
 
 
 
 void btRigidBody::addConstraintRef(btTypedConstraint* c)
 {
-       ///disable collision with the 'other' body
-
        int index = m_constraintRefs.findLinearSearch(c);
-       //don't add constraints that are already referenced
-       //btAssert(index == m_constraintRefs.size());
        if (index == m_constraintRefs.size())
-       {
-               m_constraintRefs.push_back(c);
-               btCollisionObject* colObjA = &c->getRigidBodyA();
-               btCollisionObject* colObjB = &c->getRigidBodyB();
-               if (colObjA == this)
-               {
-                       colObjA->setIgnoreCollisionCheck(colObjB, true);
-               }
-               else
-               {
-                       colObjB->setIgnoreCollisionCheck(colObjA, true);
-               }
-       } 
+               m_constraintRefs.push_back(c); 
+
+       m_checkCollideWith = true;
 }
 
 void btRigidBody::removeConstraintRef(btTypedConstraint* c)
 {
-       int index = m_constraintRefs.findLinearSearch(c);
-       //don't remove constraints that are not referenced
-       if(index < m_constraintRefs.size())
-    {
-        m_constraintRefs.remove(c);
-        btCollisionObject* colObjA = &c->getRigidBodyA();
-        btCollisionObject* colObjB = &c->getRigidBodyB();
-        if (colObjA == this)
-        {
-            colObjA->setIgnoreCollisionCheck(colObjB, false);
-        }
-        else
-        {
-            colObjB->setIgnoreCollisionCheck(colObjA, false);
-        }
-    }
+       m_constraintRefs.remove(c);
+       m_checkCollideWith = m_constraintRefs.size() > 0;
 }
 
 int    btRigidBody::calculateSerializeBufferSize()     const
index 1d177db802ae524900dad5c153979745ca30ec4c..c2f8c5d64ae0fdb2cd3ffdff5af0cf6989edcc0c 100644 (file)
@@ -509,6 +509,8 @@ public:
                return (getBroadphaseProxy() != 0);
        }
 
+       virtual bool checkCollideWithOverride(const  btCollisionObject* co) const;
+
        void addConstraintRef(btTypedConstraint* c);
        void removeConstraintRef(btTypedConstraint* c);