У меня есть 2 объекта, сфера и ящик, который, когда один сталкивается с другим, будет выполнять какое-либо действие (то есть разрушать ящик).
Я пробовал несколько способов:
Может ли кто-нибудь привести пример того, как вызывать метод, например, CollissionResult (), когда сталкиваются 2 btRigidBodies (то есть bodyA и bodyB)?
Возможно, этот пример поможет объяснить концепцию. Вы должны определить новый класс, производный от существующего абстрактного класса. Вы переопределяете один из методов абстрактных классов своим кодом обратного вызова. Затем вы создаете объект производного класса и передаете его в функцию, которую хотите вызвать обратным вызовом. Это достаточно распространенная техника 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.
}
}