2012-12-13 59 views
0

我在一個非常簡單的XNA 4測試遊戲中使用Farseer Physics Engine 3.3.1。 (注意:我也在標註這個Box2D,因爲Farseer是Box2D的直接端口,我很樂意接受Box2D的解決方案來解決這個問題。)當IgnoreCCD = false時,使用AfterCollision/NormalImpulse計算碰撞力不可靠嗎?

在這個遊戲中,我創建了兩個物體。第一個正文使用BodyFactory.CreateCircleBodyType.Dynamic創建。這個身體可以使用鍵盤(它設置Body.LinearVelocity)四處移動。第二個機構使用BodyFactory.CreateRectangleBodyType.Static創建。這個身體是靜止的,永遠不會移動。

然後,我用這個代碼來計算碰撞力時,兩具屍體碰撞:如果這兩個機構都設置爲IgnoreCCD=true

staticBody.FixtureList[0].AfterCollision += new AfterCollisionEventHandler(AfterCollision); 

protected void AfterCollision(Fixture fixtureA, Fixture fixtureB, Contact contact) 
{ 
    float maxImpulse = 0f; 
    for (int i = 0; i < contact.Manifold.PointCount; i++) 
     maxImpulse = Math.Max(maxImpulse, contact.Manifold.Points[i].NormalImpulse); 

    // maxImpulse should contain the force of the collision 
} 

此代碼的偉大工程。我可以100%可靠地計算它們之間的碰撞力。完善。

但問題在於:如果我將主體設置爲IgnoreCCD = false,則該代碼變得難以預料。 AfterCollision被可靠地調用,但由於某種原因,大約75%的時間是正常脈衝,因此只有約四分之一的碰撞被註冊。更糟糕的是,由於完全隨機的原因,NormalImpulse似乎爲零。動態物體可以以同樣的方式與連續10次的靜態物體碰撞10次,並且只有2或3次點擊將以大於零的NormalImpulse進行註冊。在兩個物體上設置IgnoreCCD=true可以立即解決問題,但隨後我失去了連續的物理檢測。

爲什麼會發生這種情況,我該如何解決?


下面是一個簡單的XNA 4溶液的鏈接,以實際行動體現這個問題: http://www.mediafire.com/?a1w242q9sna54j4

回答

0

雖然我沒有試過,所以我不會在一個位置,給出一個明確的答案,我覺得從Box2D的源代碼,此摘錄可能是相關的:

/// This lets you inspect a contact after the solver is finished. This is useful 
/// for inspecting impulses. 
/// Note: the contact manifold does not include time of impact impulses, which can be 
/// arbitrarily large if the sub-step is small. Hence the impulse is provided explicitly 
/// in a separate data structure. 
/// Note: this is only called for contacts that are touching, solid, and awake. 
virtual void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) 
{ 
    B2_NOT_USED(contact); 
    B2_NOT_USED(impulse); 
} 

這可能是什麼AfterContact是基於,和它說的是,從用於推動身體回到了所有的衝動的中間結果原稿CCD的最初接觸位置(衝擊衝擊時間)基本不可用於您:(