159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/*
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Copyright (c) 2009-2010 jMonkeyEngine
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * All rights reserved.
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Redistribution and use in source and binary forms, with or without
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * modification, are permitted provided that the following conditions are
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * met:
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions of source code must retain the above copyright
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer.
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions in binary form must reproduce the above copyright
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer in the
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   documentation and/or other materials provided with the distribution.
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   may be used to endorse or promote products derived from this software
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   without specific prior written permission.
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.scene.shape;
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.InputCapsule;
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.JmeExporter;
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.JmeImporter;
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.OutputCapsule;
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector3f;
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Mesh;
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.IOException;
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/**
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * An eight sided box.
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <p>
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * A {@code Box} is defined by a minimal point and a maximal point. The eight
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * vertices that make the box are then computed, they are computed in such
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * a way as to generate an axis-aligned box.
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <p>
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * This class does not control how the geometry data is generated, see {@link Box}
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * for that.
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author <a href="mailto:ianp@ianp.org">Ian Phillips</a>
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @version $Revision: 4131 $, $Date: 2009-03-19 16:15:28 -0400 (Thu, 19 Mar 2009) $
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic abstract class AbstractBox extends Mesh {
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public final Vector3f center = new Vector3f(0f, 0f, 0f);
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public float xExtent, yExtent, zExtent;
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AbstractBox() {
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        super();
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Gets the array or vectors representing the 8 vertices of the box.
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return a newly created array of vertex vectors.
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected final Vector3f[] computeVertices() {
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f[] axes = {
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                Vector3f.UNIT_X.mult(xExtent),
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                Vector3f.UNIT_Y.mult(yExtent),
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                Vector3f.UNIT_Z.mult(zExtent)
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        };
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return new Vector3f[] {
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                center.subtract(axes[0]).subtractLocal(axes[1]).subtractLocal(axes[2]),
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                center.add(axes[0]).subtractLocal(axes[1]).subtractLocal(axes[2]),
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                center.add(axes[0]).addLocal(axes[1]).subtractLocal(axes[2]),
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                center.subtract(axes[0]).addLocal(axes[1]).subtractLocal(axes[2]),
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                center.add(axes[0]).subtractLocal(axes[1]).addLocal(axes[2]),
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                center.subtract(axes[0]).subtractLocal(axes[1]).addLocal(axes[2]),
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                center.add(axes[0]).addLocal(axes[1]).addLocal(axes[2]),
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                center.subtract(axes[0]).addLocal(axes[1]).addLocal(axes[2])
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        };
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Convert the indices into the list of vertices that define the box's geometry.
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected abstract void duUpdateGeometryIndices();
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Update the normals of each of the box's planes.
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected abstract void duUpdateGeometryNormals();
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Update the points that define the texture of the box.
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <p>
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * It's a one-to-one ratio, where each plane of the box has it's own copy
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * of the texture. That is, the texture is repeated one time for each face.
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected abstract void duUpdateGeometryTextures();
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Update the position of the vertices that define the box.
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <p>
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * These eight points are determined from the minimum and maximum point.
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected abstract void duUpdateGeometryVertices();
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Get the center point of this box.
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public final Vector3f getCenter() {
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return center;
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Get the x-axis size (extent) of this box.
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public final float getXExtent() {
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return xExtent;
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Get the y-axis size (extent) of this box.
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public final float getYExtent() {
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return yExtent;
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Get the z-axis size (extent) of this box.
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public final float getZExtent() {
13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return zExtent;
14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Rebuilds the box after a property has been directly altered.
14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <p>
14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * For example, if you call {@code getXExtent().x = 5.0f} then you will
14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * need to call this method afterwards in order to update the box.
14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public final void updateGeometry() {
14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        duUpdateGeometryVertices();
15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        duUpdateGeometryNormals();
15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        duUpdateGeometryTextures();
15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        duUpdateGeometryIndices();
15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Rebuilds this box based on a new set of parameters.
15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <p>
15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Note that the actual sides will be twice the given extent values because
15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * the box extends in both directions from the center for each extent.
16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param center the center of the box.
16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param x the x extent of the box, in each directions.
16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param y the y extent of the box, in each directions.
16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param z the z extent of the box, in each directions.
16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public final void updateGeometry(Vector3f center, float x, float y, float z) {
16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (center != null) {this.center.set(center); }
16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.xExtent = x;
16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.yExtent = y;
17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.zExtent = z;
17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        updateGeometry();
17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Rebuilds this box based on a new set of parameters.
17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <p>
17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The box is updated so that the two opposite corners are {@code minPoint}
17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * and {@code maxPoint}, the other corners are created from those two positions.
17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param minPoint the new minimum point of the box.
18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param maxPoint the new maximum point of the box.
18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public final void updateGeometry(Vector3f minPoint, Vector3f maxPoint) {
18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        center.set(maxPoint).addLocal(minPoint).multLocal(0.5f);
18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float x = maxPoint.x - center.x;
18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float y = maxPoint.y - center.y;
18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float z = maxPoint.z - center.z;
18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        updateGeometry(center, x, y, z);
18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void read(JmeImporter e) throws IOException {
19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        super.read(e);
19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        InputCapsule capsule = e.getCapsule(this);
19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        xExtent = capsule.readFloat("xExtent", 0);
19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        yExtent = capsule.readFloat("yExtent", 0);
19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        zExtent = capsule.readFloat("zExtent", 0);
19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        center.set((Vector3f) capsule.readSavable("center", Vector3f.ZERO.clone()));
19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void write(JmeExporter e) throws IOException {
20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        super.write(e);
20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        OutputCapsule capsule = e.getCapsule(this);
20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        capsule.write(xExtent, "xExtent", 0);
20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        capsule.write(yExtent, "yExtent", 0);
20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        capsule.write(zExtent, "zExtent", 0);
20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        capsule.write(center, "center", Vector3f.ZERO);
20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
212