【问题标题】:OgreBullet RigidBOdy collision detectionOgreBullet RigidBOdy 碰撞检测
【发布时间】:2014-01-02 16:57:08
【问题描述】:

我无法在 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?

谢谢

【问题讨论】:

    标签: c++ collision ogre bullet


    【解决方案1】:

    虽然我回答这个问题迟了,但它可能对其他人有所帮助。对于OgreBullet 中的碰撞检测,您需要依赖 Bullet 的官方 API。我假设你有 Ogre3d 提供的应用程序的基本架构。有一个方法bool frameRenderingQueued(const Ogre::FrameEvent &amp;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 &amp;fe); 方法中的此方法即可。每次如果发生碰撞,就会将碰撞 bool 设置为 true,否则为 false。

    此外,如果你想在节点上进行一些操作,这个 btCollisionObject 代表,你需要为此做一些额外的事情。当你像这样创建刚体时:

    OgreBulletDynamics::RigidBody *defaultBody = new 
    OgreBulletDynamics::RigidBody("Body_Name", mBulletWorld);
    

    然后只需在这个 defaultBody 中添加您创建的节点,如下所示:

    defaultBody->getBulletObject()->setUserPointer((void *) node);
    

    然后像这样检索它:

    Ogre::SceneNode *node = (Ogre::SceneNode *) obA->getUserPointer();
    

    现在你有了节点,你可以用它做任何事情。

    干杯:-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-05
      • 2019-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多