bullet setp 流程
好的
我要开始新篇了
新篇是Bullet的
刚开始看Bullet时 代码不熟 看后忘前 不过 怎么说呢 那我就每天看 草
于是 我就明白了
先看看那个step函数:
1
void
btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep)
2
![]()
{
3
4
BT_PROFILE("internalSingleStepSimulation");
5![]()
6![]()
if(0 != m_internalPreTickCallback)
{
7
(*m_internalPreTickCallback)(this, timeStep);
8
}
9![]()
10![]()
/**////apply gravity, predict motion
11
predictUnconstraintMotion(timeStep);
12![]()
13
btDispatcherInfo& dispatchInfo = getDispatchInfo();
14![]()
15
dispatchInfo.m_timeStep = timeStep;
16
dispatchInfo.m_stepCount = 0;
17
dispatchInfo.m_debugDraw = getDebugDrawer();
18![]()
19![]()
20
createPredictiveContacts(timeStep);
21
22![]()
/**////perform collision detection
23
performDiscreteCollisionDetection();
24![]()
25
calculateSimulationIslands();
26![]()
27
28
getSolverInfo().m_timeStep = timeStep;
29
30![]()
31![]()
32![]()
/**////solve contact and other joint constraints
33
solveConstraints(getSolverInfo());
34
35![]()
/**////CallbackTriggers();
36![]()
37
///integrate transforms
38![]()
39
integrateTransforms(timeStep);
40![]()
41![]()
/**////update vehicle simulation
42
updateActions(timeStep);
43
44
updateActivationState( timeStep );
45![]()
46![]()
if(0 != m_internalTickCallback)
{
47
(*m_internalTickCallback)(this, timeStep);
48
}
49
}
50
看看里面几个重要的函数:
1 predictUnconstraintMotion(timeStep) :给每个物体加重力作用力
2 createPredictiveContacts(timeStep) :和ccd有关 处理物体在高速运动时的碰撞
3 performDiscreteCollisionDetection():此函数做碰撞 我们来看看
void
btCollisionWorld::performDiscreteCollisionDetection()
![]()
{
BT_PROFILE("performDiscreteCollisionDetection");
![]()
btDispatcherInfo& dispatchInfo = getDispatchInfo();
![]()
updateAabbs();
![]()
![]()
computeOverlappingPairs();
* dispatcher = getDispatcher();
![]()
{
BT_PROFILE("dispatchAllCollisionPairs");
if (dispatcher)
dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1);
}
![]()
![]()
}
1) updateAabbs():
把要参加broad碰撞的物体放进paircache,此时没有进行任何碰撞检测,仅仅是把物体加进paircache(addOverlappingPair)同时,放进ghost的paircache里
if (m_ghostPairCallback)
m_ghostPairCallback->addOverlappingPair(proxy0,proxy1);
在这个阶段可以设置一个回调函数,用于过滤一些特定物体
SIMD_FORCE_INLINE bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
{
if (m_overlapFilterCallback)
return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1);
bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
return collides;
}
m_overlapFilterCallback就是那个回调函数
2) computeOverlappingPairs():
该函数执行broad碰撞,也就是类似于AABB的粗线条碰撞,以此过滤paircache中不用进行narrow碰撞的pair
3) dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1):
该函数进行narrow碰撞,也就是精确碰撞,在这里,我们也可以设置回调,以过滤掉某些物体的精确碰撞
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;
![]()
if (dispatcher.needsCollision(colObj0,colObj1))
![]()
![]()
{
btCollisionObjectWrapper obj0Wrap(0,colObj0->getCollisionShape(),colObj0,colObj0->getWorldTransform());
btCollisionObjectWrapper obj1Wrap(0,colObj1->getCollisionShape(),colObj1,colObj1->getWorldTransform());
![]()
![]()
//dispatcher will keep algorithms persistent in the collision pair
if (!collisionPair.m_algorithm)
![]()
{
collisionPair.m_algorithm = dispatcher.findAlgorithm(&obj0Wrap,&obj1Wrap);
}
![]()
if (collisionPair.m_algorithm)
![]()
{
btManifoldResult contactPointResult(&obj0Wrap,&obj1Wrap);
if (dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE)
![]()
{
//discrete collision detection query
collisionPair.m_algorithm->processCollision(&obj0Wrap,&obj1Wrap,dispatchInfo,&contactPointResult);
} else
![]()
{
//continuous collision detection query, time of impact (toi)
btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult);
if (dispatchInfo.m_timeOfImpact > toi)
dispatchInfo.m_timeOfImpact = toi;
![]()
}
}
}
![]()
}
这个是默认的callback所做的活,正如bulletManual上所说,可以换成我们自己的callback
void setNearCallback(btNearCallback nearCallback)
{
m_nearCallback = nearCallback;
}
另外,还可以重载btCollisionDispatcher,重写其
virtual bool needsCollision(const btCollisionObject* body0,const btCollisionObject* body1);
virtual bool needsResponse(const btCollisionObject* body0,const btCollisionObject* body1);
virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) ;
从而完全定制其行为
好 暂时over