Slick Forums

Discuss the Slick 2D Library
It is currently Fri Oct 31, 2014 11:49 am

All times are UTC




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: New DebugDraw for JBox2d
PostPosted: Thu Aug 04, 2011 10:19 am 
Hey guys,
So I created a DebugDraw class for Slick 2D. I posted it here in Fizzy because it was the only part of the forum related to JBox2d. Note that it is licensed under GPLv3.

Code:
/*
Implementation of JBox2d's DebugDraw using Slick2d
@version 1.0.1
@author liamzebedee

Created by Liam Edwards-Playne
Cryptum Technologies - http://cryptum.net
Licensed under the GPLv3 license

Copyright (C) 2011 by Liam Edwards-Playne
    */


package lessur.engine.physics;

import org.jbox2d.callbacks.DebugDraw;
import org.jbox2d.collision.AABB;
import org.jbox2d.common.*;
import org.jbox2d.pooling.arrays.IntArray;
import org.jbox2d.pooling.arrays.Vec2Array;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.ShapeFill;
import org.newdawn.slick.geom.Polygon;

public class Slick2dDebugDraw extends DebugDraw{
    public static int circlePoints = 20;
    Graphics g;
   GameContainer gc;
    /**
     * @param viewport
     */
    public Slick2dDebugDraw(Graphics g,GameContainer gc) {
            super(new OBBViewportTransform());
            viewportTransform.setYFlip(true);
            viewportTransform.setExtents(gc.getWidth()/2, gc.getHeight()/2);
            this.g = g;
          this.gc = gc;
          
            System.out.println("Slick2D DebugDraw for JBox2D has been initialised!");
    }

    private final Vec2Array vec2Array = new Vec2Array();
    /**
     * @see org.jbox2d.callbacks.DebugDraw#drawCircle1(org.jbox2d.common.Vec2, float, org.jbox2d.common.Color3f)
     */
    @Override
    public void drawCircle(Vec2 center, float radius, Color3f color) {
            Vec2[] vecs = vec2Array.get(circlePoints );
            generateCirle(center, radius, vecs, circlePoints);
            drawPolygon(vecs, circlePoints, color);
    }
   
    @Override
    public void drawPoint(Vec2 argPoint, float argRadiusOnScreen, Color3f argColor) {
            getWorldToScreenToOut(argPoint, sp1);
            g.setColor(new Color(argColor.x,argColor.y,argColor.z));
           
            sp1.x -= argRadiusOnScreen;
            sp1.y -= argRadiusOnScreen;
            g.fillOval((int)sp1.x, (int)sp1.y, (int)argRadiusOnScreen*2, (int)argRadiusOnScreen*2);
            g.setColor(Color.white);
    }

    private final Vec2 sp1 = new Vec2();
    private final Vec2 sp2 = new Vec2();
    /**
     * @see org.jbox2d.callbacks.DebugDraw#drawSegment(org.jbox2d.common.Vec2, org.jbox2d.common.Vec2, org.jbox2d.common.Color3f)
     */
    @Override
    public void drawSegment(Vec2 p1, Vec2 p2, Color3f color) {
            getWorldToScreenToOut(p1, sp1);
            getWorldToScreenToOut(p2, sp2);
            g.setColor(new Color(color.x,color.y,color.z));
           
            g.drawLine((int)sp1.x, (int)sp1.y, (int)sp2.x, (int)sp2.y);
            g.setColor(Color.white);
    }
   
   
    public void drawAABB(AABB argAABB, Color3f color){
       g.setColor(new Color(color.x,color.y,color.z));
            Vec2 vecs[] = vec2Array.get(4);
            argAABB.getVertices(vecs);
            drawPolygon(vecs, 4, color);
            g.setColor(Color.white);
    }
   

