Box2D Отримайте обмежувальну коробку тіла


12

У Box2D мені було цікаво, чи можна отримати обмежувальний ящик тіла, вже створеного у світі.

Таким чином, Тіло створене, воно взаємодіє зі світом і таким. І мені потрібна була обмежувальна скринька Тіла. Це можливо?

Відповіді:


11

У Box2D тіла не мають пов'язаних з ними обмежувальних коробок, як це робиться кріплення. Тож вам потрібно перебрати всі світильники та створити новий AABB. Щось на зразок цього:

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
Це дійсно правильно. У box2d, який я використовую, fixture->GetAABB()не існує, але є fixture->GetAABB(int32 childIndex).
Джоні

- верхній і нижній кути верхнього і прямого кутів?
jokoon

1

просто використовуючи кріплення aabb також включає радіус форми - якщо ви хочете отримати справжній aabb без радіуса форми, зробіть це так:

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

Чому б ви не хотіли отримати радіус форми? Я спочатку скопіював джерело з цієї відповіді, вважаючи, що це більш ретельно, ніж інші відповіді, але тепер я виявив, що це неправильно для моєї справи, і мені цікаво, у якому сценарії цей код слід використовувати.
Мітч,

Я бачу, що для цього використовується новіший API Box2D. Це одна з причин віддати перевагу цій відповіді. Однак, пов'язане з тим, що я згадував вище, мені довелося прокоментувати shapeAABB.lowerBound = shapeAABB.lowerBound + r;та shapeAABB.upperBound = shapeAABB.upperBound - r;отримати поведінку, яку я хотів.
Мітч

0

Дійсно, цикл for for, як правило, краще для ітерації. Беручи відповідь @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());
}

Вираз fixture, сприйнятий як булевий, є, я розумію, рівнозначним fixture != NULL.


0

Це те, що я зазвичай використовую:

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

Де це якийсь батьківський вузол. Я навіть додав це до самого вузла (наприклад, деякий вузол), і це, здається, працює, просто переконайтеся, що ваш z-індекс досить високий.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.