子弹物理:接触力/冲量

Posted

技术标签:

【中文标题】子弹物理:接触力/冲量【英文标题】:BulletPhysic: contacts force/impulse 【发布时间】:2012-10-11 15:11:44 【问题描述】:

我想检测一个(球)何时接触到另一个物体(目标),我想知道那个接触的冲动。

我知道三种检测联系人的方法

gContactAddedCallback

    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
            
        
    

检查线速度和角速度的变化。 (不清楚是否有接触以及是什么物体改变了速度,是物体还是阻尼、重力还是一些力场。


我希望有联系信息,包括联系冲动。 我注意到在 1 帧模拟中解决了一些接触,其他需要 2 帧并且脉冲低两倍。 (我得到了调试代码。) 我会很完美地获得 1 个完全冲动的联系通知。

我列出的所有方法都没有为我提供联系人的完整信息。 有时当球飞到目标附近甚至没有碰到它时它就会发射。

预期的方法是什么?

如果接触能量很高,这些信息可以用来播放撞击声或开始一些动画。

【问题讨论】:

pt.getAppliedImpulse() - 我错过了这个!添加答案,我将其标记为这样。谢谢 【参考方案1】:

此代码应为您指明可能的方向

// 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
        
    

【讨论】:

对不起。我无法标记它已响应。我只给+1。我测试了 pt.getAppliedImpulse() 并且它不起作用。即使我看到它发生在模拟中并且我的速度发生了显着变化,它的总脉冲通常为 0。或 numContacts 为零。

以上是关于子弹物理:接触力/冲量的主要内容,如果未能解决你的问题,请参考以下文章

在具有统一初始脉冲的抛物线路径上移动 2D 物理体

子弹物理,纹理球体不滚动

盒子在子弹物理中不滚动

子弹物理和 OpenGL 将方向转换为前、上和右

子弹物理质心和奇怪的物体反应

子弹物理引擎,如何冻结物体?