我有 2 个物体,一个球体和一个盒子,当一个物体与另一个物体发生碰撞时,它们会做一些动作(即摧毁盒子)。
我尝试了几种方法:
- checkCollideWith 总是返回 true;
- contactPairTest - 这个我不明白怎么用。它需要 3 个参数、2 个对象和一个回调。我认为回调可以是我的代码中的任何函数,但它不是那样工作的。
有人可以举例说明当 2 个 btRigidBodies 碰撞(即 bodyA 和 bodyB)时如何调用方法,例如 CollissionResult()?
也许这个例子将有助于解释这个概念。您必须定义一个从现有抽象类派生的新类。您使用回调代码覆盖抽象类方法之一。然后创建派生类的对象并将其传递给要调用回调的函数。这是一种足够常见的 C++ 技术。
struct MyContactResultCallback : public ContactResultCallback
{
btScalar addSingleResult(btManifoldPoint& cp,
const btCollisionObjectWrapper* colObj0Wrap,
int partId0,
int index0,
const btCollisionObjectWrapper* colObj1Wrap,
int partId1,
in index1)
{
// your callback code here
}
};
MyContactResultCallback callback;
world.contactPairTest(bodyA, bodyB, callback);
我应该补充一点,我对这个图书馆一无所知。我刚刚阅读了文档。
编辑
展示如何将上下文成员添加到MyContactResultCallback
.
struct MyContactResultCallback : public ContactResultCallback
{
MyContactResultCallback(some_type* ptr) : context(ptr) {}
btScalar addSingleResult(btManifoldPoint& cp,
const btCollisionObjectWrapper* colObj0Wrap,
int partId0,
int index0,
const btCollisionObjectWrapper* colObj1Wrap,
int partId1,
in index1)
{
context->currentPoints += 10;
}
some_type* context;
};
MyContactResultCallback callback(ptr_to_some_object);
world.contactPairTest(bodyA, bodyB, callback);
ptr_to_some_object
是指向要currentPoints
增加的对象的指针。我不知道那是什么类型的对象,所以我刚刚说过some_type
,你可以用任何真正的类型来替换它。
这就是使用对象作为回调而不是函数的要点。如果回调是一个对象,您可以将数据成员添加到您想要的任何目的,您不能对函数执行此操作。
我发现最简单的方法是检查歧管。如果您只是询问调度员,则不需要自定义类。
每次踏入世界后执行此操作:
btDispatcher* dp = world->getDispatcher();
const int numManifolds = dp->getNumManifolds();
for ( int m=0; m<numManifolds; ++m )
{
btPersistentManifold* man = dp->getManifoldByIndexInternal( m );
const btRigidBody* obA = static_cast<const btRigidBody*>(man->getBody0());
const btRigidBody* obB = static_cast<const btRigidBody*>(man->getBody1());
const void* ptrA = obA->getUserPointer();
const void* ptrB = obB->getUserPointer();
// use user pointers to determine if objects are eligible for destruction.
...
const int numc = man->getNumContacts();
float totalImpact = 0.0f;
for ( int c=0; c<numc; ++c )
totalImpact += man->getContactPoint(c).m_appliedImpulse;
if ( totalImpact > threshold )
{
// Here you can break one, or both shapes, if so desired.
}
}