+ improved KinematicCharacterController

+ improved btSubsimplexConvexCast, btContinuousConvexCollision and btGjkConvexCast to support configuration that start in touching/penetration, required for 'sliding'.
+ added files to CMakeLists.txt for CharacterController
+ bump up version to 2.70 (preparation for beta)
This commit is contained in:
erwin.coumans
2008-07-09 00:08:49 +00:00
parent 76bac83937
commit dcd57f333b
23 changed files with 431 additions and 243 deletions

View File

@@ -44,6 +44,8 @@ struct btDispatcherInfo
m_debugDraw(0),
m_enableSatConvex(false),
m_enableSPU(true),
m_useEpa(true),
m_allowedCcdPenetration(btScalar(0.04)),
m_stackAllocator(0)
{
@@ -51,12 +53,13 @@ struct btDispatcherInfo
btScalar m_timeStep;
int m_stepCount;
int m_dispatchFunc;
btScalar m_timeOfImpact;
mutable btScalar m_timeOfImpact;
bool m_useContinuous;
class btIDebugDraw* m_debugDraw;
bool m_enableSatConvex;
bool m_enableSPU;
bool m_useEpa;
btScalar m_allowedCcdPenetration;
btStackAlloc* m_stackAllocator;
};
@@ -82,7 +85,7 @@ public:
virtual bool needsResponse(btCollisionObject* body0,btCollisionObject* body1)=0;
virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher)=0;
virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) =0;
virtual int getNumManifolds() const = 0;
@@ -90,7 +93,7 @@ public:
virtual btPersistentManifold** getInternalManifoldPointer() = 0;
virtual void* allocateCollisionAlgorithm(int size) = 0;
virtual void* allocateCollisionAlgorithm(int size) = 0;
virtual void freeCollisionAlgorithm(void* ptr) = 0;

View File

@@ -399,7 +399,7 @@ public:
{
}
virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* /*dispatcher*/)
virtual void processAllOverlappingPairs(btOverlapCallback*,const btDispatcher* /*dispatcher*/)
{
}

View File

@@ -191,23 +191,25 @@ bool btCollisionDispatcher::needsCollision(btCollisionObject* body0,btCollisionO
///this is useful for the collision dispatcher.
class btCollisionPairCallback : public btOverlapCallback
{
btDispatcherInfo& m_dispatchInfo;
const btDispatcherInfo& m_dispatchInfo;
btCollisionDispatcher* m_dispatcher;
public:
btCollisionPairCallback(btDispatcherInfo& dispatchInfo,btCollisionDispatcher* dispatcher)
btCollisionPairCallback(const btDispatcherInfo& dispatchInfo,btCollisionDispatcher* dispatcher)
:m_dispatchInfo(dispatchInfo),
m_dispatcher(dispatcher)
{
}
btCollisionPairCallback& operator=(btCollisionPairCallback& other)
/*btCollisionPairCallback& operator=(btCollisionPairCallback& other)
{
m_dispatchInfo = other.m_dispatchInfo;
m_dispatcher = other.m_dispatcher;
return *this;
}
*/
virtual ~btCollisionPairCallback() {}
@@ -221,7 +223,8 @@ public:
};
void btCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher)
void btCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher)
{
//m_blockedForChanges = true;
@@ -237,7 +240,7 @@ void btCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pa
//by default, Bullet will use this near callback
void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, btDispatcherInfo& dispatchInfo)
void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo)
{
btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;

View File

@@ -35,7 +35,7 @@ class btCollisionConfiguration;
class btCollisionDispatcher;
///user can override this nearcallback for collision filtering and more finegrained control over collision detection
typedef void (*btNearCallback)(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, btDispatcherInfo& dispatchInfo);
typedef void (*btNearCallback)(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo);
///btCollisionDispatcher supports algorithms that handle ConvexConvex and ConvexConcave collision pairs.
@@ -107,7 +107,7 @@ public:
virtual bool needsResponse(btCollisionObject* body0,btCollisionObject* body1);
virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher);
virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) ;
void setNearCallback(btNearCallback nearCallback)
{
@@ -120,7 +120,7 @@ public:
}
//by default, Bullet will use this near callback
static void defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, btDispatcherInfo& dispatchInfo);
static void defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo);
virtual void* allocateCollisionAlgorithm(int size);

