add FractureDemo to AllBulletDemos

improvements in CCD handling
some cleanup of CcdPhysicsDemo and BasicDemo
This commit is contained in:
erwin.coumans
2011-04-09 01:14:21 +00:00
parent 2291a6a9d3
commit cdddf9d25a
29 changed files with 550 additions and 867 deletions

View File

@@ -40,15 +40,14 @@ struct btDispatcherInfo
m_stepCount(0),
m_dispatchFunc(DISPATCH_DISCRETE),
m_timeOfImpact(btScalar(1.)),
m_useContinuous(false),
m_useContinuous(true),
m_debugDraw(0),
m_enableSatConvex(true),
m_enableSatConvex(false),
m_enableSPU(true),
m_useEpa(true),
m_allowedCcdPenetration(btScalar(0.04)),
m_useConvexConservativeDistanceUtil(false),
m_convexConservativeDistanceThreshold(0.0f),
m_convexMaxDistanceUseCPT(false),
m_stackAllocator(0)
{
@@ -65,7 +64,6 @@ struct btDispatcherInfo
btScalar m_allowedCcdPenetration;
bool m_useConvexConservativeDistanceUtil;
btScalar m_convexConservativeDistanceThreshold;
bool m_convexMaxDistanceUseCPT;
btStackAlloc* m_stackAllocator;
};

View File

@@ -155,7 +155,7 @@ void btCollisionWorld::updateSingleAabb(btCollisionObject* colObj)
minAabb -= contactThreshold;
maxAabb += contactThreshold;
if(getDispatchInfo().m_convexMaxDistanceUseCPT)
if(getDispatchInfo().m_useContinuous && colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY)
{
btVector3 minAabb2,maxAabb2;
colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2);
@@ -1452,12 +1452,14 @@ void btCollisionWorld::debugDrawWorld()
btVector3 minAabb2,maxAabb2;
colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2);
minAabb2 -= contactThreshold;
maxAabb2 += contactThreshold;
minAabb.setMin(minAabb2);
maxAabb.setMax(maxAabb2);
if(colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY)
{
colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2);
minAabb2 -= contactThreshold;
maxAabb2 += contactThreshold;
minAabb.setMin(minAabb2);
maxAabb.setMax(maxAabb2);
}
m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec);
}

View File

@@ -361,13 +361,14 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
} else
#endif //USE_SEPDISTANCE_UTIL2
{
if (dispatchInfo.m_convexMaxDistanceUseCPT)
{
input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactProcessingThreshold();
} else
{
input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
}
//if (dispatchInfo.m_convexMaxDistanceUseCPT)
//{
// input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactProcessingThreshold();
//} else
//{
input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
// }
input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
}

View File

@@ -68,9 +68,53 @@ void btContactConstraint::buildJacobian()
#include "LinearMath/btMinMax.h"
#include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h"
#define ASSERT2 btAssert
#define USE_INTERNAL_APPLY_IMPULSE 1
//response between two dynamic objects without friction, assuming 0 penetration depth
btScalar resolveSingleCollision(
btRigidBody* body1,
btCollisionObject* colObj2,
const btVector3& contactPositionWorld,
const btVector3& contactNormalOnB,
const btContactSolverInfo& solverInfo,
btScalar distance)
{
btRigidBody* body2 = btRigidBody::upcast(colObj2);
const btVector3& normal = contactNormalOnB;
btVector3 rel_pos1 = contactPositionWorld - body1->getWorldTransform().getOrigin();
btVector3 rel_pos2 = contactPositionWorld - colObj2->getWorldTransform().getOrigin();
btVector3 vel1 = body1->getVelocityInLocalPoint(rel_pos1);
btVector3 vel2 = body2? body2->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0);
btVector3 vel = vel1 - vel2;
btScalar rel_vel;
rel_vel = normal.dot(vel);
btScalar combinedRestitution = body1->getRestitution() * colObj2->getRestitution();
btScalar restitution = combinedRestitution* -rel_vel;
btScalar positionalError = solverInfo.m_erp *-distance /solverInfo.m_timeStep ;
btScalar velocityError = -(1.0f + restitution) * rel_vel;// * damping;
btScalar denom0 = body1->computeImpulseDenominator(contactPositionWorld,normal);
btScalar denom1 = body2? body2->computeImpulseDenominator(contactPositionWorld,normal) : 0.f;
btScalar relaxation = 1.f;
btScalar jacDiagABInv = relaxation/(denom0+denom1);
btScalar penetrationImpulse = positionalError * jacDiagABInv;
btScalar velocityImpulse = velocityError * jacDiagABInv;
btScalar normalImpulse = penetrationImpulse+velocityImpulse;
normalImpulse = 0.f > normalImpulse ? 0.f: normalImpulse;
body1->applyImpulse(normal*(normalImpulse), rel_pos1);
if (body2)
body2->applyImpulse(-normal*(normalImpulse), rel_pos2);
return normalImpulse;
}
//bilateral constraint between two dynamic objects
@@ -83,7 +127,7 @@ void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1,
btScalar normalLenSqr = normal.length2();
ASSERT2(btFabs(normalLenSqr) < btScalar(1.1));
btAssert(btFabs(normalLenSqr) < btScalar(1.1));
if (normalLenSqr > btScalar(1.1))
{
impulse = btScalar(0.);

View File

@@ -57,6 +57,9 @@ public:
};
///very basic collision resolution without friction
btScalar resolveSingleCollision(btRigidBody* body1, class btCollisionObject* colObj2, const btVector3& contactPositionWorld,const btVector3& contactNormalOnB, const struct btContactSolverInfo& solverInfo,btScalar distance);
///resolveSingleBilateral is an obsolete methods used for vehicle friction between two dynamic objects
void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1,

