📄 boundingbox.java
字号:
if( polytope.verts[i].z < lower.z ) lower.z = polytope.verts[i].z; if( polytope.verts[i].x > upper.x ) upper.x = polytope.verts[i].x; if( polytope.verts[i].y > upper.y ) upper.y = polytope.verts[i].y; if( polytope.verts[i].z > upper.z ) upper.z = polytope.verts[i].z; } } else { throw new IllegalArgumentException(J3dI18N.getString("BoundingBox3")); } updateBoundsStates(); } /** * Combines this bounding box with an array of bounding objects * so that the resulting bounding box encloses the original bounding * box and the array of bounding objects. * @param bounds an array of bounds objects */ public void combine(Bounds[] bounds) { int i=0; if( (bounds == null) || (bounds.length <= 0) || (boundsIsInfinite)) return; // find first non empty bounds object while( (i<bounds.length) && ((bounds[i]==null) || bounds[i].boundsIsEmpty)) { i++; } if( i >= bounds.length) return; // no non empty bounds so do not modify current bounds if(boundsIsEmpty) this.set(bounds[i++]); if(boundsIsInfinite) return; for(;i<bounds.length;i++) { if( bounds[i] == null ); // do nothing else if( bounds[i].boundsIsEmpty); // do nothing else if( bounds[i].boundsIsInfinite ) { lower.x = lower.y = lower.z = Double.NEGATIVE_INFINITY; upper.x = upper.y = upper.z = Double.POSITIVE_INFINITY; break; // We're done. } else if( bounds[i].boundId == BOUNDING_BOX){ BoundingBox box = (BoundingBox)bounds[i]; if( lower.x > box.lower.x) lower.x = box.lower.x; if( lower.y > box.lower.y) lower.y = box.lower.y; if( lower.z > box.lower.z) lower.z = box.lower.z; if( upper.x < box.upper.x) upper.x = box.upper.x; if( upper.y < box.upper.y) upper.y = box.upper.y; if( upper.z < box.upper.z) upper.z = box.upper.z; } else if( bounds[i].boundId == BOUNDING_SPHERE ) { BoundingSphere sphere = (BoundingSphere)bounds[i]; if( lower.x > (sphere.center.x - sphere.radius)) lower.x = sphere.center.x - sphere.radius; if( lower.y > (sphere.center.y - sphere.radius)) lower.y = sphere.center.y - sphere.radius; if( lower.z > (sphere.center.z - sphere.radius)) lower.z = sphere.center.z - sphere.radius; if( upper.x < (sphere.center.x + sphere.radius)) upper.x = sphere.center.x + sphere.radius; if( upper.y < (sphere.center.y + sphere.radius)) upper.y = sphere.center.y + sphere.radius; if( upper.z < (sphere.center.z + sphere.radius)) upper.z = sphere.center.z + sphere.radius; } else if(bounds[i].boundId == BOUNDING_POLYTOPE) { BoundingPolytope polytope = (BoundingPolytope)bounds[i]; for(i=1;i<polytope.nVerts;i++) { if( polytope.verts[i].x < lower.x ) lower.x = polytope.verts[i].x; if( polytope.verts[i].y < lower.y ) lower.y = polytope.verts[i].y; if( polytope.verts[i].z < lower.z ) lower.z = polytope.verts[i].z; if( polytope.verts[i].x > upper.x ) upper.x = polytope.verts[i].x; if( polytope.verts[i].y > upper.y ) upper.y = polytope.verts[i].y; if( polytope.verts[i].z > upper.z ) upper.z = polytope.verts[i].z; } } else { throw new IllegalArgumentException(J3dI18N.getString("BoundingBox4")); } } updateBoundsStates(); } /** * Combines this bounding box with a point so that the resulting * bounding box encloses the original bounding box and the point. * @param point a 3d point in space */ public void combine(Point3d point) { if( boundsIsInfinite) { return; } if( boundsIsEmpty) { upper.x = lower.x = point.x; upper.y = lower.y = point.y; upper.z = lower.z = point.z; } else { if( point.x > upper.x) upper.x = point.x; if( point.y > upper.y) upper.y = point.y; if( point.z > upper.z) upper.z = point.z; if( point.x < lower.x) lower.x = point.x; if( point.y < lower.y) lower.y = point.y; if( point.z < lower.z) lower.z = point.z; } updateBoundsStates(); } /** * Combines this bounding box with an array of points so that the * resulting bounding box encloses the original bounding box and the * array of points. * @param points an array of 3d points in space */ public void combine(Point3d[] points) { int i; if( boundsIsInfinite) { return; } if( boundsIsEmpty) { this.setUpper(points[0]); this.setLower(points[0]); } for(i=0;i<points.length;i++) { if( points[i].x > upper.x) upper.x = points[i].x; if( points[i].y > upper.y) upper.y = points[i].y; if( points[i].z > upper.z) upper.z = points[i].z; if( points[i].x < lower.x) lower.x = points[i].x; if( points[i].y < lower.y) lower.y = points[i].y; if( points[i].z < lower.z) lower.z = points[i].z; } updateBoundsStates(); } /** * Modifies the bounding box 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 */ public void transform( Bounds boundsObject, Transform3D matrix) { if( boundsObject == null || boundsObject.boundsIsEmpty) { // Negative volume. lower.x = lower.y = lower.z = 1.0d; upper.x = upper.y = upper.z = -1.0d; updateBoundsStates(); return; } if(boundsObject.boundsIsInfinite) { lower.x = lower.y = lower.z = Double.NEGATIVE_INFINITY; upper.x = upper.y = upper.z = Double.POSITIVE_INFINITY; updateBoundsStates(); return; } if(boundsObject.boundId == BOUNDING_BOX){ if (tmpBox == null) { tmpBox = new BoundingBox( (BoundingBox)boundsObject); } else { tmpBox.set((BoundingBox)boundsObject); } tmpBox.transform(matrix); this.set(tmpBox); } else if(boundsObject.boundId == BOUNDING_SPHERE) { if (tmpSphere == null) { tmpSphere = new BoundingSphere( (BoundingSphere)boundsObject); } else { tmpSphere.set((BoundingSphere)boundsObject); } tmpSphere.transform(matrix); this.set(tmpSphere); } else if(boundsObject.boundId == BOUNDING_POLYTOPE) { if (tmpPolytope == null) { tmpPolytope = new BoundingPolytope((BoundingPolytope) boundsObject); } else { tmpPolytope.set((BoundingPolytope)boundsObject); } tmpPolytope.transform(matrix); this.set(tmpPolytope); } else { throw new IllegalArgumentException(J3dI18N.getString("BoundingBox5")); } } /** * Transforms this bounding box by the given matrix. * @param matrix a transformation matrix */ public void transform(Transform3D matrix) { if(boundsIsInfinite) return; double ux, uy, uz, lx, ly, lz; ux = upper.x; uy = upper.y; uz = upper.z; lx = lower.x; ly = lower.y; lz = lower.z; tmpP3d.set(ux, uy, uz); matrix.transform( tmpP3d ); upper.x = tmpP3d.x; upper.y = tmpP3d.y; upper.z = tmpP3d.z; lower.x = tmpP3d.x; lower.y = tmpP3d.y; lower.z = tmpP3d.z; tmpP3d.set(lx, uy, uz); matrix.transform( tmpP3d ); if ( tmpP3d.x > upper.x ) upper.x = tmpP3d.x; if ( tmpP3d.y > upper.y ) upper.y = tmpP3d.y; if ( tmpP3d.z > upper.z ) upper.z = tmpP3d.z; if ( tmpP3d.x < lower.x ) lower.x = tmpP3d.x; if ( tmpP3d.y < lower.y ) lower.y = tmpP3d.y; if ( tmpP3d.z < lower.z ) lower.z = tmpP3d.z; tmpP3d.set(lx, ly, uz); matrix.transform( tmpP3d ); if ( tmpP3d.x > upper.x ) upper.x = tmpP3d.x; if ( tmpP3d.y > upper.y ) upper.y = tmpP3d.y; if ( tmpP3d.z > upper.z ) upper.z = tmpP3d.z; if ( tmpP3d.x < lower.x ) lower.x = tmpP3d.x; if ( tmpP3d.y < lower.y ) lower.y = tmpP3d.y; if ( tmpP3d.z < lower.z ) lower.z = tmpP3d.z; tmpP3d.set(ux, ly, uz); matrix.transform( tmpP3d ); if ( tmpP3d.x > upper.x ) upper.x = tmpP3d.x; if ( tmpP3d.y > upper.y ) upper.y = tmpP3d.y; if ( tmpP3d.z > upper.z ) upper.z = tmpP3d.z; if ( tmpP3d.x < lower.x ) lower.x = tmpP3d.x; if ( tmpP3d.y < lower.y ) lower.y = tmpP3d.y; if ( tmpP3d.z < lower.z ) lower.z = tmpP3d.z; tmpP3d.set(lx, uy, lz); matrix.transform( tmpP3d ); if ( tmpP3d.x > upper.x ) upper.x = tmpP3d.x; if ( tmpP3d.y > upper.y ) upper.y = tmpP3d.y; if ( tmpP3d.z > upper.z ) upper.z = tmpP3d.z; if ( tmpP3d.x < lower.x ) lower.x = tmpP3d.x; if ( tmpP3d.y < lower.y ) lower.y = tmpP3d.y; if ( tmpP3d.z < lower.z ) lower.z = tmpP3d.z; tmpP3d.set(ux, uy, lz); matrix.transform( tmpP3d ); if ( tmpP3d.x > upper.x ) upper.x = tmpP3d.x; if ( tmpP3d.y > upper.y ) upper.y = tmpP3d.y; if ( tmpP3d.z > upper.z ) upper.z = tmpP3d.z; if ( tmpP3d.x < lower.x ) lower.x = tmpP3d.x; if ( tmpP3d.y < lower.y ) lower.y = tmpP3d.y; if ( tmpP3d.z < lower.z ) lower.z = tmpP3d.z; tmpP3d.set(lx, ly, lz); matrix.transform( tmpP3d ); if ( tmpP3d.x > upper.x ) upper.x = tmpP3d.x; if ( tmpP3d.y > upper.y ) upper.y = tmpP3d.y; if ( tmpP3d.z > upper.z ) upper.z = tmpP3d.z; if ( tmpP3d.x < lower.x ) lower.x = tmpP3d.x; if ( tmpP3d.y < lower.y ) lower.y = tmpP3d.y; if ( tmpP3d.z < lower.z ) lower.z = tmpP3d.z; tmpP3d.set(ux, ly, lz); matrix.transform( tmpP3d ); if ( tmpP3d.x > upper.x ) upper.x = tmpP3d.x; if ( tmpP3d.y > upper.y ) upper.y = tmpP3d.y; if ( tmpP3d.z > upper.z ) upper.z = tmpP3d.z; if ( tmpP3d.x < lower.x ) lower.x = tmpP3d.x; if ( tmpP3d.y < lower.y ) lower.y = tmpP3d.y; if ( tmpP3d.z < lower.z ) lower.z = tmpP3d.z; } /** * Test for intersection with a ray. * @param origin the starting point of the ray * @param direction the direction of the ray * @param position3 a point defining the location of the pick w= distance to pick * @return true or false indicating if an intersection occured */ boolean intersect(Point3d origin, Vector3d direction, Point4d position ) { double t1,t2,tmp,tnear,tfar,invDir,invMag; double dirx, diry, dirz; /* System.err.println("BoundingBox.intersect(p,d,p) called\n"); System.err.println("bounds = " + lower + " -> " + upper); */ if( boundsIsEmpty ) { return false; } if( boundsIsInfinite ) { position.x = origin.x; position.y = origin.y; position.z = origin.z; position.w = 0.0; return true; } double dirLen = direction.x*direction.x + direction.y*direction.y + direction.z*direction.z; // Handle zero length direction vector. if(dirLen == 0.0) return intersect(origin, position); invMag = 1.0/Math.sqrt(dirLen); dirx = direction.x*invMag; diry = direction.y*invMag; dirz = direction.z*invMag; /* System.err.println("dir = " + dirx + ", " + diry + ", " + dirz); System.err.println("origin = " + origin); */ // initialize tnear and tfar to handle dir.? == 0 cases tnear = -Double.MAX_VALUE; tfar = Double.MAX_VALUE; if(dirx == 0.0) { //System.err.println("dirx == 0.0"); if (origin.x < lower.x || origin.x > upper.x ) { //System.err.println( "parallel to x plane and outside"); return false; } } else { invDir = 1.0/dirx; t1 = (lower.x-origin.x)*invDir; t2 = (upper.x-origin.x)*invDir; //System.err.println("x t1 = " + t1 + " t2 = " + t2); if( t1 > t2) { tnear = t2; tfar = t1; }else { tnear = t1; tfar = t2; } if( tfar < 0.0 ) { //System.err.println( "x failed: tnear="+tnear+" tfar="+tfar); return false; } //System.err.println("x tnear = " + tnear + " tfar = " + tfar); } // y if (diry == 0.0) { //System.err.println("diry == 0.0"); if( origin.y < lower.y || origin.y > upper.y ){ //System.err.println( "parallel to y plane and outside"); return false; } } else { invDir = 1.0/diry; //System.err.println("invDir = " + invDir); t1 = (lower.y-origin.y)*invDir; t2 = (upper.y-origin.y)*invDir; if( t1 > t2) { tmp = t1; t1 = t2; t2 = tmp; } //System.err.println("y t1 = " + t1 + " t2 = " + t2); if( t1 > tnear) tnear = t1; if( t2 < tfar ) tfar = t2; if( (tfar < 0.0) || (tnear > tfar)){ //System.err.println( "y failed: tnear="+tnear+" tfar="+tfar); return false; } //System.err.println("y tnear = " + tnear + " tfar = " + tfar); } // z if (dirz == 0.0) { //System.err.println("dirz == 0.0"); if( origin.z < lower.z || origin.z > upper.z ) { //System.err.println( "parallel to z plane and outside"); return false; } } else { invDir = 1.0/dirz; t1 = (lower.z-origin.z)*invDir; t2 = (upper.z-origin.z)*invDir; if( t1 > t2) { tmp = t1; t1 = t2; t2 = tmp; } //System.err.println("z t1 = " + t1 + " t2 = " + t2); if( t1 > tnear) tnear = t1; if( t2 < tfar ) tfar = t2; if( (tfar < 0.0) || (tnear > tfar)){ //System.err.println( "z failed: tnear="+tnear+" tfar="+tfar); return false; } //System.err.println("z tnear = " + tnear + " tfar = " + tfar); } if((tnear < 0.0) && (tfar >= 0.0)) { // origin is inside the BBox. position.x = origin.x + dirx*tfar; position.y = origin.y + diry*tfar; position.z = origin.z + dirz*tfar; position.w = tfar; } else { position.x = origin.x + dirx*tnear; position.y = origin.y + diry*tnear; position.z = origin.z + dirz*tnear; position.w = tnear; } return true; } /** * Test for intersection with a point. * @param point the pick point * @param position a point defining the location of the pick w= distance to pick * @return true or false indicating if an intersection occured */ boolean intersect(Point3d point, Point4d position ) { if( boundsIsEmpty ) { return false; } if( boundsIsInfinite ) { position.x = point.x; position.y = point.y; position.z = point.z; position.w = 0.0; return true; } if( point.x <= upper.x && point.x >= lower.x && point.y <= upper.y && point.y >= lower.y && point.z <= upper.z && point.z >= lower.z) { position.x = point.x; position.y = point.y; position.z = point.z; position.w = 0.0; return true; } else return false; } /** * Test for intersection with a segment. * @param start a point defining the start of the line segment * @param end a point defining the end of the line segment * @param position a point defining the location of the pick w= distance to pick
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -