Box2D Bir Vücudun Sınırlayıcı Kutusu


12

Box2D'de, dünyada zaten yaratılmış bir vücudun sınırlayıcı kutusunu almanın mümkün olup olmadığını merak ettim.

Temel olarak, Beden yaratılır, dünyayla ve benzerleriyle etkileşime girer. Ve vücudun sınırlayıcı kutusuna ihtiyacım vardı. Mümkün mü?

Yanıtlar:


11

Box2D'de, gövdelerin kendileriyle ilişkili sınırlayıcı kutuları yoktur, fikstür de. Yani tüm armatürleri tekrarlamanız ve yeni bir AABB oluşturmanız gerekiyor. Bunun gibi bir şey:

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
Bu gerçekten doğru mu? Kullandığım box2d'de fixture->GetAABB()mevcut değil, bir fixture->GetAABB(int32 childIndex)yok.
Jonny

ve alt köşeler üst ve alt sınırlar mı?
jokoon

1

sadece fikstür aabb'ı kullanmak da şekil yarıçapını içerir - eğer şekil yarıçapı olmadan gerçek aabb almak istiyorsanız, bunu şöyle yapın:

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

Neden şekil yarıçapını almak istemezsiniz? Başlangıçta bu cevaptan kaynağı kopyaladım, diğer cevaplardan daha kapsamlı olduğunu düşündüm, ama şimdi benim durumum için doğru olmadığını buldum ve bu kodun hangi senaryoda kullanılması gerektiğini merak ediyorum.
Mitch

Ancak bunun daha yeni Box2D API'sini kullandığını görüyorum. Bu cevabı tercih etmenizin bir nedeni bu. Ancak, yukarıda bahsettiğim şeyle ilgili olarak, yorum yapmak shapeAABB.lowerBound = shapeAABB.lowerBound + r;ve shapeAABB.upperBound = shapeAABB.upperBound - r;istediğim davranışı elde etmek zorunda kaldım.
Mitch

0

Gerçekten, bir for döngüsü, yineleme için genellikle daha iyidir. @Noel yanıtı alarak:

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

fixtureBoolean olarak alınan ifade , anlıyorum fixture != NULL.


0

Genelde kullandığım şey bu:

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

Bu bir üst düğüm. Ben bile bu düğümün kendisine ekledim (örn. SomeNode) ve bu da işe yarıyor gibi görünüyor, sadece z-endeksinizin yeterince yüksek olduğundan emin olun.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.