我在OgreBulletDynamics包装器中查找函数时遇到麻烦。
我试图使用子弹维基的示例来检测2个刚性体之间的碰撞
http://bulletphysics.org/mediawiki-1.5.8/index.php/Collision_Callbacks_and_Triggers
在“联系信息”示例中

btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());

btCollision对象仅与btRigidBody一起使用,而不与OgreBulletDynamics::RigidBody一起使用,我无法找到OgreBullet中btCollision的位置。

在contactTest示例中,它正在创建一个从公共(public)btCollisionWorld::ContactResultCallback?派生的结构。

但我无法通过OgreBulletDynamics RigidBody,因为它无法从OgreBulletDynamics::RigidBody转换为btRigidBody。

在哪里可以从OgreBulletDynamics访问btCollisionWorld?

谢谢

最佳答案

尽管我回答这个问题很晚,但是它可能会对其他人有所帮助。对于OgreBullet中的冲突检测,您需要依赖Bullet的官方API。我假设您具有Ogre3d提供的应用程序的基本体系结构。有一种方法bool frameRenderingQueued(const Ogre::FrameEvent &fe);,每当有一个队列要显示时,都会调用此方法。当然,您在此过程中还会做其他一些事情。只要复制下面的函数,就像我从Collision Callbacks and Triggers提取的那样:

void MainApp::checkCollisions()
{
    btCollisionWorld *collisionWorld = mBulletWorld->getBulletCollisionWorld();
    btDynamicsWorld *dynamicWorld = mBulletWorld->getBulletDynamicsWorld();

    int numManifolds = collisionWorld->getDispatcher()->getNumManifolds();
    bool collide = false;
    for (int i=0;i<numManifolds;i++)
    {
        btPersistentManifold* contactManifold =  collisionWorld->getDispatcher()->getManifoldByIndexInternal(i);
        btCollisionObject* obA = (btCollisionObject *) contactManifold->getBody0();
        btCollisionObject* obB = (btCollisionObject *) contactManifold->getBody1();

        int numContacts = contactManifold->getNumContacts();
        for (int j=0;j<numContacts;j++)
        {
            btManifoldPoint& pt = contactManifold->getContactPoint(j);
            if (pt.getDistance()<0.f)
            {
                const btVector3& ptA = pt.getPositionWorldOnA();
                const btVector3& ptB = pt.getPositionWorldOnB();
                const btVector3& normalOnB = pt.m_normalWorldOnB;
                collide = true;
                std::cout << "Collision Body A: " << obA->getCollisionShape()->getName() << std::endl;
                std::cout << "Collision Body B: " << obB->getCollisionShape()->getName() << std::endl;
            }
        }
    }

    // this is label for debugging
    mInfoLabel->setCaption("Collision = " + Ogre::StringConverter::toString(collide));
}

只是在最后用bool frameRenderingQueued(const Ogre::FrameEvent &fe);方法调用此方法。每次发生碰撞时,都将碰撞bool设置为true,否则为false。

此外,如果您想对Node进行一些操作(此btCollisionObject表示),则需要为此做一些额外的操作。当您创建RigidBody时,如下所示:
OgreBulletDynamics::RigidBody *defaultBody = new
OgreBulletDynamics::RigidBody("Body_Name", mBulletWorld);

然后只需将您创建的节点添加到此defaultBody中,如下所示:
defaultBody->getBulletObject()->setUserPointer((void *) node);

然后像这样检索它:
Ogre::SceneNode *node = (Ogre::SceneNode *) obA->getUserPointer();

现在您有了节点,就可以使用它进行任何操作。

欢呼声:-)

10-04 23:19