обратный вызов пули столкновения между 2 телами

У меня есть 2 объекта, сфера и ящик, который, когда один сталкивается с другим, будет выполнять какое-либо действие (то есть разрушать ящик).

Я пробовал несколько способов:

  • checkCollideWith всегда возвращает true;
  • contactPairTest — это я не понимаю, как использовать.
    Требуется 3 аргумента, 2 объекта и обратный вызов. Я думал, что обратный вызов может быть любой функцией в моем коде, но это не работает так.

Может ли кто-нибудь привести пример того, как вызывать метод, например, CollissionResult (), когда сталкиваются 2 btRigidBodies (то есть bodyA и bodyB)?

2

Решение

Возможно, этот пример поможет объяснить концепцию. Вы должны определить новый класс, производный от существующего абстрактного класса. Вы переопределяете один из методов абстрактных классов своим кодом обратного вызова. Затем вы создаете объект производного класса и передаете его в функцию, которую хотите вызвать обратным вызовом. Это достаточно распространенная техника 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Вы можете заменить это на любой реальный тип.

Это смысл использования объекта в качестве обратного вызова вместо функции. Если обратный вызов является объектом, вы можете добавлять к нему элементы данных для любых целей, которые вы хотите, вы не можете сделать это для функции.

6

Другие решения

Я нашел самый простой способ — проверить коллекторы. Не нужно никаких пользовательских классов, если вы просто спросите диспетчер.

Просто выполните это каждый раз, когда наступите на мир:

    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.
}
}
0

По вопросам рекламы [email protected]