2012-02-02 122 views
3

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

我看了一下CollisionInterfaceDemo演示,它不符合我的需求。

什么是检测碰撞之间需要什么步骤让我们说3球,只知道它是否碰撞(我不关心碰撞点)?

我只知道我可以通过设置其转换来移动CollisionObject。

+1

难道你不能使用数学做碰撞检测吗? – 2012-02-02 18:37:24

+0

如果我有很多实体,我需要一些物理引擎,它可以选择掉大部分球体来跳过大量的加法/乘法运算。我想它被称为bulletphysics中的broadphare – jokoon 2012-02-02 18:56:46

+0

http://stackoverflow.com/questions/9117932/detecting-collisions-with-bullet || http://gamedev.stackexchange.com/questions/22442/how-get-collision-callback-of-two-specific-objects-using-bullet-physics – 2016-05-02 16:22:43

回答

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. 初始化一个模拟的东西子弹需求。
  2. 创建一个对象并将其添加到项目符号的“世界”。
  3. 通过一些时间步更新世界每一帧。

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

希望这有助于!

+0

我不想让子弹移动我的物体,我只是自己动一下。 – jokoon 2012-02-02 20:21:18

1

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

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

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

这是基本的2D距离公式,使其三维所有你需要做的就是添加(Z2 - Z1)的平方其他2个坐标坊前生根结果。

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

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

+0

bulletphysics.org – jokoon 2012-02-02 18:51:57

+2

顺便说一句,你不需要sqrt的结果,需要太多的周期。只是比较正方形就足够了。 – jokoon 2012-02-02 18:56:25

+0

@gokoon我没有想过这样做,看着“适当”的数学有点过分。这不会是一笔很大的储蓄,但你说得对一个数字的平方比一个平方根更快(略微)。感谢这个想法。 – Cdaragorn 2012-02-02 19:17:48