4

我用 Ogre3D 制作了一个应用程序,已经生成了子弹的对象,我现在需要的只是检测对象之间的碰撞。

我查看了 CollisionInterfaceDemo 演示,它并不真正符合我的需求。

检测3个球体之间的碰撞所需的步骤是什么,只知道它是否发生碰撞(我不关心碰撞点)?

我只知道我可以通过设置它的变换来移动一个 CollisionObject。

4

2 回答 2

4

如果您使用的是 Bullet,您可以查看几个演示来帮助您入门。

但基本上,这是概要(其中大部分来自他们的示例):

在您的标题或您的物理系统所在的位置:

btDefaultCollisionConfiguration*        mPhysicsConfig;
btCollisionDispatcher*                  mPhysicsDispatcher;
btBroadphaseInterface*                  mPhysicsCache;
btSequentialImpulseConstraintSolver*    mPhysicsSolver;
btDiscreteDynamicsWorld*                mPhysicsWorld;
btAlignedObjectArray<btCollisionShape*> mPhysicsShapes;

首先(初始化):

///collision configuration contains default setup for memory, collision setup.
mPhysicsConfig = new btDefaultCollisionConfiguration();

///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
mPhysicsDispatcher = new    btCollisionDispatcher(mPhysicsConfig);

///btDbvtBroadphase is a good general purpose broadphase. You can also try out btAxis3Sweep.
mPhysicsCache = new btDbvtBroadphase();

///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
mPhysicsSolver = new btSequentialImpulseConstraintSolver;
mPhysicsWorld = new btDiscreteDynamicsWorld(mPhysicsDispatcher,mPhysicsCache,mPhysicsSolver,mPhysicsConfig);
mPhysicsWorld->setGravity(btVector3(0,-9.81f,0));

每一帧(这通常在更新函数中):

mPhysicsWorld->stepSimulation( timestep , 10 );

添加一个球体(指针只是返回以使创建后访问更容易):

btRigidBody* MyPhysicsSystem::CreateSphere(float sx, float px, float py, float pz, float mass)
{
    btCollisionShape* colShape = new btSphereShape(btScalar(sx));
    mPhysicsShapes.push_back(colShape);

    btTransform startTransform;
    startTransform.setIdentity();

    btScalar    tMass(mass);

    //rigidbody is dynamic if and only if mass is non zero, otherwise static
    bool isDynamic = (tMass != 0.f);

    btVector3 localInertia(0,0,0);
    if (isDynamic)
        colShape->calculateLocalInertia(tMass,localInertia);

    startTransform.setOrigin(btVector3(px,py,pz));

    //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
    btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
    btRigidBody::btRigidBodyConstructionInfo rbInfo(tMass,myMotionState,colShape,localInertia);
    btRigidBody* body = new btRigidBody(rbInfo);
    mPhysicsWorld->addRigidBody(body);
    return body;
}

就是这样!

重申:

  1. 初始化 Bullet 进行模拟所需的东西。
  2. 创建一个对象并将其添加到子弹的“世界”中。
  3. 每帧更新该世界某个时间步长。

Bullet 将为您处理碰撞。如果您需要某种方式在发生碰撞时完成功能,我相信您可以将自定义回调分配为将发生的碰撞行为。

希望这可以帮助!

于 2012-02-02T19:35:01.490 回答
1

在处理球体之间的碰撞检测时,您需要知道两件事:每个球体的半径和它们的位置。

然后,您必须遍历每个领域并将其与其他领域进行比较。对于每一对,您需要首先找出它们之间的距离。

http://www.purplemath.com/modules/distform.htm

这是基本的 2d 距离公式,要使其成为 3d,您只需将 (z2 - z1)squared 与其他 2 个坐标相加,然后再将结果平方根。

一旦你有了那个距离,只需将 2 个球体半径相加,并将其与它们之间的距离进行比较。如果距离小于或等于半径之和,则球体发生碰撞。

我对 Ogre3D 不是特别熟悉,但如果你可以变换一个对象,你也应该能够得到它的位置。

于 2012-02-02T18:48:13.990 回答