diff options
Diffstat (limited to 'src/javax/media/j3d/Bounds.java')
-rw-r--r-- | src/javax/media/j3d/Bounds.java | 673 |
1 files changed, 0 insertions, 673 deletions
diff --git a/src/javax/media/j3d/Bounds.java b/src/javax/media/j3d/Bounds.java deleted file mode 100644 index 9672859..0000000 --- a/src/javax/media/j3d/Bounds.java +++ /dev/null @@ -1,673 +0,0 @@ -/* - * Copyright 1996-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.Matrix3d; -import javax.vecmath.Point3d; -import javax.vecmath.Point4d; -import javax.vecmath.Vector3d; -import javax.vecmath.Vector4d; - -/** - * The abstract base class for bounds objects. Bounds objects define - * a convex, closed volume that is used for various intersection and - * culling operations. - */ - -public abstract class Bounds extends Object implements Cloneable { - static final double EPSILON = .000001; - static final boolean debug = false; - - static final int BOUNDING_BOX = 0x1; - static final int BOUNDING_SPHERE = 0x2; - static final int BOUNDING_POLYTOPE = 0x4; - - boolean boundsIsEmpty = false; - boolean boundsIsInfinite = false; - int boundId = 0; - - /** - * Constructs a new Bounds object. - */ - public Bounds() { - } - - - /** - * Makes a copy of a bounds object. - */ - @Override - public abstract Object clone(); - - - /** - * Indicates whether the specified <code>bounds</code> object is - * equal to this Bounds object. They are equal if both the - * specified <code>bounds</code> object and this Bounds are - * instances of the same Bounds subclass and all of the data - * members of <code>bounds</code> are equal to the corresponding - * data members in this Bounds. - * @param bounds the object with which the comparison is made. - * @return true if this Bounds object is equal to <code>bounds</code>; - * otherwise false - * - * @since Java 3D 1.2 - */ - @Override - public abstract boolean equals(Object bounds); - - - /** - * Returns a hash code for this Bounds object based on the - * data values in this object. Two different Bounds objects of - * the same type with identical data values (i.e., Bounds.equals - * returns true) will return the same hash code. Two Bounds - * objects with different data members may return the same hash code - * value, although this is not likely. - * @return a hash code for this Bounds object. - * - * @since Java 3D 1.2 - */ - @Override - public abstract int hashCode(); - - - /** - * 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 - */ - public abstract boolean intersect( Point3d origin, Vector3d direction ); - - /** - * 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 - */ - public abstract boolean intersect( Point3d point ); - - /** - * 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 - */ - abstract boolean intersect( Point3d origin, Vector3d direction, Point4d position ); - - /** - * Test for intersection with a point - * @param point is a point defining a position in 3-space - * @param position is a point defining the location of the pick w= distance to pick - * @return true or false indicating if an intersection occured - */ - abstract boolean intersect( Point3d point, Point4d position); - - /** - * 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 - */ - abstract boolean intersect( Point3d start, Point3d end, Point4d position ); - - /** - * Test for intersection with another bounds object - * - * Test for intersection with another bounds object - * @param boundsObject is another bounds object - * @return true or false indicating if an intersection occured - */ - abstract boolean intersect( Bounds boundsObject, Point4d position ); - - /** - * Test for intersection with another bounds object. - * @param boundsObject another bounds object - * @return true or false indicating if an intersection occurred - */ - public abstract boolean intersect( Bounds boundsObject ); - - /** - * Test for intersection with another bounds object. - * @param boundsObjects an array of bounding objects - * @return true or false indicating if an intersection occured - */ - public abstract boolean intersect( Bounds[] boundsObjects ); - - - /** - * Finds closest bounding object that intersects this bounding object. - * @param boundsObjects an array of bounds objects - * @return closest bounding object - */ - public abstract Bounds closestIntersection( Bounds[] boundsObjects); - -/** - * Returns the center of the bounds - * @return bounds center - */ -abstract Point3d getCenter(); - -/** - * Gets the centroid of this bounding region. - * @param center a Point to receive the centroid of the bounding region - */ -public abstract void getCenter(Point3d center); - - /** - * Combines this bounding object with a bounding object so that the - * resulting bounding object encloses the original bounding object and the - * given bounds object. - * @param boundsObject another bounds object - */ - public abstract void combine( Bounds boundsObject ); - - - /** - * Combines this bounding object with an array of bounding objects so that the - * resulting bounding object encloses the original bounding object and the - * given array of bounds object. - * @param boundsObjects an array of bounds objects - */ - public abstract void combine( Bounds[] boundsObjects); - - /** - * Combines this bounding object with a point. - * @param point a 3d point in space - */ - public abstract void combine( Point3d point); - - /** - * Combines this bounding object with an array of points. - * @param points an array of 3d points in space - */ - public abstract void combine( Point3d[] points); - - /** - * Transforms this bounding object by the given matrix. - * @param trans the transformation matrix - */ - public abstract void transform(Transform3D trans); - - /** - * Modifies the bounding object so that it bounds the volume - * generated by transforming the given bounding object. - * @param bounds the bounding object to be transformed - * @param trans the transformation matrix - */ - public abstract void transform( Bounds bounds, Transform3D trans); - - /** - * Tests whether the bounds is empty. A bounds is - * empty if it is null (either by construction or as the result of - * a null intersection) or if its volume is negative. A bounds - * with a volume of zero is <i>not</i> empty. - * @return true if the bounds is empty; otherwise, it returns false - */ - public abstract boolean isEmpty(); - - /** - * Sets the value of this Bounds object. - * @param boundsObject another bounds object. - */ - public abstract void set( Bounds boundsObject); - - - abstract Bounds copy(Bounds region); - - - private void test_point(Vector4d[] planes, Point3d new_point) { - for (int i = 0; i < planes.length; i++){ - double dist = (new_point.x*planes[i].x + new_point.y*planes[i].y + - new_point.z*planes[i].z + planes[i].w ) ; - if (dist > EPSILON ){ - System.err.println("new point is outside of" + - " plane["+i+"] dist = " + dist); - } - } - } - - /** - * computes the closest point from the given point to a set of planes - * (polytope) - * @param g the point - * @param planes array of bounding planes - * @param new_point point on planes closest g - */ - boolean closest_point( Point3d g, Vector4d[] planes, Point3d new_point ) { - - double t,s,dist,w; - boolean converged, inside, firstPoint, firstInside; - int i,count; - double ab,ac,bc,ad,bd,cd,aa,bb,cc; - double b1,b2,b3,d1,d2,d3,y1,y2,y3; - double h11,h12,h13,h22,h23,h33; - double l12,l13,l23; - Point3d n = new Point3d(); - Point3d p = new Point3d(); - Vector3d delta = null; - - // These are temporary until the solve code is working - - - /* - * The algorithm: - * We want to find the point "n", closest to "g", while still within - * the the polytope defined by "planes". We find the solution by - * minimizing the value for a "penalty function"; - * - * f = distance(n,g)^2 + sum for each i: w(distance(n, planes[i])) - * - * Where "w" is a weighting which indicates how much more important - * it is to be close to the planes than it is to be close to "g". - * - * We minimize this function by taking it's derivitive, and then - * solving for the value of n when the derivitive equals 0. - * - * For the 1D case with a single plane (a,b,c,d), x = n.x and g = g.x, - * this looks like: - * - * f(x) = (x - g) ^ 2 + w(ax + d)^2 - * f'(x) = 2x -2g + 2waax + 2wad - * - * (note aa = a^2) setting f'(x) = 0 gives: - * - * (1 + waa)x = g - wad - * - * Note that the solution is just outside the plane [a, d]. With the - * correct choice of w, this should be inside of the EPSILON tolerance - * outside the planes. - * - * Extending to 3D gives the matrix solution: - * - * | (1 + waa) wab wac | - * H = | wab (1 + wbb) wbc | - * | wac wbc (1 + wcc) | - * - * b = [g.x - wad, g.y - wbd, g.z - wcd] - * - * H * n = b - * - * n = b * H.inverse() - * - * The implementation speeds this process up by recognizing that - * H is symmetric, so that it can be decomposed into three matrices: - * - * H = L * D * L.transpose() - * - * 1.0 0.0 0.0 d1 0.0 0.0 - * L = l12 1.0 0.0 D = 0.0 d2 0.0 - * l13 l23 1.0 0.0 0.0 d3 - * - * n can then be derived by back-substitution, where the original - * problem is decomposed as: - * - * H * n = b - * L * D * L.transpose() * n = b - * L * D * y = b; L.transpose() * n = y - * - * We can then multiply out the terms of L * D and solve for y, and - * then use y to solve for n. - */ - - w=100.0 / EPSILON; // must be large enough to ensure that solution - // is within EPSILON of planes - - count = 0; - p.set(g); - - if (debug) { - System.err.println("closest_point():\nincoming g="+" "+g.x+" "+g.y+ - " "+g.z); - } - - converged = false; - firstPoint = true; - firstInside = false; - - Vector4d pln; - - while( !converged ) { - if (debug) { - System.err.println("start: p="+" "+p.x+" "+p.y+" "+p.z); - } - - // test the current point against the planes, for each - // plane that is violated, add it's contribution to the - // penalty function - inside = true; - aa=0.0; bb=0.0; cc=0.0; - ab=0.0; ac=0.0; bc=0.0; ad=0.0; bd=0.0; cd=0.0; - for(i = 0; i < planes.length; i++){ - pln = planes[i]; - dist = (p.x*pln.x + p.y*pln.y + - p.z*pln.z + pln.w ) ; - // if point is outside or within EPSILON of the boundary, add - // the plane to the penalty matrix. We do this even if the - // point is already inside the polytope to prevent numerical - // instablity in cases where the point is just outside the - // boundary of several planes of the polytope - if (dist > -EPSILON ){ - aa = aa + pln.x * pln.x; - bb = bb + pln.y * pln.y; - cc = cc + pln.z * pln.z; - ab = ab + pln.x * pln.y; - ac = ac + pln.x * pln.z; - bc = bc + pln.y * pln.z; - ad = ad + pln.x * pln.w; - bd = bd + pln.y * pln.w; - cd = cd + pln.z * pln.w; - } - // If the point is inside if dist is <= EPSILON - if (dist > EPSILON ){ - inside = false; - if (debug) { - System.err.println("point outside plane["+i+"]=("+ - pln.x+ ","+pln.y+",\n\t"+pln.z+ - ","+ pln.w+")\ndist = " + dist); - } - } - } - // see if we are done - if (inside) { - if (debug) { - System.err.println("p is inside"); - } - if (firstPoint) { - firstInside = true; - } - new_point.set(p); - converged = true; - } else { // solve for a closer point - firstPoint = false; - - // this is the upper right corner of H, which is all we - // need to do the decomposition since the matrix is symetric - h11 = 1.0 + aa * w; - h12 = ab * w; - h13 = ac * w; - h22 = 1.0 + bb * w; - h23 = bc * w; - h33 = 1.0 + cc * w; - - if (debug) { - System.err.println(" hessin= "); - System.err.println(h11+" "+h12+" "+h13); - System.err.println(" "+h22+" "+h23); - System.err.println(" "+h33); - } - - // these are the constant terms - b1 = g.x - w * ad; - b2 = g.y - w * bd; - b3 = g.z - w * cd; - - if (debug) { - System.err.println(" b1,b2,b3 = "+b1+" "+b2+" " +b3); - } - - // solve, d1, d2, d3 actually 1/dx, which is more useful - d1 = 1/h11; - l12 = d1 * h12; - l13 = d1 * h13; - s = h22-l12*h12; - d2 = 1/s; - t = h23-h12*l13; - l23 = d2 * t; - d3 = 1/(h33 - h13*l13 - t*l23); - - if (debug) { - System.err.println(" l12,l13,l23 "+l12+" "+l13+" "+l23); - System.err.println(" d1,d2,d3 "+ d1+" "+d2+" "+d3); - } - - // we have L and D, now solve for y - y1 = d1 * b1; - y2 = d2 * (b2 - h12*y1); - y3 = d3 * (b3 - h13*y1 - t*y2); - - if (debug) { - System.err.println(" y1,y2,y3 = "+y1+" "+y2+" "+y3); - } - - // we have y, solve for n - n.z = y3; - n.y = (y2 - l23*n.z); - n.x = (y1 - l13*n.z - l12*n.y); - - if (debug) { - System.err.println("new point = " + n.x+" " + n.y+" " + - n.z); - test_point(planes, n); - - if (delta == null) delta = new Vector3d(); - delta.sub(n, p); - delta.normalize(); - System.err.println("p->n direction: " + delta); - Matrix3d hMatrix = new Matrix3d(); - // check using the the javax.vecmath routine - hMatrix.m00 = h11; - hMatrix.m01 = h12; - hMatrix.m02 = h13; - hMatrix.m10 = h12; // h21 = h12 - hMatrix.m11 = h22; - hMatrix.m12 = h23; - hMatrix.m20 = h13; // h31 = h13 - hMatrix.m21 = h23; // h32 = h22 - hMatrix.m22 = h33; - hMatrix.invert(); - Point3d check = new Point3d(b1, b2, b3); - hMatrix.transform(check); - - System.err.println("check point = " + check.x+" " + - check.y+" " + check.z); - } - - // see if we have converged yet - dist = (p.x-n.x)*(p.x-n.x) + (p.y-n.y)*(p.y-n.y) + - (p.z-n.z)*(p.z-n.z); - - if (debug) { - System.err.println("p->n distance =" + dist ); - } - - if( dist < EPSILON) { // close enough - converged = true; - new_point.set(n); - } else { - p.set(n); - count++; - if(count > 4 ){ // watch for cycling between two minimums - new_point.set(n); - converged = true; - } - } - } - } - if (debug) { - System.err.println("returning pnt ("+new_point.x+" "+ - new_point.y+" "+new_point.z+")"); - - if(firstInside) System.err.println("input point inside polytope "); - } - return firstInside; - } - - boolean intersect_ptope_sphere( BoundingPolytope polyTope, - BoundingSphere sphere) { - Point3d p = new Point3d(); - boolean inside; - - - if (debug) { - System.err.println("ptope_sphere intersect sphere ="+sphere); - } - inside = closest_point( sphere.center, polyTope.planes, p ); - if (debug) { - System.err.println("ptope sphere intersect point ="+p); - } - if (!inside){ - // if distance between polytope and sphere center is greater than - // radius then no intersection - if (p.distanceSquared( sphere.center) > - sphere.radius*sphere.radius){ - if (debug) { - System.err.println("ptope_sphere returns false"); - } - return false; - } else { - if (debug) { - System.err.println("ptope_sphere returns true"); - } - return true; - } - } else { - if (debug) { - System.err.println("ptope_sphere returns true"); - } - return true; - } - } - - boolean intersect_ptope_abox( BoundingPolytope polyTope, BoundingBox box) { - Vector4d planes[] = new Vector4d[6]; - - if (debug) { - System.err.println("ptope_abox, box = " + box); - } - planes[0] = new Vector4d( -1.0, 0.0, 0.0, box.lower.x); - planes[1] = new Vector4d( 1.0, 0.0, 0.0,-box.upper.x); - planes[2] = new Vector4d( 0.0,-1.0, 0.0, box.lower.y); - planes[3] = new Vector4d( 0.0, 1.0, 0.0,-box.upper.y); - planes[4] = new Vector4d( 0.0, 0.0,-1.0, box.lower.z); - planes[5] = new Vector4d( 0.0, 0.0, 1.0,-box.upper.z); - - - BoundingPolytope pbox = new BoundingPolytope( planes); - - boolean result = intersect_ptope_ptope( polyTope, pbox ); - if (debug) { - System.err.println("ptope_abox returns " + result); - } - return(result); - } - - - boolean intersect_ptope_ptope( BoundingPolytope poly1, - BoundingPolytope poly2) { - boolean intersect; - Point3d p = new Point3d(); - Point3d g = new Point3d(); - Point3d gnew = new Point3d(); - Point3d pnew = new Point3d(); - - intersect = false; - - p.x = 0.0; - p.y = 0.0; - p.z = 0.0; - - // start from an arbitrary point on poly1 - closest_point( p, poly1.planes, g); - - // get the closest points on each polytope - if (debug) { - System.err.println("ptope_ptope: first g = "+g); - } - intersect = closest_point( g, poly2.planes, p); - - if (intersect) { - return true; - } - - if (debug) { - System.err.println("first p = "+p+"\n"); - } - intersect = closest_point( p, poly1.planes, gnew); - if (debug) { - System.err.println("gnew = "+gnew+" intersect="+intersect); - } - - // loop until the closest points on the two polytopes are not changing - - double prevDist = p.distanceSquared(g); - double dist; - - while( !intersect ) { - - dist = p.distanceSquared(gnew); - - if (dist < prevDist) { - g.set(gnew); - intersect = closest_point( g, poly2.planes, pnew ); - if (debug) { - System.err.println("pnew = "+pnew+" intersect="+intersect); - } - } else { - g.set(gnew); - break; - } - prevDist = dist; - dist = pnew.distanceSquared(g); - - if (dist < prevDist) { - p.set(pnew); - if( !intersect ) { - intersect = closest_point( p, poly1.planes, gnew ); - if (debug) { - System.err.println("gnew = "+gnew+" intersect="+ - intersect); - } - } - } else { - p.set(pnew); - break; - } - prevDist = dist; - } - - if (debug) { - System.err.println("gnew="+" "+gnew.x+" "+gnew.y+" "+gnew.z); - System.err.println("pnew="+" "+pnew.x+" "+pnew.y+" "+pnew.z); - } - return intersect; - } - - - synchronized void setWithLock(Bounds b) { - this.set(b); - } - - synchronized void getWithLock(Bounds b) { - b.set(this); - } - - // Return one of Pick Bounds type define in PickShape - abstract int getPickType(); -} |