1 /******************************************************************************* 2 * Copyright 2011 See AUTHORS file. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ******************************************************************************/ 16 17 package com.badlogic.gdx.physics.bullet; 18 19 import com.badlogic.gdx.Gdx; 20 import com.badlogic.gdx.graphics.Camera; 21 import com.badlogic.gdx.graphics.g2d.BitmapFont; 22 import com.badlogic.gdx.graphics.g2d.SpriteBatch; 23 import com.badlogic.gdx.graphics.glutils.ShapeRenderer; 24 import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; 25 import com.badlogic.gdx.math.Vector3; 26 import com.badlogic.gdx.physics.bullet.linearmath.btIDebugDraw; 27 import com.badlogic.gdx.utils.Align; 28 import com.badlogic.gdx.utils.Disposable; 29 import com.badlogic.gdx.utils.viewport.Viewport; 30 31 /** @author xoppa */ 32 public class DebugDrawer extends btIDebugDraw implements Disposable { 33 34 private ShapeRenderer shapeRenderer = new ShapeRenderer(); 35 private SpriteBatch spriteBatch; 36 private BitmapFont font; 37 38 private boolean ownsShapeRenderer = true, ownsSpriteBatch = true, ownsFont = true; 39 40 private Camera camera; 41 private Viewport viewport; 42 private int debugMode = btIDebugDraw.DebugDrawModes.DBG_NoDebug; 43 44 @Override drawLine(Vector3 from, Vector3 to, Vector3 color)45 public void drawLine (Vector3 from, Vector3 to, Vector3 color) { 46 shapeRenderer.setColor(color.x, color.y, color.z, 1f); 47 shapeRenderer.line(from, to); 48 } 49 50 @Override drawContactPoint(Vector3 pointOnB, Vector3 normalOnB, float distance, int lifeTime, Vector3 color)51 public void drawContactPoint (Vector3 pointOnB, Vector3 normalOnB, float distance, int lifeTime, Vector3 color) { 52 shapeRenderer.setColor(color.x, color.y, color.z, 1f); 53 shapeRenderer.point(pointOnB.x, pointOnB.y, pointOnB.z); 54 55 shapeRenderer.line(pointOnB, normalOnB.scl(distance).add(pointOnB)); 56 } 57 58 @Override drawTriangle(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 color, float arg4)59 public void drawTriangle (Vector3 v0, Vector3 v1, Vector3 v2, Vector3 color, float arg4) { 60 shapeRenderer.setColor(color.x, color.y, color.z, arg4); 61 shapeRenderer.line(v0, v1); 62 shapeRenderer.line(v1, v2); 63 shapeRenderer.line(v2, v0); 64 } 65 66 @Override reportErrorWarning(String warningString)67 public void reportErrorWarning (String warningString) { 68 Gdx.app.error("Bullet", warningString); 69 } 70 71 @Override draw3dText(Vector3 location, String textString)72 public void draw3dText (Vector3 location, String textString) { 73 if (spriteBatch == null) { 74 spriteBatch = new SpriteBatch(); 75 } 76 if (font == null) { 77 font = new BitmapFont(); 78 } 79 80 // this check is necessary to avoid "mirrored" instances of the text 81 if (camera.frustum.pointInFrustum(location)) { 82 if (viewport != null) { 83 camera.project(location, viewport.getScreenX(), viewport.getScreenY(), viewport.getScreenWidth(), 84 viewport.getScreenHeight()); 85 } else { 86 camera.project(location); 87 } 88 89 shapeRenderer.end(); 90 spriteBatch.begin(); 91 92 // the text will be centered on the position 93 font.draw(spriteBatch, textString, location.x, location.y, 0, textString.length(), 0, Align.center, false); 94 95 spriteBatch.end(); 96 shapeRenderer.begin(ShapeType.Line); 97 } 98 } 99 100 @Override setDebugMode(int debugMode)101 public void setDebugMode (int debugMode) { 102 this.debugMode = debugMode; 103 } 104 105 @Override getDebugMode()106 public int getDebugMode () { 107 return debugMode; 108 } 109 110 /** Use this in case no {@code glViewport} is in use. Otherwise please supply the used {@link Viewport} to 111 * {@link #begin(Viewport)}. 112 * @param camera The (perspective) camera to be used when doing the debug rendering. */ begin(Camera camera)113 public void begin (Camera camera) { 114 this.camera = camera; 115 116 shapeRenderer.setProjectionMatrix(camera.combined); 117 shapeRenderer.begin(ShapeType.Line); 118 } 119 120 /** This has to be used in case the camera to be used is managed via a {@link Viewport}. 121 * @param viewport The currently used viewport with its managed (perspective) camera. */ begin(Viewport viewport)122 public void begin (Viewport viewport) { 123 this.viewport = viewport; 124 begin(viewport.getCamera()); 125 } 126 127 /** Ends the debug rendering process and leads to a flush. */ end()128 public void end () { 129 shapeRenderer.end(); 130 } 131 getShapeRenderer()132 public ShapeRenderer getShapeRenderer () { 133 return shapeRenderer; 134 } 135 136 /** Switches the {@link ShapeRenderer}. The given shape renderer won't be disposed when {@link #dispose()} is called. */ setShapeRenderer(ShapeRenderer shapeRenderer)137 public void setShapeRenderer (ShapeRenderer shapeRenderer) { 138 if (ownsShapeRenderer) { 139 this.shapeRenderer.dispose(); 140 } 141 this.shapeRenderer = shapeRenderer; 142 ownsShapeRenderer = false; 143 } 144 getSpriteBatch()145 public SpriteBatch getSpriteBatch () { 146 return spriteBatch; 147 } 148 149 /** Switches the {@link SpriteBatch}. The given sprite batch won't be disposed when {@link #dispose()} is called. */ setSpriteBatch(SpriteBatch spriteBatch)150 public void setSpriteBatch (SpriteBatch spriteBatch) { 151 if (ownsSpriteBatch && this.spriteBatch != null) { 152 this.spriteBatch.dispose(); 153 } 154 this.spriteBatch = spriteBatch; 155 ownsSpriteBatch = false; 156 } 157 getFont()158 public BitmapFont getFont () { 159 return font; 160 } 161 162 /** Switches the {@link BitmapFont}. The given font won't be disposed when {@link #dispose()} is called. */ setFont(BitmapFont font)163 public void setFont (BitmapFont font) { 164 if (ownsFont && this.font != null) { 165 this.font.dispose(); 166 } 167 this.font = font; 168 ownsFont = false; 169 } 170 171 @Override dispose()172 public void dispose () { 173 super.dispose(); 174 if (ownsShapeRenderer) { 175 shapeRenderer.dispose(); 176 } 177 if (ownsSpriteBatch && spriteBatch != null) { 178 spriteBatch.dispose(); 179 } 180 if (ownsFont && font != null) { 181 font.dispose(); 182 } 183 } 184 185 } 186