Box2D Ottieni la Bounding Box of a Body


12

In Box2D, ero curioso di sapere se è possibile ottenere un riquadro di delimitazione di un corpo già creato nel mondo.

Quindi, fondamentalmente, il Corpo è stato creato, interagisce con il mondo e così via. E avevo bisogno del riquadro di delimitazione di quel Corpo. È possibile?

Risposte:


11

In Box2D, ai corpi non sono associate caselle di delimitazione, ad esempio. Quindi è necessario iterare su tutti gli infissi e generare un nuovo AABB. Qualcosa come questo:

b2AABB aabb;
aabb.lowerBound = b2Vec2(FLT_MAX,FLT_MAX);
aabb.upperBound = b2Vec2(-FLT_MAX,-FLT_MAX); 
b2Fixture* fixture = body->GetFixtureList();
while (fixture != NULL)
{
    aabb.Combine(aabb, fixture->GetAABB());
    fixture = fixture->GetNext();
}

1
È davvero corretto? Nel box2d che sto usando, fixture->GetAABB()non esiste, ma fixture->GetAABB(int32 childIndex)esiste.
Jonny

sono in alto e in basso gli angoli superiori e inferiori?
jokoon

1

il solo utilizzo del dispositivo aabb include anche il raggio della forma - se vuoi ottenere il vero aabb senza il raggio della forma, fallo in questo modo:

b2AABB aabb;
b2Transform t;
t.SetIdentity();
aabb.lowerBound = b2Vec2(FLT_MAX,FLT_MAX);
aabb.upperBound = b2Vec2(-FLT_MAX,-FLT_MAX); 
b2Fixture* fixture = body->GetFixtureList();
while (fixture != nullptr) {
     const b2Shape *shape = fixture->GetShape();
     const int childCount = shape->GetChildCount();
     for (int child = 0; child < childCount; ++child) {
            const b2Vec2 r(shape->m_radius, shape->m_radius);
            b2AABB shapeAABB;
            shape->ComputeAABB(&shapeAABB, t, child);
            shapeAABB.lowerBound = shapeAABB.lowerBound + r;
            shapeAABB.upperBound = shapeAABB.upperBound - r;
            aabb.Combine(shapeAABB);
    }
    fixture = fixture->GetNext();
}

Perché non vorresti ottenere il raggio della forma? Inizialmente ho copiato la fonte da questa risposta, pensando che fosse più approfondita delle altre risposte, ma ora ho scoperto che non è corretto per il mio caso, e sono curioso di sapere in quale scenario dovrebbe essere usato questo codice.
Mitch

Vedo che questo utilizza però la più recente API Box2D. Questa è una ragione per preferire questa risposta. Tuttavia, in relazione a ciò che ho menzionato sopra, ho dovuto commentare shapeAABB.lowerBound = shapeAABB.lowerBound + r;e shapeAABB.upperBound = shapeAABB.upperBound - r;ottenere il comportamento che volevo.
Mitch,

0

In realtà, un ciclo for è di solito migliore per l'iterazione. Prendendo la risposta di @noel:

b2AABB aabb;
aabb.lowerBound = b2Vec2(FLT_MAX,FLT_MAX);
aabb.upperBound = b2Vec2(-FLT_MAX,-FLT_MAX); 
for (b2Fixture* fixture = body->GetFixtureList(); fixture; fixture = fixture->GetNext())
{
    aabb.Combine(aabb, fixture->GetAABB());
}

L'espressione fixture, considerata booleana, è, a mio avviso, equivalente fixture != NULL.


0

Questo è ciò che generalmente utilizzo:

Rect aabb = someNode->getBoundingBox();
DrawNode* drawNode = DrawNode::create();
drawNode->drawRect(aabb.origin, aabb.origin + aabb.size, Color4F(1, 0, 0, 1));
this->addChild(drawNode, 100);

Dove questo è un nodo genitore. Ho anche aggiunto questo al nodo stesso (ad esempio someNode) e anche quello sembra funzionare, assicurati solo che il tuo indice z sia abbastanza alto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.