Box2d 看似随机创建特定的主体和夹具
Box2d creates specific body and fixture seemingly at random
我使用 Libgdx 和 Box2d 创建了一个类似于 Not Tetris 2 的 android 应用程序。
它可以成功地从世界中移除一个切片,这显然涉及复制多个物体和 destroying/creating fixtures。然而,看似随机地,一个带有 2x2 固定装置的物体会出现。 body 和 fixture 在创建时使用与其周围对象相关的信息显示,因此我将其创建范围缩小到以下功能:
Body duplicateBody(Body original){
BodyDef d = new BodyDef();
d.position.set(original.getPosition());
d.angle = original.getAngle();
d.linearVelocity.set(original.getLinearVelocity());
d.angularVelocity = original.getAngularVelocity();
Body dup = world.createBody(d);
dup.setType(BodyDef.BodyType.DynamicBody);
return dup;
}
我在 2 个不同的上下文中使用此函数:
- 如果 "slice" 将主体一分为二,则制作主体的副本 -- 然后我将下面的固定装置转移到它上面。
- 当夹具在线下方时,它会被添加到为下方的夹具创建的主体中
- 当固定装置组分开时制作主体的副本
我注释掉了负责第三个实例的代码,但仍然生成了 2x2 框,所以这里是与其他函数相关的函数:
...
if (below && !above) {
//copy fixture, add copy to lower body and remove original
Body top = fixture.getBody();
FixtureDef n = new FixtureDef();
PolygonShape s = new PolygonShape();
s.set(getLocalVerticesOfFixture(fixture));
n.shape = s;
n.density = fixture.getDensity();
//create lower body if a lower one doesn't already exist
if (!topBottomPairs.containsKey(top)) {
Body dup = duplicateBody(top);
topBottomPairs.put(top, dup);
}
//delete fixture
remove.add(fixture);
Fixture f = topBottomPairs.get(top).createFixture(n);
s.dispose();
}
...
if (below && above) {
//copy fixture, add copy to lower body, but keep original on upper as it needs to split
FixtureDef n = new FixtureDef();
PolygonShape s = new PolygonShape();
s.set(getLocalVerticesOfFixture(fixture));
n.shape = s;
n.density = fixture.getDensity();
Body top = fixture.getBody();
//create lower body if a lower one doesn't already exist
if (!topBottomPairs.containsKey(top)) {
Body dup = duplicateBody(top);
topBottomPairs.put(top, dup);
}
Fixture second = topBottomPairs.get(top).createFixture(n);
s.dispose();
}
....
private Vector2[] getLocalVerticesOfFixture(Fixture fixture) {
PolygonShape shape = ((PolygonShape) fixture.getShape());
Vector2[] localVertices = new Vector2[shape.getVertexCount()];
for (int i = 0; i < shape.getVertexCount(); i++) {
localVertices[i] = new Vector2();
shape.getVertex(i, localVertices[i]);
}
return localVertices;
}
我还有这个删除夹具功能,它在我要删除的所有灯具上运行:
private void smartDeleteFixture(Fixture f){
f.getBody().destroyFixture(f);
if(f.getBody().getFixtureList().size == 0){
world.destroyBody(f.getBody());
}
}
我没有在任何地方创建顶点,更不用说 2x2 形状的固定装置了。我想知道这个复制函数是否有任何缺陷,或者我是否偶然发现了 box2d 使用的一些 "default shape"。
编辑:我删除了与 box2d 物体操作无关的任何内容。希望有帮助
删除了这个问题,因为我决定进行一次重大的重新编码,希望这能解决我的问题。它没有,但我找到了原因。
我查看了 box2d,在多边形形状中发现了几个与此类似的代码实例 class:
if (n < 3)
{
// Polygon is degenerate.
b2Assert(false);
SetAsBox(1.0f, 1.0f);
return;
}
这些实例在各种操作后检查顶点的数量,如果少于 3 个,则将形状变成 2x2 的框。这些操作之一使形状凸起。另一个检查顶点是否靠近(靠近 0.0025f),如果是则删除一个。
就我而言,问题很简单。我的一些顶点彼此之间的距离小于 0.0025f,导致它们被删除,顶点数下降到 3 以下,一个断言被忽略,然后我的形状变成了一个 2x2 的盒子。我希望这对某人有所帮助。
我使用 Libgdx 和 Box2d 创建了一个类似于 Not Tetris 2 的 android 应用程序。
它可以成功地从世界中移除一个切片,这显然涉及复制多个物体和 destroying/creating fixtures。然而,看似随机地,一个带有 2x2 固定装置的物体会出现。 body 和 fixture 在创建时使用与其周围对象相关的信息显示,因此我将其创建范围缩小到以下功能:
Body duplicateBody(Body original){
BodyDef d = new BodyDef();
d.position.set(original.getPosition());
d.angle = original.getAngle();
d.linearVelocity.set(original.getLinearVelocity());
d.angularVelocity = original.getAngularVelocity();
Body dup = world.createBody(d);
dup.setType(BodyDef.BodyType.DynamicBody);
return dup;
}
我在 2 个不同的上下文中使用此函数:
- 如果 "slice" 将主体一分为二,则制作主体的副本 -- 然后我将下面的固定装置转移到它上面。
- 当夹具在线下方时,它会被添加到为下方的夹具创建的主体中
- 当固定装置组分开时制作主体的副本
我注释掉了负责第三个实例的代码,但仍然生成了 2x2 框,所以这里是与其他函数相关的函数:
...
if (below && !above) {
//copy fixture, add copy to lower body and remove original
Body top = fixture.getBody();
FixtureDef n = new FixtureDef();
PolygonShape s = new PolygonShape();
s.set(getLocalVerticesOfFixture(fixture));
n.shape = s;
n.density = fixture.getDensity();
//create lower body if a lower one doesn't already exist
if (!topBottomPairs.containsKey(top)) {
Body dup = duplicateBody(top);
topBottomPairs.put(top, dup);
}
//delete fixture
remove.add(fixture);
Fixture f = topBottomPairs.get(top).createFixture(n);
s.dispose();
}
...
if (below && above) {
//copy fixture, add copy to lower body, but keep original on upper as it needs to split
FixtureDef n = new FixtureDef();
PolygonShape s = new PolygonShape();
s.set(getLocalVerticesOfFixture(fixture));
n.shape = s;
n.density = fixture.getDensity();
Body top = fixture.getBody();
//create lower body if a lower one doesn't already exist
if (!topBottomPairs.containsKey(top)) {
Body dup = duplicateBody(top);
topBottomPairs.put(top, dup);
}
Fixture second = topBottomPairs.get(top).createFixture(n);
s.dispose();
}
....
private Vector2[] getLocalVerticesOfFixture(Fixture fixture) {
PolygonShape shape = ((PolygonShape) fixture.getShape());
Vector2[] localVertices = new Vector2[shape.getVertexCount()];
for (int i = 0; i < shape.getVertexCount(); i++) {
localVertices[i] = new Vector2();
shape.getVertex(i, localVertices[i]);
}
return localVertices;
}
我还有这个删除夹具功能,它在我要删除的所有灯具上运行:
private void smartDeleteFixture(Fixture f){
f.getBody().destroyFixture(f);
if(f.getBody().getFixtureList().size == 0){
world.destroyBody(f.getBody());
}
}
我没有在任何地方创建顶点,更不用说 2x2 形状的固定装置了。我想知道这个复制函数是否有任何缺陷,或者我是否偶然发现了 box2d 使用的一些 "default shape"。
编辑:我删除了与 box2d 物体操作无关的任何内容。希望有帮助
删除了这个问题,因为我决定进行一次重大的重新编码,希望这能解决我的问题。它没有,但我找到了原因。
我查看了 box2d,在多边形形状中发现了几个与此类似的代码实例 class:
if (n < 3)
{
// Polygon is degenerate.
b2Assert(false);
SetAsBox(1.0f, 1.0f);
return;
}
这些实例在各种操作后检查顶点的数量,如果少于 3 个,则将形状变成 2x2 的框。这些操作之一使形状凸起。另一个检查顶点是否靠近(靠近 0.0025f),如果是则删除一个。
就我而言,问题很简单。我的一些顶点彼此之间的距离小于 0.0025f,导致它们被删除,顶点数下降到 3 以下,一个断言被忽略,然后我的形状变成了一个 2x2 的盒子。我希望这对某人有所帮助。