code-google-com / bullet

Automatically exported from code.google.com/p/bullet
0 stars 0 forks source link

Create speculative contacts #355

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago

Right now, Bullet only calculates contact points based on current world 
transforms. There is an option for contact clamping (a simplified form of 
CCD) but this doesn't generate contacts.

We already predict a future world transform, and this can be used to compute 
speculative contacts, with positive distance. Adding such speculative 
contacts ahead of time might reduce the amount of penetration.

We already add contacts with small positive distance (called 
contactProcessingThreshold) for more stable touching contact, so the 
constraint solver already can deal with contacts with positive distance.

Original issue reported on code.google.com by erwin.coumans on 5 Mar 2010 at 12:08

GoogleCodeExporter commented 9 years ago
 Below is how dvc3D do that:

================================================================================
==========

       // Use predicted transformations
       if (m_useSpeculativeContact)
       {
               btAlignedObjectArray<btTransform>       saveTransforms;
               saveTransforms.resize(m_nonStaticRigidBodies.size());

               for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
               {
                       btRigidBody* body = m_nonStaticRigidBodies[i];
                       if (!body->isStaticObject())
                       {
                               // save current transform
                               saveTransforms[i] = body->getWorldTransform();

body->setWorldTransform(body->getInterpolationWorldTransform());
                               body->predictIntegratedTransform(timeStep,
body->getInterpolationWorldTransform());
                       }
               }

               ///perform collision detection
               performDiscreteCollisionDetection();

               for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
               {
                       btRigidBody* body = m_nonStaticRigidBodies[i];
                       if (!body->isStaticObject())
                       {
                               // save current transform

body->setInterpolationWorldTransform(body->getWorldTransform());
                               body->setWorldTransform(saveTransforms[i]);
                       }
               }
       }
       else
       {
               ///perform collision detection
               performDiscreteCollisionDetection();
       }

================================================================================
==========

Original comment by ngb...@gmail.com on 5 Mar 2010 at 12:18

GoogleCodeExporter commented 9 years ago
A quick test shows that it does help : BasicDemo now can handle stack of 6 boxes
dropped then stack. Without it, only stack of 3 works.

Original comment by ngb...@gmail.com on 5 Mar 2010 at 12:27

GoogleCodeExporter commented 9 years ago
I forgot the part where we need to project contact information back to current 
time step:
================================================================================
==========
for (int iContact = contactManifold->getNumContacts()-1;iContact>=0;iContact--)
        {
            btManifoldPoint &manifoldPoint = contactManifold->getContactPoint(iContact);
            manifoldPoint.m_positionWorldOnA = trA( manifoldPoint.m_localPointA );
            manifoldPoint.m_positionWorldOnB = trB( manifoldPoint.m_localPointB );
            manifoldPoint.m_distance1 = (manifoldPoint.m_positionWorldOnA - 
manifoldPoint.m_positionWorldOnB).dot(manifoldPoint.m_normalWorldOnB);
            manifoldPoint.m_lifeTime++;
        }

================================================================================
==========

Or calling
contactManifold->refreshContactPoints(obA->getWorldTransform(),obB->getWorldTran
sform())
should also work.

Original comment by ngb...@gmail.com on 5 Mar 2010 at 12:30

GoogleCodeExporter commented 9 years ago

But if you call 
contactManifold->refreshContactPoints(obA->getWorldTransform(),obB-
>getWorldTransform()), with transforms at the old position,

doesn't it throw away contacts with distance > contactBreakingThreshold (which 
around 
0.04 or so)?

Original comment by erwin.coumans on 5 Mar 2010 at 12:43

GoogleCodeExporter commented 9 years ago
http://code.google.com/p/bullet/issues/detail?id=355 introduces predictive 
contacts.
I modified the Demos/BasicDemo to show how to enable the feature (disabled by 
default).

It is also discussed here on gamedev.net forum:
http://www.gamedev.net/topic/596865-sweep-test-and-physics/

Thanks,
Erwin

Original comment by erwin.coumans on 5 Mar 2011 at 6:23

GoogleCodeExporter commented 9 years ago
By the way, ngbinh: my solution is much simpler, because I adjust the right 
hand side of the constraint solver to take speculative contacts into account. 
Drawback is that in that case there is no restitution support.

See the changes in this commit:
http://code.google.com/p/bullet/source/detail?r=2326

Original comment by erwin.coumans on 5 Mar 2011 at 6:25