View File

@@ -4,8 +4,8 @@ Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
@@ -57,7 +57,7 @@ btCollisionWorld::~btCollisionWorld()
for (i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* collisionObject= m_collisionObjects[i];
btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
if (bp)
{
@@ -107,7 +107,7 @@ void btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,sho
m_dispatcher1,0
)) ;
@@ -116,12 +116,12 @@ void btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,sho
void btCollisionWorld::updateAabbs()
{
BT_PROFILE("updateAabbs");
btTransform predictedTrans;
for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
//only update aabb of active objects
if (colObj->isActive())
{
@@ -138,7 +138,7 @@ void btCollisionWorld::updateAabbs()
//something went wrong, investigate
//this assert is unwanted in 3D modelers (danger of loosing work)
colObj->setActivationState(DISABLE_SIMULATION);
static bool reportMe = true;
if (reportMe && m_debugDrawer)
{
@@ -151,7 +151,7 @@ void btCollisionWorld::updateAabbs()
}
}
}
}
@@ -183,12 +183,12 @@ void btCollisionWorld::performDiscreteCollisionDetection()
void btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject)
{
//bool removeFromBroadphase = false;
{
btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
if (bp)
{
@@ -233,12 +233,12 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
//btGjkConvexCast convexCaster(castShape,convexShape,&simplexSolver);
//btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
#endif //#USE_SUBSIMPLEX_CONVEX_CAST
if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
{
//add hit
if (castResult.m_normal.length2() > btScalar(0.0001))
{
{
if (castResult.m_fraction < resultCallback.m_closestHitFraction)
{
#ifdef USE_SUBSIMPLEX_CONVEX_CAST
@@ -249,7 +249,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
castResult.m_normal.normalize();
btCollisionWorld::LocalRayResult localRayResult
(
collisionObject,
collisionObject,
0,
castResult.m_normal,
castResult.m_fraction
@@ -273,7 +273,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
//ConvexCast::CastResult
struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
{
btCollisionWorld::RayResultCallback* m_resultCallback;
btCollisionObject* m_collisionObject;
@@ -294,13 +294,13 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
btCollisionWorld::LocalShapeInfo shapeInfo;
shapeInfo.m_shapePart = partId;
shapeInfo.m_triangleIndex = triangleIndex;
btCollisionWorld::LocalRayResult rayResult
(m_collisionObject,
(m_collisionObject,
&shapeInfo,
hitNormalLocal,
hitFraction);
bool normalInWorldSpace = false;
return m_resultCallback->AddSingleResult(rayResult,normalInWorldSpace);
}
@@ -313,7 +313,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
} else
{
btTriangleMeshShape* triangleMesh = (btTriangleMeshShape*)collisionShape;
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
@@ -321,7 +321,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
//ConvexCast::CastResult
struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
{
btCollisionWorld::RayResultCallback* m_resultCallback;
btCollisionObject* m_collisionObject;
@@ -342,17 +342,17 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
btCollisionWorld::LocalShapeInfo shapeInfo;
shapeInfo.m_shapePart = partId;
shapeInfo.m_triangleIndex = triangleIndex;
btCollisionWorld::LocalRayResult rayResult
(m_collisionObject,
(m_collisionObject,
&shapeInfo,
hitNormalLocal,
hitFraction);
bool normalInWorldSpace = false;
return m_resultCallback->AddSingleResult(rayResult,normalInWorldSpace);
}
};
@@ -395,29 +395,39 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
btCollisionObject* collisionObject,
const btCollisionShape* collisionShape,
const btTransform& colObjWorldTransform,
ConvexResultCallback& resultCallback,short int collisionFilterMask)
ConvexResultCallback& resultCallback, btScalar allowedPenetration,short int collisionFilterMask)
{
if (collisionShape->isConvex())
{
btConvexCast::CastResult castResult;
castResult.m_allowedPenetration = allowedPenetration;
castResult.m_fraction = btScalar(1.);//??
btConvexShape* convexShape = (btConvexShape*) collisionShape;
btVoronoiSimplexSolver simplexSolver;
btGjkEpaPenetrationDepthSolver gjkEpaPenetrationSolver;
btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,&gjkEpaPenetrationSolver);
bool result = false;
if (convexCaster.calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
btContinuousConvexCollision convexCaster1(castShape,convexShape,&simplexSolver,&gjkEpaPenetrationSolver);
//btGjkConvexCast convexCaster2(castShape,convexShape,&simplexSolver);
//btSubsimplexConvexCast convexCaster3(castShape,convexShape,&simplexSolver);
btConvexCast* castPtr = &convexCaster1;
if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
{
//add hit
if (castResult.m_normal.length2() > btScalar(0.0001))
{
{
if (castResult.m_fraction < resultCallback.m_closestHitFraction)
{
castResult.m_normal.normalize();
btCollisionWorld::LocalConvexResult localConvexResult
(
collisionObject,
collisionObject,
0,
castResult.m_normal,
castResult.m_hitPoint,
@@ -443,7 +453,7 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
//ConvexCast::CastResult
struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
{
btCollisionWorld::ConvexResultCallback* m_resultCallback;
btCollisionObject* m_collisionObject;
@@ -468,15 +478,15 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
{
btCollisionWorld::LocalConvexResult convexResult
(m_collisionObject,
(m_collisionObject,
&shapeInfo,
hitNormalLocal,
hitPointLocal,
hitFraction);
bool normalInWorldSpace = true;
return m_resultCallback->AddSingleResult(convexResult,normalInWorldSpace);
}
return hitFraction;
@@ -499,7 +509,7 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
//ConvexCast::CastResult
struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
{
btCollisionWorld::ConvexResultCallback* m_resultCallback;
btCollisionObject* m_collisionObject;
@@ -524,12 +534,12 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
{
btCollisionWorld::LocalConvexResult convexResult
(m_collisionObject,
(m_collisionObject,
&shapeInfo,
hitNormalLocal,
hitPointLocal,
hitFraction);
bool normalInWorldSpace = false;
return m_resultCallback->AddSingleResult(convexResult,normalInWorldSpace);
@@ -543,7 +553,7 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
tccb.m_hitFraction = resultCallback.m_closestHitFraction;
btVector3 boxMinLocal, boxMaxLocal;
castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
btVector3 rayAabbMinLocal = convexFromLocal;
rayAabbMinLocal.setMin(convexToLocal);
btVector3 rayAabbMaxLocal = convexFromLocal;
@@ -567,26 +577,26 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
collisionObject,
childCollisionShape,
childWorldTrans,
resultCallback, collisionFilterMask);
resultCallback, allowedPenetration,collisionFilterMask);
}
}
}
}
}
void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback,short int collisionFilterMask)
void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback,short int collisionFilterMask) const
{
btTransform rayFromTrans,rayToTrans;
rayFromTrans.setIdentity();
rayFromTrans.setOrigin(rayFromWorld);
rayToTrans.setIdentity();
rayToTrans.setOrigin(rayToWorld);
/// go over all objects, and if the ray intersects their aabb, do a ray-shape query using convexCaster (CCD)
int i;
for (i=0;i<m_collisionObjects.size();i++)
{
@@ -596,7 +606,7 @@ void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& r
btCollisionObject* collisionObject= m_collisionObjects[i];
//only perform raycast if filterMask matches
if(collisionObject->getBroadphaseHandle()->m_collisionFilterGroup & collisionFilterMask) {
if(collisionObject->getBroadphaseHandle()->m_collisionFilterGroup & collisionFilterMask) {
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
@@ -610,14 +620,14 @@ void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& r
collisionObject->getCollisionShape(),
collisionObject->getWorldTransform(),
resultCallback);
}
}
}
}
}
void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback,short int collisionFilterMask)
void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback,short int collisionFilterMask) const
{
btTransform convexFromTrans,convexToTrans;
convexFromTrans = convexFromWorld;
@@ -640,7 +650,7 @@ void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btT
{
btCollisionObject* collisionObject= m_collisionObjects[i];
//only perform raycast if filterMask matches
if(collisionObject->getBroadphaseHandle()->m_collisionFilterGroup & collisionFilterMask) {
if(collisionObject->getBroadphaseHandle()->m_collisionFilterGroup & collisionFilterMask) {
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
@@ -653,8 +663,10 @@ void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btT
collisionObject,
collisionObject->getCollisionShape(),
collisionObject->getWorldTransform(),
resultCallback);
}
resultCallback,
getDispatchInfo().m_allowedCcdPenetration,
collisionFilterMask);
}
}
}

View File

@@ -123,6 +123,11 @@ public:
return m_dispatcher1;
}
const btDispatcher* getDispatcher() const
{
return m_dispatcher1;
}
virtual void updateAabbs();
virtual void setDebugDrawer(btIDebugDraw* debugDrawer)
@@ -309,11 +314,11 @@ public:
/// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback
/// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback.
void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback, short int collisionFilterMask=-1);
void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback, short int collisionFilterMask=-1) const;
// convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultCallback
// This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback.
void convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback, short int collisionFilterMask=-1);
void convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback, short int collisionFilterMask=-1) const;
/// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
@@ -330,7 +335,7 @@ public:
btCollisionObject* collisionObject,
const btCollisionShape* collisionShape,
const btTransform& colObjWorldTransform,
ConvexResultCallback& resultCallback, short int collisionFilterMask=-1);
ConvexResultCallback& resultCallback, btScalar allowedPenetration, short int collisionFilterMask=-1);
void addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=1,short int collisionFilterMask=1);
@@ -354,6 +359,11 @@ public:
return m_dispatchInfo;
}
const btDispatcherInfo& getDispatchInfo() const
{
return m_dispatchInfo;
}
};