View File

@@ -35,6 +35,8 @@ subject to the following restrictions:
#include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h"
#include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h"
#include "BulletDynamics/ConstraintSolver/btSliderConstraint.h"
#include "BulletDynamics/ConstraintSolver/btContactConstraint.h"
#include "LinearMath/btIDebugDraw.h"
#include "BulletCollision/CollisionShapes/btSphereShape.h"
@@ -325,7 +327,8 @@ void btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep)
///perform collision detection
performDiscreteCollisionDetection();
addSpeculativeContacts(timeStep);
if (getDispatchInfo().m_useContinuous)
addSpeculativeContacts(timeStep);
calculateSimulationIslands();
@@ -851,36 +854,93 @@ void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep)
if (body->isActive() && (!body->isStaticOrKinematicObject()))
{
body->predictIntegratedTransform(timeStep, predictedTrans);
btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
if (body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion)
if (getDispatchInfo().m_useContinuous && body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion)
{
BT_PROFILE("CCD motion clamping");
if (body->getCollisionShape()->isConvex())
{
gNumClampedCcdMotions++;
#ifdef USE_STATIC_ONLY
class StaticOnlyCallback : public btClosestNotMeConvexResultCallback
{
public:
StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) :
btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher)
{
}
virtual bool needsCollision(btBroadphaseProxy* proxy0) const
{
btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
if (!otherObj->isStaticOrKinematicObject())
return false;
return btClosestNotMeConvexResultCallback::needsCollision(proxy0);
}
};
StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
#else
btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
#endif
//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration;
sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
btTransform modifiedPredictedTrans = predictedTrans;
modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis());
convexSweepTest(&tmpSphere,body->getWorldTransform(),predictedTrans,sweepResults);
convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults);
if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
{
//printf("clamped integration to hit fraction = %f\n",fraction);
body->setHitFraction(sweepResults.m_closestHitFraction);
body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans);
body->setHitFraction(0.f);
body->setLinearVelocity(btVector3(0,0.1,0));
body->proceedToTransform( predictedTrans);
// printf("clamped integration to hit fraction = %f\n",fraction);
#if 0
btVector3 linVel = body->getLinearVelocity();
btScalar maxSpeed = body->getCcdMotionThreshold()/getSolverInfo().m_timeStep;
btScalar maxSpeedSqr = maxSpeed*maxSpeed;
if (linVel.length2()>maxSpeedSqr)
{
linVel.normalize();
linVel*= maxSpeed;
body->setLinearVelocity(linVel);
btScalar ms2 = body->getLinearVelocity().length2();
body->predictIntegratedTransform(timeStep, predictedTrans);
btScalar sm2 = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
btScalar smt = body->getCcdSquareMotionThreshold();
printf("sm2=%f\n",sm2);
}
#else
//response between two dynamic objects without friction, assuming 0 penetration depth
btScalar appliedImpulse = 0.f;
btScalar depth = 0.f;
appliedImpulse = resolveSingleCollision(body,sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth);
#endif
continue;
}
}
}
body->proceedToTransform( predictedTrans);
}
}

View File

@@ -102,9 +102,14 @@ bool ManifoldResultAddContactPoint(const btVector3& normalOnBInWorld,
#ifdef DEBUG_SPU_COLLISION_DETECTION
spu_printf("SPU: contactTreshold %f\n",contactTreshold);
#endif //DEBUG_SPU_COLLISION_DETECTION
if (depth > manifoldPtr->getContactBreakingThreshold())
//if (depth > manifoldPtr->getContactBreakingThreshold())
// return false;
if (depth > manifoldPtr->getContactProcessingThreshold())
return false;
btVector3 pointA;
btVector3 localA;
btVector3 localB;
@@ -156,6 +161,7 @@ bool ManifoldResultAddContactPoint(const btVector3& normalOnBInWorld,
(*gContactAddedCallback)(newPt,m_body0,m_partId0,m_index0,m_body1,m_partId1,m_index1);
}
*/
manifoldPtr->addManifoldPoint(newPt);
return true;

View File

@@ -1138,6 +1138,9 @@ btScalar btParallelConstraintSolver::solveGroup(btCollisionObject** bodies1,int
pfxSetBroadphaseFlag(pair,0);
int contactId = m-offsetContactManifolds;
//likely the contact pool is not contiguous, make sure to allocate large enough contact pool
btAssert(contactId>=0);
btAssert(contactId<dispatcher->getInternalManifoldPool()->getUsedCount());
pfxSetContactId(pair,contactId);
pfxSetNumConstraints(pair,numPosPoints);//manifoldPtr[i]->getNumContacts());

View File

@@ -25,8 +25,6 @@ subject to the following restrictions:
#include <math.h>
#include <stdlib.h>//size_t for MSVC 6.0
#include <cstdlib>
#include <cfloat>
#include <float.h>
/* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/