Yes, it seems the java version is broken. I've rewritten the above program using the C++ version and it works as expected:
Code:
#define GL_GLEXT_PROTOTYPES 1
#include <assert.h>
#include <stdio.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glext.h>
#include <err.h>
#include <Box2D/Box2D.h>
static b2World *world;
static b2Vec2 gravity;
static b2Fixture *floor_fixture;
static b2Fixture *roof_fixture;
static b2Fixture *left_fixture;
static b2Fixture *right_fixture;
static b2Fixture *wheel_fixture;
static b2Fixture *box_fixture;
static b2WheelJoint *joint;
static void
init (void)
{
gravity.x = 0.0f;
gravity.y = -10.0f;
world = new b2World(gravity);
/*
* Ground
*/
{
b2BodyDef bd;
b2PolygonShape s;
b2Vec2 v;
bd.position.x = 20.0f;
bd.position.y = 2.0f;
bd.type = b2_staticBody;
b2Body *b = world->CreateBody(&bd);
v.x = 0.0f;
v.y = 0.0f;
s.SetAsBox(20.0f, 0.5f, v, 0.0f);
b2FixtureDef floor;
floor.density = 1.0f;
floor.friction = 0.5f;
floor.shape = &s;
floor_fixture = b->CreateFixture(&floor);
v.x = 0.0f;
v.y = 17.0f;
s.SetAsBox(20.0f, 0.5f, v, 0.0f);
b2FixtureDef roof;
roof.density = 1.0f;
roof.friction = 0.5f;
roof.shape = &s;
roof_fixture = b->CreateFixture(&roof);
v.x = -18.0f;
v.y = 0.0f;
s.SetAsBox(0.5f, 20.0f, v, 0.0f);
b2FixtureDef left;
left.density = 1.0f;
left.friction = 0.5f;
left.shape = &s;
left_fixture = b->CreateFixture(&left);
v.x = 18.0f;
v.y = 0.0f;
s.SetAsBox(0.5f, 20.0f, v, 0.0f);
b2FixtureDef right;
right.density = 1.0f;
right.friction = 0.5f;
right.shape = &s;
right_fixture = b->CreateFixture(&right);
}
/*
* Wheel
*/
{
b2CircleShape wheel_shape;
wheel_shape.m_radius = 2.0f;
b2FixtureDef wheel_fixture_def;
wheel_fixture_def.density = 1.0f;
wheel_fixture_def.friction = 0.5f;
wheel_fixture_def.shape = &wheel_shape;
b2BodyDef wheel_body;
wheel_body.position.x = 20.0f;
wheel_body.position.y = 10.0f;
wheel_body.type = b2_dynamicBody;
b2Body *b = world->CreateBody(&wheel_body);
wheel_fixture = b->CreateFixture(&wheel_fixture_def);
}
/*
* Box above wheel.
*/
{
b2PolygonShape box_shape;
b2Vec2 v;
v.x = 0.0f;
v.y = 0.0f;
box_shape.SetAsBox(1.0f, 1.0f, v, 0.0f);
b2BodyDef box_body;
box_body.position.x = 20.0f;
box_body.position.y = 15.0f;
box_body.type = b2_dynamicBody;
box_body.fixedRotation = true;
b2FixtureDef box_fixture_def;
box_fixture_def.density = 1.0f;
box_fixture_def.friction = 0.5f;
box_fixture_def.shape = &box_shape;
b2Body *b = world->CreateBody(&box_body);
box_fixture = b->CreateFixture(&box_fixture_def);
}
/*
* Joint.
*/
{
b2Vec2 v;
b2WheelJointDef jd;
v.x = 0.0f;
v.y = 1.0f;
jd.Initialize(
box_fixture->GetBody(),
wheel_fixture->GetBody(),
wheel_fixture->GetBody()->GetWorldCenter(),
v);
jd.motorSpeed = 100.0f;
jd.maxMotorTorque = 1000.0f;
jd.enableMotor = true;
joint = (b2WheelJoint *) world->CreateJoint(&jd);
}
}
static void drawCircle(float radius)
{
glBegin(GL_LINES);
{
for (int index = 0; index < 180; ++index) {
double x0 = radius * cos(index);
double y0 = radius * sin(index);
glVertex3d(x0, y0, 0.0f);
double x1 = radius * cos(index + 0.1);
double y1 = radius * sin(index + 0.1);
glVertex3d(x1, y1, 0.0f);
}
}
glEnd();
}
static void drawFixture(b2Fixture *fix)
{
b2Body *b = fix->GetBody();
b2Shape *s = fix->GetShape();
glPushMatrix();
{
b2Vec2 p = b->GetWorldCenter();
glColor3d(1.0f, 0.0f, 0.0f);
glTranslated(p.x, p.y, 0.0);
drawCircle(0.125f);
}
glPopMatrix();
glPushMatrix();
{
glColor3d(0.0f, 1.0f, 0.0f);
b2Shape::Type type = s->GetType();
switch (s->GetType()) {
case b2Shape::e_circle:
{
b2CircleShape *c = (b2CircleShape *) s;
b2Vec2 p = b->GetWorldPoint(c->m_p);
glTranslated(p.x, p.y, 0.0);
glRotated(b->GetAngle() * (180 / 3.14), 0, 0, 1);
drawCircle(c->m_radius);
glBegin(GL_LINES);
{
glVertex3d(0.0, 0.0, 0.0);
glVertex3d(0.0, 1.0, 0.0);
}
glEnd();
}
case b2Shape::e_polygon:
{
b2PolygonShape *ps = (b2PolygonShape *) s;
glBegin(GL_LINE_LOOP);
{
b2Vec2 *vs = ps->m_vertices;
for (int index = 0; index < ps->GetVertexCount(); ++index) {
b2Vec2 v = b->GetWorldPoint(vs[index]);
glVertex3d(v.x, v.y, 0.0);
}
}
glEnd();
}
}
}
glPopMatrix();
}
static void
display (void)
{
world->Step(1.0 / 60.0, 8, 4);
glClearColor(0.2, 0.2, 0.2, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 40, 0, 20, 0, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawFixture(floor_fixture);
drawFixture(roof_fixture);
drawFixture(left_fixture);
drawFixture(right_fixture);
drawFixture(wheel_fixture);
drawFixture(box_fixture);
drawJoint(joint);
glutSwapBuffers();
glutPostRedisplay();
}
int
main (int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize(640, 480);
glutCreateWindow("B2D");
glutDisplayFunc(display);
init();
glutMainLoop();
return 0;
}
I'll file a bug.