2012-02-02 61 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