View File

@@ -51,10 +51,18 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
btTransformUtil::calculateVelocity(fromA,toA,btScalar(1.),linVelA,angVelA);
btTransformUtil::calculateVelocity(fromB,toB,btScalar(1.),linVelB,angVelB);
btScalar boundingRadiusA = m_convexA->getAngularMotionDisc();
btScalar boundingRadiusB = m_convexB->getAngularMotionDisc();
btScalar maxAngularProjectedVelocity = angVelA.length() * boundingRadiusA + angVelB.length() * boundingRadiusB;
btVector3 relLinVel = (linVelB-linVelA);
btScalar relLinVelocLength = (linVelB-linVelA).length();
if ((relLinVelocLength+maxAngularProjectedVelocity) == 0.f)
return false;
btScalar radius = btScalar(0.001);
@@ -108,8 +116,8 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
dist = pointCollector1.m_distance;
n = pointCollector1.m_normalOnBInWorld;
btScalar projectedLinearVelocity = relLinVel.dot(n);
//not close enough
while (dist > radius)
{
@@ -120,7 +128,7 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
}
btScalar dLambda = btScalar(0.);
btScalar projectedLinearVelocity = (linVelB-linVelA).dot(n);
projectedLinearVelocity = relLinVel.dot(n);
//calculate safe moving fraction from distance / (linear+rotational velocity)
@@ -130,6 +138,8 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
dLambda = dist / (projectedLinearVelocity+ maxAngularProjectedVelocity);
lambda = lambda + dLambda;
if (lambda > btScalar(1.))
@@ -187,6 +197,10 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
}
//don't report time of impact for motion away from the contact normal (or causes minor penetration)
if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=result.m_allowedPenetration)//SIMD_EPSILON)
return false;
result.m_fraction = lambda;
result.m_normal = n;
result.m_hitPoint = c;

