Box2D Dapatkan Bounding Box of a Body

12

Di Box2D, saya ingin tahu apakah mungkin untuk mendapatkan kotak pembatas tubuh yang sudah dibuat di dunia.

Jadi pada dasarnya, Tubuh diciptakan, ia berinteraksi dengan dunia dan semacamnya. Dan aku membutuhkan kotak pembatas tubuh itu. Apa itu mungkin?

Colin Gislason
sumber

Jawaban:

11

Di Box2D, tubuh tidak memiliki kotak terikat yang terkait dengannya, fixture lakukan. Jadi, Anda perlu mengulangi semua perlengkapan dan menghasilkan AABB baru. Sesuatu seperti ini:

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();
}
Noel Llopis
sumber
1
Apakah ini benar? Dalam box2d yang saya gunakan, fixture->GetAABB()tidak ada, tetapi fixture->GetAABB(int32 childIndex)tidak.
Jonny
Apakah upperbound dan lowerbound adalah sudut kiri dan kanan?
jokoon
1

hanya menggunakan fixture aabb juga termasuk jari-jari bentuk - jika Anda ingin mendapatkan aabb nyata tanpa jari-jari bentuknya, lakukan seperti ini:

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();
}
Martin Gerhardy
sumber
Mengapa Anda tidak ingin mendapatkan radius bentuk? Saya awalnya menyalin sumber dari jawaban ini, berpikir itu lebih menyeluruh daripada jawaban lain, tetapi sekarang saya telah menemukan bahwa itu tidak benar untuk kasus saya, dan saya ingin tahu tentang skenario mana kode ini harus digunakan.
Mitch
Saya melihat bahwa ini menggunakan API Box2D yang lebih baru. Itulah salah satu alasan untuk memilih jawaban ini. Namun, terkait dengan apa yang saya sebutkan di atas, saya harus berkomentar shapeAABB.lowerBound = shapeAABB.lowerBound + r;dan shapeAABB.upperBound = shapeAABB.upperBound - r;untuk mendapatkan perilaku yang saya inginkan.
Mitch
0

Sungguh, loop untuk biasanya lebih baik untuk iterasi. Mengambil jawaban @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());
}

Ekspresi fixture, diambil sebagai boolean, adalah, saya mengerti, setara dengan fixture != NULL.

GKFX
sumber
0

Inilah yang biasanya saya gunakan:

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);

Di mana ini adalah beberapa simpul orangtua. Saya bahkan telah menambahkan ini ke node itu sendiri (misalnya someNode) dan itu juga tampaknya berfungsi, pastikan saja z-index Anda cukup tinggi.

nikc
sumber