1/*
2 * Copyright (c) 2009-2010 jMonkeyEngine
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 *   notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 *   notice, this list of conditions and the following disclaimer in the
14 *   documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17 *   may be used to endorse or promote products derived from this software
18 *   without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33// $Id: Box.java 4131 2009-03-19 20:15:28Z blaine.dev $
34package com.jme3.scene.shape;
35
36import com.jme3.math.Vector3f;
37import com.jme3.scene.VertexBuffer.Type;
38import com.jme3.util.BufferUtils;
39import java.nio.FloatBuffer;
40
41/**
42 * A box with solid (filled) faces.
43 *
44 * @author Mark Powell
45 * @version $Revision: 4131 $, $Date: 2009-03-19 16:15:28 -0400 (Thu, 19 Mar 2009) $
46 */
47public class Box extends AbstractBox {
48
49    private static final short[] GEOMETRY_INDICES_DATA = {
50         2,  1,  0,  3,  2,  0, // back
51         6,  5,  4,  7,  6,  4, // right
52        10,  9,  8, 11, 10,  8, // front
53        14, 13, 12, 15, 14, 12, // left
54        18, 17, 16, 19, 18, 16, // top
55        22, 21, 20, 23, 22, 20  // bottom
56    };
57
58    private static final float[] GEOMETRY_NORMALS_DATA = {
59        0,  0, -1,  0,  0, -1,  0,  0, -1,  0,  0, -1, // back
60        1,  0,  0,  1,  0,  0,  1,  0,  0,  1,  0,  0, // right
61        0,  0,  1,  0,  0,  1,  0,  0,  1,  0,  0,  1, // front
62       -1,  0,  0, -1,  0,  0, -1,  0,  0, -1,  0,  0, // left
63        0,  1,  0,  0,  1,  0,  0,  1,  0,  0,  1,  0, // top
64        0, -1,  0,  0, -1,  0,  0, -1,  0,  0, -1,  0  // bottom
65    };
66
67    private static final float[] GEOMETRY_TEXTURE_DATA = {
68        1, 0, 0, 0, 0, 1, 1, 1, // back
69        1, 0, 0, 0, 0, 1, 1, 1, // right
70        1, 0, 0, 0, 0, 1, 1, 1, // front
71        1, 0, 0, 0, 0, 1, 1, 1, // left
72        1, 0, 0, 0, 0, 1, 1, 1, // top
73        1, 0, 0, 0, 0, 1, 1, 1  // bottom
74    };
75
76    /**
77     * Creates a new box.
78     * <p>
79     * The box has a center of 0,0,0 and extends in the out from the center by
80     * the given amount in <em>each</em> direction. So, for example, a box
81     * with extent of 0.5 would be the unit cube.
82     *
83     * @param x the size of the box along the x axis, in both directions.
84     * @param y the size of the box along the y axis, in both directions.
85     * @param z the size of the box along the z axis, in both directions.
86     */
87    public Box(float x, float y, float z) {
88        super();
89        updateGeometry(Vector3f.ZERO, x, y, z);
90    }
91
92    /**
93     * Creates a new box.
94     * <p>
95     * The box has the given center and extends in the out from the center by
96     * the given amount in <em>each</em> direction. So, for example, a box
97     * with extent of 0.5 would be the unit cube.
98     *
99     * @param center the center of the box.
100     * @param x the size of the box along the x axis, in both directions.
101     * @param y the size of the box along the y axis, in both directions.
102     * @param z the size of the box along the z axis, in both directions.
103     */
104    public Box(Vector3f center, float x, float y, float z) {
105        super();
106        updateGeometry(center, x, y, z);
107    }
108
109    /**
110     * Constructor instantiates a new <code>Box</code> object.
111     * <p>
112     * The minimum and maximum point are provided, these two points define the
113     * shape and size of the box but not it's orientation or position. You should
114     * use the {@link #setLocalTranslation()} and {@link #setLocalRotation()}
115     * methods to define those properties.
116     *
117     * @param min the minimum point that defines the box.
118     * @param max the maximum point that defines the box.
119     */
120    public Box(Vector3f min, Vector3f max) {
121        super();
122        updateGeometry(min, max);
123    }
124
125    /**
126     * Empty constructor for serialization only. Do not use.
127     */
128    public Box(){
129        super();
130    }
131
132    /**
133     * Creates a clone of this box.
134     * <p>
135     * The cloned box will have '_clone' appended to it's name, but all other
136     * properties will be the same as this box.
137     */
138    @Override
139    public Box clone() {
140        return new Box(center.clone(), xExtent, yExtent, zExtent);
141    }
142
143    protected void duUpdateGeometryIndices() {
144        if (getBuffer(Type.Index) == null){
145            setBuffer(Type.Index, 3, BufferUtils.createShortBuffer(GEOMETRY_INDICES_DATA));
146        }
147    }
148
149    protected void duUpdateGeometryNormals() {
150        if (getBuffer(Type.Normal) == null){
151            setBuffer(Type.Normal, 3, BufferUtils.createFloatBuffer(GEOMETRY_NORMALS_DATA));
152        }
153    }
154
155    protected void duUpdateGeometryTextures() {
156        if (getBuffer(Type.TexCoord) == null){
157            setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(GEOMETRY_TEXTURE_DATA));
158        }
159    }
160
161    protected void duUpdateGeometryVertices() {
162        FloatBuffer fpb = BufferUtils.createVector3Buffer(24);
163        Vector3f[] v = computeVertices();
164        fpb.put(new float[] {
165                v[0].x, v[0].y, v[0].z, v[1].x, v[1].y, v[1].z, v[2].x, v[2].y, v[2].z, v[3].x, v[3].y, v[3].z, // back
166                v[1].x, v[1].y, v[1].z, v[4].x, v[4].y, v[4].z, v[6].x, v[6].y, v[6].z, v[2].x, v[2].y, v[2].z, // right
167                v[4].x, v[4].y, v[4].z, v[5].x, v[5].y, v[5].z, v[7].x, v[7].y, v[7].z, v[6].x, v[6].y, v[6].z, // front
168                v[5].x, v[5].y, v[5].z, v[0].x, v[0].y, v[0].z, v[3].x, v[3].y, v[3].z, v[7].x, v[7].y, v[7].z, // left
169                v[2].x, v[2].y, v[2].z, v[6].x, v[6].y, v[6].z, v[7].x, v[7].y, v[7].z, v[3].x, v[3].y, v[3].z, // top
170                v[0].x, v[0].y, v[0].z, v[5].x, v[5].y, v[5].z, v[4].x, v[4].y, v[4].z, v[1].x, v[1].y, v[1].z  // bottom
171        });
172        setBuffer(Type.Position, 3, fpb);
173        updateBound();
174    }
175
176}