我只是好奇,如果我的身体有2个或更多的固定装置没有“连接在一起”,我怎么能在代码中明确地确定这个?这是我的意思的一个例子:
我标记了每个独特夹具的顶点,只是为了使它们完全清楚,这些是不相互共享顶点的独立形状。然而,它们组合成一个整体。正如您所看到的,两个灯具彼此非常接近或“接触”,并且一个灯具本身是分开的。我想知道如何在Box2D中查询正文的装置,以便能够在运行时找到它。
为了全面考虑这一点,它是用于创建和处理可破坏的物体。该图像粗略地表示在穿过身体中的一组固定器孔之后会发生什么。我需要查询以查看哪些灯具相互接触,以便我可以将一个机构分成两个,当然它们应该在那一点。
答案 0 :(得分:3)
如果您已准备好新灯具,则可以使用b2TestOverlap功能检查它们是否重叠。该函数可在b2Collision.h中找到:
/// Determine if two generic shapes overlap.
bool b2TestOverlap( const b2Shape* shapeA, int32 indexA,
const b2Shape* shapeB, int32 indexB,
const b2Transform& xfA, const b2Transform& xfB );
可以通过fixture-> GetShape()找到形状,并且多边形的索引参数将为零。 由于灯具位于同一主体上,最后两个参数都可以是body-> GetTransform()。
我自己从未使用过这个,所以我无法确切地告诉你,但是注意到这个函数的名称是'重叠',它可能不会为图中的A和B灯具的情况返回正数从技术上讲,我不认为它们是重叠的。如果是这种情况,我认为你是独立的,因为Box2D不提供任何“接触”测试。
顺便提一下Constantinius提到的联系人列表仅对不同身体碰撞时的灯具有效 - 同一身体上的灯具不会碰撞。
答案 1 :(得分:2)
在" 9.3访问联系人" 下的Box2D manual中,您可以使用GetContactList
功能访问正文的所有联系人:
for (b2ContactEdge* ce = myBody->GetContactList(); ce; ce = ce->next)
{
b2Contact* c = ce->contact;
...
}
在b2ContactEdge
和b2Contact
中,您可以找到实际的形状和标志,如果它们实际上正在触摸(b2Contact::IsTouching
)。
答案 2 :(得分:1)
我建议做这样的事情:
要获得准确的结果,您必须测试交叉点。在第一遍中,您可以仅比较灯具的重心,然后仅在COG位于较小距离内时计算所有线的交点。
另一种方法可能是栅格化场景。那么你可以使用类似模板缓冲区的东西来绘制栅格化像素。
模板将是一个大小(w * h)的数组,其中w和h是光栅化图像的宽度和高度,并且每个像素保持一个整数。
为每个像素初始化模板缓冲区为0。
对于您“绘制”的每个光栅化灯具,您只需增加其所有像素位置的缓冲值。
所以最后模板缓冲区在没有被任何夹具占据的位置包含0,其中只有一个夹具位于该位置,而对于任何更大的值,你有交叉点。
这种方法的复杂性主要取决于所选择的光栅化分辨率。
答案 3 :(得分:0)
执行此操作的另一种方法(作为其他人之前建议使用b2TestOverlap
的替代方法),将使用b2CollidePolygons
函数(来自b2Collision.h
)。您可以在灯具的多边形形状上使用它,然后查看b2Manifold
' pointCount
字段是否大于零。
这里有一些C ++ 11之前的代码示例(我没有编译和测试过,所以希望它还没有得到foobar' ed):
bool isTouching(const b2PolygonShape& polygonA, const b2Transform& xfA, const b2PolygonShape& polygonB, const b2Transform& xfb)
{
b2Manifold manifold;
b2CollidePolygons(&manifold, &polygonA, xfA, &polygonB, xfB);
return manifold.pointCount > 0;
}
bool isPolygonFixturesTouching(const b2Fixture& fixtureA, const b2Fixture& fixtureB)
{
const b2Shape* shapeA = fixtureA.GetShape();
const b2Shape* shapeB = fixtureB.GetShape();
if (shapeA->GetType() == b2Shape::e_polygon && shapeB->GetType() == b2Shape::e_polygon)
{
const b2Body* bodyA = fixtureA.GetBody();
const b2Transform& xfA = bodyA->GetTransform();
const b2Body* bodyB = fixtureB.GetBody();
const b2Transform& xfB = bodyB->GetTransform();
return isTouching(*(static_cast<b2PolygonShape*>(shapeA)), xfA, *(static_cast<b2PolygonShape*>(shapeB)), xfB);
}
return false;
}
int main()
{
...
if (isPolygonFixturesTouching(fixtureA, fixtureB))
{
std::cout << "hooray!" << std::endl;
}
}
注意:我刚试过的一些原始时序测试比较b2TestOverlap
与b2CollidePolygons
显示b2TestOverlap
为4或5倍更快(比b2CollidePolygons
)。鉴于前者只是在寻找任何重叠,而后者正在计算碰撞流形,我认为速度差异并不令人惊讶。无论如何,这个故事的寓意似乎是b2TestOverlap
可能是一个更好的功能,如果你只是想知道2个灯具是否正在触摸,而b2CollidePolygons
则更有用如果你还想知道更多的东西,比如2个灯具是如何接触的。