/******************************************************************************* * Copyright (c) 2013, Daniel Murphy * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ /** * Created at 4:35:29 AM Jul 15, 2010 */ package org.jbox2d.callbacks; import org.jbox2d.common.Color3f; import org.jbox2d.common.IViewportTransform; import org.jbox2d.common.Transform; import org.jbox2d.common.Vec2; import org.jbox2d.particle.ParticleColor; /** * Implement this abstract class to allow JBox2d to automatically draw your physics for debugging * purposes. Not intended to replace your own custom rendering routines! * * @author Daniel Murphy */ public abstract class DebugDraw { /** Draw shapes */ public static final int e_shapeBit = 1 << 1; /** Draw joint connections */ public static final int e_jointBit = 1 << 2; /** Draw axis aligned bounding boxes */ public static final int e_aabbBit = 1 << 3; /** Draw pairs of connected objects */ public static final int e_pairBit = 1 << 4; /** Draw center of mass frame */ public static final int e_centerOfMassBit = 1 << 5; /** Draw dynamic tree */ public static final int e_dynamicTreeBit = 1 << 6; /** Draw only the wireframe for drawing performance */ public static final int e_wireframeDrawingBit = 1 << 7; protected int m_drawFlags; protected IViewportTransform viewportTransform; public DebugDraw() { this(null); } public DebugDraw(IViewportTransform viewport) { m_drawFlags = 0; viewportTransform = viewport; } public void setViewportTransform(IViewportTransform viewportTransform) { this.viewportTransform = viewportTransform; } public void setFlags(int flags) { m_drawFlags = flags; } public int getFlags() { return m_drawFlags; } public void appendFlags(int flags) { m_drawFlags |= flags; } public void clearFlags(int flags) { m_drawFlags &= ~flags; } /** * Draw a closed polygon provided in CCW order. This implementation uses * {@link #drawSegment(Vec2, Vec2, Color3f)} to draw each side of the polygon. * * @param vertices * @param vertexCount * @param color */ public void drawPolygon(Vec2[] vertices, int vertexCount, Color3f color) { if (vertexCount == 1) { drawSegment(vertices[0], vertices[0], color); return; } for (int i = 0; i < vertexCount - 1; i += 1) { drawSegment(vertices[i], vertices[i + 1], color); } if (vertexCount > 2) { drawSegment(vertices[vertexCount - 1], vertices[0], color); } } public abstract void drawPoint(Vec2 argPoint, float argRadiusOnScreen, Color3f argColor); /** * Draw a solid closed polygon provided in CCW order. * * @param vertices * @param vertexCount * @param color */ public abstract void drawSolidPolygon(Vec2[] vertices, int vertexCount, Color3f color); /** * Draw a circle. * * @param center * @param radius * @param color */ public abstract void drawCircle(Vec2 center, float radius, Color3f color); /** Draws a circle with an axis */ public void drawCircle(Vec2 center, float radius, Vec2 axis, Color3f color) { drawCircle(center, radius, color); } /** * Draw a solid circle. * * @param center * @param radius * @param axis * @param color */ public abstract void drawSolidCircle(Vec2 center, float radius, Vec2 axis, Color3f color); /** * Draw a line segment. * * @param p1 * @param p2 * @param color */ public abstract void drawSegment(Vec2 p1, Vec2 p2, Color3f color); /** * Draw a transform. Choose your own length scale * * @param xf */ public abstract void drawTransform(Transform xf); /** * Draw a string. * * @param x * @param y * @param s * @param color */ public abstract void drawString(float x, float y, String s, Color3f color); /** * Draw a particle array * * @param colors can be null */ public abstract void drawParticles(Vec2[] centers, float radius, ParticleColor[] colors, int count); /** * Draw a particle array * * @param colors can be null */ public abstract void drawParticlesWireframe(Vec2[] centers, float radius, ParticleColor[] colors, int count); /** Called at the end of drawing a world */ public void flush() {} public void drawString(Vec2 pos, String s, Color3f color) { drawString(pos.x, pos.y, s, color); } public IViewportTransform getViewportTranform() { return viewportTransform; } /** * @param x * @param y * @param scale * @deprecated use the viewport transform in {@link #getViewportTranform()} */ public void setCamera(float x, float y, float scale) { viewportTransform.setCamera(x, y, scale); } /** * @param argScreen * @param argWorld */ public void getScreenToWorldToOut(Vec2 argScreen, Vec2 argWorld) { viewportTransform.getScreenToWorld(argScreen, argWorld); } /** * @param argWorld * @param argScreen */ public void getWorldToScreenToOut(Vec2 argWorld, Vec2 argScreen) { viewportTransform.getWorldToScreen(argWorld, argScreen); } /** * Takes the world coordinates and puts the corresponding screen coordinates in argScreen. * * @param worldX * @param worldY * @param argScreen */ public void getWorldToScreenToOut(float worldX, float worldY, Vec2 argScreen) { argScreen.set(worldX, worldY); viewportTransform.getWorldToScreen(argScreen, argScreen); } /** * takes the world coordinate (argWorld) and returns the screen coordinates. * * @param argWorld */ public Vec2 getWorldToScreen(Vec2 argWorld) { Vec2 screen = new Vec2(); viewportTransform.getWorldToScreen(argWorld, screen); return screen; } /** * Takes the world coordinates and returns the screen coordinates. * * @param worldX * @param worldY */ public Vec2 getWorldToScreen(float worldX, float worldY) { Vec2 argScreen = new Vec2(worldX, worldY); viewportTransform.getWorldToScreen(argScreen, argScreen); return argScreen; } /** * takes the screen coordinates and puts the corresponding world coordinates in argWorld. * * @param screenX * @param screenY * @param argWorld */ public void getScreenToWorldToOut(float screenX, float screenY, Vec2 argWorld) { argWorld.set(screenX, screenY); viewportTransform.getScreenToWorld(argWorld, argWorld); } /** * takes the screen coordinates (argScreen) and returns the world coordinates * * @param argScreen */ public Vec2 getScreenToWorld(Vec2 argScreen) { Vec2 world = new Vec2(); viewportTransform.getScreenToWorld(argScreen, world); return world; } /** * takes the screen coordinates and returns the world coordinates. * * @param screenX * @param screenY */ public Vec2 getScreenToWorld(float screenX, float screenY) { Vec2 screen = new Vec2(screenX, screenY); viewportTransform.getScreenToWorld(screen, screen); return screen; } }