    private final Vec2 saxis = new Vec2();
    /**
     * @see org.jbox2d.callbacks.DebugDraw#drawSolidCircle(org.jbox2d.common.Vec2, float, org.jbox2d.common.Vec2, org.jbox2d.common.Color3f)
     */
    @Override
    public void drawSolidCircle(Vec2 center, float radius, Vec2 axis, Color3f color) {
            Vec2[] vecs = vec2Array.get(circlePoints );
            generateCirle(center, radius, vecs, circlePoints);
            drawSolidPolygon(vecs, circlePoints, color);
            if(axis != null){
                    saxis.set(axis).mulLocal(radius).addLocal(center);
                    drawSegment(center, saxis, color);
            }
            g.setColor(Color.white);
    }

   
    // TODO change IntegerArray to a specific class for int[] arrays
    private final Vec2 temp = new Vec2();
    private final static IntArray xIntsPool = new IntArray();
    private final static IntArray yIntsPool = new IntArray();
    /**
     * @see org.jbox2d.callbacks.DebugDraw#drawSolidPolygon(org.jbox2d.common.Vec2[], int, org.jbox2d.common.Color3f)
     */
    @Override
    public void drawSolidPolygon(Vec2[] vertices, int vertexCount, Color3f color) {
           
            int[] xInts = xIntsPool.get(vertexCount);
            int[] yInts = yIntsPool.get(vertexCount);
            Polygon p = new Polygon();
           
           
            for(int i=0; i<vertexCount; i++){
                    getWorldToScreenToOut(vertices[i], temp);
                    xInts[i] = (int)temp.x;
                    yInts[i] = (int)temp.y;
                    p.addPoint(xInts[i], yInts[i]);
            }
           
            g.setColor(new Color(color.x,color.y,color.z));
            g.fill(p); //Draws shape filled with colour
            g.setColor(Color.white);
            //drawPolygon(vertices, vertexCount, color);
    }

    /**
     * @see org.jbox2d.callbacks.DebugDraw#drawString(float, float, java.lang.String, org.jbox2d.common.Color3f)
     */
    @Override
    public void drawString(float x, float y, String s, Color3f color) {
          g.setColor(new Color(color.x,color.y,color.z));
            g.drawString(s, x, y);
            g.setColor(Color.white);
    }
   

    private final Vec2 temp2 = new Vec2();
    /**
     * @see org.jbox2d.callbacks.DebugDraw#drawTransform(org.jbox2d.common.Transform)
     */
    @Override
    public void drawTransform(Transform xf) {         
            getWorldToScreenToOut(xf.position, temp);
            temp2.setZero();
            float k_axisScale = 0.4f;
           
            g.setColor(new Color(1,0,0));
            temp2.x = xf.position.x + k_axisScale * xf.R.col1.x;
            temp2.y = xf.position.y + k_axisScale * xf.R.col1.y;
            getWorldToScreenToOut(temp2, temp2);
            g.drawLine((int)temp.x, (int)temp.y, (int)temp2.x, (int)temp2.y);
           
            g.setColor(new Color(0,1,0));
            temp2.x = xf.position.x + k_axisScale * xf.R.col2.x;
            temp2.y = xf.position.y + k_axisScale * xf.R.col2.y;
            getWorldToScreenToOut(temp2, temp2);
            g.drawLine((int)temp.x, (int)temp.y, (int)temp2.x, (int)temp2.y);
            g.setColor(Color.white);
    }

    // CIRCLE GENERATOR
           
    private void generateCirle(Vec2 argCenter, float argRadius, Vec2[] argPoints, int argNumPoints){
            float inc = MathUtils.TWOPI/argNumPoints;
           
            for(int i=0; i<argNumPoints; i++){
                    argPoints[i].x = (argCenter.x + MathUtils.cos(i*inc)*argRadius);
                    argPoints[i].y = (argCenter.y + MathUtils.sin(i*inc)*argRadius);
            }
            g.setColor(Color.white);
    }

   


}


If you want some quick setup code-

Code:
Slick2dDebugDraw sDD = new Slick2dDebugDraw(arg0.getGraphics(), arg0); // arg0 is the GameContainer in this case, I put this code in my init method
sDD.setFlags(0x0001); //Setting the debug draw flags,
/*
Here are the flags available,
 public static final int e_shapeBit                              = 0x0001; ///< draw shapes
        public static final int e_jointBit                              = 0x0002; ///< draw joint connections
        public static final int e_coreShapeBit                  = 0x0004; ///< draw core (TOI) shapes
        public static final int e_aabbBit                               = 0x0008; ///< draw axis aligned bounding boxes
        public static final int e_obbBit                                = 0x0010; ///< draw oriented bounding boxes
        public static final int e_pairBit                               = 0x0020; ///< draw broad-phase pairs
        public static final int e_centerOfMassBit               = 0x0040; ///< draw center of mass frame
        public static final int e_controllerBit                 = 0x0080; ///< draw controllers
From http://code.google.com/p/jbox2d/source/browse/branches/jbox2d-2.0.1/src/org/jbox2d/dynamics/DebugDraw.java
*/
world.setDebugDraw(sDD);

