OgreBullet刚性Ody碰撞检测

OgreBullet RigidBOdy collision detection

本文关键字:碰撞检测 Ody 刚性 OgreBullet      更新时间:2023-10-16

我在OgreBulletDynamics包装器中查找函数时遇到问题。我试图使用项目符号wiki中的示例来检测两个刚体之间的碰撞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示例中,它正在创建一个派生自公共btCollisionWorld::ContactResultCallback?的结构?

但是我不能通过OgreBulletDynamics刚体,因为它不能从OgreBullteDynamics::RigidBody转换为btRigidBody。

我可以从哪里访问OgreBulletDynamics中的btCollisionWorld?

感谢

虽然我回答这个问题迟到了,但它可能会帮助其他人。对于OgreBullet中的碰撞检测,您需要依赖Bullet的官方API。我假设你有Ogre3d提供的应用程序的基本架构。有一种方法bool frameRenderingQueued(const Ogre::FrameEvent &fe);,每当有帧排队显示时,都会调用该方法。当然,你在做一些其他的事情。只需复制下面的函数,因为我从碰撞回调和触发器中获得了这个函数:

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。

此外,如果你想对这个btCollisionObject所代表的Node进行一些操作,你需要为此做一些额外的事情。当你创建类似刚体的:

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

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

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

然后像这样检索:

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

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

欢呼:-)