Trong Box2D, tôi đã tò mò liệu có thể lấy một hộp giới hạn của một cơ thể đã được tạo ra trên thế giới hay không.
Về cơ bản, Cơ thể được tạo ra, nó tương tác với thế giới và như vậy. Và tôi cần cái hộp giới hạn của Cơ thể đó. Có thể không?
Trong Box2D, tôi đã tò mò liệu có thể lấy một hộp giới hạn của một cơ thể đã được tạo ra trên thế giới hay không.
Về cơ bản, Cơ thể được tạo ra, nó tương tác với thế giới và như vậy. Và tôi cần cái hộp giới hạn của Cơ thể đó. Có thể không?
Câu trả lời:
Trong Box2D, các cơ quan không có các hộp giới hạn liên kết với chúng, vật cố định làm. Vì vậy, bạn cần lặp đi lặp lại tất cả các đồ đạc và tạo AABB mới. Một cái gì đó như thế này:
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();
}
chỉ cần sử dụng vật cố aabb cũng bao gồm bán kính hình dạng - nếu bạn muốn có được aabb thật mà không có bán kính của hình dạng, hãy làm như thế này:
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();
}
shapeAABB.lowerBound = shapeAABB.lowerBound + r;
và shapeAABB.upperBound = shapeAABB.upperBound - r;
để có được hành vi mà tôi muốn.
Thực sự, một vòng lặp for thường tốt hơn cho việc lặp lại. Lấy câu trả lời của @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());
}
Biểu thức fixture
, được coi là boolean, là, tôi hiểu, tương đương với fixture != NULL
.
Đây là những gì tôi thường sử dụng:
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);
Đây là một số nút cha. Tôi thậm chí đã thêm nó vào nút (ví dụ: someNode) và nó dường như cũng hoạt động, chỉ cần đảm bảo chỉ số z của bạn đủ cao.
fixture->GetAABB()
không tồn tại, nhưngfixture->GetAABB(int32 childIndex)
có.