C++ 用子弹探测碰撞

C++ 用子弹探测碰撞,c++,bulletphysics,C++,Bulletphysics,我用Ogre3D制作了一个应用程序,已经生成了bullet的对象,现在我只需要检测对象之间的碰撞 我看了CollisionInterfaceDemo演示,它与我的需求不太匹配 检测3个球体之间的碰撞所需的步骤是什么,只知道它是否碰撞(我不关心碰撞点) 我只知道可以通过设置碰撞对象的变换来移动碰撞对象。在处理球体之间的碰撞检测时,您需要知道两件事:每个球体的半径及其位置 然后你必须穿过每个球体,并将其与其他球体进行比较。对于每一对,您需要首先找出它们之间的距离 这是基本的2d距离公式,要使其成为

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

我看了CollisionInterfaceDemo演示,它与我的需求不太匹配

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


我只知道可以通过设置碰撞对象的变换来移动碰撞对象。

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

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

这是基本的2d距离公式,要使其成为3d,您只需将(z2-z1)平方添加到其他2个坐标,然后再对结果进行平方根运算

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


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

如果你使用Bullet,你可以看几个演示让你开始

但基本上,这里有一个概要(大部分内容取自他们的示例):

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

btDefaultCollisionConfiguration*        mPhysicsConfig;
btCollisionDispatcher*                  mPhysicsDispatcher;
btBroadphaseInterface*                  mPhysicsCache;
btSequentialImpulseConstraintSolver*    mPhysicsSolver;
btDiscreteDynamicsWorld*                mPhysicsWorld;
btAlignedObjectArray<btCollisionShape*> mPhysicsShapes;
每个帧(通常在更新函数中):

添加一个球体(仅返回指针,以便在创建后更容易访问):

就这样

重申:

  • 初始化bullet模拟所需的内容
  • 创建一个对象并将其添加到bullet的“世界”
  • 以一定的时间步长更新每个帧的世界
  • 子弹会帮你解决碰撞。如果您需要某种方法在发生冲突时完成功能,我相信您可以将自定义回调指定为将要发生的冲突行为

    • 以下是指向项目符号参考的链接:
    • 一份完整的报告 检测和响应与子弹的碰撞:

    希望这有帮助

    你不能用数学来做碰撞检测吗?如果我有很多实体,我需要一些物理引擎,它可以选择大部分球体来跳过许多加法/乘法。我猜它在Bullet Physics中被称为broadphare,顺便说一下,你不需要计算结果,需要太多的周期。仅仅比较正方形就足够了。@gokoon我没有想过要这么做,只是看了“适当的”数学有点太多了。这不会带来很大的节约,但你是对的,平方一个数字比平方根一个更快(略)。谢谢你的主意。我不想让子弹移动我的物体,我只是自己移动它。
    ///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;
    }