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.math; 3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.*; 3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.TempVars; 3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.IOException; 3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/** 3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <p>LineSegment represents a segment in the space. This is a portion of a Line 4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * that has a limited start and end points.</p> 4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <p>A LineSegment is defined by an origin, a direction and an extent (or length). 4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Direction should be a normalized vector. It is not internally normalized.</p> 4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <p>This class provides methods to calculate distances between LineSegments, Rays and Vectors. 4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * It is also possible to retrieve both end points of the segment {@link LineSegment#getPositiveEnd(Vector3f)} 4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * and {@link LineSegment#getNegativeEnd(Vector3f)}. There are also methods to check whether 4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * a point is within the segment bounds.</p> 4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @see Ray 4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Mark Powell 5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Joshua Slack 5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class LineSegment implements Cloneable, Savable, java.io.Serializable { 5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta static final long serialVersionUID = 1; 5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private Vector3f origin; 5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private Vector3f direction; 5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private float extent; 5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public LineSegment() { 6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta origin = new Vector3f(); 6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta direction = new Vector3f(); 6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public LineSegment(LineSegment ls) { 6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.origin = new Vector3f(ls.getOrigin()); 6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.direction = new Vector3f(ls.getDirection()); 6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.extent = ls.getExtent(); 6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <p>Creates a new LineSegment with the given origin, direction and extent.</p> 7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <p>Note that the origin is not one of the ends of the LineSegment, but its center.</p> 7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public LineSegment(Vector3f origin, Vector3f direction, float extent) { 7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.origin = origin; 7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.direction = direction; 7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.extent = extent; 7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <p>Creates a new LineSegment with a given origin and end. This constructor will calculate the 8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * center, the direction and the extent.</p> 8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public LineSegment(Vector3f start, Vector3f end) { 8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.origin = new Vector3f(0.5f * (start.x + end.x), 0.5f * (start.y + end.y), 0.5f * (start.z + end.z)); 8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.direction = end.subtract(start); 8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.extent = direction.length() * 0.5f; 8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta direction.normalizeLocal(); 9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void set(LineSegment ls) { 9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.origin = new Vector3f(ls.getOrigin()); 9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.direction = new Vector3f(ls.getDirection()); 9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.extent = ls.getExtent(); 9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public float distance(Vector3f point) { 9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return FastMath.sqrt(distanceSquared(point)); 10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public float distance(LineSegment ls) { 10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return FastMath.sqrt(distanceSquared(ls)); 10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public float distance(Ray r) { 10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return FastMath.sqrt(distanceSquared(r)); 10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public float distanceSquared(Vector3f point) { 11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta TempVars vars = TempVars.get(); 11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f compVec1 = vars.vect1; 11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta point.subtract(origin, compVec1); 11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float segmentParameter = direction.dot(compVec1); 11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (-extent < segmentParameter) { 11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (segmentParameter < extent) { 11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta origin.add(direction.mult(segmentParameter, compVec1), 12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta compVec1); 12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta origin.add(direction.mult(extent, compVec1), compVec1); 12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta origin.subtract(direction.mult(extent, compVec1), compVec1); 12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta compVec1.subtractLocal(point); 12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float len = compVec1.lengthSquared(); 13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return len; 13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public float distanceSquared(LineSegment test) { 13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta TempVars vars = TempVars.get(); 13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f compVec1 = vars.vect1; 13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta origin.subtract(test.getOrigin(), compVec1); 13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float negativeDirectionDot = -(direction.dot(test.getDirection())); 14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float diffThisDot = compVec1.dot(direction); 14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float diffTestDot = -(compVec1.dot(test.getDirection())); 14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float lengthOfDiff = compVec1.lengthSquared(); 14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float determinant = FastMath.abs(1.0f - negativeDirectionDot 14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * negativeDirectionDot); 14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float s0, s1, squareDistance, extentDeterminant0, extentDeterminant1, tempS0, tempS1; 14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (determinant >= FastMath.FLT_EPSILON) { 14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // segments are not parallel 15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = negativeDirectionDot * diffTestDot - diffThisDot; 15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = negativeDirectionDot * diffThisDot - diffTestDot; 15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta extentDeterminant0 = extent * determinant; 15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta extentDeterminant1 = test.getExtent() * determinant; 15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (s0 >= -extentDeterminant0) { 15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (s0 <= extentDeterminant0) { 15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (s1 >= -extentDeterminant1) { 15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (s1 <= extentDeterminant1) // region 0 (interior) 15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta { 16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // minimum at two interior points of 3D lines 16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float inverseDeterminant = ((float) 1.0) 16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta / determinant; 16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 *= inverseDeterminant; 16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 *= inverseDeterminant; 16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s0 16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s0 + negativeDirectionDot * s1 + (2.0f) * diffThisDot) 16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + s1 16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (negativeDirectionDot * s0 + s1 + (2.0f) * diffTestDot) 16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else // region 3 (side) 17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta { 17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = test.getExtent(); 17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tempS0 = -(negativeDirectionDot * s1 + diffThisDot); 17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (tempS0 < -extent) { 17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = -extent; 17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s0 * (s0 - (2.0f) * tempS0) 17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + s1 * (s1 + (2.0f) * diffTestDot) 17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (tempS0 <= extent) { 18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = tempS0; 18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = -s0 * s0 + s1 18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s1 + (2.0f) * diffTestDot) 18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = extent; 18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s0 * (s0 - (2.0f) * tempS0) 18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + s1 * (s1 + (2.0f) * diffTestDot) 18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else // region 7 (side) 19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta { 19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = -test.getExtent(); 19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tempS0 = -(negativeDirectionDot * s1 + diffThisDot); 19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (tempS0 < -extent) { 19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = -extent; 19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s0 * (s0 - (2.0f) * tempS0) + s1 19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s1 + (2.0f) * diffTestDot) 19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (tempS0 <= extent) { 20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = tempS0; 20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = -s0 * s0 + s1 20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s1 + (2.0f) * diffTestDot) 20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = extent; 20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s0 * (s0 - (2.0f) * tempS0) + s1 20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s1 + (2.0f) * diffTestDot) 20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (s1 >= -extentDeterminant1) { 21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (s1 <= extentDeterminant1) // region 1 (side) 21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta { 21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = extent; 21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tempS1 = -(negativeDirectionDot * s0 + diffTestDot); 21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (tempS1 < -test.getExtent()) { 21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = -test.getExtent(); 22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s1 * (s1 - (2.0f) * tempS1) 22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + s0 * (s0 + (2.0f) * diffThisDot) 22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (tempS1 <= test.getExtent()) { 22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = tempS1; 22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = -s1 * s1 + s0 22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s0 + (2.0f) * diffThisDot) 22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = test.getExtent(); 23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s1 * (s1 - (2.0f) * tempS1) 23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + s0 * (s0 + (2.0f) * diffThisDot) 23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else // region 2 (corner) 23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta { 23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = test.getExtent(); 23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tempS0 = -(negativeDirectionDot * s1 + diffThisDot); 23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (tempS0 < -extent) { 23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = -extent; 24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s0 * (s0 - (2.0f) * tempS0) 24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + s1 * (s1 + (2.0f) * diffTestDot) 24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (tempS0 <= extent) { 24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = tempS0; 24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = -s0 * s0 + s1 24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s1 + (2.0f) * diffTestDot) 24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = extent; 25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tempS1 = -(negativeDirectionDot * s0 + diffTestDot); 25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (tempS1 < -test.getExtent()) { 25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = -test.getExtent(); 25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s1 25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s1 - (2.0f) * tempS1) + s0 25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s0 + (2.0f) * diffThisDot) 25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (tempS1 <= test.getExtent()) { 25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = tempS1; 25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = -s1 * s1 + s0 26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s0 + (2.0f) * diffThisDot) 26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = test.getExtent(); 26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s1 26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s1 - (2.0f) * tempS1) + s0 26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s0 + (2.0f) * diffThisDot) 26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else // region 8 (corner) 27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta { 27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = -test.getExtent(); 27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tempS0 = -(negativeDirectionDot * s1 + diffThisDot); 27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (tempS0 < -extent) { 27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = -extent; 27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s0 * (s0 - (2.0f) * tempS0) + s1 27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s1 + (2.0f) * diffTestDot) 27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (tempS0 <= extent) { 28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = tempS0; 28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = -s0 * s0 + s1 28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s1 + (2.0f) * diffTestDot) 28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = extent; 28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tempS1 = -(negativeDirectionDot * s0 + diffTestDot); 28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (tempS1 > test.getExtent()) { 28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = test.getExtent(); 29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s1 * (s1 - (2.0f) * tempS1) 29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + s0 * (s0 + (2.0f) * diffThisDot) 29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (tempS1 >= -test.getExtent()) { 29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = tempS1; 29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = -s1 * s1 + s0 29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s0 + (2.0f) * diffThisDot) 29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = -test.getExtent(); 30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s1 * (s1 - (2.0f) * tempS1) 30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + s0 * (s0 + (2.0f) * diffThisDot) 30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (s1 >= -extentDeterminant1) { 30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (s1 <= extentDeterminant1) // region 5 (side) 31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta { 31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = -extent; 31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tempS1 = -(negativeDirectionDot * s0 + diffTestDot); 31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (tempS1 < -test.getExtent()) { 31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = -test.getExtent(); 31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s1 * (s1 - (2.0f) * tempS1) + s0 31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s0 + (2.0f) * diffThisDot) 31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (tempS1 <= test.getExtent()) { 31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = tempS1; 32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = -s1 * s1 + s0 32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s0 + (2.0f) * diffThisDot) 32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = test.getExtent(); 32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s1 * (s1 - (2.0f) * tempS1) + s0 32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s0 + (2.0f) * diffThisDot) 32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else // region 4 (corner) 33059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta { 33159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = test.getExtent(); 33259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tempS0 = -(negativeDirectionDot * s1 + diffThisDot); 33359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (tempS0 > extent) { 33459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = extent; 33559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s0 * (s0 - (2.0f) * tempS0) + s1 33659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s1 + (2.0f) * diffTestDot) 33759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 33859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (tempS0 >= -extent) { 33959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = tempS0; 34059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = -s0 * s0 + s1 34159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s1 + (2.0f) * diffTestDot) 34259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 34359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 34459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = -extent; 34559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tempS1 = -(negativeDirectionDot * s0 + diffTestDot); 34659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (tempS1 < -test.getExtent()) { 34759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = -test.getExtent(); 34859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s1 * (s1 - (2.0f) * tempS1) 34959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + s0 * (s0 + (2.0f) * diffThisDot) 35059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 35159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (tempS1 <= test.getExtent()) { 35259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = tempS1; 35359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = -s1 * s1 + s0 35459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s0 + (2.0f) * diffThisDot) 35559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 35659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 35759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = test.getExtent(); 35859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s1 * (s1 - (2.0f) * tempS1) 35959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + s0 * (s0 + (2.0f) * diffThisDot) 36059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 36159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 36259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 36359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 36459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else // region 6 (corner) 36559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta { 36659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = -test.getExtent(); 36759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tempS0 = -(negativeDirectionDot * s1 + diffThisDot); 36859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (tempS0 > extent) { 36959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = extent; 37059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s0 * (s0 - (2.0f) * tempS0) + s1 37159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s1 + (2.0f) * diffTestDot) + lengthOfDiff; 37259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (tempS0 >= -extent) { 37359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = tempS0; 37459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = -s0 * s0 + s1 37559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s1 + (2.0f) * diffTestDot) + lengthOfDiff; 37659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 37759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s0 = -extent; 37859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tempS1 = -(negativeDirectionDot * s0 + diffTestDot); 37959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (tempS1 < -test.getExtent()) { 38059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = -test.getExtent(); 38159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s1 * (s1 - (2.0f) * tempS1) + s0 38259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s0 + (2.0f) * diffThisDot) 38359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 38459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (tempS1 <= test.getExtent()) { 38559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = tempS1; 38659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = -s1 * s1 + s0 38759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s0 + (2.0f) * diffThisDot) 38859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 38959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 39059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta s1 = test.getExtent(); 39159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = s1 * (s1 - (2.0f) * tempS1) + s0 39259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (s0 + (2.0f) * diffThisDot) 39359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 39459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 39559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 39659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 39759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 39859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 39959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // The segments are parallel. The average b0 term is designed to 40059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // ensure symmetry of the function. That is, dist(seg0,seg1) and 40159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // dist(seg1,seg0) should produce the same number.get 40259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float extentSum = extent + test.getExtent(); 40359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float sign = (negativeDirectionDot > 0.0f ? -1.0f : 1.0f); 40459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float averageB0 = (0.5f) * (diffThisDot - sign * diffTestDot); 40559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float lambda = -averageB0; 40659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (lambda < -extentSum) { 40759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta lambda = -extentSum; 40859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (lambda > extentSum) { 40959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta lambda = extentSum; 41059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 41159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 41259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta squareDistance = lambda * (lambda + (2.0f) * averageB0) 41359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + lengthOfDiff; 41459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 41559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 41659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return FastMath.abs(squareDistance); 41759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 41859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 41959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public float distanceSquared(Ray r) { 42059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f kDiff = r.getOrigin().subtract(origin); 42159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float fA01 = -r.getDirection().dot(direction); 42259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float fB0 = kDiff.dot(r.getDirection()); 42359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float fB1 = -kDiff.dot(direction); 42459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float fC = kDiff.lengthSquared(); 42559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float fDet = FastMath.abs(1.0f - fA01 * fA01); 42659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float fS0, fS1, fSqrDist, fExtDet; 42759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 42859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fDet >= FastMath.FLT_EPSILON) { 42959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // The ray and segment are not parallel. 43059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS0 = fA01 * fB1 - fB0; 43159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS1 = fA01 * fB0 - fB1; 43259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fExtDet = extent * fDet; 43359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 43459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fS0 >= (float) 0.0) { 43559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fS1 >= -fExtDet) { 43659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fS1 <= fExtDet) // region 0 43759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta { 43859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // minimum at interior points of ray and segment 43959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float fInvDet = ((float) 1.0) / fDet; 44059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS0 *= fInvDet; 44159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS1 *= fInvDet; 44259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fSqrDist = fS0 44359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (fS0 + fA01 * fS1 + ((float) 2.0) * fB0) 44459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + fS1 44559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (fA01 * fS0 + fS1 + ((float) 2.0) * fB1) + fC; 44659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else // region 1 44759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta { 44859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS1 = extent; 44959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS0 = -(fA01 * fS1 + fB0); 45059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fS0 > (float) 0.0) { 45159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fSqrDist = -fS0 * fS0 + fS1 45259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (fS1 + ((float) 2.0) * fB1) + fC; 45359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 45459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS0 = (float) 0.0; 45559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fSqrDist = fS1 * (fS1 + ((float) 2.0) * fB1) + fC; 45659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 45759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 45859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else // region 5 45959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta { 46059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS1 = -extent; 46159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS0 = -(fA01 * fS1 + fB0); 46259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fS0 > (float) 0.0) { 46359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fSqrDist = -fS0 * fS0 + fS1 46459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (fS1 + ((float) 2.0) * fB1) + fC; 46559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 46659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS0 = (float) 0.0; 46759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fSqrDist = fS1 * (fS1 + ((float) 2.0) * fB1) + fC; 46859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 46959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 47059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 47159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fS1 <= -fExtDet) // region 4 47259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta { 47359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS0 = -(-fA01 * extent + fB0); 47459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fS0 > (float) 0.0) { 47559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS1 = -extent; 47659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fSqrDist = -fS0 * fS0 + fS1 47759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (fS1 + ((float) 2.0) * fB1) + fC; 47859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 47959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS0 = (float) 0.0; 48059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS1 = -fB1; 48159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fS1 < -extent) { 48259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS1 = -extent; 48359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (fS1 > extent) { 48459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS1 = extent; 48559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 48659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fSqrDist = fS1 * (fS1 + ((float) 2.0) * fB1) + fC; 48759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 48859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (fS1 <= fExtDet) // region 3 48959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta { 49059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS0 = (float) 0.0; 49159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS1 = -fB1; 49259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fS1 < -extent) { 49359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS1 = -extent; 49459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (fS1 > extent) { 49559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS1 = extent; 49659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 49759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fSqrDist = fS1 * (fS1 + ((float) 2.0) * fB1) + fC; 49859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else // region 2 49959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta { 50059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS0 = -(fA01 * extent + fB0); 50159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fS0 > (float) 0.0) { 50259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS1 = extent; 50359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fSqrDist = -fS0 * fS0 + fS1 50459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (fS1 + ((float) 2.0) * fB1) + fC; 50559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 50659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS0 = (float) 0.0; 50759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS1 = -fB1; 50859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fS1 < -extent) { 50959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS1 = -extent; 51059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (fS1 > extent) { 51159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS1 = extent; 51259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 51359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fSqrDist = fS1 * (fS1 + ((float) 2.0) * fB1) + fC; 51459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 51559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 51659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 51759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 51859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // ray and segment are parallel 51959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fA01 > (float) 0.0) { 52059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // opposite direction vectors 52159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS1 = -extent; 52259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 52359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // same direction vectors 52459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS1 = extent; 52559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 52659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 52759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS0 = -(fA01 * fS1 + fB0); 52859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fS0 > (float) 0.0) { 52959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fSqrDist = -fS0 * fS0 + fS1 * (fS1 + ((float) 2.0) * fB1) + fC; 53059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 53159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fS0 = (float) 0.0; 53259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fSqrDist = fS1 * (fS1 + ((float) 2.0) * fB1) + fC; 53359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 53459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 53559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return FastMath.abs(fSqrDist); 53659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 53759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 53859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Vector3f getDirection() { 53959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return direction; 54059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 54159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 54259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void setDirection(Vector3f direction) { 54359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.direction = direction; 54459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 54559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 54659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public float getExtent() { 54759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return extent; 54859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 54959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 55059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void setExtent(float extent) { 55159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.extent = extent; 55259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 55359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 55459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Vector3f getOrigin() { 55559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return origin; 55659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 55759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 55859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void setOrigin(Vector3f origin) { 55959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.origin = origin; 56059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 56159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 56259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // P+e*D 56359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Vector3f getPositiveEnd(Vector3f store) { 56459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (store == null) { 56559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta store = new Vector3f(); 56659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 56759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return origin.add((direction.mult(extent, store)), store); 56859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 56959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 57059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // P-e*D 57159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Vector3f getNegativeEnd(Vector3f store) { 57259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (store == null) { 57359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta store = new Vector3f(); 57459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 57559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return origin.subtract((direction.mult(extent, store)), store); 57659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 57759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 57859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void write(JmeExporter e) throws IOException { 57959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta OutputCapsule capsule = e.getCapsule(this); 58059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta capsule.write(origin, "origin", Vector3f.ZERO); 58159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta capsule.write(direction, "direction", Vector3f.ZERO); 58259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta capsule.write(extent, "extent", 0); 58359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 58459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 58559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void read(JmeImporter e) throws IOException { 58659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta InputCapsule capsule = e.getCapsule(this); 58759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta origin = (Vector3f) capsule.readSavable("origin", Vector3f.ZERO.clone()); 58859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta direction = (Vector3f) capsule.readSavable("direction", Vector3f.ZERO.clone()); 58959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta extent = capsule.readFloat("extent", 0); 59059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 59159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 59259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 59359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public LineSegment clone() { 59459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta try { 59559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta LineSegment segment = (LineSegment) super.clone(); 59659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta segment.direction = direction.clone(); 59759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta segment.origin = origin.clone(); 59859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return segment; 59959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } catch (CloneNotSupportedException e) { 60059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new AssertionError(); 60159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 60259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 60359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 60459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 60559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <p>Evaluates whether a given point is contained within the axis aligned bounding box 60659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * that contains this LineSegment.</p><p>This function is float error aware.</p> 60759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 60859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public boolean isPointInsideBounds(Vector3f point) { 60959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return isPointInsideBounds(point, Float.MIN_VALUE); 61059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 61159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 61259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 61359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <p>Evaluates whether a given point is contained within the axis aligned bounding box 61459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * that contains this LineSegment.</p><p>This function accepts an error parameter, which 61559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * is added to the extent of the bounding box.</p> 61659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 61759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public boolean isPointInsideBounds(Vector3f point, float error) { 61859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 61959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (FastMath.abs(point.x - origin.x) > FastMath.abs(direction.x * extent) + error) { 62059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return false; 62159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 62259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (FastMath.abs(point.y - origin.y) > FastMath.abs(direction.y * extent) + error) { 62359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return false; 62459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 62559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (FastMath.abs(point.z - origin.z) > FastMath.abs(direction.z * extent) + error) { 62659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return false; 62759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 62859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 62959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return true; 63059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 63159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta} 632