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)ทำ
Jonny

บนและล่างมุมบนและล่างใช่ไหม?
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();
}

ทำไมคุณไม่ต้องการได้รัศมีรูปร่าง ฉันเดิมคัดลอกแหล่งที่มาจากคำตอบนี้คิดว่ามันเป็นอย่างละเอียดมากขึ้นกว่าคำตอบอื่น ๆ แต่ตอนนี้ฉันได้พบว่ามันไม่ถูกต้องสำหรับกรณีของฉันและฉันอยากรู้อยากเห็นเกี่ยวกับการที่สถานการณ์รหัสนี้ควรจะใช้ใน.
มิทช์

ฉันเห็นว่านี่ใช้ Box2D API ที่ใหม่กว่า นั่นเป็นเหตุผลหนึ่งที่ต้องการคำตอบนี้ อย่างไรก็ตามเกี่ยวข้องกับสิ่งที่ฉันกล่าวถึงข้างต้นฉันต้องแสดงความคิดเห็นshapeAABB.lowerBound = shapeAABB.lowerBound + r;และshapeAABB.upperBound = shapeAABB.upperBound - r;รับพฤติกรรมที่ฉันต้องการ
มิทช์

0

จริงๆแล้วการวนซ้ำมักจะดีกว่าสำหรับการวนซ้ำ รับคำตอบของ @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());
}

การแสดงออกที่นำมาเป็นบูลีนคือผมเข้าใจเทียบเท่ากับfixturefixture != 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 ของคุณสูงพอ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.