编辑 2:http: //youtu.be/KiCzUZ69gpA - 正如您在此视频中看到的,当我还为每个身体渲染一些文本时,晃动效果会被放大。观察当每个物体在其附近渲染一些文本时,地面主体(蓝色)如何剧烈晃动,以及在文本渲染被注释掉时它是如何不剧烈晃动的。这个必须连接!
编辑:我对原始问题做了两个重要的补充:我添加了我的渲染函数和相机(翻译)方法,我认为错误实际上是存在的,而不是在 JBox2D 中。
我正在尝试模拟和渲染许多与RevoluteJoint
s 连接的随机体(2-20)。一个主体可以连接到多个其他主体,并且没有单独的结构,即所有主体都是相互连接的。
但是,在观看实时渲染时,它非常不稳定且不稳定。我的意思是,物体的位置(或者角度)似乎无缘无故地随机波动,使模拟看起来不稳定。
这是我正在观察的视频:
注意中间的正方形和旋转的矩形。中间的正方形以看似随机的间隔轻微地前后移动,旋转的矩形非常抖动(看看它旋转的点)。
这种影响可能是什么原因造成的?是 (J)Box2D 的一些已知问题,还是我的渲染系统的问题?我认为我以某种方式错误地配置了物理引擎,但渲染系统中的一些浮点数学也可能是罪魁祸首。
以下是我创建身体和关节的方式:
private Body setPart(Part part) {
// body definition
BodyDef bd = new BodyDef();
bd.position.set(0f, -10f);
bd.angle = 0f;
bd.type = BodyType.DYNAMIC;
// define shape of the body.
PolygonShape Shape = new PolygonShape();
Shape.setAsBox(part.width / 2, part.height / 2);
// define fixture of the body.
FixtureDef fd = new FixtureDef();
Filter filter = new Filter();
filter.groupIndex = -1;
fd.filter = filter;
fd.shape = Shape;
fd.density = 0.5f;
fd.friction = 0.3f;
fd.restitution = 0.5f;
// create the body and add fixture to it
Body body = world.createBody(bd);
body.createFixture(fd);
body.setUserData(new PartUserData());
return body;
}
private void setJoint(PartJoint partJoint) {
Body bodyOne = partToBody.get(partJoint.partOne);
Body bodyTwo = partToBody.get(partJoint.partTwo);
RevoluteJointDef jointDef = new RevoluteJointDef();
jointDef.bodyA = bodyOne;
jointDef.bodyB = bodyTwo;
jointDef.localAnchorA = partJoint.partOne
.getAnchor(partJoint.percentOne);
jointDef.localAnchorB = partJoint.partTwo
.getAnchor(partJoint.percentTwo);
// rotation
jointDef.lowerAngle = GeomUtil.circle(partJoint.rotateFrom);
jointDef.upperAngle = GeomUtil.circle(partJoint.rotateTo);
jointDef.enableLimit = true;
jointDef.maxMotorTorque = 10.0f; // TODO limit maximum torque
jointDef.motorSpeed = GeomUtil.circle(partJoint.angularVelocity);
jointDef.enableMotor = true;
world.createJoint(jointDef);
}
时间步长为0.01f
。
这是我绘制身体的方式:
private void drawBody(Body body) {
// setup the transforms
Vector position = camera.translate(body.getPosition());
currentGraphics.translate(position.x, position.y);
currentGraphics.rotate(body.getAngle());
// do the actual rendering
for (Fixture fixture = body.getFixtureList(); fixture != null; fixture = fixture
.getNext()) {
PolygonShape shape = (PolygonShape) fixture.getShape();
if (body.getUserData() instanceof PartUserData) {
fillShape(shape, partFillColor);
currentGraphics.setStroke(partOutlineStroke);
outlineShape(shape, partOutlineColor);
} else {
fillShape(shape, groundFillColor);
outlineShape(shape, groundOutlineColor);
}
}
// clean up
currentGraphics.rotate(-body.getAngle());
currentGraphics.translate(-position.x, -position.y);
currentGraphics.setColor(defaultColor);
currentGraphics.setStroke(defaultStroke);
}
我认为问题可能是我处理所有身体渲染的方式。
这是每个主体的算法: 1. 将Graphics2D
对象平移到其位置 2. 将其旋转body.getAngle()
3. 渲染主体 4. 将图形向后旋转 5. 将图形向后平移
难道是在所有这些转换中出现了问题吗?
当我删除对相机方法的调用时,效果似乎已经降低。这些是相关的相机方法:
public Vector translate(Vec2 worldPosition) {
Vector point = new Vector();
point.x = (int) (worldPosition.x * pixelsPerMeter) - position.x;
point.y = (int) (worldPosition.y * pixelsPerMeter) - position.y;
point.x = (int) (point.x * zoom);
point.y = (int) (point.y * zoom);
point.x += renderer.getWidth() / 2;
point.y += renderer.getHeight() / 2;
return point;
}
public Vector translateRelative(Vec2 worldPosition) {
Vector point = new Vector();
point.x = (int) (worldPosition.x * pixelsPerMeter);
point.y = (int) (worldPosition.y * pixelsPerMeter);
point.x = (int) (point.x * zoom);
point.y = (int) (point.y * zoom);
return point;
}
但是它们的哪一部分会引起问题?