add FractureDemo to AllBulletDemos
improvements in CCD handling some cleanup of CcdPhysicsDemo and BasicDemo
This commit is contained in:
@@ -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.);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user