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.graphics.g3d.utils.shapebuilders; 18 19 import com.badlogic.gdx.graphics.Color; 20 import com.badlogic.gdx.graphics.GL20; 21 import com.badlogic.gdx.graphics.VertexAttributes.Usage; 22 import com.badlogic.gdx.graphics.g3d.utils.MeshPartBuilder; 23 import com.badlogic.gdx.graphics.g3d.utils.MeshPartBuilder.VertexInfo; 24 import com.badlogic.gdx.math.Matrix4; 25 import com.badlogic.gdx.math.Vector3; 26 import com.badlogic.gdx.math.collision.BoundingBox; 27 28 /** Helper class with static methods to build box shapes using {@link MeshPartBuilder}. 29 * @author realitix, xoppa */ 30 public class BoxShapeBuilder extends BaseShapeBuilder { 31 32 /** Build a box with the shape of the specified {@link BoundingBox}. 33 * @param box */ build(MeshPartBuilder builder, BoundingBox box)34 public static void build (MeshPartBuilder builder, BoundingBox box) { 35 builder.box(box.getCorner000(tmpV0), box.getCorner010(tmpV1), box.getCorner100(tmpV2), box.getCorner110(tmpV3), 36 box.getCorner001(tmpV4), box.getCorner011(tmpV5), box.getCorner101(tmpV6), box.getCorner111(tmpV7)); 37 } 38 39 /** Add a box. Requires GL_POINTS, GL_LINES or GL_TRIANGLES primitive type. */ build(MeshPartBuilder builder, VertexInfo corner000, VertexInfo corner010, VertexInfo corner100, VertexInfo corner110, VertexInfo corner001, VertexInfo corner011, VertexInfo corner101, VertexInfo corner111)40 public static void build (MeshPartBuilder builder, VertexInfo corner000, VertexInfo corner010, VertexInfo corner100, 41 VertexInfo corner110, VertexInfo corner001, VertexInfo corner011, VertexInfo corner101, VertexInfo corner111) { 42 builder.ensureVertices(8); 43 final short i000 = builder.vertex(corner000); 44 final short i100 = builder.vertex(corner100); 45 final short i110 = builder.vertex(corner110); 46 final short i010 = builder.vertex(corner010); 47 final short i001 = builder.vertex(corner001); 48 final short i101 = builder.vertex(corner101); 49 final short i111 = builder.vertex(corner111); 50 final short i011 = builder.vertex(corner011); 51 52 final int primitiveType = builder.getPrimitiveType(); 53 if (primitiveType == GL20.GL_LINES) { 54 builder.ensureIndices(24); 55 builder.rect(i000, i100, i110, i010); 56 builder.rect(i101, i001, i011, i111); 57 builder.index(i000, i001, i010, i011, i110, i111, i100, i101); 58 } else if (primitiveType == GL20.GL_POINTS) { 59 builder.ensureRectangleIndices(2); 60 builder.rect(i000, i100, i110, i010); 61 builder.rect(i101, i001, i011, i111); 62 } else { // GL20.GL_TRIANGLES 63 builder.ensureRectangleIndices(6); 64 builder.rect(i000, i100, i110, i010); 65 builder.rect(i101, i001, i011, i111); 66 builder.rect(i000, i010, i011, i001); 67 builder.rect(i101, i111, i110, i100); 68 builder.rect(i101, i100, i000, i001); 69 builder.rect(i110, i111, i011, i010); 70 } 71 } 72 73 /** Add a box. Requires GL_POINTS, GL_LINES or GL_TRIANGLES primitive type. */ build(MeshPartBuilder builder, Vector3 corner000, Vector3 corner010, Vector3 corner100, Vector3 corner110, Vector3 corner001, Vector3 corner011, Vector3 corner101, Vector3 corner111)74 public static void build (MeshPartBuilder builder, Vector3 corner000, Vector3 corner010, Vector3 corner100, Vector3 corner110, 75 Vector3 corner001, Vector3 corner011, Vector3 corner101, Vector3 corner111) { 76 if ((builder.getAttributes().getMask() & (Usage.Normal | Usage.BiNormal | Usage.Tangent | Usage.TextureCoordinates)) == 0) { 77 build(builder, vertTmp1.set(corner000, null, null, null), vertTmp2.set(corner010, null, null, null), 78 vertTmp3.set(corner100, null, null, null), vertTmp4.set(corner110, null, null, null), 79 vertTmp5.set(corner001, null, null, null), vertTmp6.set(corner011, null, null, null), 80 vertTmp7.set(corner101, null, null, null), vertTmp8.set(corner111, null, null, null)); 81 } else { 82 builder.ensureVertices(24); 83 builder.ensureRectangleIndices(6); 84 Vector3 nor = tmpV1.set(corner000).lerp(corner110, 0.5f).sub(tmpV2.set(corner001).lerp(corner111, 0.5f)).nor(); 85 builder.rect(corner000, corner010, corner110, corner100, nor); 86 builder.rect(corner011, corner001, corner101, corner111, nor.scl(-1)); 87 nor = tmpV1.set(corner000).lerp(corner101, 0.5f).sub(tmpV2.set(corner010).lerp(corner111, 0.5f)).nor(); 88 builder.rect(corner001, corner000, corner100, corner101, nor); 89 builder.rect(corner010, corner011, corner111, corner110, nor.scl(-1)); 90 nor = tmpV1.set(corner000).lerp(corner011, 0.5f).sub(tmpV2.set(corner100).lerp(corner111, 0.5f)).nor(); 91 builder.rect(corner001, corner011, corner010, corner000, nor); 92 builder.rect(corner100, corner110, corner111, corner101, nor.scl(-1)); 93 } 94 } 95 96 /** Add a box given the matrix. Requires GL_POINTS, GL_LINES or GL_TRIANGLES primitive type. */ build(MeshPartBuilder builder, Matrix4 transform)97 public static void build (MeshPartBuilder builder, Matrix4 transform) { 98 build(builder, obtainV3().set(-0.5f, -0.5f, -0.5f).mul(transform), obtainV3().set(-0.5f, 0.5f, -0.5f).mul(transform), 99 obtainV3().set(0.5f, -0.5f, -0.5f).mul(transform), obtainV3().set(0.5f, 0.5f, -0.5f).mul(transform), 100 obtainV3().set(-0.5f, -0.5f, 0.5f).mul(transform), obtainV3().set(-0.5f, 0.5f, 0.5f).mul(transform), 101 obtainV3().set(0.5f, -0.5f, 0.5f).mul(transform), obtainV3().set(0.5f, 0.5f, 0.5f).mul(transform)); 102 freeAll(); 103 } 104 105 /** Add a box with the specified dimensions. Requires GL_POINTS, GL_LINES or GL_TRIANGLES primitive type. */ build(MeshPartBuilder builder, float width, float height, float depth)106 public static void build (MeshPartBuilder builder, float width, float height, float depth) { 107 build(builder, 0, 0, 0, width, height, depth); 108 } 109 110 /** Add a box at the specified location, with the specified dimensions */ build(MeshPartBuilder builder, float x, float y, float z, float width, float height, float depth)111 public static void build (MeshPartBuilder builder, float x, float y, float z, float width, float height, float depth) { 112 final float hw = width * 0.5f; 113 final float hh = height * 0.5f; 114 final float hd = depth * 0.5f; 115 final float x0 = x - hw, y0 = y - hh, z0 = z - hd, x1 = x + hw, y1 = y + hh, z1 = z + hd; 116 build(builder, // 117 obtainV3().set(x0, y0, z0), obtainV3().set(x0, y1, z0), obtainV3().set(x1, y0, z0), obtainV3().set(x1, y1, z0), // 118 obtainV3().set(x0, y0, z1), obtainV3().set(x0, y1, z1), obtainV3().set(x1, y0, z1), obtainV3().set(x1, y1, z1)); 119 freeAll(); 120 } 121 122 } 123