BulletPhysic: contacts force/impulse

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.


这段代码应该指向你的可能方向

// 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("%fn", 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
        }
    }
}
链接地址: http://www.djcxy.com/p/11330.html

上一篇: ACRA可以用于图书馆项目吗?

下一篇: BulletPhysic:联系力量/冲动