2012-06-02 81 views
0

我有一些代碼導致box2d物理模擬在這段代碼被調用一次後永遠口吃。我對它進行了性能測試,OSSpinLockLock花了很多時間。 b2Island :: Solve和其他一些box2d函數正在導致這花費了很多時間。我不確定這裏發生了什麼事。對於具有更多重疊靜態物體的地圖,這種效果似乎更糟,然後映射的重疊靜態物體更少。引起口吃的代碼如下:Box2d物理模擬口吃

for (b2Body*b = currentWorld->GetBodyList(); b!=nil; b = b->GetNext()) { 



    float distance = 0; 
    float strength = 0; 
    float force = 0; 
    float angle = 0; 

    CGPoint curPos = [Helper toPixels:b->GetWorldCenter()]; 

    distance = ccpDistance(selfPos, curPos); 
    if (distance>maxDistance) { 
     distance = maxDistance - 0.01; 
    } 

    //strength = (maxDistance - distance)/maxDistance; 
    strength = (distance - maxDistance)/maxDistance; 
    force = strength * maxForce; 
    angle = atan2f(selfPos.y - curPos.y, selfPos.x - curPos.x); 
    //b2Vec2 forceVec = [Helper toMeters:force]; 

    //CCLOG(@"strength = %f force = %f angle = %f distance = %f",strength,angle,force, distance); 
    b->ApplyLinearImpulse(b2Vec2(cosf(angle) * force, sinf(angle) * force), b->GetPosition()); 
    BodyNode * bn = (BodyNode*)b->GetUserData(); 
    if ([bn isKindOfClass:[Soldier class]]) { 
     ((Soldier*)bn).health-=abs(force*(damage * kRocketDamageFactor)); //used to be 50 
    } 
    if ([bn isKindOfClass:[BaseAI class]]) { 
     ((BaseAI*)bn).health-=abs(force*(damage * kRocketDamageFactor)); 
    } 
    if ([bn isKindOfClass:[BaseLevelObject class]]) { 
     if (((BaseLevelObject*)bn).takesDamageFromBullets == YES) { 
      ((BaseLevelObject*)bn).health-=abs(force*(damage * kRocketDamageFactor)); 
     } 

    } 

我懷疑ApplyLinearImpulse部分是什麼原因造成的口吃,因爲它涉及到物理學的唯一的事情。我剛剛評論了整個循環,口吃從來沒有出現過。但是,一旦我用相同的代碼爆炸了其他一些爆炸物,就出現了口吃。重疊的靜態b2body對象會減慢物理模擬的速度嗎?

+0

確認。導致抖動的是ApplyLinearImpulse函數。 –

+0

我進行了另一次性能測試,並肯定與抖動有關的過程是b2PairLessThan(b2Pair const&,b2Pair const&)。當抖動不存在時,這個過程甚至不會出現在前50位。導致抖動的代碼(上面的大樣本)是從b2ContactListener的BeginContact函數中調用的。 –

回答

0

這個問題是由代碼給出的所有物體遠離最大距離的一個小點擊爆炸。我不確定爲什麼這會導致物理模擬結果,但添加continue語句代替distance = maxDistance - 0.01;解決了這個問題。