Really weird issue in a jbox2d application

Discuss issues specific the Java port of Box2D
Finalspace
Posts: 5
Joined: Sat Aug 02, 2014 10:53 am

Really weird issue in a jbox2d application

Postby Finalspace » Sat Aug 02, 2014 11:11 am

Hi there,

i am currently playing around with jbox2d and i got a weird issue already :-(
My simple demo of creating a simple scene with some falling boxes either does not behave correctly or the rendering is completly off.
There are gaps around every body and the gravity affection is too much for a vector of (0, -10) and locked fps of 60.

First i had integrated jbox2d into my existing game engine, but encountered that issues, so i decided to create a one class sample app to test if the same behavior occurs and it does :-(

Here is a video which shows the problem:

http://www.youtube.com/watch?v=oRJwfYilnJQ

and here is the one class file source (requires LWJGL and JBox2D):

Code: Select all

import java.io.File;

import org.jbox2d.collision.AABB;
import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.collision.shapes.Shape;
import org.jbox2d.collision.shapes.ShapeType;
import org.jbox2d.common.Transform;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.Fixture;
import org.jbox2d.dynamics.FixtureDef;
import org.jbox2d.dynamics.World;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;

public class Box2D_LWJGL {
   private final String OS = System.getProperty("os.name").toLowerCase();
   
   final float rad2deg = 180f / (float)Math.PI;
   final float deg2rad = (float)Math.PI / 180f;
   
   // Window
   int w;
   int h;
   
   // Delta calculation stuff
   final float framerate = 60.0f;
   final float dt = 1.0f / framerate;
   final float nanoToSecs = 1.0f / 1000000000.0f;
   long last;
   float accum;

   // Fps calculation stuff
   long lastFpsTime;
   int frames;
   double fps;
   
   // Box2d
   World world;
   
   public Box2D_LWJGL() {
      w = 800;
      h = 600;
      last = 0;
      accum = 0.0f;
      lastFpsTime = 0;
      frames = 0;
      fps = 0.0;
   }
   
   public String getNativeName() throws LWJGLException {
      if (OS.indexOf("win") > -1) {
         return "windows";
      } else if (OS.indexOf("linux") > -1) {
         return "linux";
      }
      throw new LWJGLException("Platform '" + OS + "' is not supported!");
   }
   
   private Body createBox(float x, float y, float angle, float hw, float hh, BodyType type) {
      BodyDef def = new BodyDef();
      def.position.set(x, y);
      def.angle = angle * deg2rad;
      def.type = type;
      
      PolygonShape shape = new PolygonShape();
      shape.setAsBox(hw, hh);
      
      FixtureDef fixDef = new FixtureDef();
      fixDef.friction = 1f; // 100% friction - so no tangent impulses
      fixDef.restitution = 0f; // No bounciness
      fixDef.density = 1f;
      fixDef.shape = shape;
      
      Body body = world.createBody(def);
      body.createFixture(fixDef);
      return body;
   }
   
   private void init() {
      GL11.glMatrixMode(GL11.GL_MODELVIEW);
      GL11.glClearColor(0f, 0f, 0.2f, 1f);
      
      GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
      
      world = new World(new Vec2(0f, -10f));
      world.setAllowSleep(true);
      world.setContinuousPhysics(true);
      
      final float thickness = 0.025f;
      float bottom = -0.5f + thickness;
      
      createBox(0f, -0.5f, 0f, 1f, thickness, BodyType.STATIC);
      createBox(-0.85f, 0f, 90f, 0.75f, thickness, BodyType.STATIC);
      createBox(0.85f, 0f, 90f, 0.75f, thickness, BodyType.STATIC);
      
      final float rad = 0.05f;
      final float jr = rad * 0.5f;
      final int count = 100;
      float x = 0f, y = bottom + rad * 2f * 1.1f;
      for (int i = 0; i < count; i++) {
         x = -jr + (float)Math.random() * jr * 2f;
         createBox(x, y, 0f, rad, rad, BodyType.DYNAMIC);
         y += rad * 2f * 1.5f;
      }
   }
   
   private void update(float dt) {
      world.step(dt, 6, 3);
   }
   
   private void drawAABB(AABB aabb) {
      float hw = (aabb.upperBound.x - aabb.lowerBound.x) * 0.5f;
      float hh = (aabb.upperBound.y - aabb.lowerBound.y) * 0.5f;
      GL11.glEnable(GL11.GL_BLEND);
      GL11.glColor4f(0f, 1f, 0f, 0.25f);
      GL11.glBegin(GL11.GL_LINE_LOOP);
      GL11.glVertex2f(hw, hh);
      GL11.glVertex2f(-hw, hh);
      GL11.glVertex2f(-hw, -hh);
      GL11.glVertex2f(hw, -hh);
      GL11.glEnd();
      GL11.glDisable(GL11.GL_BLEND);
   }
   
   private void drawShape(Shape shape) {
      if (shape.getType().equals(ShapeType.POLYGON)) {
         PolygonShape polyShape = (PolygonShape) shape;
         int vertexCount = polyShape.getVertexCount();
         Vec2[] vertices = polyShape.getVertices();
         GL11.glColor3f(1f, 1f, 1f);
         GL11.glBegin(GL11.GL_LINE_LOOP);
         for (int i = 0; i < vertexCount; i++) {
            GL11.glVertex2f(vertices[i].x, vertices[i].y);
         }
         GL11.glEnd();
      }
   }

   private void draw(){
      GL11.glLoadIdentity();
      GLU.gluPerspective(45f, (float)Display.getWidth()/Display.getHeight(), 0.1f, 100f);
      GL11.glTranslatef(0f, 0f, -2f);

      GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

      // Bodies
      Body body = world.getBodyList();
      while (body != null) {
         Transform transform = body.getTransform();
         GL11.glPushMatrix();
         GL11.glTranslatef(transform.p.x, transform.p.y, 0f);
         GL11.glRotatef(transform.q.getAngle() * rad2deg, 0f, 0f, 1f);
         Fixture fixture = body.getFixtureList();
         while (fixture != null) {
            drawShape(fixture.getShape());
            fixture = fixture.m_next;
         }
         GL11.glPopMatrix();
         body = body.m_next;
      }
      
      // AABBs
      body = world.getBodyList();
      while (body != null) {
         Transform transform = body.getTransform();
         GL11.glPushMatrix();
         GL11.glTranslatef(transform.p.x, transform.p.y, 0f);
         Fixture fixture = body.getFixtureList();
         while (fixture != null) {
            AABB aabb = fixture.getAABB(0);
            drawAABB(aabb);
            fixture = fixture.m_next;
         }
         GL11.glPopMatrix();
         body = body.m_next;
      }
   }
   
   private void tick() {
      // Fps
      long curFpsTime = System.currentTimeMillis();
      frames++;
      if (curFpsTime > lastFpsTime + 1000) {
         fps = frames * 1000 / (curFpsTime - lastFpsTime);
         Display.setTitle("Game - " + String.format("%3.2f fps", fps));
         lastFpsTime = curFpsTime;
         frames = 0;
      }

      // Delta time
      long now = System.nanoTime();
      float delta = (now - last) * nanoToSecs;
      if (delta > 0.25f) {
         delta = 0.25f;
      }
      last = now;

      // Accumulate delta time
      accum += dt;
      while (!Display.isCloseRequested() && accum >= dt) {
         update(dt);
         accum -= dt;
      }

      // Draw frame
      draw();
   }

   public void run() throws LWJGLException {
      System.setProperty("org.lwjgl.librarypath", new File("lib/lwjgl-2.9.1/native/" + getNativeName()).getAbsolutePath());

      try {
         Display.setDisplayMode(new DisplayMode(w,h));
         Display.create();
      } catch (LWJGLException e) {
         throw e;
      }
      
      init();
      
      while (!Display.isCloseRequested()) {
         tick();
         Display.update();
         Display.sync(60);
      }
      
      Display.destroy();      
   }
   
   public static void main(String[] args) throws Exception {
      Box2D_LWJGL app = new Box2D_LWJGL();
      app.run();
   }
}


Please help me to fix this problem, i am stuck right now....

Thanks in regards,
Finalspace

irresistible force
Posts: 1991
Joined: Tue Jun 24, 2008 8:25 pm
Location: Tokyo
Contact:

Re: Really weird issue in a jbox2d application

Postby irresistible force » Sat Aug 02, 2014 4:02 pm

0.025 is too small to fit well with the default settings Box2D uses for separation buffer between polygons.
I think you need to scale all sizes up, so that your shapes are more commonly around 1.
http://www.iforce2d.net/b2dtut/gotchas#smallgap

Finalspace
Posts: 5
Joined: Sat Aug 02, 2014 10:53 am

Re: Really weird issue in a jbox2d application

Postby Finalspace » Sat Aug 02, 2014 10:37 pm

I scaled it by a factor of 10 and now it looks right ;)
That was the explanation i was hoping for... thanks!


Return to “Java”



Who is online

Users browsing this forum: No registered users and 1 guest