Also remember to put this code in your render method otherwise it will not render the objects-
Code:
world.drawDebugData(); //Where world is your JBox2d world


I hope to be posting more tutorials on the wiki soon.


Top
  
 
PostPosted: Fri Mar 30, 2012 2:49 pm 
Offline

Joined: Fri Mar 30, 2012 2:45 pm
Posts: 3
Hi. I've got a little problem implementing the DebugDraw you coded. The thing is that when i try to draw with my images, it draws far away from the draws of you DebugDraw. I tend to think that my way is the wrong way so can you please tell me what the heck is that i do wrong?

Code:
import java.util.ArrayList;

import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.World;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;


public class GameplayState extends BasicGameState {
   private World world;
   
   private PolygonShape floorShape;
   private Body floorBody;
   
   private PolygonShape manShape;
   private Body manBody;
   
   private ArrayList<Body> bodies;
   
   private Image podeaua;
   private Image om;
      
   private int dir = 1;
   
   private int stateID;
   
   SlickDebugDraw sDD;
   
   public GameplayState(int stateID) {
      this.stateID = stateID;
   }
   
   @Override
   public void init(GameContainer container, StateBasedGame game)
         throws SlickException {
      world = new World(new Vec2(0, 10), true);

      sDD = new SlickDebugDraw(container.getGraphics(), container);
      sDD.setFlags(0x0001);
      world.setDebugDraw(sDD);
      floorShape = new PolygonShape();
      floorShape.setAsBox(400, 15);
      
      BodyDef bd = new BodyDef();
      bd.type = BodyType.STATIC;
      bd.position = new Vec2(0, 570);
      bd.allowSleep = false;
      
      
      floorBody = world.createBody(bd);
      floorBody.createFixture(floorShape, 10);
      
      manShape = new PolygonShape();
      manShape.setAsBox(15, 15);
      
      bd = new BodyDef();
      bd.type = BodyType.DYNAMIC;
      bd.position = new Vec2(400, 30);
      bd.allowSleep = false;
      
      manBody = world.createBody(bd);
      manBody.createFixture(manShape, 10);
      
      podeaua = new Image("data/podeaua.jpg");
      om = new Image("data/om.jpg");
      
      bodies = new ArrayList<Body>();
      
      
      bodies.add(manBody);
      bodies.add(floorBody);
      
   }

   @Override
   public void render(GameContainer container, StateBasedGame game, Graphics g)
         throws SlickException {
      g.drawImage(podeaua,
            floorBody.getPosition().x,
            floorBody.getPosition().y);
      g.drawImage(om,
            manBody.getPosition().x,
            manBody.getPosition().y);
      world.drawDebugData();
   }

   @Override
   public void update(GameContainer container, StateBasedGame game, int delta)
         throws SlickException {
      Input input = container.getInput();
      if(input.isMousePressed(Input.MOUSE_LEFT_BUTTON)){
         manBody.applyLinearImpulse(new Vec2(20, 10), new Vec2(0, 0));
      }
      world.step(delta * 0.001f, 6, 2);   
   }

   @Override
   public int getID() {
      // TODO Auto-generated method stub
      return stateID;
   }

}


Top
 Profile  
 
PostPosted: Mon Jul 09, 2012 8:41 am 
I've added something here


Top
  
 
PostPosted: Tue Jul 10, 2012 9:08 am 
Offline

Joined: Thu May 19, 2011 9:43 am
Posts: 50
What's the best way to scale the whole scene?
Right now the debug draws everything in 1:1 scale, which means 1 meter is 1 pixel.

EDIT
I'm using g.scale(100,100); now, but only on the debug graphics. Rest is rendered in 1.0 scale.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group