aboutsummaryrefslogtreecommitdiffstats
path: root/src/javax/media/j3d/BoundingPolytope.java
diff options
context:
space:
mode:
authorJulien Gouesse <[email protected]>2015-11-28 15:11:48 +0100
committerJulien Gouesse <[email protected]>2015-11-28 15:11:48 +0100
commitdbc98deea1884e44da2c74d6ea807253cdefa693 (patch)
tree29c3ee7dea82d7dd773d81f33f645dde67e43a17 /src/javax/media/j3d/BoundingPolytope.java
parent2c99f1329dc55bd496bce91b9aba956ecba3c67e (diff)
Relocate package prefix to org.jogamp.java3d
Diffstat (limited to 'src/javax/media/j3d/BoundingPolytope.java')
-rw-r--r--src/javax/media/j3d/BoundingPolytope.java1783
1 files changed, 0 insertions, 1783 deletions
diff --git a/src/javax/media/j3d/BoundingPolytope.java b/src/javax/media/j3d/BoundingPolytope.java
deleted file mode 100644
index 37d47c0..0000000
--- a/src/javax/media/j3d/BoundingPolytope.java
+++ /dev/null
@@ -1,1783 +0,0 @@
-/*
- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- */
-
-package javax.media.j3d;
-
-import javax.vecmath.Point3d;
-import javax.vecmath.Point4d;
-import javax.vecmath.Vector3d;
-import javax.vecmath.Vector4d;
-
-/**
- * A BoundingPolytope defines a polyhedral bounding region using the
- * intersection of four or more half spaces. The region defined by a
- * BoundingPolytope is always convex and must be closed.
- * <p>
- * Each plane in the BoundingPolytope specifies a half-space defined
- * by the equation:
- * <ul>
- * Ax + By + Cz + D <= 0
- * </ul>
- * where A, B, C, D are the parameters that specify the plane. The
- * parameters are passed in the x, y, z, and w fields, respectively,
- * of a Vector4d object. The intersection of the set of half-spaces
- * corresponding to the planes in this BoundingPolytope defines the
- * bounding region.
- */
-
-public class BoundingPolytope extends Bounds {
-
- /**
- * An array of bounding planes.
- */
- Vector4d[] planes;
- double[] mag; // magnitude of plane vector
- double[] pDotN; // point on plane dotted with normal
- Point3d[] verts; // vertices of polytope
- int nVerts; // number of verts in polytope
- Point3d centroid = new Point3d(); // centroid of polytope
-
- Point3d boxVerts[];
- boolean allocBoxVerts = false;
-
- /**
- * Constructs a BoundingPolytope using the specified planes.
- * @param planes a set of planes defining the polytope.
- * @exception IllegalArgumentException if the length of the
- * specified array of planes is less than 4.
- */
- public BoundingPolytope(Vector4d[] planes) {
- if (planes.length < 4) {
- throw new IllegalArgumentException(J3dI18N.getString("BoundingPolytope11"));
- }
-
- boundId = BOUNDING_POLYTOPE;
- int i;
- double invMag;
- this.planes = new Vector4d[planes.length];
- mag = new double[planes.length];
- pDotN = new double[planes.length];
-
- for(i=0;i<planes.length;i++) {
-
- // normalize the plane normals
- mag[i] = Math.sqrt(planes[i].x*planes[i].x + planes[i].y*planes[i].y +
- planes[i].z*planes[i].z);
- invMag = 1.0/mag[i];
- this.planes[i] = new Vector4d( planes[i].x*invMag, planes[i].y*invMag,
- planes[i].z*invMag, planes[i].w*invMag );
-
- }
- computeAllVerts(); // XXXX: lazy evaluate
- }
-
- /**
- * Constructs a BoundingPolytope and initializes it to a set of 6
- * planes that defines a cube such that -1 <= x,y,z <= 1. The
- * values of the planes are as follows:
- * <ul>
- * planes[0] : x <= 1 (1,0,0,-1)<br>
- * planes[1] : -x <= 1 (-1,0,0,-1)<br>
- * planes[2] : y <= 1 (0,1,0,-1)<br>
- * planes[3] : -y <= 1 (0,-1,0,-1)<br>
- * planes[4] : z <= 1 (0,0,1,-1)<br>
- * planes[5] : -z <= 1 (0,0,-1,-1)<br>
- * </ul>
- */
- public BoundingPolytope() {
- boundId = BOUNDING_POLYTOPE;
- planes = new Vector4d[6];
- mag = new double[planes.length];
- pDotN = new double[planes.length];
-
- planes[0] = new Vector4d( 1.0, 0.0, 0.0, -1.0 );
- planes[1] = new Vector4d(-1.0, 0.0, 0.0, -1.0 );
- planes[2] = new Vector4d( 0.0, 1.0, 0.0, -1.0 );
- planes[3] = new Vector4d( 0.0,-1.0, 0.0, -1.0 );
- planes[4] = new Vector4d( 0.0, 0.0, 1.0, -1.0 );
- planes[5] = new Vector4d( 0.0, 0.0,-1.0, -1.0 );
- mag[0] = 1.0;
- mag[1] = 1.0;
- mag[2] = 1.0;
- mag[3] = 1.0;
- mag[4] = 1.0;
- mag[5] = 1.0;
-
- computeAllVerts(); // XXXX: lazy evaluate
- }
-
-
- /**
- * Constructs a BoundingPolytope from the specified bounds object.
- * The new polytope will circumscribe the region specified by the
- * input bounds.
- * @param boundsObject the bounds object from which this polytope
- * is constructed.
- */
- public BoundingPolytope(Bounds boundsObject ) {
- int i;
-
- boundId = BOUNDING_POLYTOPE;
-
- if( boundsObject == null ) {
- boundsIsEmpty = true;
- boundsIsInfinite = false;
- initEmptyPolytope();
- computeAllVerts(); // XXXX: lazy evaluate
- return;
- }
-
- boundsIsEmpty = boundsObject.boundsIsEmpty;
- boundsIsInfinite = boundsObject.boundsIsInfinite;
-
- if( boundsObject.boundId == BOUNDING_SPHERE ) {
- BoundingSphere sphere = (BoundingSphere)boundsObject;
- planes = new Vector4d[6];
- mag = new double[planes.length];
- pDotN = new double[planes.length];
-
- planes[0] = new Vector4d( 1.0, 0.0, 0.0, -(sphere.center.x+sphere.radius) );
- planes[1] = new Vector4d(-1.0, 0.0, 0.0, sphere.center.x-sphere.radius );
- planes[2] = new Vector4d( 0.0, 1.0, 0.0, -(sphere.center.y+sphere.radius) );
- planes[3] = new Vector4d( 0.0,-1.0, 0.0, sphere.center.y-sphere.radius );
- planes[4] = new Vector4d( 0.0, 0.0, 1.0, -(sphere.center.z+sphere.radius) );
- planes[5] = new Vector4d( 0.0, 0.0,-1.0, sphere.center.z-sphere.radius );
- mag[0] = 1.0;
- mag[1] = 1.0;
- mag[2] = 1.0;
- mag[3] = 1.0;
- mag[4] = 1.0;
- mag[5] = 1.0;
- computeAllVerts(); // XXXX: lazy evaluate
-
- } else if( boundsObject.boundId == BOUNDING_BOX ){
- BoundingBox box = (BoundingBox)boundsObject;
- planes = new Vector4d[6];
- pDotN = new double[planes.length];
- mag = new double[planes.length];
-
- planes[0] = new Vector4d( 1.0, 0.0, 0.0, -box.upper.x );
- planes[1] = new Vector4d(-1.0, 0.0, 0.0, box.lower.x );
- planes[2] = new Vector4d( 0.0, 1.0, 0.0, -box.upper.y );
- planes[3] = new Vector4d( 0.0,-1.0, 0.0, box.lower.y );
- planes[4] = new Vector4d( 0.0, 0.0, 1.0, -box.upper.z );
- planes[5] = new Vector4d( 0.0, 0.0,-1.0, box.lower.z );
- mag[0] = 1.0;
- mag[1] = 1.0;
- mag[2] = 1.0;
- mag[3] = 1.0;
- mag[4] = 1.0;
- mag[5] = 1.0;
- computeAllVerts(); // XXXX: lazy evaluate
-
- } else if( boundsObject.boundId == BOUNDING_POLYTOPE ) {
- BoundingPolytope polytope = (BoundingPolytope)boundsObject;
- planes = new Vector4d[polytope.planes.length];
- mag = new double[planes.length];
- pDotN = new double[planes.length];
- nVerts = polytope.nVerts;
- verts = new Point3d[nVerts];
- for(i=0;i<planes.length;i++) {
- planes[i] = new Vector4d(polytope.planes[i]);
- mag[i] = polytope.mag[i];
- pDotN[i] = polytope.pDotN[i];
- }
- for(i=0;i<verts.length;i++) {
- verts[i] = new Point3d(polytope.verts[i]);
- }
- centroid = polytope.centroid;
-
- } else {
- throw new IllegalArgumentException(J3dI18N.getString("BoundingPolytope0"));
- }
- }
-
- /**
- * Constructs a BoundingPolytope from the specified array of bounds
- * objects. The new polytope will circumscribe the union of the
- * regions specified by the input bounds objects.
- * @param boundsObjects the array bounds objects from which this
- * polytope is constructed.
- */
- public BoundingPolytope(Bounds[] boundsObjects) {
- int i=0;
-
- boundId = BOUNDING_POLYTOPE;
- if( boundsObjects == null || boundsObjects.length <= 0 ) {
- boundsIsEmpty = true;
- boundsIsInfinite = false;
- initEmptyPolytope();
- computeAllVerts(); // XXXX: lazy evaluate
- return;
- }
- // find first non empty bounds object
- while( boundsObjects[i] == null && i < boundsObjects.length) {
- i++;
- }
-
- if( i >= boundsObjects.length ) { // all bounds objects were empty
- boundsIsEmpty = true;
- boundsIsInfinite = false;
- initEmptyPolytope();
- computeAllVerts(); // XXXX: lazy evaluate
- return;
- }
-
- boundsIsEmpty = boundsObjects[i].boundsIsEmpty;
- boundsIsInfinite = boundsObjects[i].boundsIsInfinite;
-
- if( boundsObjects[i].boundId == BOUNDING_SPHERE ) {
- BoundingSphere sphere = (BoundingSphere)boundsObjects[i];
- planes = new Vector4d[6];
- mag = new double[planes.length];
- pDotN = new double[planes.length];
-
- planes[0] = new Vector4d( 1.0, 0.0, 0.0, -(sphere.center.x+sphere.radius) );
- planes[1] = new Vector4d(-1.0, 0.0, 0.0, sphere.center.x-sphere.radius );
- planes[2] = new Vector4d( 0.0, 1.0, 0.0, -(sphere.center.y+sphere.radius) );
- planes[3] = new Vector4d( 0.0,-1.0, 0.0, sphere.center.y-sphere.radius );
- planes[4] = new Vector4d( 0.0, 0.0, 1.0, -(sphere.center.z+sphere.radius) );
- planes[5] = new Vector4d( 0.0, 0.0,-1.0, sphere.center.z-sphere.radius );
- mag[0] = 1.0;
- mag[1] = 1.0;
- mag[2] = 1.0;
- mag[3] = 1.0;
- mag[4] = 1.0;
- mag[5] = 1.0;
-
- computeAllVerts(); // XXXX: lazy evaluate
- } else if( boundsObjects[i].boundId == BOUNDING_BOX ){
- BoundingBox box = (BoundingBox)boundsObjects[i];
- planes = new Vector4d[6];
- mag = new double[planes.length];
- pDotN = new double[planes.length];
-
- planes[0] = new Vector4d( 1.0, 0.0, 0.0, -box.upper.x );
- planes[1] = new Vector4d(-1.0, 0.0, 0.0, box.lower.x );
- planes[2] = new Vector4d( 0.0, 1.0, 0.0, -box.upper.y );
- planes[3] = new Vector4d( 0.0,-1.0, 0.0, box.lower.y );
- planes[4] = new Vector4d( 0.0, 0.0, 1.0, -box.upper.z );
- planes[5] = new Vector4d( 0.0, 0.0,-1.0, box.lower.z );
- mag[0] = 1.0;
- mag[1] = 1.0;
- mag[2] = 1.0;
- mag[3] = 1.0;
- mag[4] = 1.0;
- mag[5] = 1.0;
-
- computeAllVerts(); // XXXX: lazy evaluate
- } else if( boundsObjects[i].boundId == BOUNDING_POLYTOPE ) {
- BoundingPolytope polytope = (BoundingPolytope)boundsObjects[i];
- planes = new Vector4d[polytope.planes.length];
- mag = new double[planes.length];
- pDotN = new double[planes.length];
- nVerts = polytope.nVerts;
- verts = new Point3d[nVerts];
- for(i=0;i<planes.length;i++) {
- planes[i] = new Vector4d(polytope.planes[i]);
- pDotN[i] = polytope.pDotN[i];
- mag[i] = polytope.mag[i];
- }
- for(i=0;i<verts.length;i++) {
- verts[i] = new Point3d(polytope.verts[i]);
- }
- centroid = polytope.centroid;
- } else {
- throw new IllegalArgumentException(J3dI18N.getString("BoundingPolytope1"));
- }
- for(i+=1;i<boundsObjects.length;i++) {
- this.combine(boundsObjects[i]);
- }
- }
-
- /**
- * Sets the bounding planes for this polytope.
- * @param planes the new set of planes for this polytope
- * @exception IllegalArgumentException if the length of the
- * specified array of planes is less than 4.
- */
- public void setPlanes(Vector4d[] planes) {
- if (planes.length < 4) {
- throw new IllegalArgumentException(J3dI18N.getString("BoundingPolytope11"));
- }
-
- int i;
- double invMag;
-
- this.planes = new Vector4d[planes.length];
- pDotN = new double[planes.length];
- mag = new double[planes.length];
- boundsIsEmpty = false;
-
- if( planes.length <= 0 ) {
- boundsIsEmpty = true;
- boundsIsInfinite = false;
- computeAllVerts(); // XXXX: lazy evaluate
- return;
- }
-
- for(i=0;i<planes.length;i++) {
- // normalize the plane normals
- mag[i] = Math.sqrt(planes[i].x*planes[i].x + planes[i].y*planes[i].y +
- planes[i].z*planes[i].z);
- invMag = 1.0/mag[i];
- this.planes[i] = new Vector4d( planes[i].x*invMag, planes[i].y*invMag,
- planes[i].z*invMag, planes[i].w*invMag );
- }
- computeAllVerts(); // XXXX: lazy evaluate
-
- }
-
- /**
- * Returns the equations of the bounding planes for this bounding polytope.
- * The equations are copied into the specified array.
- * The array must be large enough to hold all of the vectors.
- * The individual array elements must be allocated by the caller.
- * @param planes an array Vector4d to receive the bounding planes
- */
- public void getPlanes(Vector4d[] planes)
- {
- int i;
-
- for(i=0;i<planes.length;i++) {
- planes[i].x = this.planes[i].x*mag[i];
- planes[i].y = this.planes[i].y*mag[i];
- planes[i].z = this.planes[i].z*mag[i];
- planes[i].w = this.planes[i].w*mag[i];
- }
- }
-
- public int getNumPlanes() {
- return planes.length;
- }
-
- /**
- * Sets the planes for this BoundingPolytope by keeping its current
- * number and position of planes and computing new planes positions
- * to enclose the given bounds object.
- * @param boundsObject another bounds object
- */
- @Override
- public void set(Bounds boundsObject) {
- int i,k;
-
- // no polytope exists yet so initialize one using the boundsObject
- if( boundsObject == null ) {
- boundsIsEmpty = true;
- boundsIsInfinite = false;
- computeAllVerts(); // XXXX: lazy evaluate
-
- }else if( boundsObject.boundId == BOUNDING_SPHERE ) {
- BoundingSphere sphere = (BoundingSphere)boundsObject;
-
- if( boundsIsEmpty) {
- initEmptyPolytope(); // no ptope exist so must initialize to default
- computeAllVerts();
- }
-
- for(i=0;i<planes.length;i++) { // D = -(N dot C + radius)
- planes[i].w = -(sphere.center.x*planes[i].x +
- sphere.center.y*planes[i].y +
- sphere.center.z*planes[i].z + sphere.radius);
- }
-
- boundsIsEmpty = boundsObject.boundsIsEmpty;
- boundsIsInfinite = boundsObject.boundsIsInfinite;
- computeAllVerts(); // XXXX: lazy evaluate
-
- } else if( boundsObject.boundId == BOUNDING_BOX){
- BoundingBox box = (BoundingBox)boundsObject;
- double ux,uy,uz,lx,ly,lz,newD;
-
- if( boundsIsEmpty) {
- initEmptyPolytope(); // no ptope exist so must initialize to default
- computeAllVerts();
- }
-
- for(i=0;i<planes.length;i++) {
- ux = box.upper.x*planes[i].x;
- uy = box.upper.y*planes[i].y;
- uz = box.upper.z*planes[i].z;
- lx = box.lower.x*planes[i].x;
- ly = box.lower.y*planes[i].y;
- lz = box.lower.z*planes[i].z;
- planes[i].w = -(ux + uy + uz ); // initalize plane to upper vert
- if( (newD = ux + uy + lz ) + planes[i].w > 0.0) planes[i].w = -newD;
- if( (newD = ux + ly + uz ) + planes[i].w > 0.0) planes[i].w = -newD;
- if( (newD = ux + ly + lz ) + planes[i].w > 0.0) planes[i].w = -newD;
-
- if( (newD = lx + uy + uz ) + planes[i].w > 0.0) planes[i].w = -newD;
- if( (newD = lx + uy + lz ) + planes[i].w > 0.0) planes[i].w = -newD;
- if( (newD = lx + ly + uz ) + planes[i].w > 0.0) planes[i].w = -newD;
- if( (newD = lx + ly + lz ) + planes[i].w > 0.0) planes[i].w = -newD;
- }
-
- boundsIsEmpty = boundsObject.boundsIsEmpty;
- boundsIsInfinite = boundsObject.boundsIsInfinite;
- computeAllVerts(); // XXXX: lazy evaluate
-
- } else if(boundsObject.boundId == BOUNDING_POLYTOPE) {
- BoundingPolytope polytope = (BoundingPolytope)boundsObject;
- if( planes.length != polytope.planes.length) {
- planes = new Vector4d[polytope.planes.length];
- for(k=0;k<polytope.planes.length;k++) planes[k] = new Vector4d();
- mag = new double[polytope.planes.length];
- pDotN = new double[polytope.planes.length];
- }
-
-
- for(i=0;i<polytope.planes.length;i++) {
- planes[i].x = polytope.planes[i].x;
- planes[i].y = polytope.planes[i].y;
- planes[i].z = polytope.planes[i].z;
- planes[i].w = polytope.planes[i].w;
- mag[i] = polytope.mag[i];
- }
- nVerts = polytope.nVerts;
- verts = new Point3d[nVerts];
- for (k=0; k<nVerts; k++) {
- verts[k] = new Point3d(polytope.verts[k]);
- }
-
- boundsIsEmpty = boundsObject.boundsIsEmpty;
- boundsIsInfinite = boundsObject.boundsIsInfinite;
-
- } else {
- throw new IllegalArgumentException(J3dI18N.getString("BoundingPolytope2"));
- }
-
- }
-
-
- /**
- * Creates a copy of a polytope.
- * @return a new BoundingPolytope
- */
- @Override
- public Object clone() {
- return new BoundingPolytope(planes);
- }
-
-
- /**
- * Indicates whether the specified <code>bounds</code> object is
- * equal to this BoundingPolytope object. They are equal if the
- * specified <code>bounds</code> object is an instance of
- * BoundingPolytope and all of the data
- * members of <code>bounds</code> are equal to the corresponding
- * data members in this BoundingPolytope.
- * @param bounds the object with which the comparison is made.
- * @return true if this BoundingPolytope is equal to <code>bounds</code>;
- * otherwise false
- *
- * @since Java 3D 1.2
- */
- @Override
- public boolean equals(Object bounds) {
- try {
- BoundingPolytope polytope = (BoundingPolytope)bounds;
- if (planes.length != polytope.planes.length)
- return false;
- for (int i = 0; i < planes.length; i++)
- if (!planes[i].equals(polytope.planes[i]))
- return false;
-
- return true;
- }
- catch (NullPointerException e) {
- return false;
- }
- catch (ClassCastException e) {
- return false;
- }
- }
-
-
- /**
- * Returns a hash code value for this BoundingPolytope object
- * based on the data values in this object. Two different
- * BoundingPolytope objects with identical data values (i.e.,
- * BoundingPolytope.equals returns true) will return the same hash
- * code value. Two BoundingPolytope objects with different data
- * members may return the same hash code value, although this is
- * not likely.
- * @return a hash code value for this BoundingPolytope object.
- *
- * @since Java 3D 1.2
- */
- @Override
- public int hashCode() {
- long bits = 1L;
-
- for (int i = 0; i < planes.length; i++) {
- bits = J3dHash.mixDoubleBits(bits, planes[i].x);
- bits = J3dHash.mixDoubleBits(bits, planes[i].y);
- bits = J3dHash.mixDoubleBits(bits, planes[i].z);
- bits = J3dHash.mixDoubleBits(bits, planes[i].w);
- }
-
- return J3dHash.finish(bits);
- }
-
-
- /**
- * Combines this bounding polytope with a bounding object so that the
- * resulting bounding polytope encloses the original bounding polytope and the
- * given bounds object.
- * @param boundsObject another bounds object
- */
- @Override
- public void combine(Bounds boundsObject) {
- BoundingSphere sphere;
-
- if((boundsObject == null) || (boundsObject.boundsIsEmpty)
- || (boundsIsInfinite))
- return;
-
-
- if((boundsIsEmpty) || (boundsObject.boundsIsInfinite)) {
- this.set(boundsObject);
- return;
- }
-
- boundsIsEmpty = boundsObject.boundsIsEmpty;
- boundsIsInfinite = boundsObject.boundsIsInfinite;
-
- if( boundsObject.boundId == BOUNDING_SPHERE ) {
- sphere = (BoundingSphere)boundsObject;
- int i;
- double dis;
- for(i = 0; i < planes.length; i++){
- dis = sphere.radius+ sphere.center.x*planes[i].x +
- sphere.center.y*planes[i].y + sphere.center.z *
- planes[i].z + planes[i].w;
- if( dis > 0.0 ) {
- planes[i].w += -dis;
- }
- }
- } else if( boundsObject instanceof BoundingBox){
- BoundingBox b = (BoundingBox)boundsObject;
- if( !allocBoxVerts){
- boxVerts = new Point3d[8];
- for(int j=0;j<8;j++)boxVerts[j] = new Point3d();
- allocBoxVerts = true;
- }
- boxVerts[0].set(b.lower.x, b.lower.y, b.lower.z );
- boxVerts[1].set(b.lower.x, b.upper.y, b.lower.z );
- boxVerts[2].set(b.upper.x, b.lower.y, b.lower.z );
- boxVerts[3].set(b.upper.x, b.upper.y, b.lower.z );
- boxVerts[4].set(b.lower.x, b.lower.y, b.upper.z );
- boxVerts[5].set(b.lower.x, b.upper.y, b.upper.z );
- boxVerts[6].set(b.upper.x, b.lower.y, b.upper.z );
- boxVerts[7].set(b.upper.x, b.upper.y, b.upper.z );
- this.combine(boxVerts);
-
- } else if(boundsObject.boundId == BOUNDING_POLYTOPE) {
- BoundingPolytope polytope = (BoundingPolytope)boundsObject;
- this.combine(polytope.verts);
- } else {
- throw new IllegalArgumentException(J3dI18N.getString("BoundingPolytope3"));
- }
-
- computeAllVerts();
- }
-
- /**
- * Combines this bounding polytope with an array of bounding objects so that the
- * resulting bounding polytope encloses the original bounding polytope and the
- * given array of bounds object.
- * @param boundsObjects an array of bounds objects
- */
- @Override
- public void combine(Bounds[] boundsObjects) {
- int i=0;
- double dis;
-
- if( (boundsObjects == null) || (boundsObjects.length <= 0)
- || (boundsIsInfinite))
- return;
-
- // find first non empty bounds object
- while( (i<boundsObjects.length) && ((boundsObjects[i]==null)
- || boundsObjects[i].boundsIsEmpty)) {
- i++;
- }
- if( i >= boundsObjects.length)
- return; // no non empty bounds so do not modify current bounds
-
- if(boundsIsEmpty)
- this.set(boundsObjects[i++]);
-
- if(boundsIsInfinite)
- return;
-
- for(;i<boundsObjects.length;i++) {
- if( boundsObjects[i] == null ); // do nothing
- else if( boundsObjects[i].boundsIsEmpty ); // do nothing
- else if( boundsObjects[i].boundsIsInfinite ) {
- this.set(boundsObjects[i]);
- break; // We're done;
- }
- else if( boundsObjects[i].boundId == BOUNDING_SPHERE ) {
- BoundingSphere sphere = (BoundingSphere)boundsObjects[i];
- for(int j = 0; j < planes.length; j++){
- dis = sphere.radius+ sphere.center.x*planes[j].x +
- sphere.center.y*planes[j].y + sphere.center.z*
- planes[j].z + planes[j].w;
- if( dis > 0.0 ) {
- planes[j].w += -dis;
- }
- }
- } else if( boundsObjects[i].boundId == BOUNDING_BOX){
- BoundingBox b = (BoundingBox)boundsObjects[i];
- if( !allocBoxVerts){
- boxVerts = new Point3d[8];
- for(int j=0;j<8;j++)boxVerts[j] = new Point3d();
- allocBoxVerts = true;
- }
- boxVerts[0].set(b.lower.x, b.lower.y, b.lower.z );
- boxVerts[1].set(b.lower.x, b.upper.y, b.lower.z );
- boxVerts[2].set(b.upper.x, b.lower.y, b.lower.z );
- boxVerts[3].set(b.upper.x, b.upper.y, b.lower.z );
- boxVerts[4].set(b.lower.x, b.lower.y, b.upper.z );
- boxVerts[5].set(b.lower.x, b.upper.y, b.upper.z );
- boxVerts[6].set(b.upper.x, b.lower.y, b.upper.z );
- boxVerts[7].set(b.upper.x, b.upper.y, b.upper.z );
- this.combine(boxVerts);
-
- } else if(boundsObjects[i] instanceof BoundingPolytope) {
- BoundingPolytope polytope = (BoundingPolytope)boundsObjects[i];
- this.combine(polytope.verts);
-
- } else {
- throw new IllegalArgumentException(J3dI18N.getString("BoundingPolytope4"));
- }
-
- computeAllVerts();
- }
- }
-
- /**
- * Combines this bounding polytope with a point.
- * @param point a 3d point in space
- */
- @Override
- public void combine(Point3d point) {
- int i;
- double dis;
-
- if(boundsIsInfinite) {
- return;
- }
-
- if( boundsIsEmpty ){
- planes = new Vector4d[6];
- mag = new double[planes.length];
- pDotN = new double[planes.length];
- nVerts = 1;
- verts = new Point3d[nVerts];
- verts[0] = new Point3d( point.x, point.y, point.z);
-
- for(i=0;i<planes.length;i++) {
- pDotN[i] = 0.0;
- }
- planes[0] = new Vector4d( 1.0, 0.0, 0.0, -point.x );
- planes[1] = new Vector4d(-1.0, 0.0, 0.0, point.x );
- planes[2] = new Vector4d( 0.0, 1.0, 0.0, -point.y );
- planes[3] = new Vector4d( 0.0,-1.0, 0.0, point.y );
- planes[4] = new Vector4d( 0.0, 0.0, 1.0, -point.z );
- planes[5] = new Vector4d( 0.0, 0.0,-1.0, point.z );
- mag[0] = 1.0;
- mag[1] = 1.0;
- mag[2] = 1.0;
- mag[3] = 1.0;
- mag[4] = 1.0;
- mag[5] = 1.0;
- centroid.x = point.x;
- centroid.y = point.y;
- centroid.z = point.z;
- boundsIsEmpty = false;
- boundsIsInfinite = false;
- } else {
-
- for(i = 0; i < planes.length; i++){
- dis = point.x*planes[i].x + point.y*planes[i].y + point.z*
- planes[i].z + planes[i].w;
- if( dis > 0.0 ) {
- planes[i].w += -dis;
- }
- }
- computeAllVerts();
- }
- }
-
- /**
- * Combines this bounding polytope with an array of points.
- * @param points an array of 3d points in space
- */
- @Override
- public void combine(Point3d[] points) {
- int i,j;
- double dis;
-
- if( boundsIsInfinite) {
- return;
- }
-
- if( boundsIsEmpty ){
- planes = new Vector4d[6];
- mag = new double[planes.length];
- pDotN = new double[planes.length];
- nVerts = points.length;
- verts = new Point3d[nVerts];
- verts[0] = new Point3d( points[0].x, points[0].y, points[0].z);
-
- for(i=0;i<planes.length;i++) {
- pDotN[i] = 0.0;
- }
- planes[0] = new Vector4d( 1.0, 0.0, 0.0, -points[0].x );
- planes[1] = new Vector4d(-1.0, 0.0, 0.0, points[0].x );
- planes[2] = new Vector4d( 0.0, 1.0, 0.0, -points[0].y );
- planes[3] = new Vector4d( 0.0,-1.0, 0.0, points[0].y );
- planes[4] = new Vector4d( 0.0, 0.0, 1.0, -points[0].z );
- planes[5] = new Vector4d( 0.0, 0.0,-1.0, points[0].z );
- mag[0] = 1.0;
- mag[1] = 1.0;
- mag[2] = 1.0;
- mag[3] = 1.0;
- mag[4] = 1.0;
- mag[5] = 1.0;
- centroid.x = points[0].x;
- centroid.y = points[0].y;
- centroid.z = points[0].z;
- boundsIsEmpty = false;
- boundsIsInfinite = false;
- }
-
- for(j = 0; j < points.length; j++){
- for(i = 0; i < planes.length; i++){
- dis = points[j].x*planes[i].x + points[j].y*planes[i].y +
- points[j].z*planes[i].z + planes[i].w;
- if( dis > 0.0 ) {
- planes[i].w += -dis;
- }
- }
- }
-
- computeAllVerts();
- }
-
- /**
- * Modifies the bounding polytope so that it bounds the volume
- * generated by transforming the given bounding object.
- * @param boundsObject the bounding object to be transformed
- * @param matrix a transformation matrix
- */
- @Override
- public void transform( Bounds boundsObject, Transform3D matrix) {
-
- if( boundsObject == null || boundsObject.boundsIsEmpty) {
- boundsIsEmpty = true;
- boundsIsInfinite = false;
- computeAllVerts();
- return;
- }
-
- if(boundsObject.boundsIsInfinite) {
- this.set(boundsObject);
- return;
- }
-
- if( boundsObject.boundId == BOUNDING_SPHERE ) {
- BoundingSphere sphere = new BoundingSphere(boundsObject);
- sphere.transform(matrix);
- this.set(sphere);
- } else if( boundsObject.boundId == BOUNDING_BOX){
- BoundingBox box = new BoundingBox(boundsObject);
- box.transform(matrix);
- this.set(box);
- } else if(boundsObject.boundId == BOUNDING_POLYTOPE) {
- BoundingPolytope polytope = new BoundingPolytope(boundsObject);
- polytope.transform(matrix);
- this.set(polytope);
- } else {
- throw new IllegalArgumentException(J3dI18N.getString("BoundingPolytope5"));
- }
- }
-
- /**
- * Transforms this bounding polytope by the given transformation matrix.
- * @param matrix a transformation matrix
- */
- @Override
- public void transform( Transform3D matrix) {
-
- if(boundsIsInfinite)
- return;
-
- int i;
- double invMag;
- Transform3D invTrans = new Transform3D(matrix);
-
- invTrans.invert();
- invTrans.transpose();
-
- for(i = 0; i < planes.length; i++){
- planes[i].x = planes[i].x * mag[i];
- planes[i].y = planes[i].y * mag[i];
- planes[i].z = planes[i].z * mag[i];
- planes[i].w = planes[i].w * mag[i];
- invTrans.transform( planes[i] );
- }
-
- for(i=0;i<planes.length;i++) {
-
- // normalize the plane normals
- mag[i] = Math.sqrt(planes[i].x*planes[i].x + planes[i].y*planes[i].y +
- planes[i].z*planes[i].z);
- invMag = 1.0/mag[i];
- this.planes[i] = new Vector4d( planes[i].x*invMag, planes[i].y*invMag,
- planes[i].z*invMag, planes[i].w*invMag );
-
- }
-
- for (i=0; i < verts.length; i++) {
- matrix.transform(verts[i]);
- }
-
- }
-
- /**
- * Test for intersection with a ray.
- * @param origin is a the starting point of the ray
- * @param direction is the direction of the ray
- * @param intersectPoint is a point defining the location of the intersection
- * @return true or false indicating if an intersection occured
- */
- boolean intersect(Point3d origin, Vector3d direction, Point3d intersectPoint ) {
-
- double t,v0,vd,x,y,z,invMag;
- double dx, dy, dz;
- int i;
-
- if( boundsIsEmpty ) {
- return false;
- }
-
- if( boundsIsInfinite ) {
- intersectPoint.x = origin.x;
- intersectPoint.y = origin.y;
- intersectPoint.z = origin.z;
- return true;
- }
-
- invMag = 1.0/Math.sqrt(direction.x*direction.x +
- direction.y*direction.y + direction.z*direction.z);
- dx = direction.x*invMag;
- dy = direction.y*invMag;
- dz = direction.z*invMag;
-
- // compute intersection point of ray and each plane then test if point is in polytope
- for(i=0;i<planes.length;i++) {
- vd = planes[i].x*dx + planes[i].y*dy + planes[i].z*dz;
- v0 = -(planes[i].x*origin.x + planes[i].y*origin.y +
- planes[i].z*origin.z + planes[i].w);
- if(vd != 0.0) { // ray is parallel to plane
- t = v0/vd;
-
- if( t >= 0.0) { // plane is behind origin
-
- x = origin.x + dx*t; // compute intersection point
- y = origin.y + dy*t;
- z = origin.z + dz*t;
-
- if( pointInPolytope(x,y,z) ) {
- intersectPoint.x = x;
- intersectPoint.y = y;
- intersectPoint.z = z;
- return true; // ray intersects a face of polytope
- }
- }
- }
- }
-
- return false;
- }
-
- /**
- * Test for intersection with a ray
- * @param origin is a the starting point of the ray
- * @param direction is the direction of the ray
- * @param position is a point defining the location of the pick w= distance to pick
- * @return true or false indicating if an intersection occured
- */
- @Override
- boolean intersect(Point3d origin, Vector3d direction, Point4d position ) {
- double t,v0,vd,x,y,z,invMag;
- double dx, dy, dz;
- int i;
-
- if( boundsIsEmpty ) {
- return false;
- }
-
- if( boundsIsInfinite ) {
- position.x = origin.x;
- position.y = origin.y;
- position.z = origin.z;
- position.w = 0.0;
- return true;
- }
-
- invMag = 1.0/Math.sqrt(direction.x*direction.x + direction.y*
- direction.y + direction.z*direction.z);
- dx = direction.x*invMag;
- dy = direction.y*invMag;
- dz = direction.z*invMag;
-
- for(i=0;i<planes.length;i++) {
- vd = planes[i].x*dx + planes[i].y*dy + planes[i].z*dz;
- v0 = -(planes[i].x*origin.x + planes[i].y*origin.y +
- planes[i].z*origin.z + planes[i].w);
- // System.err.println("v0="+v0+" vd="+vd);
- if(vd != 0.0) { // ray is parallel to plane
- t = v0/vd;
-
- if( t >= 0.0) { // plane is behind origin
-
- x = origin.x + dx*t; // compute intersection point
- y = origin.y + dy*t;
- z = origin.z + dz*t;
- // System.err.println("t="+t+" point="+x+" "+y+" "+z);
-
- if( pointInPolytope(x,y,z) ) {
- position.x = x;
- position.y = y;
- position.z = z;
- position.w = t;
- return true; // ray intersects a face of polytope
- }
- }
- }
- }
-
- return false;
-
- }
-
- /**
- * Test for intersection with a point
- * @param point is the pick point
- * @param position is a point defining the location of the pick w= distance to pick
- * @return true or false indicating if an intersection occured
- */
- @Override
- boolean intersect(Point3d point, Point4d position ) {
- int i;
-
- if( boundsIsEmpty ) {
- return false;
- }
-
- if( boundsIsInfinite ) {
- position.x = point.x;
- position.y = point.y;
- position.z = point.z;
- position.w = 0.0;
- return true;
- }
-
- for(i = 0; i < this.planes.length; i++){
- if(( point.x*this.planes[i].x +
- point.y*this.planes[i].y +
- point.z*this.planes[i].z + planes[i].w ) > 0.0 )
- return false;
-
- }
- return true;
-
- }
-
- /**
- * Test for intersection with a segment
- * @param start is a point defining the start of the line segment
- * @param end is a point defining the end of the line segment
- * @param position is a point defining the location of the pick w= distance to pick
- * @return true or false indicating if an intersection occured
- */
- @Override
- boolean intersect( Point3d start, Point3d end, Point4d position ) {
- double t,v0,vd,x,y,z;
- int i;
-
- //System.err.println("line segment intersect : planes.length " + planes.length);
-
- if( boundsIsEmpty ) {
- return false;
- }
-
- if( boundsIsInfinite ) {
- position.x = start.x;
- position.y = start.y;
- position.z = start.z;
- position.w = 0.0;
- return true;
- }
-
- Point3d direction = new Point3d();
-
- direction.x = end.x - start.x;
- direction.y = end.y - start.y;
- direction.z = end.z - start.z;
-
- for(i=0;i<planes.length;i++) {
- vd = planes[i].x*direction.x + planes[i].y*direction.y +
- planes[i].z*direction.z;
- v0 = -(planes[i].x*start.x + planes[i].y*start.y +
- planes[i].z*start.z + planes[i].w);
- // System.err.println("v0="+v0+" vd="+vd);
- if(vd != 0.0) { // ray is parallel to plane
- t = v0/vd;
-
- // System.err.println("t is " + t);
-
- if( t >= 0.0) { // plane is behind start
-
- x = start.x + direction.x*t; // compute intersection point
- y = start.y + direction.y*t;
- z = start.z + direction.z*t;
- // System.err.println("t="+t+" point="+x+" "+y+" "+z);
-
- if( pointInPolytope(x,y,z) ) {
- // if((t*t) > (end.x-start.x)*(end.x-start.x) +
- // (end.y-start.y)*(end.y-start.y) +
- // (end.z-start.z)*(end.z-start.z)) {
- if(t <= 1.0) {
- position.x = x;
- position.y = y;
- position.z = z;
- position.w = t;
- return true; // ray intersects a face of polytope
- }
- }
- }
- }
- }
-
- return false;
-
- }
-
- /**
- * Test for intersection with a ray.
- * @param origin the starting point of the ray
- * @param direction the direction of the ray
- * @return true or false indicating if an intersection occured
- */
- @Override
- public boolean intersect(Point3d origin, Vector3d direction ) {
-
- // compute intersection point of ray and each plane then test if point is in polytope
-
- double t,v0,vd,x,y,z;
- int i;
-
- if( boundsIsEmpty ) {
- return false;
- }
-
- if( boundsIsInfinite ) {
- return true;
- }
-
- for(i=0;i<planes.length;i++) {
- vd = planes[i].x*direction.x + planes[i].y*direction.y +
- planes[i].z*direction.z;
- v0 = -(planes[i].x*origin.x + planes[i].y*origin.y +
- planes[i].z*origin.z + planes[i].w);
- if(vd != 0.0) { // ray is parallel to plane
- t = v0/vd;
-
- if( t >= 0.0) { // plane is behind origin
-
- x = origin.x + direction.x*t; // compute intersection point
- y = origin.y + direction.y*t;
- z = origin.z + direction.z*t;
-
- if( pointInPolytope(x,y,z) ) {
- return true; // ray intersects a face of polytope
- } else {
- // System.err.println("point outside polytope");
- }
- }
- }
- }
-
- return false;
-
- }
-
- /**
- * Tests whether the bounding polytope is empty. A bounding polytope is
- * empty if it is null (either by construction or as the result of
- * a null intersection) or if its volume is negative. A bounding polytope
- * with a volume of zero is <i>not</i> empty.
- * @return true if the bounding polytope is empty;
- * otherwise, it returns false
- */
- @Override
- public boolean isEmpty() {
- // if nVerts > 0 after computeAllVerts(), that means
- // there is some intersection between 3 planes.
- return (boundsIsEmpty || (nVerts <= 0));
- }
-
- /**
- * Test for intersection with a point.
- * @param point a Point defining a position in 3-space
- * @return true or false indicating if an intersection occured
- */
- @Override
- public boolean intersect(Point3d point ) {
-
- int i;
- if( boundsIsEmpty ) {
- return false;
- }
- if( boundsIsInfinite ) {
- return true;
- }
-
- for(i = 0; i < this.planes.length; i++){
- if(( point.x*this.planes[i].x +
- point.y*this.planes[i].y +
- point.z*this.planes[i].z + planes[i].w ) > 0.0 )
- return false;
-
- }
- return true;
- }
-
-
- /**
- * Test for intersection with another bounds object.
- * @param boundsObject another bounds object
- * @return true or false indicating if an intersection occured
- */
- @Override
- boolean intersect(Bounds boundsObject, Point4d position) {
- return intersect(boundsObject);
- }
-
- /**
- * Test for intersection with another bounds object.
- * @param boundsObject another bounds object
- * @return true or false indicating if an intersection occured
- */
- @Override
- public boolean intersect(Bounds boundsObject) {
-
- if( boundsObject == null ) {
- return false;
- }
-
- if( boundsIsEmpty || boundsObject.boundsIsEmpty ) {
- return false;
- }
-
- if( boundsIsInfinite || boundsObject.boundsIsInfinite ) {
- return true;
- }
-
- if( boundsObject.boundId == BOUNDING_SPHERE ) {
- return intersect_ptope_sphere( this, (BoundingSphere)boundsObject);
- } else if( boundsObject.boundId == BOUNDING_BOX){
- return intersect_ptope_abox( this, (BoundingBox)boundsObject);
- } else if(boundsObject.boundId == BOUNDING_POLYTOPE) {
- return intersect_ptope_ptope( this, (BoundingPolytope)boundsObject);
- } else {
- throw new IllegalArgumentException(J3dI18N.getString("BoundingPolytope6"));
- }
- }
-
- /**
- * Test for intersection with another bounds object.
- * @param boundsObjects an array of bounding objects
- * @return true or false indicating if an intersection occured
- */
- @Override
- public boolean intersect(Bounds[] boundsObjects) {
-
- double distsq, radsq;
- BoundingSphere sphere;
- int i;
- if( boundsObjects == null || boundsObjects.length <= 0 ) {
- return false;
- }
-
- if( boundsIsEmpty ) {
- return false;
- }
-
- for(i = 0; i < boundsObjects.length; i++){
- if( boundsObjects[i] == null || boundsObjects[i].boundsIsEmpty) ;
- else if( boundsIsInfinite || boundsObjects[i].boundsIsInfinite ) {
- return true; // We're done here.
- }
- if( boundsObjects[i].boundId == BOUNDING_SPHERE ) {
- sphere = (BoundingSphere)boundsObjects[i];
- radsq = sphere.radius;
- radsq *= radsq;
- distsq = sphere.center.distanceSquared(sphere.center);
- if (distsq < radsq) {
- return true;
- }
- } else if(boundsObjects[i].boundId == BOUNDING_BOX){
- if( this.intersect(boundsObjects[i])) return true;
- } else if(boundsObjects[i].boundId == BOUNDING_POLYTOPE) {
- if( this.intersect(boundsObjects[i])) return true;
- } else {
- throw new IllegalArgumentException(J3dI18N.getString("BoundingPolytope7"));
- }
- }
-
- return false;
- }
- /**
- * Test for intersection with another bounds object.
- * @param boundsObject another bounds object
- * @param newBoundPolytope the new bounding polytope, which is the intersection of
- * the boundsObject and this BoundingPolytope
- * @return true or false indicating if an intersection occured
- */
- public boolean intersect(Bounds boundsObject, BoundingPolytope newBoundPolytope) {
- int i;
-
- if((boundsObject == null) || boundsIsEmpty || boundsObject.boundsIsEmpty ) {
- newBoundPolytope.boundsIsEmpty = true;
- newBoundPolytope.boundsIsInfinite = false;
- newBoundPolytope.computeAllVerts();
- return false;
- }
- if(boundsIsInfinite && (!boundsObject.boundsIsInfinite)) {
- newBoundPolytope.set(boundsObject);
- return true;
- }
- else if((!boundsIsInfinite) && boundsObject.boundsIsInfinite) {
- newBoundPolytope.set(this);
- return true;
- }
- else if(boundsIsInfinite && boundsObject.boundsIsInfinite) {
- newBoundPolytope.set(this);
- return true;
- }
-
-
- BoundingBox tbox = new BoundingBox(); // convert sphere to box
-
- if( boundsObject.boundId == BOUNDING_SPHERE ) {
- BoundingSphere sphere = (BoundingSphere)boundsObject;
- if( this.intersect( sphere)) {
- BoundingBox sbox = new BoundingBox( sphere ); // convert sphere to box
- BoundingBox pbox = new BoundingBox( this ); // convert polytope to box
- pbox.intersect(sbox, tbox); // insersect two boxes
- newBoundPolytope.set( tbox );
- return true;
- }
- } else if( boundsObject.boundId == BOUNDING_BOX){
- BoundingBox box = (BoundingBox)boundsObject;
- if( this.intersect( box)) {
- BoundingBox pbox = new BoundingBox( this ); // convert polytope to box
- pbox.intersect(box, tbox); // insersect two boxes
- newBoundPolytope.set( tbox );
- return true;
- }
-
- } else if(boundsObject.boundId == BOUNDING_POLYTOPE) {
- BoundingPolytope polytope = (BoundingPolytope)boundsObject;
- if( this.intersect( polytope)) {
- Vector4d newPlanes[] = new Vector4d[planes.length + polytope.planes.length];
- for(i=0;i<planes.length;i++) {
- newPlanes[i] = new Vector4d(planes[i]);
- }
- for(i=0;i<polytope.planes.length;i++) {
- newPlanes[planes.length + i] = new Vector4d(polytope.planes[i]);
- }
- BoundingPolytope newPtope= new BoundingPolytope( newPlanes );
-
- newBoundPolytope.set(newPtope);
- return true;
- }
-
- } else {
- throw new IllegalArgumentException(J3dI18N.getString("BoundingPolytope8"));
- }
-
- newBoundPolytope.boundsIsEmpty = true;
- newBoundPolytope.boundsIsInfinite = false;
- newBoundPolytope.computeAllVerts();
-
- return false;
- }
-
- /**
- * Test for intersection with an array of bounds objects.
- * @param boundsObjects an array of bounds objects
- * @param newBoundingPolytope the new bounding polytope, which is the intersection of
- * the boundsObject and this BoundingPolytope
- * @return true or false indicating if an intersection occured
- */
- public boolean intersect(Bounds[] boundsObjects, BoundingPolytope newBoundingPolytope) {
-
- if( boundsObjects == null || boundsObjects.length <= 0 || boundsIsEmpty ) {
- newBoundingPolytope.boundsIsEmpty = true;
- newBoundingPolytope.boundsIsInfinite = false;
- newBoundingPolytope.computeAllVerts();
- return false;
- }
-
- int i=0;
- // find first non null bounds object
- while( boundsObjects[i] == null && i < boundsObjects.length) {
- i++;
- }
-
- if( i >= boundsObjects.length ) { // all bounds objects were empty
- newBoundingPolytope.boundsIsEmpty = true;
- newBoundingPolytope.boundsIsInfinite = false;
- newBoundingPolytope.computeAllVerts();
- return false;
- }
-
- boolean status = false;
- BoundingBox tbox = new BoundingBox(); // convert sphere to box
-
- for(i=0;i<boundsObjects.length;i++) {
- if( boundsObjects[i] == null || boundsObjects[i].boundsIsEmpty) ;
- else if( boundsObjects[i].boundId == BOUNDING_SPHERE ) {
- BoundingSphere sphere = (BoundingSphere)boundsObjects[i];
- if( this.intersect( sphere)) {
- BoundingBox sbox = new BoundingBox( sphere ); // convert sphere to box
- BoundingBox pbox = new BoundingBox( this ); // convert polytope to box
- pbox.intersect(sbox, tbox); // insersect two boxes
- if ( status ) {
- newBoundingPolytope.combine( tbox );
- } else {
- newBoundingPolytope.set( tbox );
- status = true;
- }
- }
- } else if( boundsObjects[i].boundId == BOUNDING_BOX){
- BoundingBox box = (BoundingBox)boundsObjects[i];
- if( this.intersect( box) ){
- BoundingBox pbox = new BoundingBox( this ); // convert polytope to box
- pbox.intersect(box,tbox); // insersect two boxes
- if ( status ) {
- newBoundingPolytope.combine( tbox );
- } else {
- newBoundingPolytope.set( tbox );
- status = true;
- }
- } else {
- }
-
- } else if(boundsObjects[i].boundId == BOUNDING_POLYTOPE) {
- BoundingPolytope polytope = (BoundingPolytope)boundsObjects[i];
- if( this.intersect( polytope)) {
- Vector4d newPlanes[] = new Vector4d[planes.length + polytope.planes.length];
- for(i=0;i<planes.length;i++) {
- newPlanes[i] = new Vector4d(planes[i]);
- }
- for(i=0;i<polytope.planes.length;i++) {
- newPlanes[planes.length + i] = new Vector4d(polytope.planes[i]);
- }
- BoundingPolytope newPtope= new BoundingPolytope( newPlanes );
- if ( status ) {
- newBoundingPolytope.combine( newPtope );
- } else {
- newBoundingPolytope.set( newPtope );
- status = true;
- }
- }
- } else {
- throw new IllegalArgumentException(J3dI18N.getString("BoundingPolytope8"));
- }
-
- if(newBoundingPolytope.boundsIsInfinite)
- break; // We're done.
-
- }
-
- if( status == false ) {
- newBoundingPolytope.boundsIsEmpty = true;
- newBoundingPolytope.boundsIsInfinite = false;
- newBoundingPolytope.computeAllVerts();
- }
- return status;
-
- }
- /**
- * Finds closest bounding object that intersects this bounding polytope.
- * @param boundsObjects is an array of bounds objects
- * @return closest bounding object
- */
- @Override
- public Bounds closestIntersection( Bounds[] boundsObjects) {
-
- if( boundsObjects == null || boundsObjects.length <= 0 ) {
- return null;
- }
-
- if( boundsIsEmpty ) {
- return null;
- }
-
- double dis,disToPlane;
- boolean contains = false;
- boolean inside;
- double smallest_distance = Double.MAX_VALUE;
- int i,j,index=0;
- double cenX = 0.0, cenY = 0.0, cenZ = 0.0;
-
- for(i = 0; i < boundsObjects.length; i++){
- if( boundsObjects[i] == null );
-
- else if( this.intersect( boundsObjects[i])) {
- if( boundsObjects[i] instanceof BoundingSphere ) {
- BoundingSphere sphere = (BoundingSphere)boundsObjects[i];
- dis = Math.sqrt( (centroid.x-sphere.center.x)*(centroid.x-sphere.center.x) +
- (centroid.y-sphere.center.y)*(centroid.y-sphere.center.y) +
- (centroid.z-sphere.center.z)*(centroid.z-sphere.center.z) );
- inside = true;
- for(j=0;j<planes.length;j++) {
- if( ( sphere.center.x*planes[j].x +
- sphere.center.y*planes[j].y +
- sphere.center.z*planes[j].z + planes[i].w ) > 0.0 ) { // check if sphere center in polytope
- disToPlane = sphere.center.x*planes[j].x +
- sphere.center.y*planes[j].y +
- sphere.center.z*planes[j].z + planes[j].w;
-
- // check if distance from center to plane is larger than radius
- if( disToPlane > sphere.radius ) inside = false;
- }
- }
- if( inside) { // contains the sphere
- if( !contains ){ // initialize smallest_distance for the first containment
- index = i;
- smallest_distance = dis;
- contains = true;
- } else{
- if( dis < smallest_distance){
- index = i;
- smallest_distance = dis;
- }
- }
- } else if (!contains) {
- if( dis < smallest_distance){
- index = i;
- smallest_distance = dis;
- }
- }
- } else if( boundsObjects[i] instanceof BoundingBox){
- BoundingBox box = (BoundingBox)boundsObjects[i];
- cenX = (box.upper.x+box.lower.x)/2.0;
- cenY = (box.upper.y+box.lower.y)/2.0;
- cenZ = (box.upper.z+box.lower.z)/2.0;
- dis = Math.sqrt( (centroid.x-cenX)*(centroid.x-cenX) +
- (centroid.y-cenY)*(centroid.y-cenY) +
- (centroid.z-cenZ)*(centroid.z-cenZ) );
- inside = true;
- if( !pointInPolytope( box.upper.x, box.upper.y, box.upper.z ) ) inside = false;
- if( !pointInPolytope( box.upper.x, box.upper.y, box.lower.z ) ) inside = false;
- if( !pointInPolytope( box.upper.x, box.lower.y, box.upper.z ) ) inside = false;
- if( !pointInPolytope( box.upper.x, box.lower.y, box.lower.z ) ) inside = false;
- if( !pointInPolytope( box.lower.x, box.upper.y, box.upper.z ) ) inside = false;
- if( !pointInPolytope( box.lower.x, box.upper.y, box.lower.z ) ) inside = false;
- if( !pointInPolytope( box.lower.x, box.lower.y, box.upper.z ) ) inside = false;
- if( !pointInPolytope( box.lower.x, box.lower.y, box.lower.z ) ) inside = false;
-
- if( inside ) { // contains box
- if( !contains ){ // initialize smallest_distance for the first containment
- index = i;
- smallest_distance = dis;
- contains = true;
- } else{
- if( dis < smallest_distance){
- index = i;
- smallest_distance = dis;
- }
- }
- } else if (!contains) {
- if( dis < smallest_distance){
- index = i;
- smallest_distance = dis;
- }
- }
-
- } else if(boundsObjects[i] instanceof BoundingPolytope) {
- BoundingPolytope polytope = (BoundingPolytope)boundsObjects[i];
- dis = Math.sqrt( (centroid.x-polytope.centroid.x)*(centroid.x-polytope.centroid.x) +
- (centroid.y-polytope.centroid.y)*(centroid.y-polytope.centroid.y) +
- (centroid.z-polytope.centroid.z)*(centroid.z-polytope.centroid.z) );
- inside = true;
- for(j=0;j<polytope.nVerts;j++) {
- if ( !pointInPolytope( polytope.verts[j].x, polytope.verts[j].y, polytope.verts[j].z ) )
- inside = false;
- }
- if( inside ) {
- if( !contains ){ // initialize smallest_distance for the first containment
- index = i;
- smallest_distance = dis;
- contains = true;
- } else{
- if( dis < smallest_distance){
- index = i;
- smallest_distance = dis;
- }
- }
- } else if (!contains) {
- if( dis < smallest_distance){
- index = i;
- smallest_distance = dis;
- }
- }
-
- } else {
- throw new IllegalArgumentException(J3dI18N.getString("BoundingPolytope10"));
- }
- }
- }
-
- return boundsObjects[index];
- }
-
- /**
- * Returns a string representation of this class
- */
- @Override
- public String toString() {
- int i;
-
- String description = new String("BoundingPolytope:\n Num Planes ="+planes.length);
- for(i = 0; i < planes.length; i++){
- description = description+"\n"+mag[i]*planes[i].x+" "+
- mag[i]*planes[i].y+" "+mag[i]*planes[i].z+" "+mag[i]*planes[i].w;
- }
-
- return description;
- }
-
- private void computeVertex( int a, int b, int c ) {
- double det,x,y,z;
-
- det = planes[a].x*planes[b].y*planes[c].z + planes[a].y*planes[b].z*planes[c].x +
- planes[a].z*planes[b].x*planes[c].y - planes[a].z*planes[b].y*planes[c].x -
- planes[a].y*planes[b].x*planes[c].z - planes[a].x*planes[b].z*planes[c].y;
-
- // System.err.println("\n det="+det);
- if( det*det < EPSILON ){
- // System.err.println("parallel planes="+a+" "+b+" "+c);
- return; // two planes are parallel
- }
-
- det = 1.0/det;
-
- x = (planes[b].y*planes[c].z - planes[b].z*planes[c].y) * pDotN[a];
- y = (planes[b].z*planes[c].x - planes[b].x*planes[c].z) * pDotN[a];
- z = (planes[b].x*planes[c].y - planes[b].y*planes[c].x) * pDotN[a];
-
- x += (planes[c].y*planes[a].z - planes[c].z*planes[a].y) * pDotN[b];
- y += (planes[c].z*planes[a].x - planes[c].x*planes[a].z) * pDotN[b];
- z += (planes[c].x*planes[a].y - planes[c].y*planes[a].x) * pDotN[b];
-
- x += (planes[a].y*planes[b].z - planes[a].z*planes[b].y) * pDotN[c];
- y += (planes[a].z*planes[b].x - planes[a].x*planes[b].z) * pDotN[c];
- z += (planes[a].x*planes[b].y - planes[a].y*planes[b].x) * pDotN[c];
-
- x = x*det;
- y = y*det;
- z = z*det;
-
- if (pointInPolytope( x, y, z ) ) {
- if (nVerts >= verts.length) {
- Point3d newVerts[] = new Point3d[nVerts << 1];
- for(int i=0;i<nVerts;i++) {
- newVerts[i] = verts[i];
- }
- verts = newVerts;
- }
- verts[nVerts++] = new Point3d( x,y,z);
- }
- }
-
-
- private void computeAllVerts() {
- int i,a,b,c;
- double x,y,z;
-
- nVerts = 0;
-
- if( boundsIsEmpty) {
- verts = null;
- return;
- }
-
- verts = new Point3d[planes.length*planes.length];
-
- for(i=0;i<planes.length;i++) {
- pDotN[i] = -planes[i].x*planes[i].w*planes[i].x -
- planes[i].y*planes[i].w*planes[i].y -
- planes[i].z*planes[i].w*planes[i].z;
- }
-
- for(a=0;a<planes.length-2;a++) {
- for(b=a+1;b<planes.length-1;b++) {
- for(c=b+1;c<planes.length;c++) {
- computeVertex(a,b,c);
- }
- }
- }
- // XXXX: correctly compute centroid
-
- x=y=z=0.0;
- Point3d newVerts[] = new Point3d[nVerts];
-
- for(i=0;i<nVerts;i++) {
- x += verts[i].x;
- y += verts[i].y;
- z += verts[i].z;
- // copy the verts into an array of the correct size
- newVerts[i] = verts[i];
- }
-
- this.verts = newVerts; // copy the verts into an array of the correct size
-
- centroid.x = x/nVerts;
- centroid.y = y/nVerts;
- centroid.z = z/nVerts;
-
- checkBoundsIsEmpty();
-
- }
-
- private boolean pointInPolytope( double x, double y, double z ){
-
- for (int i = 0; i < planes.length; i++){
- if(( x*planes[i].x +
- y*planes[i].y +
- z*planes[i].z + planes[i].w ) > EPSILON ) {
- return false;
- }
-
- }
- return true;
- }
-
- private void checkBoundsIsEmpty() {
- boundsIsEmpty = (planes.length < 4);
- }
-
- private void initEmptyPolytope() {
- planes = new Vector4d[6];
- pDotN = new double[6];
- mag = new double[6];
- verts = new Point3d[planes.length*planes.length];
- nVerts = 0;
-
- planes[0] = new Vector4d( 1.0, 0.0, 0.0, -1.0 );
- planes[1] = new Vector4d(-1.0, 0.0, 0.0, -1.0 );
- planes[2] = new Vector4d( 0.0, 1.0, 0.0, -1.0 );
- planes[3] = new Vector4d( 0.0,-1.0, 0.0, -1.0 );
- planes[4] = new Vector4d( 0.0, 0.0, 1.0, -1.0 );
- planes[5] = new Vector4d( 0.0, 0.0,-1.0, -1.0 );
- mag[0] = 1.0;
- mag[1] = 1.0;
- mag[2] = 1.0;
- mag[3] = 1.0;
- mag[4] = 1.0;
- mag[5] = 1.0;
-
- checkBoundsIsEmpty();
- }
-
- @Override
- Point3d getCenter() {
- return centroid;
- }
-
-@Override
-public void getCenter(Point3d center) {
- center.set(centroid);
-}
-
- /**
- * if the passed the "region" is same type as this object
- * then do a copy, otherwise clone the Bounds and
- * return
- */
- @Override
- Bounds copy(Bounds r) {
- int i, k;
-
- if (r != null && this.boundId == r.boundId) {
- BoundingPolytope region = (BoundingPolytope) r;
- if( region.planes.length !=planes.length) {
- region.planes = new Vector4d[planes.length];
-
- for(k=0;k< region.planes.length;k++)
- region.planes[k] = new Vector4d();
-
- region.mag = new double[planes.length];
- region.pDotN = new double[planes.length];
- region.verts = new Point3d[nVerts];
- region.nVerts = nVerts;
- for(k=0;k<nVerts;k++)
- region.verts[k] = new Point3d(verts[k]);
- }
-
-
- for(i=0;i<planes.length;i++) {
- region.planes[i].x = planes[i].x;
- region.planes[i].y = planes[i].y;
- region.planes[i].z = planes[i].z;
- region.planes[i].w = planes[i].w;
- region.mag[i] = mag[i];
- }
-
- region.boundsIsEmpty = boundsIsEmpty;
- region.boundsIsInfinite = boundsIsInfinite;
- return region;
- }
- else {
- return (Bounds) this.clone();
- }
- }
-
- @Override
- int getPickType() {
- return PickShape.PICKBOUNDINGPOLYTOPE;
- }
-}