View File

@@ -42,20 +42,21 @@ public:
CastResult()
:m_fraction(btScalar(1e30)),
m_debugDrawer(0)
m_debugDrawer(0),
m_allowedPenetration(btScalar(0))
{
}
virtual ~CastResult() {};
btVector3 m_normal;
btVector3 m_hitPoint;
btScalar m_fraction;
btTransform m_hitTransformA;
btTransform m_hitTransformB;
btVector3 m_normal;
btVector3 m_hitPoint;
btScalar m_fraction; //input and output
btIDebugDraw* m_debugDrawer;
btScalar m_allowedPenetration;
};

View File

@@ -158,6 +158,11 @@ bool btGjkConvexCast::calcTimeOfImpact(
}
//is n normalized?
//don't report time of impact for motion away from the contact normal (or causes minor penetration)
if (n.dot(r)>=-result.m_allowedPenetration)
return false;
result.m_fraction = lambda;
result.m_normal = n;
result.m_hitPoint = c;

View File

@@ -119,6 +119,8 @@ bool btSubsimplexConvexCast::calcTimeOfImpact(
{
dist2 = v.length2();
hasResult = true;
//todo: check this normal for validity
n=v;
//printf("V=%f , %f, %f\n",v[0],v[1],v[2]);
//printf("DIST2=%f\n",dist2);
//printf("numverts = %i\n",m_simplexSolver->numVertices());
@@ -130,8 +132,17 @@ bool btSubsimplexConvexCast::calcTimeOfImpact(
//int numiter = MAX_ITERATIONS - maxIter;
// printf("number of iterations: %d", numiter);
//don't report a time of impact when moving 'away' from the hitnormal
result.m_fraction = lambda;
result.m_normal = n.normalized();
//don't report time of impact for motion away from the contact normal (or causes minor penetration)
if (result.m_normal.dot(r)>=-result.m_allowedPenetration)
return false;
btVector3 hitA,hitB;
m_simplexSolver->compute_points(hitA,hitB);
result.m_hitPoint=hitB;

View File

@@ -39,15 +39,16 @@ class btDynamicsWorld : public btCollisionWorld
{
protected:
btInternalTickCallback m_internalTickCallback;
btInternalTickCallback m_internalTickCallback;
void* m_worldUserInfo;
btContactSolverInfo m_solverInfo;
btContactSolverInfo m_solverInfo;
public:
btDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphase,btCollisionConfiguration* collisionConfiguration)
:btCollisionWorld(dispatcher,broadphase,collisionConfiguration), m_internalTickCallback(0)
:btCollisionWorld(dispatcher,broadphase,collisionConfiguration), m_internalTickCallback(0), m_worldUserInfo(0)
{
}
@@ -95,8 +96,17 @@ public:
virtual void clearForces() = 0;
/// Set the callback for when an internal tick (simulation substep) happens
void setInternalTickCallback(btInternalTickCallback cb) { m_internalTickCallback = cb; }
/// Set the callback for when an internal tick (simulation substep) happens, optional user info
void setInternalTickCallback(btInternalTickCallback cb, void* worldUserInfo=0)
{
m_internalTickCallback = cb;
m_worldUserInfo = worldUserInfo;
}
void* getWorldUserInfo() const
{
return m_worldUserInfo;
}
btContactSolverInfo& getSolverInfo()
{

View File

@@ -23,7 +23,7 @@ subject to the following restrictions:
#include <cfloat>
#include <float.h>
#define BT_BULLET_VERSION 269
#define BT_BULLET_VERSION 270
inline int btGetVersion()
{