I wish to detect when one (ball) touches another object (target) and I wish to know the impulse of that contact.
I know three ways to detect contacts
gContactAddedCallback
or
int numManifolds = m_dynamicsWorld->getDispatcher()->getNumManifolds();
for (int i=0;i<numManifolds;i++)
{
btRigidBody* obA = static_cast<btRigidBody*>(contactManifold->getBody0());
btRigidBody* obB = static_cast<btRigidBody*>(contactManifold->getBody1());
// May be there is contact obA and obB
btPersistentManifold* contactManifold = m_dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i);
int numContacts = contactManifold->getNumContacts();
for (int j=0;j<numContacts;j++)
{
btManifoldPoint& pt = contactManifold->getContactPoint(j);
if (pt.getDistance()<0.f)
{
// One contact point is inside of another object
// But some contacts are ignored
}
}
}
or
Check the linear and angular velocity change. (Not clear if there was contact and what object made the speed change, was it object or damping, gravity or some force field.
I wish to have contact information to include contacts impulse. I noticed that some contact resolved in 1 frame simulation other take 2 frames and impulse is twice lower. (I got it debugging code.) I would be perfect to get 1 contact notification with total impulse.
None of the methods I listed give me full information for the contact. Some time it fires when ball flies near target and even does not touch it.
What is an anticipated way to do it?
Such information could used to play impact sound or start some animation if contacts energy is high.
This code should point you in on posible direction
// some global constants needed
enum collisiontypes {
NOTHING = 0, // things that don't collide
BALL_BODY = 1<<2, // is ball
TARGET_BODY = 1<<3 // is target
};
int ballBodyCollidesWith = TARGET_BODY | BALL_BODY; // balls collide with targets and other balls
int targetBodyCollidesWith = BALL_BODY; // targets collide with balls
// ...
// bodies creation
dynamicsWorld->addRigidBody(ballBody, BALL_BODY, ballBodyCollidesWith);
dynamicsWorld->addRigidBody(targetBody, TARGET_BODY, targetBodyCollidesWith);
//...
// find out whether a ball collides with a target
int numManifolds = m_dynamicsWorld->getDispatcher()->getNumManifolds();
for (int i=0;i<numManifolds;i++)
{
btRigidBody* obA = static_cast<btRigidBody*>(contactManifold->getBody0());
btRigidBody* obB = static_cast<btRigidBody*>(contactManifold->getBody1());
// May be there is contact obA and obB
// ignore bodies that are not balls or targets
if (
(!(obA->getCollisionFlags() | BALL_TYPE) && !(obB->getCollisionFlags() | BALL_TYPE)) // there is no BALL_TYPE colliding
||
(!(obA->getCollisionFlags() | TARGET_TYPE) && !(obB->getCollisionFlags() | TARGET_TYPE)) // there is no TARGET_TYPE colliding
)
continue; // no more searching needed
btPersistentManifold* contactManifold = m_dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i);
int numContacts = contactManifold->getNumContacts();
for (int j=0;j<numContacts;j++)
{
btManifoldPoint& pt = contactManifold->getContactPoint(j);
printf("%f\n", pt.getAppliedImpulse()); // log to see the variation range of getAppliedImpulse and to chose the appropriate impulseThreshold
if (pt.getAppliedImpulse() > impulseThreshold)
{
// increase score or something
break; // no more searching needed
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With