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 Bartapackage com.jme3.bounding; 3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.collision.Collidable; 3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.collision.CollisionResult; 3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.collision.CollisionResults; 3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.collision.UnsupportedCollisionException; 3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.InputCapsule; 3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.JmeExporter; 4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.JmeImporter; 4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.OutputCapsule; 4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.*; 4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Mesh; 4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.BufferUtils; 4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.TempVars; 4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.IOException; 4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.FloatBuffer; 4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//import com.jme.scene.TriMesh; 4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/** 5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <code>BoundingBox</code> defines an axis-aligned cube that defines a 5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * container for a group of vertices of a particular piece of geometry. This box 5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * defines a center and extents from that center along the x, y and z axis. <br> 5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <br> 5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * A typical usage is to allow the class define the center and radius by calling 5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * either <code>containAABB</code> or <code>averagePoints</code>. A call to 5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <code>computeFramePoint</code> in turn calls <code>containAABB</code>. 5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Joshua Slack 6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @version $Id: BoundingBox.java,v 1.50 2007/09/22 16:46:35 irrisor Exp $ 6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class BoundingBox extends BoundingVolume { 6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float xExtent, yExtent, zExtent; 6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Default constructor instantiates a new <code>BoundingBox</code> 6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * object. 6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public BoundingBox() { 7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Contstructor instantiates a new <code>BoundingBox</code> object with 7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * given specs. 7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public BoundingBox(Vector3f c, float x, float y, float z) { 7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.center.set(c); 7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.xExtent = x; 8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.yExtent = y; 8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.zExtent = z; 8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public BoundingBox(BoundingBox source) { 8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.center.set(source.center); 8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.xExtent = source.xExtent; 8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.yExtent = source.yExtent; 8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.zExtent = source.zExtent; 8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public BoundingBox(Vector3f min, Vector3f max) { 9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta setMinMax(min, max); 9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Type getType() { 9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return Type.AABB; 9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <code>computeFromPoints</code> creates a new Bounding Box from a given 10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * set of points. It uses the <code>containAABB</code> method as default. 10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param points 10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the points to contain. 10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void computeFromPoints(FloatBuffer points) { 10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta containAABB(points); 10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <code>computeFromTris</code> creates a new Bounding Box from a given 11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * set of triangles. It is used in OBBTree calculations. 11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param tris 11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param start 11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param end 11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void computeFromTris(Triangle[] tris, int start, int end) { 11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (end - start <= 0) { 12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return; 12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta TempVars vars = TempVars.get(); 12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f min = vars.vect1.set(new Vector3f(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY)); 12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f max = vars.vect2.set(new Vector3f(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY)); 12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f point; 12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int i = start; i < end; i++) { 13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta point = tris[i].get(0); 13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta checkMinMax(min, max, point); 13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta point = tris[i].get(1); 13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta checkMinMax(min, max, point); 13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta point = tris[i].get(2); 13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta checkMinMax(min, max, point); 13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta center.set(min.addLocal(max)); 13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta center.multLocal(0.5f); 14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta xExtent = max.x - center.x; 14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta yExtent = max.y - center.y; 14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta zExtent = max.z - center.z; 14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void computeFromTris(int[] indices, Mesh mesh, int start, int end) { 14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (end - start <= 0) { 15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return; 15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta TempVars vars = TempVars.get(); 15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f vect1 = vars.vect1; 15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f vect2 = vars.vect2; 15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Triangle triangle = vars.triangle; 15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f min = vect1.set(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY); 16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f max = vect2.set(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY); 16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f point; 16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int i = start; i < end; i++) { 16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta mesh.getTriangle(indices[i], triangle); 16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta point = triangle.get(0); 16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta checkMinMax(min, max, point); 16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta point = triangle.get(1); 16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta checkMinMax(min, max, point); 16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta point = triangle.get(2); 17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta checkMinMax(min, max, point); 17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta center.set(min.addLocal(max)); 17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta center.multLocal(0.5f); 17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta xExtent = max.x - center.x; 17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta yExtent = max.y - center.y; 17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta zExtent = max.z - center.z; 17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static void checkMinMax(Vector3f min, Vector3f max, Vector3f point) { 18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (point.x < min.x) { 18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta min.x = point.x; 18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (point.x > max.x) { 18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta max.x = point.x; 18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (point.y < min.y) { 19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta min.y = point.y; 19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (point.y > max.y) { 19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta max.y = point.y; 19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (point.z < min.z) { 19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta min.z = point.z; 19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (point.z > max.z) { 20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta max.z = point.z; 20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <code>containAABB</code> creates a minimum-volume axis-aligned bounding 20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * box of the points, then selects the smallest enclosing sphere of the box 20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * with the sphere centered at the boxes center. 20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param points 21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the list of points. 21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void containAABB(FloatBuffer points) { 21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (points == null) { 21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return; 21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta points.rewind(); 21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (points.remaining() <= 2) // we need at least a 3 float vector 21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta { 22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return; 22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta TempVars vars = TempVars.get(); 22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BufferUtils.populateFromBuffer(vars.vect1, points, 0); 22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float minX = vars.vect1.x, minY = vars.vect1.y, minZ = vars.vect1.z; 22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float maxX = vars.vect1.x, maxY = vars.vect1.y, maxZ = vars.vect1.z; 22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int i = 1, len = points.remaining() / 3; i < len; i++) { 23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BufferUtils.populateFromBuffer(vars.vect1, points, i); 23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (vars.vect1.x < minX) { 23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta minX = vars.vect1.x; 23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (vars.vect1.x > maxX) { 23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta maxX = vars.vect1.x; 23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (vars.vect1.y < minY) { 23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta minY = vars.vect1.y; 24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (vars.vect1.y > maxY) { 24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta maxY = vars.vect1.y; 24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (vars.vect1.z < minZ) { 24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta minZ = vars.vect1.z; 24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (vars.vect1.z > maxZ) { 24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta maxZ = vars.vect1.z; 24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta center.set(minX + maxX, minY + maxY, minZ + maxZ); 25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta center.multLocal(0.5f); 25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta xExtent = maxX - center.x; 25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta yExtent = maxY - center.y; 25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta zExtent = maxZ - center.z; 25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <code>transform</code> modifies the center of the box to reflect the 26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * change made via a rotation, translation and scale. 26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param trans 26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the transform to apply 26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param store 26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * box to store result in 26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public BoundingVolume transform(Transform trans, BoundingVolume store) { 27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingBox box; 27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (store == null || store.getType() != Type.AABB) { 27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta box = new BoundingBox(); 27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta box = (BoundingBox) store; 27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta center.mult(trans.getScale(), box.center); 28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta trans.getRotation().mult(box.center, box.center); 28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta box.center.addLocal(trans.getTranslation()); 28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta TempVars vars = TempVars.get(); 28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Matrix3f transMatrix = vars.tempMat3; 28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta transMatrix.set(trans.getRotation()); 28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // Make the rotation matrix all positive to get the maximum x/y/z extent 28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta transMatrix.absoluteLocal(); 28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f scale = trans.getScale(); 29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.vect1.set(xExtent * scale.x, yExtent * scale.y, zExtent * scale.z); 29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta transMatrix.mult(vars.vect1, vars.vect2); 29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // Assign the biggest rotations after scales. 29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta box.xExtent = FastMath.abs(vars.vect2.getX()); 29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta box.yExtent = FastMath.abs(vars.vect2.getY()); 29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta box.zExtent = FastMath.abs(vars.vect2.getZ()); 29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return box; 30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public BoundingVolume transform(Matrix4f trans, BoundingVolume store) { 30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingBox box; 30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (store == null || store.getType() != Type.AABB) { 30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta box = new BoundingBox(); 30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta box = (BoundingBox) store; 30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta TempVars vars = TempVars.get(); 31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float w = trans.multProj(center, box.center); 31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta box.center.divideLocal(w); 31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Matrix3f transMatrix = vars.tempMat3; 31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta trans.toRotationMatrix(transMatrix); 31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // Make the rotation matrix all positive to get the maximum x/y/z extent 32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta transMatrix.absoluteLocal(); 32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.vect1.set(xExtent, yExtent, zExtent); 32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta transMatrix.mult(vars.vect1, vars.vect1); 32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // Assign the biggest rotations after scales. 32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta box.xExtent = FastMath.abs(vars.vect1.getX()); 32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta box.yExtent = FastMath.abs(vars.vect1.getY()); 32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta box.zExtent = FastMath.abs(vars.vect1.getZ()); 32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 33059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 33159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 33259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return box; 33359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 33459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 33559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 33659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <code>whichSide</code> takes a plane (typically provided by a view 33759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * frustum) to determine which side this bound is on. 33859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 33959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param plane 34059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the plane to check against. 34159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 34259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Plane.Side whichSide(Plane plane) { 34359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float radius = FastMath.abs(xExtent * plane.getNormal().getX()) 34459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + FastMath.abs(yExtent * plane.getNormal().getY()) 34559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + FastMath.abs(zExtent * plane.getNormal().getZ()); 34659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 34759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float distance = plane.pseudoDistance(center); 34859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 34959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //changed to < and > to prevent floating point precision problems 35059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (distance < -radius) { 35159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return Plane.Side.Negative; 35259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (distance > radius) { 35359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return Plane.Side.Positive; 35459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 35559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return Plane.Side.None; 35659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 35759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 35859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 35959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 36059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <code>merge</code> combines this sphere with a second bounding sphere. 36159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * This new sphere contains both bounding spheres and is returned. 36259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 36359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param volume 36459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the sphere to combine with this sphere. 36559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return the new sphere 36659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 36759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public BoundingVolume merge(BoundingVolume volume) { 36859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (volume == null) { 36959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return this; 37059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 37159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 37259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta switch (volume.getType()) { 37359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case AABB: { 37459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingBox vBox = (BoundingBox) volume; 37559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return merge(vBox.center, vBox.xExtent, vBox.yExtent, 37659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vBox.zExtent, new BoundingBox(new Vector3f(0, 0, 0), 0, 37759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 0, 0)); 37859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 37959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 38059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case Sphere: { 38159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingSphere vSphere = (BoundingSphere) volume; 38259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return merge(vSphere.center, vSphere.radius, vSphere.radius, 38359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vSphere.radius, new BoundingBox(new Vector3f(0, 0, 0), 38459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 0, 0, 0)); 38559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 38659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 38759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// case OBB: { 38859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// OrientedBoundingBox box = (OrientedBoundingBox) volume; 38959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// BoundingBox rVal = (BoundingBox) this.clone(null); 39059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// return rVal.mergeOBB(box); 39159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 39259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 39359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta default: 39459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return null; 39559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 39659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 39759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 39859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 39959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <code>mergeLocal</code> combines this sphere with a second bounding 40059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * sphere locally. Altering this sphere to contain both the original and the 40159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * additional sphere volumes; 40259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 40359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param volume 40459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the sphere to combine with this sphere. 40559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return this 40659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 40759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public BoundingVolume mergeLocal(BoundingVolume volume) { 40859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (volume == null) { 40959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return this; 41059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 41159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 41259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta switch (volume.getType()) { 41359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case AABB: { 41459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingBox vBox = (BoundingBox) volume; 41559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return merge(vBox.center, vBox.xExtent, vBox.yExtent, 41659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vBox.zExtent, this); 41759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 41859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 41959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case Sphere: { 42059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingSphere vSphere = (BoundingSphere) volume; 42159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return merge(vSphere.center, vSphere.radius, vSphere.radius, 42259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vSphere.radius, this); 42359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 42459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 42559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// case OBB: { 42659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// return mergeOBB((OrientedBoundingBox) volume); 42759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 42859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 42959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta default: 43059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return null; 43159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 43259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 43359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 43459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 43559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Merges this AABB with the given OBB. 43659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 43759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param volume 43859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the OBB to merge this AABB with. 43959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return This AABB extended to fit the given OBB. 44059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 44159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// private BoundingBox mergeOBB(OrientedBoundingBox volume) { 44259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// if (!volume.correctCorners) 44359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// volume.computeCorners(); 44459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 44559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// TempVars vars = TempVars.get(); 44659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// Vector3f min = vars.compVect1.set(center.x - xExtent, center.y - yExtent, 44759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// center.z - zExtent); 44859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// Vector3f max = vars.compVect2.set(center.x + xExtent, center.y + yExtent, 44959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// center.z + zExtent); 45059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 45159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// for (int i = 1; i < volume.vectorStore.length; i++) { 45259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// Vector3f temp = volume.vectorStore[i]; 45359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// if (temp.x < min.x) 45459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// min.x = temp.x; 45559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// else if (temp.x > max.x) 45659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// max.x = temp.x; 45759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 45859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// if (temp.y < min.y) 45959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// min.y = temp.y; 46059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// else if (temp.y > max.y) 46159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// max.y = temp.y; 46259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 46359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// if (temp.z < min.z) 46459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// min.z = temp.z; 46559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// else if (temp.z > max.z) 46659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// max.z = temp.z; 46759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 46859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 46959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// center.set(min.addLocal(max)); 47059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// center.multLocal(0.5f); 47159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 47259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// xExtent = max.x - center.x; 47359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// yExtent = max.y - center.y; 47459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// zExtent = max.z - center.z; 47559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// return this; 47659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 47759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 47859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <code>merge</code> combines this bounding box with another box which is 47959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * defined by the center, x, y, z extents. 48059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 48159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param boxCenter 48259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the center of the box to merge with 48359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param boxX 48459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the x extent of the box to merge with. 48559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param boxY 48659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the y extent of the box to merge with. 48759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param boxZ 48859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the z extent of the box to merge with. 48959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param rVal 49059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the resulting merged box. 49159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return the resulting merged box. 49259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 49359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private BoundingBox merge(Vector3f boxCenter, float boxX, float boxY, 49459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float boxZ, BoundingBox rVal) { 49559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 49659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta TempVars vars = TempVars.get(); 49759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 49859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.vect1.x = center.x - xExtent; 49959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (vars.vect1.x > boxCenter.x - boxX) { 50059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.vect1.x = boxCenter.x - boxX; 50159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 50259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.vect1.y = center.y - yExtent; 50359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (vars.vect1.y > boxCenter.y - boxY) { 50459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.vect1.y = boxCenter.y - boxY; 50559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 50659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.vect1.z = center.z - zExtent; 50759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (vars.vect1.z > boxCenter.z - boxZ) { 50859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.vect1.z = boxCenter.z - boxZ; 50959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 51059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 51159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.vect2.x = center.x + xExtent; 51259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (vars.vect2.x < boxCenter.x + boxX) { 51359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.vect2.x = boxCenter.x + boxX; 51459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 51559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.vect2.y = center.y + yExtent; 51659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (vars.vect2.y < boxCenter.y + boxY) { 51759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.vect2.y = boxCenter.y + boxY; 51859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 51959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.vect2.z = center.z + zExtent; 52059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (vars.vect2.z < boxCenter.z + boxZ) { 52159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.vect2.z = boxCenter.z + boxZ; 52259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 52359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 52459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta center.set(vars.vect2).addLocal(vars.vect1).multLocal(0.5f); 52559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 52659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta xExtent = vars.vect2.x - center.x; 52759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta yExtent = vars.vect2.y - center.y; 52859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta zExtent = vars.vect2.z - center.z; 52959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 53059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 53159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 53259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return rVal; 53359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 53459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 53559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 53659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <code>clone</code> creates a new BoundingBox object containing the same 53759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * data as this one. 53859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 53959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param store 54059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * where to store the cloned information. if null or wrong class, 54159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * a new store is created. 54259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return the new BoundingBox 54359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 54459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public BoundingVolume clone(BoundingVolume store) { 54559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (store != null && store.getType() == Type.AABB) { 54659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingBox rVal = (BoundingBox) store; 54759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rVal.center.set(center); 54859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rVal.xExtent = xExtent; 54959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rVal.yExtent = yExtent; 55059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rVal.zExtent = zExtent; 55159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rVal.checkPlane = checkPlane; 55259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return rVal; 55359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 55459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 55559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingBox rVal = new BoundingBox(center.clone(), 55659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta xExtent, yExtent, zExtent); 55759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return rVal; 55859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 55959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 56059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 56159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <code>toString</code> returns the string representation of this object. 56259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * The form is: "Radius: RRR.SSSS Center: <Vector>". 56359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 56459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return the string representation of this. 56559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 56659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 56759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public String toString() { 56859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return getClass().getSimpleName() + " [Center: " + center + " xExtent: " 56959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + xExtent + " yExtent: " + yExtent + " zExtent: " + zExtent 57059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + "]"; 57159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 57259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 57359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 57459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * intersects determines if this Bounding Box intersects with another given 57559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * bounding volume. If so, true is returned, otherwise, false is returned. 57659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 57759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @see BoundingVolume#intersects(com.jme3.bounding.BoundingVolume) 57859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 57959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public boolean intersects(BoundingVolume bv) { 58059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return bv.intersectsBoundingBox(this); 58159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 58259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 58359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 58459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * determines if this bounding box intersects a given bounding sphere. 58559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 58659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @see BoundingVolume#intersectsSphere(com.jme3.bounding.BoundingSphere) 58759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 58859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public boolean intersectsSphere(BoundingSphere bs) { 58959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta assert Vector3f.isValidVector(center) && Vector3f.isValidVector(bs.center); 59059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 59159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (FastMath.abs(center.x - bs.center.x) < bs.getRadius() 59259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + xExtent 59359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta && FastMath.abs(center.y - bs.center.y) < bs.getRadius() 59459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + yExtent 59559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta && FastMath.abs(center.z - bs.center.z) < bs.getRadius() 59659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + zExtent) { 59759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return true; 59859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 59959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 60059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return false; 60159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 60259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 60359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 60459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * determines if this bounding box intersects a given bounding box. If the 60559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * two boxes intersect in any way, true is returned. Otherwise, false is 60659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * returned. 60759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 60859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @see BoundingVolume#intersectsBoundingBox(com.jme3.bounding.BoundingBox) 60959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 61059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public boolean intersectsBoundingBox(BoundingBox bb) { 61159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta assert Vector3f.isValidVector(center) && Vector3f.isValidVector(bb.center); 61259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 61359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (center.x + xExtent < bb.center.x - bb.xExtent 61459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta || center.x - xExtent > bb.center.x + bb.xExtent) { 61559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return false; 61659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (center.y + yExtent < bb.center.y - bb.yExtent 61759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta || center.y - yExtent > bb.center.y + bb.yExtent) { 61859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return false; 61959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (center.z + zExtent < bb.center.z - bb.zExtent 62059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta || center.z - zExtent > bb.center.z + bb.zExtent) { 62159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return false; 62259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 62359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return true; 62459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 62559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 62659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 62759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 62859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * determines if this bounding box intersects with a given oriented bounding 62959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * box. 63059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 63159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @see com.jme.bounding.BoundingVolume#intersectsOrientedBoundingBox(com.jme.bounding.OrientedBoundingBox) 63259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 63359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// public boolean intersectsOrientedBoundingBox(OrientedBoundingBox obb) { 63459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// return obb.intersectsBoundingBox(this); 63559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 63659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 63759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * determines if this bounding box intersects with a given ray object. If an 63859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * intersection has occurred, true is returned, otherwise false is returned. 63959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 64059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @see BoundingVolume#intersects(com.jme3.math.Ray) 64159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 64259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public boolean intersects(Ray ray) { 64359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta assert Vector3f.isValidVector(center); 64459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 64559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float rhs; 64659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 64759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta TempVars vars = TempVars.get(); 64859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 64959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f diff = ray.origin.subtract(getCenter(vars.vect2), vars.vect1); 65059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 65159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta final float[] fWdU = vars.fWdU; 65259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta final float[] fAWdU = vars.fAWdU; 65359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta final float[] fDdU = vars.fDdU; 65459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta final float[] fADdU = vars.fADdU; 65559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta final float[] fAWxDdU = vars.fAWxDdU; 65659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 65759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fWdU[0] = ray.getDirection().dot(Vector3f.UNIT_X); 65859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fAWdU[0] = FastMath.abs(fWdU[0]); 65959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fDdU[0] = diff.dot(Vector3f.UNIT_X); 66059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fADdU[0] = FastMath.abs(fDdU[0]); 66159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fADdU[0] > xExtent && fDdU[0] * fWdU[0] >= 0.0) { 66259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 66359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return false; 66459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 66559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 66659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fWdU[1] = ray.getDirection().dot(Vector3f.UNIT_Y); 66759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fAWdU[1] = FastMath.abs(fWdU[1]); 66859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fDdU[1] = diff.dot(Vector3f.UNIT_Y); 66959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fADdU[1] = FastMath.abs(fDdU[1]); 67059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fADdU[1] > yExtent && fDdU[1] * fWdU[1] >= 0.0) { 67159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 67259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return false; 67359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 67459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 67559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fWdU[2] = ray.getDirection().dot(Vector3f.UNIT_Z); 67659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fAWdU[2] = FastMath.abs(fWdU[2]); 67759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fDdU[2] = diff.dot(Vector3f.UNIT_Z); 67859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fADdU[2] = FastMath.abs(fDdU[2]); 67959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fADdU[2] > zExtent && fDdU[2] * fWdU[2] >= 0.0) { 68059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 68159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return false; 68259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 68359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 68459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f wCrossD = ray.getDirection().cross(diff, vars.vect2); 68559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 68659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fAWxDdU[0] = FastMath.abs(wCrossD.dot(Vector3f.UNIT_X)); 68759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rhs = yExtent * fAWdU[2] + zExtent * fAWdU[1]; 68859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fAWxDdU[0] > rhs) { 68959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 69059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return false; 69159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 69259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 69359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fAWxDdU[1] = FastMath.abs(wCrossD.dot(Vector3f.UNIT_Y)); 69459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rhs = xExtent * fAWdU[2] + zExtent * fAWdU[0]; 69559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fAWxDdU[1] > rhs) { 69659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 69759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return false; 69859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 69959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 70059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fAWxDdU[2] = FastMath.abs(wCrossD.dot(Vector3f.UNIT_Z)); 70159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rhs = xExtent * fAWdU[1] + yExtent * fAWdU[0]; 70259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fAWxDdU[2] > rhs) { 70359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 70459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return false; 70559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 70659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 70759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 70859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return true; 70959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 71059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 71159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 71259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @see com.jme.bounding.BoundingVolume#intersectsWhere(com.jme.math.Ray) 71359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 71459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private int collideWithRay(Ray ray, CollisionResults results) { 71559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta TempVars vars = TempVars.get(); 71659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 71759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f diff = vars.vect1.set(ray.origin).subtractLocal(center); 71859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f direction = vars.vect2.set(ray.direction); 71959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 72059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float[] t = {0f, Float.POSITIVE_INFINITY}; 72159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 72259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float saveT0 = t[0], saveT1 = t[1]; 72359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta boolean notEntirelyClipped = clip(+direction.x, -diff.x - xExtent, t) 72459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta && clip(-direction.x, +diff.x - xExtent, t) 72559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta && clip(+direction.y, -diff.y - yExtent, t) 72659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta && clip(-direction.y, +diff.y - yExtent, t) 72759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta && clip(+direction.z, -diff.z - zExtent, t) 72859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta && clip(-direction.z, +diff.z - zExtent, t); 72959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 73059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 73159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (notEntirelyClipped && (t[0] != saveT0 || t[1] != saveT1)) { 73259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (t[1] > t[0]) { 73359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float[] distances = t; 73459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f[] points = new Vector3f[]{ 73559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta new Vector3f(ray.direction).multLocal(distances[0]).addLocal(ray.origin), 73659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta new Vector3f(ray.direction).multLocal(distances[1]).addLocal(ray.origin) 73759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta }; 73859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 73959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta CollisionResult result = new CollisionResult(points[0], distances[0]); 74059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta results.addCollision(result); 74159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result = new CollisionResult(points[1], distances[1]); 74259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta results.addCollision(result); 74359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return 2; 74459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 74559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 74659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f point = new Vector3f(ray.direction).multLocal(t[0]).addLocal(ray.origin); 74759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta CollisionResult result = new CollisionResult(point, t[0]); 74859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta results.addCollision(result); 74959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return 1; 75059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 75159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return 0; 75259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 75359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 75459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public int collideWith(Collidable other, CollisionResults results) { 75559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (other instanceof Ray) { 75659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Ray ray = (Ray) other; 75759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return collideWithRay(ray, results); 75859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (other instanceof Triangle) { 75959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Triangle t = (Triangle) other; 76059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (intersects(t.get1(), t.get2(), t.get3())) { 76159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta CollisionResult r = new CollisionResult(); 76259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta results.addCollision(r); 76359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return 1; 76459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 76559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return 0; 76659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 76759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new UnsupportedCollisionException("With: " + other.getClass().getSimpleName()); 76859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 76959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 77059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 77159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 77259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * C code ported from <a href="http://www.cs.lth.se/home/Tomas_Akenine_Moller/code/tribox3.txt"> 77359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * http://www.cs.lth.se/home/Tomas_Akenine_Moller/code/tribox3.txt</a> 77459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 77559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param v1 The first point in the triangle 77659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param v2 The second point in the triangle 77759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param v3 The third point in the triangle 77859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return True if the bounding box intersects the triangle, false 77959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * otherwise. 78059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 78159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public boolean intersects(Vector3f v1, Vector3f v2, Vector3f v3) { 78259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return Intersection.intersect(this, v1, v2, v3); 78359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 78459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 78559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 78659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public boolean contains(Vector3f point) { 78759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return FastMath.abs(center.x - point.x) < xExtent 78859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta && FastMath.abs(center.y - point.y) < yExtent 78959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta && FastMath.abs(center.z - point.z) < zExtent; 79059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 79159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 79259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 79359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public boolean intersects(Vector3f point) { 79459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return FastMath.abs(center.x - point.x) <= xExtent 79559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta && FastMath.abs(center.y - point.y) <= yExtent 79659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta && FastMath.abs(center.z - point.z) <= zExtent; 79759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 79859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 79959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public float distanceToEdge(Vector3f point) { 80059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // compute coordinates of point in box coordinate system 80159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta TempVars vars= TempVars.get(); 80259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f closest = vars.vect1; 80359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 80459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta point.subtract(center,closest); 80559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 80659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // project test point onto box 80759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float sqrDistance = 0.0f; 80859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float delta; 80959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 81059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (closest.x < -xExtent) { 81159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta delta = closest.x + xExtent; 81259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta sqrDistance += delta * delta; 81359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta closest.x = -xExtent; 81459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (closest.x > xExtent) { 81559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta delta = closest.x - xExtent; 81659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta sqrDistance += delta * delta; 81759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta closest.x = xExtent; 81859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 81959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 82059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (closest.y < -yExtent) { 82159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta delta = closest.y + yExtent; 82259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta sqrDistance += delta * delta; 82359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta closest.y = -yExtent; 82459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (closest.y > yExtent) { 82559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta delta = closest.y - yExtent; 82659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta sqrDistance += delta * delta; 82759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta closest.y = yExtent; 82859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 82959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 83059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (closest.z < -zExtent) { 83159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta delta = closest.z + zExtent; 83259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta sqrDistance += delta * delta; 83359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta closest.z = -zExtent; 83459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (closest.z > zExtent) { 83559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta delta = closest.z - zExtent; 83659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta sqrDistance += delta * delta; 83759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta closest.z = zExtent; 83859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 83959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 84059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 84159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return FastMath.sqrt(sqrDistance); 84259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 84359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 84459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 84559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <code>clip</code> determines if a line segment intersects the current 84659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * test plane. 84759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 84859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param denom 84959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the denominator of the line segment. 85059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param numer 85159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the numerator of the line segment. 85259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param t 85359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * test values of the plane. 85459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return true if the line segment intersects the plane, false otherwise. 85559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 85659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private boolean clip(float denom, float numer, float[] t) { 85759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // Return value is 'true' if line segment intersects the current test 85859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // plane. Otherwise 'false' is returned in which case the line segment 85959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // is entirely clipped. 86059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (denom > 0.0f) { 86159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (numer > denom * t[1]) { 86259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return false; 86359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 86459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (numer > denom * t[0]) { 86559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t[0] = numer / denom; 86659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 86759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return true; 86859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (denom < 0.0f) { 86959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (numer > denom * t[0]) { 87059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return false; 87159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 87259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (numer > denom * t[1]) { 87359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta t[1] = numer / denom; 87459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 87559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return true; 87659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 87759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return numer <= 0.0; 87859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 87959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 88059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 88159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 88259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Query extent. 88359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 88459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param store 88559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * where extent gets stored - null to return a new vector 88659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return store / new vector 88759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 88859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Vector3f getExtent(Vector3f store) { 88959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (store == null) { 89059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta store = new Vector3f(); 89159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 89259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta store.set(xExtent, yExtent, zExtent); 89359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return store; 89459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 89559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 89659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public float getXExtent() { 89759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return xExtent; 89859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 89959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 90059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public float getYExtent() { 90159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return yExtent; 90259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 90359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 90459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public float getZExtent() { 90559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return zExtent; 90659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 90759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 90859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void setXExtent(float xExtent) { 90959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (xExtent < 0) { 91059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new IllegalArgumentException(); 91159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 91259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 91359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.xExtent = xExtent; 91459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 91559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 91659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void setYExtent(float yExtent) { 91759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (yExtent < 0) { 91859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new IllegalArgumentException(); 91959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 92059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 92159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.yExtent = yExtent; 92259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 92359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 92459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void setZExtent(float zExtent) { 92559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (zExtent < 0) { 92659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new IllegalArgumentException(); 92759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 92859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 92959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.zExtent = zExtent; 93059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 93159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 93259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Vector3f getMin(Vector3f store) { 93359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (store == null) { 93459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta store = new Vector3f(); 93559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 93659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta store.set(center).subtractLocal(xExtent, yExtent, zExtent); 93759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return store; 93859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 93959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 94059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Vector3f getMax(Vector3f store) { 94159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (store == null) { 94259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta store = new Vector3f(); 94359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 94459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta store.set(center).addLocal(xExtent, yExtent, zExtent); 94559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return store; 94659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 94759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 94859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void setMinMax(Vector3f min, Vector3f max) { 94959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.center.set(max).addLocal(min).multLocal(0.5f); 95059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta xExtent = FastMath.abs(max.x - center.x); 95159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta yExtent = FastMath.abs(max.y - center.y); 95259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta zExtent = FastMath.abs(max.z - center.z); 95359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 95459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 95559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 95659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void write(JmeExporter e) throws IOException { 95759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super.write(e); 95859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta OutputCapsule capsule = e.getCapsule(this); 95959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta capsule.write(xExtent, "xExtent", 0); 96059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta capsule.write(yExtent, "yExtent", 0); 96159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta capsule.write(zExtent, "zExtent", 0); 96259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 96359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 96459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 96559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void read(JmeImporter e) throws IOException { 96659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super.read(e); 96759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta InputCapsule capsule = e.getCapsule(this); 96859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta xExtent = capsule.readFloat("xExtent", 0); 96959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta yExtent = capsule.readFloat("yExtent", 0); 97059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta zExtent = capsule.readFloat("zExtent", 0); 97159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 97259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 97359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 97459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public float getVolume() { 97559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return (8 * xExtent * yExtent * zExtent); 97659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 97759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta} 978